If you enjoy the pain of reading my rants, you may have come across a recent parody I did of a certain blog (http://xorl.wordpress.com) that for some reason gets a lot of (IMNSHO) undeserved praise. The parody, available at http://grsecurity.net/~spender/xorl_simulator.txt, should ring true if you're a reader of the blog. It characterizes my continued criticism of its content (alliteration streak) and posits the reason for its popularity. A recent post to the blog was about as clear of a demonstration of my criticism as is humanly possible.
I've archived the important excerpt from the post for the sake of posterity (as I imagine it'll soon be removed) at http://grsecurity.net/~spender/xorl_lol.txt. Give it a read, and also visit the links it references to the original vuln report: http://bugs.irssi.org/index.php?do=details&task_id=790 and to Nelson's vuln if you haven't already read about it: http://blog.nelhage.com/2010/12/cve-2010-4258-from-dos-to-privesc/. I'm not going to make a habit out of pointing out the mistakes of another person (which we all make) but this particular example I felt was noteworthy as demonstration.
A sampling of the questions that would have run through my mind that would have made me think twice about copy+pasting the amazingly confused "exploit technique":
1. What does Nelson's CVE have to do with null pointer dereferences? (more on this below)
2. How do you "make a call" with arbitrary args in a process you have yet to obtain code execution in (the whole reason you want to make this call right?)
3. If you're not doing it within the process context, but doing it locally otherwise, what would the mapping of the NULL page (again ignoring mmap_min_addr) in your own process have to do with the presence of it in a completely different process?
4. What does access_ok() have to do with mmap_min_addr?
5. What does access_ok() have to do with the creation of a mapping at NULL?
6. What does a userland NULL pointer dereference have to do with one in the kernel?
7. Where did the arbitrary write come from that allowed you to write to this NULL mapping you magically created?
8. Why am I exploiting my own client?
..ad infinitum
Critical thinking is essential to security, as even the most minute detail matters. Another recent example occurred in a channel where exploiting failed setuid() calls on suid root binaries via lowering RLIMIT_NPROC was discussed. We had all heard before from a number of sources that this was exploitable and so assumed it to be the case without actually verifying/testing it ourselves. I think it was stealth that pointed out that setuid() won't fail in the suid root case (via RLIMIT_NPROC at least, while failing via OOM is theoretical at best as small GFP_KERNEL allocations should never fail), because euid is being changed to ruid, causing the code to skip the set_user() call that normally would be able to fail due to the RLIMIT_NPROC limiting.
To prevent any future silliness in discussing Nelson's CVE (which I've seen numerous times in multiple places), please re-read Nelson's writeup of it, and recognize:
His vuln was not itself a null pointer dereference, rather, it allowed a very limited (only one example reported so far) subset of {NULL pointer dereferences or any other exit-triggering kernel bug} to be exploitable.
The vulnerability itself was essentially an arbitrary write: set_tid_address is the syscall that allows userland to specify the address for the kernel to write to. Normally this would be fine, as put_user when running under USER_DS would restrict the kernel from writing to kernel memory. Under KERNEL_DS (on vanilla kernels at least ) the kernel is able to write to both userland and kernelspace. set_tid_address by design never returns an error (there's a legitimate reason for not bothering to check for a valid userland address at the time of the syscall, but not one for not checking against the kernel limit), so this pushed special handling of the userland-controlled pointer to the users of it.
In summary, Nelson's vuln had nothing to do with userland NULL pointer dereferences, nor with bypassing mmap_min_addr, nor anything else having to do with the irssi "exploitable vulnerability" which isn't useful for anything but DoSing your own irssi client. Free, fully-operational 0day exploit if that's your thing: "/quit"
And here I thought after seeing the copy+pasted "exploitable" su NULL pointer dereference (copy+pasted onto the same blog) that we'd never see an exploit technique for it! Further proof that the imagination knows no bounds.
-Brad