tech-kern archive

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

amd64: kernel aslr support



Here is a Kernel ASLR implementation for NetBSD-amd64. It is light, functional,
user-friendly, and does not break any feature of the system. Instructions on
how to install and use it can be found here [1].

There are three patches, incompatible.diff is the one that needs more work or
proper #ifdefs. I give here a brief summary, but basically if you want to
understand how the implementation works in details, you need to read the code.

This implementation is based on a specialized kernel, called the prekern, which
relocates the real NetBSD kernel. The bootloader loads both the prekern and the
kernel in memory, and jumps into the prekern with a set of arguments; the
prekern relocates the kernel and then jumps into it, passing it the arguments
from the bootloader plus several other values.

The kernel is entered in the same state as the one created by the generic
locore: 64bit mode, paging, and several cpu features enabled. The only cleanup
it has to do is unmapping the prekern. The physical space of the prekern gets
recycled by UVM.

Before the kernel initializes a new IDT, it lives with that of the prekern.
Therefore, if the kernel faults early - assuming due to a mistake in the passed
arguments -, the prekern is re-entered and the exception is handled safely.

Known issues:
 * Right now, the kernel segments are contiguous. Starting from this
   implementation, it wouldn't be really difficult to randomize the segments
   independently - adding gaps between them and changing their order too.
   Then, we could split the segments themselves in sub-blocks and intertwine
   them.
 * In the set of patches, I'm sometimes replacing PA+KERNBASE by a pointer to
   the direct map. That's because I haven't found a clean way of doing it with
   bootspace yet - it will be solved later.
 * The kernel is not mapped with large pages. Doing so depends on the alignment
   the bootloader uses (KERNALIGN). This too will be solved later.
 * The RNG is not really strong. Help in this area would be greatly
   appreciated.
 * There are several redefinitions in the prekern headers. The way to remove
   them depends on where we put the prekern in the source tree.
 * And several other minor things that will be fixed soon...

Once the RNG is more robust, it is not complicated to randomize the kernel
heap too, and end up with strictly all of the kernel VA randomized.

Contrary to what has been said in previous discussions, KASLR does not alter
debugability in any way: the symbols are still mapped in memory as they are
right now, and ddb resolves them as usual.

Regarding address exposure, several entry points will have to be changed not
to disclose kernel VAs (eg "modstat -k"), but that's another debate. Finally,
when it comes to the performance impact, I don't have a very clear answer; we
don't use large pages yet so it's necessarily slower than usual. This being
said, I didn't experience any extravagant performance regression.

Comments, suggestions, tests and feedbacks are welcome.

Maxime

[1] http://m00nbsd.net/542a5cfd448aaf7db7adcadce74123d2.html


Home | Main Index | Thread Index | Old Index