login
Header Space

 
 

mprotect patch for compat_linux in OpenBSD 4.2

Score:
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <misc@...>
Date: Sunday, November 11, 2007 - 12:02 pm

As some of you may recall, there are Linux binaries (such as Mathematica) 
which will not run under OpenBSD's Linux emulation because the 
Linux mprotect system-call uses flags that are not supported by OpenBSD.  
To remedy this problem, I had posted a patch for OpenBSD 4.1

 http://marc.info/?l=openbsd-misc&m=118275040601937

I have included a new version of that patch, updated for OpenBSD 4.2, at 
the end of this message.

After applying the patch to the OpenBSD 4.2 source-code, be sure to run 
make in the directory

 /usr/src/sys/compat/linux/

If you forget to run that special makefile, then the patch will fail.

As before, I should mention that I am not the author of the majority of 
the code in this patch.  Instead, it has been ported from the 
corresponding 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...

The OpenBSD 4.2 patch follows:


--- /usr/src/sys/compat/linux/linux_misc.c.orig	Wed Feb 14 18:07:51 2007
+++ /usr/src/sys/compat/linux/linux_misc.c	Sun Nov 11 02:40:01 2007
@@ -718,6 +718,70 @@
 
 }
 
+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_p->ps_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	Sat Nov 10 23:21:24 2007
@@ -38,6 +38,8 @@
 #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	Mon Jun 18 20:33:13 2007
+++ /usr/src/sys/compat/linux/syscalls.master	Sat Nov 10 23:21:24 2007
@@ -223,7 +223,8 @@
 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); }
+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