State of the Kernel Self Protection Project
At the Linux Security Summit in Toronto, Kees Cook updated attendees on the Kernel Self Protection Project (KSPP), which was announced only nine months ago. KSPP is targeted at adding protections to the kernel to guard against kernel bugs so that those bugs can't lead to a kernel compromise. Progress has been made, but there is lots more to do.
"Security" is a somewhat loaded word, but for the context of the presentation, he is really talking about "self protection", he said. That goes beyond access control (e.g. SELinux), attack surface reduction (e.g. seccomp), bug fixing, protecting user space, and kernel integrity. It is proactive and does rely on kernel integrity, but it is more than that.
Why KSPP?
There are huge numbers of systems using Linux and the vast majority are running old software. Many will never get updates. As we move forward, we need devices protecting themselves because the lifetime of bugs in the field is much longer than even the long bug lifetimes in the kernel. Things will be getting worse with the "Internet of Things" (IoT); while users may replace phones every few years, a door lock or other IoT device may live for fifteen years or more.
Cook has seen a lot of blame shifting. Once a bug is fixed, it is seen as someone else's problem to get it rolled out. But even if every bug was found and fixes were magically sent to all affected devices, bugs live for a long time in the kernel.
In 2010, Jonathan Corbet looked at the lifetime of security flaws in the kernel and found that the average time between introduction and fix was roughly five years. Cook analyzed the Ubuntu bug tracker for the kernel from 2011 through 2016 and found much the same, though the two critical bugs in that time frame averaged 3.3 years between introduction and fix. He put up a graph of the lifetime of all of those bugs and another that focused on just the critical and high severity bugs (as can be seen in his slides [PDF]). Bugs are clearly living for quite some time in the kernel.
One question he gets a lot is: "isn't this all just theoretical?" If kernel developers are not finding the bugs, maybe others aren't either. But that is "demonstrably untrue", Cook said. Attackers are finding these bugs and they are better at it than the kernel community is. Most attackers do not publicly boast about the zero-day flaws they have found. The window of opportunity for exploiting these bugs is large and not at all theoretical.
Kernel developers are fighting bugs, of course, and finding and fixing them. But they are also accelerating the pace of bug introduction. Bugs exist whether they are known or not and an empty bug tracker does not imply there are no bugs. The bugs are there and kernel developers need to act like they are, he said. Whack-a-mole is not a solution long-term; the current bug finding and fixing should continue, but there needs to be more.
At this point, user space is becoming more difficult to attack, which is making the kernel's attack surface more appealing. Containers are also painting a large target on Linux. In addition, it is important to recognize that lives depend on Linux. That statement makes some people uncomfortable, he said, but kernel bugs have been weaponized by organizations like Hacking Team that sell them to governments that use them to target dissidents and activists.
There is some truth to the statement that security bugs are just normal bugs. "Your security bug may not be my security bug", he said. But kernel developers have little knowledge of what bugs attackers use. Those bugs might even be in code that is not upstream, such as a vendor driver. Self protection could make kernels safer, even for that non-upstream code.
Killing bugs and bug classes
So, killing particular bugs is good, but killing bug classes is much better. That can ensure that those kind of bugs can never occur again, even if they are in out-of-tree code. But it is impossible to kill all bug classes.
So, what is best is to kill off the exploitability of bugs. That needs to be done even if the features make development more difficult. So what is needed is eliminating exploitation targets and methods, as well as removing information leaks and anything else that assists attackers. There will be tradeoffs to maintainability and performance, but those need to be judged on their merits, not just avoided at all costs.
Typical exploits are not simply using one flaw; instead they tend to chain together multiple flaws. In order to do that, they need to know where the targets are, inject or build malicious code, and redirect execution to that code.
There is already a lot of code to do self protection available in grsecurity and PaX. There are also academic papers describing ways for kernels to protect themselves. So a lot of these protections don't need to be invented, they just need to get upstream. There is, he said, a large demand for these kinds of features to be added to the kernel.
To address that, he started KSPP in order to gather people interested in self-protection technologies to discuss, test, and document them. There are other people working on excellent technologies for the kernel to protect user space, but he wants to focus on the kernel protecting itself. Currently, there are around ten organizations and five individuals working on roughly twenty separate technologies. It is not a fast process and he intends to take it "slow and steady".
He listed a number of people that are "under the KSPP umbrella". It shows that there are a lot of people paying attention to these ideas, which he is "extremely grateful" for. It is nice to have a deep pool of people to help, he said.
There are numerous areas of interest to the project. His slides detail multiple bug classes, examples of exploits for the class, the relevant mitigations that have already gone into the kernel (which are highlighted in bold), and the work that is either currently being done or is planned for the future.
For example, there have been protections for stack overflows in the kernel for quite some time. 2.6.30 saw the addition of the GCC -fstack-protector flag, while -fstack-protector-strong was added for 3.14. For the future, Andy Lutomirski has been working on virtually mapped stacks that will allow for guard pages around the kernel stack for further protection.
Other classes he covered include integer over and underflow, heap overflow, format string injection, kernel pointer leaks, uninitialized variables, use after free, direct kernel overwrite, function pointer overwrite, user-space execution from the kernel, accessing user-space memory directly from the kernel, and return-oriented programming (ROP).
Progress
He then went through the kernel releases since KSPP was started and noted the protections that had been added in each. For 4.3, the "Privileged Access Never" (PAN) hardware memory protection feature was emulated for the ARM architecture. That helps protect the kernel from accessing user-space memory inappropriately. Ambient capabilities were added to make Linux capabilities behave as most programmers expected them to. In addition, seccomp support was added for PowerPC in 4.3.
The 4.4 kernel saw the addition of the x86_64 configuration option to allow kernels to be built without support for three legacy virtual system calls at fixed kernel addresses. That is a significant attack surface reduction, Cook said. In 4.5, the address-space layout randomization (ASLR) feature added a way for administrators to control the amount of entropy in the random base address. It is a notable user-space protection feature.
There were numerous protection features added to the 4.6 kernel. Most were adding protections to various types of memory for different architectures. Read-only data (RODATA) became the default for ARMv7+ and arm64, while its use became mandatory for x86. The basic infrastructure for marking data as read-only after initialization (__ro_after_init) was added. x86 got execute-only memory and arm64 got support for kernel ASLR (KASLR) on the text and module base addresses.
The MIPS architecture got KASLR support for text and modules in 4.7. In addition, the SLAB memory allocator got support for randomizing its free list. The extended BPF just-in-time (JIT) compiler added constant blinding, which helps prevent exploits from using the JIT code to accomplish its purposes.
In 4.8, Cook expects quite a few features to land. KASLR on x86_64 will be able to use the full range of physical memory and randomization of the kernel memory base address will be added. The SLUB allocator will get free-list randomization. The GCC plugin infrastructure will be added with some example plugins that do not have much security impact. But it will allow grabbing plugins from grsecurity/PaX and using them on the kernel. Hardened usercopy should also make the cut, as will the changes to put ptrace() handling before seccomp handling to avoid a loophole where ptrace() can be used to avoid the seccomp rules.
Looking into his crystal ball, Cook sees several features that seem likely for the 4.9 kernel. The latent_entropy GCC plugin, which will provide more entropy at startup time, is one. Another is the virtually allocated stack work mentioned earlier. Some linked-list hardening patches and PAN emulation for arm64 round out his list.
Challenges
The biggest challenge for the project is the culture on both the kernel and security sides. The kernel side is quite conservative. It took sixteen years (and five or six different developer's attempts) to get a simple, clean solution for symbolic link restrictions upstream. It is going to require kernel developers to pay more attention to these kinds of protections. But those trying to upstream these features need to have patience and understand how kernel development is done.
One of the challenges is explaining the rationale for a particular feature. In order to get it upstream, other developers will have to understand it. Code is not written for the kernel itself, it is written for the other kernel developers, Cook said, so it is critical to make it understandable to them.
As with most projects, people are needed for KSPP. Dedicated developers, testers, reviewers, backporters (to vendor kernels), and so on are all needed. When a set of patches is posted, having them be greeted with silence is the worst outcome. He encouraged those interested to get involved.
[I would like to thank the Linux Foundation for travel support to attend
the Linux Security Summit in Toronto.]
| Index entries for this article | |
|---|---|
| Security | Hardening |
| Security | Linux kernel/Hardening |
| Conference | Linux Security Summit/2016 |
