tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: UVM and the NULL page



Le 30/07/2016 à 12:54, Martin Husemann a écrit :
On Sat, Jul 30, 2016 at 11:12:57AM +0200, Maxime Villard wrote:
You know - as well as I do - that NULL pointer dereferences are quite
common,
and that it is the main way to execute malicious code in kernel mode.

Sorry, but you are not making your point very clear, please try to explain
in more details!

Many people are more familiar with sane architectures where userland and
kernel do not share any VA mappings.

In short, on amd64, the virtual space of a userland process is divided in two:
the lower half is usable by userland, and the higher half contains a copy of
the kernel virtual space. When syscalling, the CPU just jumps to the higher half
where the kernel resides, instead of loading a kernel-specific virtual space.
The kernel should never access data that is in the lower half; to do so it uses
copyin and copyout.

The problem we have in C is that NULL is a widely-used magic value that points
to page zero. From a kernel point of view, it is in the lower half of the
virtual space, which means it technically belongs to userland.

Now, let's say there is a NULL pointer dereference in the kernel (i.e., the
kernel tries to read or write to NULL). This kind of bug is common, for example
in NetBSD-SA2014-014. To exploit this bug, an attacker can create a userland
program that maps NULL, fills page zero with crafted data and performs a given
syscall. What happens is that, when syscalling, the CPU jumps to the higher
half, then at some point NULL is read, the CPU gives a look at the lower half
and sees page zero is mapped. So everything is fine, the CPU continues and reads
data at address zero that was crafted by userland. The kernel ends up using
userland data as if it were kernel data.

However, if NULL is not mappable in userland, the CPU gives a look at the lower
half, sees page zero is not mapped, and the kernel panics. We therefore turn a
whole range of exploits, most of which achieve privilege escalation, to simple
DoSes.

Now what I understood is you worry about shared VA architectures like x86,
where the 0 page is not usually mapped by the kernel for netbsd binaries.
But the code trying to prevent a userland mmap() call to map a page at
VA 0 is buggy, and the userland code could even trick the kernel into
mapping at that VA with exec permissions.

Yes.

This is all unrelated (I think, but am not sure) to all other uses of the 0 VA
page by emulation or architecture specific code (i.e. the arm case mentioned).

Yes, it is unrelated.

It is also slightly unrelated to the Wine case, where VA 0 is explicitly
requested (and either denied or granted depending on the sysctl), since
fixing the bug would still allow an explicit VA 0 mapping if allowed
and granted.

It depends on how we fix the bug. My original proposition did not make it
controllable by a sysctl, my last one (with ep_vm_minaddr) does.


Home | Main Index | Thread Index | Old Index