Previously: v4.11.
Here’s a quick summary of some of the interesting security things in last week’s v4.12 release of the Linux kernel:
x86 read-only and fixed-location GDT
With kernel memory base randomization, it was stil possible to figure out the per-cpu base address via the “sgdt” instruction, since it would reveal the per-cpu GDT location. To solve this, Thomas Garnier moved the GDT to a fixed location. And to solve the risk of an attacker targeting the GDT directly with a kernel bug, he also made it read-only.
usercopy consolidation
After hardened usercopy landed, Al Viro decided to take a closer look at all the usercopy routines and then consolidated the per-architecture uaccess code into a single implementation. The per-architecture code was functionally very similar to each other, so it made sense to remove the redundancy. In the process, he uncovered a number of unhandled corner cases in various architectures (that got fixed by the consolidation), and made hardened usercopy available on all remaining architectures.
ASLR entropy sysctl on PowerPC
Continuing to expand architecture support for the ASLR entropy sysctl, Michael Ellerman implemented the calculations needed for PowerPC. This lets userspace choose to crank up the entropy used for memory layouts.
LSM structures read-only
James Morris used __ro_after_init
to make the LSM structures read-only after boot. This removes them as a desirable target for attackers. Since the hooks are called from all kinds of places in the kernel this was a favorite method for attackers to use to hijack execution of the kernel. (A similar target used to be the system call table, but that has long since been made read-only.) Be wary that CONFIG_SECURITY_SELINUX_DISABLE
removes this protection, so make sure that config stays disabled.
KASLR enabled by default on x86
With many distros already enabling KASLR on x86 with CONFIG_RANDOMIZE_BASE
and CONFIG_RANDOMIZE_MEMORY
, Ingo Molnar felt the feature was mature enough to be enabled by default.
Expand stack canary to 64 bits on 64-bit systems
The stack canary values used by CONFIG_CC_STACKPROTECTOR
is most powerful on x86 since it is different per task. (Other architectures run with a single canary for all tasks.) While the first canary chosen on x86 (and other architectures) was a full unsigned long
, the subsequent canaries chosen per-task for x86 were being truncated to 32-bits. Daniel Micay fixed this so now x86 (and future architectures that gain per-task canary support) have significantly increased entropy for stack-protector.
Expanded stack/heap gap
Hugh Dickens, with input from many other folks, improved the kernel’s mitigation against having the stack and heap crash into each other. This is a stop-gap measure to help defend against the Stack Clash attacks. Additional hardening needs to come from the compiler to produce “stack probes” when doing large stack expansions. Any Variable Length Arrays on the stack or alloca()
usage needs to have machine code generated to touch each page of memory within those areas to let the kernel know that the stack is expanding, but with single-page granularity.
That’s it for now; please let me know if I missed anything. The v4.13 merge window is open!
Edit: Brad Spengler pointed out that I failed to mention the CONFIG_SECURITY_SELINUX_DISABLE
issue with read-only LSM structures. This has been added now.
© 2017, Kees Cook. This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 License.
With all the recent KASLR improvements how does it compare to OpenBSD’s recently announced KARL (https://marc.info/?l=openbsd-tech&m=149732026405941&w=2 ). Would implementing something similar even make sense for Linux? Or is it randomizing the module load address and/or the kernel image already partly anyway?
Comment by Thorsten Leemhuis — July 10, 2017 @ 3:48 am
He had to look for a long time …
#ifdef CONFIG_CC_STACKPROTECTOR
/* tsk->stack_canary = pax_get_random_long(); */
tsk->stack_canary = get_random_long();
#endif
Comment by Pax Fan — July 11, 2017 @ 2:39 am
v4.12
Comment by adilson avila — August 22, 2017 @ 6:16 am