Over the last three weeks I've been working on a new randomization
feature which will protect the kernel.

The situation today is that many people install a kernel binary
from OpenBSD, and then run that same kernel binary for 6 months
or more.  We have substantial randomization for the memory allocations
made by the kernel, and for userland also of course.

However that kernel is always in the same physical memory, at the
same virtual address space (we call it KVA).

Improving this situation takes a few steps.

Recently I moved all our kernels to a new mapping model, with patrick
and visa taking care of two platforms.

Previously, the kernel assembly language bootstrap/runtime locore.S
was compiled and linked with all the other .c files of the kernel in a
deterministic fashion.  locore.o was always first, then the .c files
order specified by our config(8) utility and some helper files.

In the new world order, locore is split into two files: One chunk is
bootstrap, that is left at the beginning.  The assembly language
runtime and all other files are linked in random fashion.  There are
some other pieces to try to improve the randomness of the layout.

As a result, every new kernel is unique.  The relative offsets between
functions and data are unique.

It still loads at the same location in KVA.  This is not kernel ASLR!
ASLR is a concept where the base address of a module is biased to a
random location, for position-independent execution.  In this case,
the module itself is perturbed but it lands at the same location, and
does not need to use position-independent execution modes.

There is a chunk of code which is still well known at a well known
address -- the bootstrap code.  Once the kernel is up and running, it
blasts the bootstrap code into oblivion by smashing it with TRAP
instructions or unmapping, that depends upon the architecture.

Of course, if you booted that same kernel binary repeatedly, the
layout would be the same.  That is where we are today, for commited
code.

However, snapshots of -current contain a futher change, which I
worked on with Robert Peichaer (rpe@):

That change is scaffolding to ensure you boot a newly-linked kernel
upon every reboot.  The base set now contains a "link-kit" of the .o's
from the compile directory, so that a new random kernel can be linked
together.  It is linked automatically in the background by the rc
scripts, and installed as /bsd.  On a fast machine it takes less than
a second.  A mail is sent to the system administrator.  A reboot runs
the new kernel, and yet another kernel is built for the next boot.

The internal deltas between functions inside the kernel are not where
an attacker expects them to be, so he'll need better info leaks.

This mechanism is incompatible with the current workings of unhibernate,
but I working on a solution for that, so if you use -current, don't expect
unhibernate to work.  You can disable the mechanism using
       echo no > /usr/share/compile/GENER*/SHA256
but we all love security so why would you do that.


Our immune systems work better when they are unique.  Otherwise one
airline passenger from Singapore with a new flu could wipe out Europe
(they should fly to Washington instead).

Our computers should be more immune.

Reply via email to