Just some preliminary observations:
1) I'd prefer this be under a sysctl rather than require recompiling a kernel w/ a different VM_MIN_USER_ADDRESS.
2) VM_MIN_USER_ADDRESS is used for a number of other things in kernel; we'd have to look more closely at what this change does to them.
3) The changes to vm_mmap.c above only affect mcontrol and madvise; its not clear to me that changes to madvise() are required -- if you can't create a mapping at zero, there's no reason to check in madvise() that its being applied to 0, as the 'is-there-a-mapping' test will cover that.
I'd rather see something like this in kern_mmap():
/*
* Address range must be all in user VM space and not wrap.
*/
tmpaddr = addr + size;
if (tmpaddr < addr)
return (EINVAL);
if (VM_MAX_USER_ADDRESS > 0 && tmpaddr > VM_MAX_USER_ADDRESS)
return (EINVAL);
if (VM_MIN_USER_ADDRESS > 0 && addr < VM_MIN_USER_ADDRESS)
return (EINVAL);
if (addr NULL && zero_mmap_ok 0)
+ return (EINVAL);
where zero_mmap_ok comes from a sysctl that defaults to '0'. (this section is under a MAP_FIXED/MAP_TRYFIXED test.
5) fp_mmap() also exists; it is mostly a hacked up clone of kern_mmap. May need to be checked to see if null mappings can be made via checkpoints from it.