COMPAT_LINUX/powerpc used the native stack setup routine, but now the

native version does non executable mappings on the stack. This is a
showstopper for Linux binaries.

To fix that we supply a copy f the native stack setup function for Linux
binaries, with the executable bit set.
This commit is contained in:
manu 2004-06-16 00:03:25 +00:00
parent 39cf7788fc
commit 6b1a152604
2 changed files with 59 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_exec.h,v 1.16 2003/08/14 02:17:10 christos Exp $ */ /* $NetBSD: linux_exec.h,v 1.17 2004/06/16 00:03:25 manu Exp $ */
/*- /*-
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@ -103,6 +103,6 @@
/* we have special powerpc ELF copyargs */ /* we have special powerpc ELF copyargs */
#define LINUX_MACHDEP_ELF_COPYARGS #define LINUX_MACHDEP_ELF_COPYARGS
#define linux_exec_setup_stack exec_setup_stack int linux_exec_setup_stack(struct proc *, struct exec_package *);
#endif /* !_POWERPC_LINUX_EXEC_H */ #endif /* !_POWERPC_LINUX_EXEC_H */

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_exec_powerpc.c,v 1.12 2003/06/29 22:29:25 fvdl Exp $ */ /* $NetBSD: linux_exec_powerpc.c,v 1.13 2004/06/16 00:03:25 manu Exp $ */
/*- /*-
* Copyright (c) 2001 The NetBSD Foundation, Inc. * Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -48,7 +48,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: linux_exec_powerpc.c,v 1.12 2003/06/29 22:29:25 fvdl Exp $"); __KERNEL_RCSID(0, "$NetBSD: linux_exec_powerpc.c,v 1.13 2004/06/16 00:03:25 manu Exp $");
#if defined (__alpha__) #if defined (__alpha__)
#define ELFSIZE 64 #define ELFSIZE 64
@ -230,3 +230,58 @@ ELFNAME2(linux,copyargs)(p, pack, arginfo, stackp, argp)
return 0; return 0;
} }
/*
* This is copied from sys/kern/exec_subr.c:exec_setup_stack()
* We need a Linux version only to avoid the non executable
* mappings. They will probably break signal delivery on Linux,
* and they surely break the stack fixup hack.
*/
int
linux_exec_setup_stack(p, epp)
struct proc *p;
struct exec_package *epp;
{
u_long max_stack_size;
u_long access_linear_min, access_size;
u_long noaccess_linear_min, noaccess_size;
#ifndef USRSTACK32
#define USRSTACK32 (0x00000000ffffffffL&~PGOFSET)
#endif
if (epp->ep_flags & EXEC_32) {
epp->ep_minsaddr = USRSTACK32;
max_stack_size = MAXSSIZ;
} else {
epp->ep_minsaddr = USRSTACK;
max_stack_size = MAXSSIZ;
}
epp->ep_maxsaddr = (u_long)STACK_GROW(epp->ep_minsaddr,
max_stack_size);
epp->ep_ssize = p->p_rlimit[RLIMIT_STACK].rlim_cur;
/*
* set up commands for stack. note that this takes *two*, one to
* map the part of the stack which we can access, and one to map
* the part which we can't.
*
* arguably, it could be made into one, but that would require the
* addition of another mapping proc, which is unnecessary
*/
access_size = epp->ep_ssize;
access_linear_min = (u_long)STACK_ALLOC(epp->ep_minsaddr, access_size);
noaccess_size = max_stack_size - access_size;
noaccess_linear_min = (u_long)STACK_ALLOC(STACK_GROW(epp->ep_minsaddr,
access_size), noaccess_size);
if (noaccess_size > 0) {
NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, noaccess_size,
noaccess_linear_min, NULL, 0, VM_PROT_NONE);
}
KASSERT(access_size > 0);
NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, access_size,
access_linear_min, NULL, 0,
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
return 0;
}