[prev in list] [next in list] [ prev in thread ] [next in thread] List: openbsd-tech Subject: KARL - kernel address randomized link From: Theo de Raadt <deraadt () openbsd ! org> Date: 2017-06-13 2:17:28 Message-ID: 25445.1497320248 () cvs ! openbsd ! org [Download RAW message or body] 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. [prev in list] [next in list] [ prev in thread ] [next in thread]