memory protection and sbrk()

Alan Cox alc at cs.rice.edu
Tue Mar 31 10:48:11 PDT 2009


For as long as I can remember, FreeBSD's sbrk() has provided memory with 
execute permission enabled.  Before we branch for FreeBSD 8.0, I'd like 
to try removing execute permission on this memory.

On (non-PAE) i386 and a few of the embedded processors, this change will 
have little tangible effect because there is no distinction in the 
processor's MMU between read and execute permissions.

On amd64, the only potential problems are likely with a very few 
applications, like the JVM, that have their own internal implementation 
of "malloc()" and generate code on the fly (i.e., JIT compilation).  
However, I have verified that at least the Sun JVM works ok.  I have 
also checked that cvsup, which is based on Modula-3 and does not use the 
standard malloc(), works ok.

It's also worth noting that our standard malloc() has flip-flopped over 
the last year or so in terms of whether it uses sbrk() or mmap() by 
default to acquire memory.  When it uses mmap(), it does not request 
execute permission on the allocated memory.  So, depending on whether 
malloc() used mmap() or sbrk(), malloc() was returning memory with 
different permissions.  Consequently, I think that any application 
problems due to the lack of execute permission on memory returned by 
malloc() would have long since been detected.

As a final sanity check, I would appreciate it if three kinds of users 
would test the attached patch: (1) some IA64, PowerPC, and Sparc64 
users, (2) amd64-based users of "exotic" languages, like common lisp, 
haskell, etc. and (3) amd64-based users of other JVMs, like kaffe.

My plan is to commit the attached patch to HEAD on the 7th of April 
unless I hear of problems.

Thanks,
Alan

-------------- next part --------------
Index: vm/vm_unix.c
===================================================================
--- vm/vm_unix.c	(revision 190506)
+++ vm/vm_unix.c	(working copy)
@@ -117,7 +117,7 @@
 			goto done;
 		}
 		rv = vm_map_insert(&vm->vm_map, NULL, 0, old, new,
-		    VM_PROT_ALL, VM_PROT_ALL, 0);
+		    VM_PROT_RW, VM_PROT_ALL, 0);
 		if (rv != KERN_SUCCESS) {
 			error = ENOMEM;
 			goto done;


More information about the freebsd-arch mailing list