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