Everyone is focused on this removal of the null check by the compiler, but to me that's a red herring. The real bug is the fact that SELinux allows you to map memory to address 0! Fix that and this is much less serious.
I'm confused by the assertion that a source code audit would catch nothing. Even if the auditors didn't know that the check would be optimised away, the code is very unnatural. Normally you check if a pointer is NULL and then deference it. In a code review, every time I see a pointer dereference I'm thinking: "how do we know that's not NULL?". So a check afterwards should not keep this code from being caught by auditors.
It's worth noting that this is a pathological NULL deference case, but that over the last couple years researchers have begun to make an art out of finding straightforwardly-exploitable NULL dereferences, particularly in the kernel; on some platforms, +0h is natively dereferenceable, and some dereferences are done with near-arbitrary offsets.
If I recall, AIX is one system which always returns 0 if NULL is dereferenced - the word at address 0 is guaranteed to a) be addressable, and b) contain a 0. These days I guess it's a security vulnerability, but the original intention was to allow wizards to optimize away the need for certain null checks. IBM actually has a number of patents related to techniques such as array boundary checking under this system.
I'm all for making the 0 page non-existent and to make it a processor feature rather than an os feature that the 0th address being referenced in any way will generate a hardware exception no matter what.
Otherwise we'll be playing null pointer dereference cat&mouse for ever.
It doesn't matter what you do with the zero page if the address is getting offset with an attacker-controlled caddr_t. I'm skeptical about NULL pointer countermeasures.
Wow, gcc generates code that's incorrect unless memory protection is being enforced? I didn't even realize it would be possible to build a kernel that way.
GCC's code isn't incorrect. As per the C standard, after you've dereferenced a NULL pointer then all behavior is undefined. If GCC emitted code that launched ICBMs after a NULL pointer dereference, that wouldn't violate the spec either.
The real WTF here is that people are still building "secure" software in a language where programmer mistakes cause undefined behavior...