login
Header Space

 
 

Re: cannot enable executable stack...

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <misc@...>
Date: Monday, June 25, 2007 - 1:39 am

> As it turns out, this bug in compat_linux was encountered in NetBSD in 

I have successfully ported the relevant material from the NetBSD patches

 http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/compat/linux/common/linux_misc.c.diff?r1=1... 
 http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/compat/linux/common/linux_mmap.h.diff?r1=1...
 http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/compat/linux/arch/i386/syscalls.master.dif...

to OpenBSD.  The OpenBSD patch is given at the end of this message.  Be 
sure to run the make file at

 /usr/src/sys/compat/linux/

after applying the patch.  The make file will update some important files.

This patch allows OpenBSD to use the PROT_GROWSUP and PROT_GROWSDOWN flags 
to mprotect under Linux emulation.  I have tested this new functionality 
with the Linux version of the Mathematica 6.0 Kernel, which now runs 
successfully.  Presumably, OpenBSD will also be able to run other Linux 
applications that use these flags, such as Adobe Acrobat Reader (for which 
the NetBSD patches were originally intended).

What steps need to be taken to ensure that this fix is merged into the 
official OpenBSD source code?


*** /usr/src/sys/compat/linux/linux_misc.c.orig	Wed Feb 14 18:07:51 2007
--- /usr/src/sys/compat/linux/linux_misc.c	Mon Jun 25 00:13:42 2007
***************
*** 718,723 ****
--- 718,787 ----
  
  }
  
+ int
+ linux_sys_mprotect(p, v, retval)
+ 	struct proc *p;
+ 	void *v;
+ 	register_t *retval;
+ {
+ 	struct linux_sys_mprotect_args /* {
+ 		syscallarg(const void *) start;
+ 		syscallarg(unsigned long) len;
+ 		syscallarg(int) prot;
+ 	} */ *uap = v;
+ 	struct vm_map_entry *entry;
+ 	struct vm_map *map;
+ 	vaddr_t end, start, len, stacklim;
+ 	int prot, grows;
+ 
+ 	start = (vaddr_t)SCARG(uap, start);
+ 	len = round_page(SCARG(uap, len));
+ 	prot = SCARG(uap, prot);
+ 	grows = prot & (LINUX_PROT_GROWSDOWN | LINUX_PROT_GROWSUP);
+ 	prot &= ~grows;
+ 	end = start + len;
+ 
+ 	if (start & PAGE_MASK)
+ 		return EINVAL;
+ 	if (end < start)
+ 		return EINVAL;
+ 	if (end == start)
+ 		return 0;
+ 
+ 	if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
+ 		return EINVAL;
+ 	if (grows == (LINUX_PROT_GROWSDOWN | LINUX_PROT_GROWSUP))
+ 		return EINVAL;
+ 
+ 	map = &p->p_vmspace->vm_map;
+ 	vm_map_lock(map);
+ 	if (!uvm_map_lookup_entry(map, start, &entry) || entry->start > start) {
+ 		vm_map_unlock(map);
+ 		return ENOMEM;
+ 	}
+ 
+ 	/*
+ 	 * Approximate the behaviour of PROT_GROWS{DOWN,UP}.
+ 	 */
+ 
+ 	stacklim = (vaddr_t)p->p_limit->pl_rlimit[RLIMIT_STACK].rlim_cur;
+ 	if (grows & LINUX_PROT_GROWSDOWN) {
+ 		if (USRSTACK - stacklim <= start && start < USRSTACK) {
+ 			start = USRSTACK - stacklim;
+ 		} else {
+ 			start = entry->start;
+ 		}
+ 	} else if (grows & LINUX_PROT_GROWSUP) {
+ 		if (USRSTACK <= end && end < USRSTACK + stacklim) {
+ 			end = USRSTACK + stacklim;
+ 		} else {
+ 			end = entry->end;
+ 		}
+ 	}
+ 	vm_map_unlock(map);
+ 	return uvm_map_protect(map, start, end, prot, FALSE);
+ }
+ 
  /*
   * This code is partly stolen from src/lib/libc/gen/times.c
   * XXX - CLK_TCK isn't declared in /sys, just in <time.h>, done here
*** /usr/src/sys/compat/linux/linux_mmap.h.orig	Wed Apr 17 05:23:56 1996
--- /usr/src/sys/compat/linux/linux_mmap.h	Mon Jun 25 00:13:42 2007
***************
*** 38,43 ****
--- 38,45 ----
  #define LINUX_PROT_READ		0x01
  #define LINUX_PROT_WRITE	0x02
  #define LINUX_PROT_EXEC		0x04
+ #define LINUX_PROT_GROWSDOWN	0x01000000
+ #define LINUX_PROT_GROWSUP	0x02000000
  
  #define LINUX_MAP_SHARED	0x0001
  #define LINUX_MAP_PRIVATE	0x0002
*** /usr/src/sys/compat/linux/syscalls.master.orig	Wed Oct 27 13:23:38 2004
--- /usr/src/sys/compat/linux/syscalls.master	Mon Jun 25 00:13:42 2007
***************
*** 223,229 ****
  123	STD		{ int linux_sys_modify_ldt(void); }
  #endif
  124	STD		{ int linux_sys_adjtimex(void); }
! 125	NOARGS		{ int sys_mprotect(caddr_t addr, int len, int prot); }
  126	STD		{ int linux_sys_sigprocmask(int how, \
  			    linux_old_sigset_t *set, linux_old_sigset_t *oset); }
  127	STD		{ int linux_sys_create_module(void); }
--- 223,230 ----
  123	STD		{ int linux_sys_modify_ldt(void); }
  #endif
  124	STD		{ int linux_sys_adjtimex(void); }
! 125	STD		{ int linux_sys_mprotect(const void *start, \
! 			    unsigned long len, int prot); }
  126	STD		{ int linux_sys_sigprocmask(int how, \
  			    linux_old_sigset_t *set, linux_old_sigset_t *oset); }
  127	STD		{ int linux_sys_create_module(void); }
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
cannot enable executable stack..., Matthew Szudzik, (Sun Jun 10, 4:51 am)
Re: cannot enable executable stack..., Matthew Szudzik, (Mon Jun 18, 11:58 pm)
Re: cannot enable executable stack..., Matthew Szudzik, (Tue Jun 19, 9:10 am)
Re: cannot enable executable stack..., Matthew Szudzik, (Thu Jun 21, 10:13 pm)
Re: cannot enable executable stack..., Matthew Szudzik, (Mon Jun 25, 1:39 am)
mprotect patch for compat_linux in OpenBSD 4.2, Matthew Szudzik, (Sun Nov 11, 12:02 pm)
Re: cannot enable executable stack..., Matthew Szudzik, (Mon Jun 25, 8:54 am)
Re: cannot enable executable stack..., Ted Unangst, (Mon Jun 25, 5:50 pm)
Re: cannot enable executable stack..., Matthew Szudzik, (Wed Jun 20, 9:08 am)
Re: cannot enable executable stack..., Ted Unangst, (Wed Jun 20, 2:20 pm)
Re: cannot enable executable stack..., Matthew Szudzik, (Wed Jun 20, 4:35 pm)
Re: cannot enable executable stack..., Ted Unangst, (Sun Jun 10, 7:02 pm)
Re: cannot enable executable stack..., Matthew Szudzik, (Sun Jun 10, 7:43 pm)
Re: cannot enable executable stack..., Ted Unangst, (Mon Jun 11, 1:37 am)
speck-geostationary