For the love of POSIX: A more useful way to not segfault from null pointers
blog.directededge.com
blog.directededge.com
Dereferencing a NULL pointer always segfaults, right? Not if you're clever...
Now, I don't actually know enough about the exploits they're talking about to know if handling the signal would avoid them or if the null pointer dereference has to actually be in kernel space and they were just starting with examples from user space, which was my assumption on the first pass of reading the article.
If you Google "linux kernel null pointer exploit" you will find many examples.
I believe that it's been widely read because of the novelty of avoiding crashes when dereferencing null pointers; in fact, for anyone who could have jumped to the conclusions about how the exploit would work, they could have reduced it to one line: "You can map address 0x0 with mmap and then segfaults on deferencing null don't happen." All of the rest of the article is only useful to people who don't know systems programming.
At any rate, I'm not sure that our fundamental disagreement is that wide; clearly the article is laying down a building block for a later piece on the security exploit and it was written to serve that purpose. This seems to be your point. My point is the actual content can stand alone and, in fact does, and is not about security.
Actually, yes. I posted a comment on the previous article saying so. The information in the current article is rather trite. The intricacies of kernel privilege escalation is a different story.
You can play games with sigaction and siginfo_t to get around this, but that's hairier than just mmap'ing.
Null pointers are typically be exactly such errors: e.g., you failed to allocate memory and malloc returned NULL, you didn't do proper validation on input or you assumed a key exists in a hash table when it doesn't. Either assumption that pointer is not NULL is an invariant (in which case it's better to crash and leave a core dump), or it's not (in which case the application should do a check for a null pointer).
It's also not advised to do complex processing inside signal handlers: the idea is to perform a single atomic operation in a signal handler (e.g., change an integer from 0 to 1), and let the application examine that operation's side effects. For example, there could be a "should_quit" integer which when 1 would mean the event loop should terminate and the signal handler would just set that integer to 1.
So it's not really about handling NULL ptr derefs, but exploiting them.
I would much rather know where my code tried to access a null memory space and what/why/how a null pointer was passed than to have it "fake" that it didn't ever happen! A signal handler for a SIGSEGV/SIGBUS is a great place to add a syslog() so you can find the error in your logic and correct it.
It's an error only if you didn't want to dereference address 0. If you know it's safe and useful to do so on the system for which you're developing, why shouldn't you be able to do it?
As the KSplice article shows, on Linux (under specific setup which is not the default), you can actually have something mapped there. I'd be hard pressed to invent a convincable scenario in which you would want to do it, but that doesn't mean there is none.
It will also turn an easy-to-debug SIGSEGV into a horrible-to-debug memory corruption; check out http://support.microsoft.com/kb/976038 for an example. This bug made debugging large applications on x64 a real pain.
You should get an error condition from dereferencing a null. When you're debugging your code, that error condition should be nice and verbose. Once you're shipping, that error condition should be very short and simple and should almost never occur. Trust me, your customers will not help you debug your code.
Test Driven Development and Design By Contract AND traditional software engineering all agree - FAIL EARLY AND OFTEN in your test suite to avoid later bugs. It is WRONG to let errors float around in your program logic, WRONG.
I went from C++ to Rails and back to C++. Is Rails reasoning trying to seep into C++? HELL NO!, The C-parts of C++ are serious and won't stand for this shit.