3

tl;dr: in my distros linux 3.08 kernel using cat /proc/kallsyms I can find out that for instance the _commit_creds function/symbol is located at address 0xc1073fe0. When either:

  • building my kernel (option 1)
  • via tweaking the kernel binary (option 2)

is it possible to influence those addresses? (i.e. randomize to mitigate exploits to the kernel?)

Am I further correctly assuming that the system calls provided by the kernel need to remain at predictable/know addresses to not break the ABI provided by the kernel?

long version

In part of the cve-2016-0728 Vulnerability of certain linux kernels the provided PoC uses those two source code lines:

#define COMMIT_CREDS_ADDR (0xffffffff81094250)
#define PREPARE_KERNEL_CREDS_ADDR (0xffffffff81094550)

which even though they play their role only after an overflow-with-use-after-free type of problem has occured, are nonetheless essential to complete the priveledge escalation. Of course the addresses are not the same for all kernels and basically change for each distribution. Anyway it seems that they are constant within the line of kernels (i.e. Ubuntu 12.04 x86 will always have the address at 0xc1073fe0).

My question is to understand if one can influence those addresses to shuffle/randomize them as to make an exploitation of the kernel more difficult (i.e. somewhat blind the attacker, after having the instruction pointer in kernel ring 0)? I would assume that in order to have a ABI for system calls I cannot change the position of sys_xxxxxxxxxxx symbols, but at least for the internals of kernel symbols I do not necessarily understand the need to have them be predictable?

Therefore I am asking here how one would go about randomizing those kernel symbols, either by

  • (1) compile custom kernel or,
  • (2) even better tweak a kernel and move the symbols around (which I think might be much harder and more fragile thing to do).

What is the consequence when changing the addresses of kernel symbols? (excluding the system call ABI ones).

  • Note that while ASLR makes exploits harder, they rarely make them impossible. The exploits just take more time to design and/or run. – Gilles 'SO- stop being evil' Jan 20 '16 at 22:06
3

If all Ubuntu 12.04 x86 have the same addresses, it is most probably because they all ship the same Linux build. If you use a modern version of GCC with optimizations enabled to compile your own kernel, it will randomize your addresses for each build.

And in fact, this is not even necessary for recent kernels. Since this commit (January 2014), the address space of the kernel on x86 architectures even changes at each boot through a mechanism called Kernel Address Space Layout Randomization: http://lwn.net/Articles/569635/.

So upgrade your distribution or recompile your kernel and you should have randomized addresses.

As for the consequences, if you let the compiler or the kernel loading process do the job, there are none. If you try to tweak the build after the compilation, the most probable outcome is that you won't be able to boot it, or worse, that it crashes randomly. Another practical consequence of post-processing the compiler's output is that you won't be able to have your kernel signed during the compilation process (which is necessary for trusted boot for example).

  • yes indeed it seems that 12.04 x86 have all the same fixed addresses but an 3.08 kernel not affected (at least I failed at running the test successfully). Sadly there is also 12.04.5 LTS which has different addresses and which I think is vulnerable to the keyctl overflow bug. With the Space Layout Randomization, your answer mentions I wonder how the vulnerability mentioned in the question can exploit the use after free of the kernel, as the space layout is so random? – humanityANDpeace Jan 20 '16 at 10:32
  • @humanityANDpeace Well, it's random but you need to leak only one pointer from the kernel to have a precise idea of the base address of the kernel and its layout so... ASLR is not as effective for a kernel (which is booted and remains running for a long time) than for a userland process which can be restarted. This post on LWN has some interesting information lwn.net/Articles/569635 as well as this post by the inventor of ASLR: forums.grsecurity.net/viewtopic.php?f=7&t=3367 – lgeorget Jan 20 '16 at 10:37
  • Oh! So what you say is that the complete .text section is randomly placed in memory, but the single symbols are still not suffled, true? That is what you mean by knowing base address. Basically ASLR has the granularity of the .text position in memory? – humanityANDpeace Jan 20 '16 at 10:45
  • In its first implementation, yes. I'm not exactly sure of the details but the kernel randomizes at least the base address as well as the addresses of the modules when they are loaded. Maybe they have improved the mechanism to randomize better the addresses but I cannot be more precise. – lgeorget Jan 20 '16 at 10:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.