> 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); }

Reply via email to