KSPP / linux

Linux kernel source tree (Kernel Self Protection Project)
https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project
Other
80 stars 5 forks source link

Dynamic/per-boot struct layout randomization #257

Open vegard opened 1 year ago

vegard commented 1 year ago

Description from the blog post by Jann Horn:

https://googleprojectzero.blogspot.com/2021/10/how-simple-linux-kernel-memory.html

To maximize the benefit of structure layout randomization in an environment where kernels are built centrally by a distribution/vendor, it would be necessary to make randomization a boot-time process by making structure offsets relocatable. (Or install-time, but that would break code signing.) Doing this cleanly (for example, such that 8-bit and 16-bit immediate displacements can still be used for struct member access where possible) would probably require a lot of fiddling with compiler internals, from the C frontend all the way to the emission of relocations. A somewhat hacky version of this approach already exists for C->BPF compilation as BPF CO-RE, using the clang builtin __builtin_preserve_access_index, but that relies on debuginfo, which probably isn't a very clean approach.

I'm attaching an old prototype patch for gcc: 0001-Dynamic-struct-layout-randomization.patch

This can output relocations for very simple cases. For example:

struct foo {
         int a, b;
};

void bar(struct foo *x)
{
         x->a = 1;
         x->b = 2;
}

compiles to:

0000000000000000 <bar>:
    0:   movl   $0x1,0x0(%rdi)
                         2: R_X86_64_32S __struct__foo__a
    a:   movl   $0x2,0x0(%rdi)
                         c: R_X86_64_32S __struct__foo__b
   14:   retq

This is a very early PoC; it only works for trivial cases, there is no way to obtain the information required to create symbols for those relocations, it doesn't do any of the work described by the blog post to minimize immediate operand sizes, and some thought needs to be put into how to do static initializers.