How To Exploit NULL Pointers
An anonymous reader writes "Ever wondered what was so bad about NULL pointer exceptions? An MIT Linux kernel programmer explains how to turn any NULL pointer into a root exploit on Linux. (There was also a previous installment about virtual memory and how to make NULL pointers benign.)"
"Ever wondered what was so bad about NULL pointer exceptions?..."
Nothing. Because if they're an exception, they've been safely caught by the platform's exception handling mechanism. This article isn't about exceptions, it's about dereferencing your actual raw NUL pointers themselves in languages that either don't have the exception mechanism or where it simply hasn't been used.
Cheers,
Ian
This is very OS dependent.
For example, on AIX on POWER, page 0 in both real and virtual addressing modes is readable by all and writable by none. So a read from a NULL pointer produces junk data (actually interrupt machine code) and a write is fatal.
Terrorist, bomb, al Qaeda, nuclear, yellowcake, kill, assassinate. Carnivore is dead... long live Echelon.
The OP's article wasn't very long, so you should be able to figure out that you just rephrased what he said: you need to have a null pointer function call kernel bug to exploit this. No combination of null pointer vulnerabilities in user space, and no null pointer reads and writes in kernel mode (which are more common) will get you root.
Yeah, shouldn't switch be easily take care of by a base register?
Well it is. On x86 systems, the intuitively named Control Register 3 is a pointer to the base of the page tables. From a software point of view, switching address spaces is as easy as writing CR3.
From a hardware point of view, that act has additional implications. You have to flush the TLBs, which sucks royal if it happens on every system call. If you have linearly tagged caches (or any other linearly tagged structure) then you'll have to flush those too. There are ways to partially mitigate these effects, but since you can't rely on them being there it's best to just avoid CR3 writes as much as possible -- which means there's less reason to implement the necessary widgets.
The enemies of Democracy are
even better, you need to do some incredibly dumb shit as root first. Next up: if you're logged in as root, su doesn't prompt for a password! security breach!!!!
It assumes that the hacker would be able to find an exploit so that no root would be necessary:
While mmap_min_addr does provide some protection against these exploits, attackers have in the past found numerous ways around this restriction. In a real exploit, an attacker would use one of those or find a new one, but for demonstration purposes it’s easier to just turn it off as root.
Sorry, but if anything that simple can cause root access, then that’s a general error of the architecture and kernel.
By default you need root access (or an exploitable bug) to map page zero into your address space, and you need to specifically configure the kernel to allow it, and then you need an exploitable kernel bug to make use of it.
I wouldn't exactly call that 'simple'.
Why should a change of the page table be needed?
It's not needed if you map your kernel into the application's page tables. ;)
All you need are separate segments for kernel and user mode.
1) Segmentation is essentially non-existent* in 64-bit mode.
2) Segmentation sucks. Always has, always will. That's why even in 32-bit mode most segments are made with base 0 and max limit, and processors are optimized for this case.
3) Okay, so you switch your CS and DS segments when you go into kernel mode (well actually you do anyway, but they're non-base-zero in this case). That's great, but you still need to map your linear address (linear = virtual address + segment base) to a physical address. So you either need to write to CR3 to use the kernel's page table, or you need to map your kernel's memory into the user's page table.
* Ask VmWare about the non-essentially existent remnants of segmentation.
The enemies of Democracy are
Wine and Dosemu take advantage of it. Also, the decision by the designers of C to make 0 an invalid address is really just a language decision, and has no basis in real hardware. The Linux kernel, however, is written in C, but can't assume the hardware will take care of a NULL dereference. That's really what the problem is. In reality, the bare hardware will allow something like *((int*) 0) = 0xdeadbeef; it's the operating systems job to enforce the rules.
FYI: AMD-V or Intel Nehalem or later
Nehalem processor TLB address mapping entries include a Virtual Processor Identifier (VPID), while AMD-V supports tagged TLBs.
-- Terry
This is not "how to exploit NULL pointers" ... this is "how to exploit a kernel NULL function pointer".
No, it's just the "simplest" example of exploiting NULL pointers. If your NULL pointer is not a function pointer, you can still exploit it in many cases, you just need to work slightly harder.