> 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.140&r2=1.141 > > > http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/compat/linux/common/linux_mmap.h.diff?r1=1.16&r2=1.17 > > http://cvsweb.netbsd.org/bsdweb.cgi/src/sys/compat/linux/arch/i386/syscalls.master.diff?r1=1.61&r2=1.62 > > to OpenBSD. The OpenBSD patch is given at the end of this message. Be
There have been requests that I resubmit the patch as a unified diff, rather than a context diff. The patch is given below. Remember to run the make file at /usr/src/sys/compat/linux/ after applying the patch. --- /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,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_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,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 Wed Oct 27 13:23:38 2004 +++ /usr/src/sys/compat/linux/syscalls.master Mon Jun 25 00:13:42 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); }