Currently, there is no real way to make sure a userland process won't be able to allocate the NULL page. There is this attempt [1], but it has two major issues.
First, it is easy to bypass ([2]). The combination of parameters in the code makes sure this branch [3] is not taken, then [4] is reached, and the page is rounded up and truncated to NULL. The hint chosen will be [5], but it is easy to perform a mmap+munmap earlier [6] to ensure first_free is set to NULL. The hint chosen will therefore be NULL, and the allocation will succeed. In the ten minutes I spent to write this thing, I figured out that this kassert [7] is easy to trigger, because of [8]. This is another issue, so I didn't investigate further. Now, if we forget about this bypass, it is still not possible to guarantee that NULL is not mappable. The hint generally chosen for userland mappings is vm_daddr, but in [9] for example userland can modify this value. If it is set to NULL, a non-fixed one-page-sized mmap will allocate the NULL page. The only proper and clean way to fix this is by introducing a new limit, VM_MINUSER_ADDRESS, or by raising VM_MIN_ADDRESS. On amd64 it could safely be set to (2 * PAGE_SIZE). On Windows the value is (16 * PAGE_SIZE). I don't know if you have particular suggestions about it, but I will add VM_MINUSER_ADDRESS. [1] https://nxr.netbsd.org/xref/src/sys/uvm/uvm_map.c#1059 [2] http://m00nbsd.net/garbage/uvm/mapnull.c [3] https://nxr.netbsd.org/xref/src/sys/uvm/uvm_mmap.c#361 [4] https://nxr.netbsd.org/xref/src/sys/uvm/uvm_mmap.c#946 [5] https://nxr.netbsd.org/xref/src/sys/uvm/uvm_map.c#1868 [6] https://nxr.netbsd.org/xref/src/sys/uvm/uvm_map.c#2177 [7] https://nxr.netbsd.org/xref/src/sys/uvm/uvm_map.c#2115 [8] https://nxr.netbsd.org/xref/src/sys/uvm/uvm_map.c#1925 [9] https://nxr.netbsd.org/xref/src/sys/compat/osf1/osf1_misc.c#140