5 weeks ago at d2k17 I started work on randomized kernels.  I've been
having conversations with other developers for nearly 5 years on the
topic... but never got off to a good start, probably because I was
trying to pawn the work off on others.

Having done this, I really had no idea we'd end up where we are today.

Here are the behaviours:

- The base set has grown, it now includes a link-kit
- At install time, a unique kernel is built from this link-kit
- At upgrade time, a unique kernel is built
- At boot time, a unique kernel is built and installed for the next boot
- If someone compiles their own kernel and uses 'make install', the
  link-kit is also updated, so that the next boot can do the work
- If a developer cp's a kernel to /, the mechanism dis-engages until a
  'make install" or upgrade is performed in the future.  That may
  help debugging.

A unique kernel is linked such that the startup assembly code is kept
in the same place, followed by randomly-sized gapping, followed by all
the other .o files randomly re-organized.  As a result the distances
between functions and variables are entirely new.  An info leak of a
pointer will not disclose other pointers or objects.  This may also
help reduce gadgets on variable-sized architectures, because
polymorphism in the instruction stream is damaged by nested offsets
changing.

At runtime, the kernel can unmap it's startup code.  On architectures
where an unmap isn't possible due to large-PTE use, the code can be
trashed instead. 

I did most of the kernel work on amd64 first, then i386.  I explained
what needed to be done to visa and patrick, who handled the arm and
mips platforms.  Then I completed all the rest of the architectures.
Some architecture are missing the unmap/trashing of startup code, that's
a step we need to get back to.

The next part was tricky and I received assistance from tb and rpe.
We had to script the behaviours at build time, snapshot time, relink
time, boot time, and later on install/upgrade time also.

While they helped, I also worked to create the "gap.o" file without
use of a C compiler so that relinks can occur without the "comp" set
installed. This uses the linkscript feature of ld.  I don't think
anyone has done this before.  It is little bit fragile, and the
various linkers may need to receive some fixes due to what I've
encountered.

To ensure this security feature works great in the 6.2 release, please
test snapshots.  By working well, I mean it should work invisibly,
without any glitch such as a broken kernel or anything.  If there are
ugly glitches we would like to know before the release.

Reply via email to