After a bit of thought I've decided the best way to address this is for LSMs to abandon the mmap_min_addr tunable altogether. That tunable lets a root user disable protections. Why would an LSM want a root user to be able to control it's protections at all? What it protects should be defined entirely by the kernel and the policy. So, what I've done is to separate out the mmap_min_addr root vs. non-root check and the LSM check. There is a new hard coded at kernel compile time amount of memory protected by the LSM. This is unrelated to the /proc/sys/vm/mmap_min_addr file. You can set that to 0 and the LSM will still be able to protect low memory.
So in upstream kernels (2.6.30-rc6ish and later) to map the 0 page you will need both CAP_SYS_RAWIO (root) and the SELinux memprotect/mmap_zero permission instead of only needing one or the other. If you set /proc/sys/vm/mmap_min_addr to 0 you will still need the SELinux mamprotect/mmap_zero permission.
Hurray until the next time someone finds a way to map the 0 page and a null pointer bug in the kernel (lots of the latter as of late)
http://git.kernel.org/linus/9c0d90103c7e0eb6e638e5b649e9f6d8d9c1b4b3 http://git.kernel.org/linus/8cf948e744e0218af604c32edecde10006dc8e9e http://git.kernel.org/linus/788084aba2ab7348257597496befcbccabdc98a3 http://git.kernel.org/linus/1d9959734a1949ea4f2427bd2d8b21ede6b2441c