closet geek wrote:I see you are well aware of this exploit and have written code to exploit it. However are people who run grsec immune from this as is? We don't run PAX just grsec, what parts of grsec would need to be running to stop this?
short answer: for this kind of bugs only i386/KERNEXEC provides protection (i.e., amd64/KERNEXEC does not).
now the long answer as i see many people are confused about what kind of bugs and exploits are affected by what methods.
first, let's talk about the bug class in question briefly. the most generic description could be something like "kernel code dereferencing an unwanted pointer". this can further be split into subclasses, depending on the type of dereference (data read, data write, code execution) and where the pointer points to (memory under direct userland control, kernel memory under indirect userland control, kernel memory under kernel control). that'd give us 9 subclasses, e.g., the sock_sendpage bug is 'code execution' and 'memory under direct userland control'. obviously each subclass gives a different kind of power into the exploit writer's hands, from userland controlled code execution being the best through leaking kernel memory to userland to causing a harmless oops or nothing at all. then one can also combine multiple such bugs to increase the power of the exploit (e.g., the vmsplice exploit first made the kernel read data under userland control then turned that into code execution in userland controlled memory).
now let's see what we can do about these subclasses (or rather, exploits, since we don't prevent the bugs from getting triggered, only their exploitation, if possible, that is). there're two PaX features that affect these exploits: KERNEXEC (i386/amd64) and UDEREF (i386). let's see what each one of them can do.
i386/KERNEXEC: this feature is primarily about implementing non-executable pages for i386 CPUs, even for those without a hw NX bit (as such CPUs didn't even exist back in 2003). due to the way it's implemented, it actually achieves more: it not only properly separates executable pages from non-executable ones in the kernel's virtual address region, it also makes the userland virtual address region non-executable as well (that is, non-executable by the kernel, userland can of course still execute there). so this feature affects all exploits that want to execute code in that such execution is restricted to the kernel's executable region. if the exploit has no control over the code pointer being dereferenced and/or it points outside of the kernel's executable region (e.g., it's a NULL function pointer as in the sock_sendpage case) then such exploits have no chance to succeed (they can however still cause problems since when the code execution attempt is caught, the kernel may be in a state where terminating the current thread may result in a deadlock or even memory corruption leading one into other exploitable situations). data dereference based exploits or code execution attempts in the kernel's executable region (think ret2libc for the kernel) are not affected by this feature.
amd64/KERNEXEC: this is similar to the i386 version in that it also implements proper executable/non-executable page separation for the kernel, but there's a big difference in that it does so only for the kernel's virtual address region, it leaves executable userland regions, well, executable for the kernel as well. in this particular case, if userland can map memory at NULL then it will be executable by the kernel and hence this bug is exploitable under amd64 even with KERNEXEC enabled. fixing this is a hard problem as AMD had butchered the segmentation logic and the alternative (address space switch on each userland/kernel transition) has a high performance impact (as a sidenote, it'd also enable UDEREF for amd64). i may still implement this one of these days but don't expect wonders, especially under virtualization.
i386/UDEREF: this feature is about separating userland/kernel virtual memory for data accesses. therefore it doesn't prevent/affect code execution attempts at all, on the other hand it catches all data accesses to userland when the kernel isn't supposed to access userland (e.g., NULL data pointer dereferences are caught this way).
finally, some notes on other archs: there seems to be some confusion about certain archs such as sparc that have a separate kernel virtual address space and therefore seem immune to this "unwanted pointer dereference" problem. this is actually not true in general, of the 9 subclasses above some are exploitable even there: both data and code pointer dereferences will succeed when they point at valid kernel addresses and much of that memory can be indirectly controlled by userland (think page cache for example) so it'd be important to tighten up page access rights for the kernel's address space as well (something i already began to do on amd64 for example, you can see it on the kmaps results).