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.
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.
Description from the blog post by Jann Horn:
https://googleprojectzero.blogspot.com/2021/10/how-simple-linux-kernel-memory.html
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:
compiles to:
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.