{"id":1075,"date":"2017-11-14T21:23:50","date_gmt":"2017-11-15T05:23:50","guid":{"rendered":"https:\/\/outflux.net\/blog\/?p=1075"},"modified":"2019-07-29T10:41:14","modified_gmt":"2019-07-29T17:41:14","slug":"security-things-in-linux-v4-14","status":"publish","type":"post","link":"https:\/\/outflux.net\/blog\/archives\/2017\/11\/14\/security-things-in-linux-v4-14\/","title":{"rendered":"security things in Linux v4.14"},"content":{"rendered":"<p>Previously: <a href=\"\/blog\/archives\/2017\/09\/05\/security-things-in-linux-v4-13\/\">v4.13<\/a>.<\/p>\n<p>Linux kernel v4.14 was <a href=\"https:\/\/lkml.org\/lkml\/2017\/11\/12\/123\">released<\/a> this last Sunday, and there&#8217;s a bunch of security things I think are interesting:<\/p>\n<p><strong>vmapped kernel stack on arm64<\/strong><br \/>\nSimilar to the <a href=\"\/blog\/archives\/2016\/12\/12\/security-things-in-linux-v4-9\/\">same feature on x86<\/a>, Mark Rutland and Ard Biesheuvel <a href=\"https:\/\/git.kernel.org\/linus\/872d8327ce8982883b8237b2c320c8666f14e561\">implemented<\/a> <code>CONFIG_VMAP_STACK<\/code> for arm64, which moves the kernel stack to an isolated and guard-paged vmap area. With traditional stacks, there were two major risks when exhausting the stack: overwriting the <code>thread_info<\/code> structure (which contained the <code>addr_limit<\/code> field which is checked during <code>copy_to\/from_user()<\/code>), and overwriting neighboring stacks (or other things allocated next to the stack). While arm64 <a href=\"\/blog\/archives\/2017\/02\/27\/security-things-in-linux-v4-10\/\">previously moved its thread_info off the stack<\/a> to deal with the former issue, this vmap change adds the last bit of protection by nature of the vmap guard pages. If the kernel tries to write past the end of the stack, it will hit the guard page and fault. (Testing for this is now possible via LKDTM&#8217;s <a href=\"https:\/\/git.kernel.org\/linus\/7b25a85c9d9f796c5be7ad3fb8b9553d3e2ed958\"><code>STACK_GUARD_PAGE_LEADING\/TRAILING<\/code> tests<\/a>.)<\/p>\n<p>One aspect of the guard page protection that will need further attention (on all architectures) is that if the stack grew because of a giant Variable Length Array on the stack (effectively an implicit <code>alloca()<\/code> call), it might be possible to jump over the guard page entirely (as seen in the userspace <a href=\"https:\/\/blog.qualys.com\/securitylabs\/2017\/06\/19\/the-stack-clash\">Stack Clash<\/a> attacks). Thankfully the use of VLAs is rare in the kernel. In the future, hopefully we&#8217;ll see the addition of <a href=\"http:\/\/www.openwall.com\/lists\/kernel-hardening\/2017\/10\/22\/1\">PaX\/grsecurity&#8217;s STACKLEAK<\/a> plugin which, in addition to its primary purpose of clearing the kernel stack on return to userspace, makes sure stack expansion cannot skip over guard pages. This &#8220;stack probing&#8221; ability will <a href=\"https:\/\/developers.redhat.com\/blog\/2017\/09\/25\/stack-clash-mitigation-gcc-background\/\">likely also become directly available from the compiler<\/a> as well.<\/p>\n<p><strong><code>set_fs()<\/code> balance checking<\/strong><br \/>\nRelated to the <code>addr_limit<\/code> field mentioned above, another class of bug is finding a way to force the kernel into accidentally leaving <code>addr_limit<\/code> open to kernel memory through an unbalanced call to <code>set_fs()<\/code>. In some areas of the kernel, in order to reuse userspace routines (usually VFS or compat related), code will do something like: <code>set_fs(KERNEL_DS); ...some code here...; set_fs(USER_DS);<\/code>. When the <code>USER_DS<\/code> call goes missing (usually due to a buggy <a href=\"https:\/\/bugs.chromium.org\/p\/project-zero\/issues\/detail?id=990\">error path<\/a> or <a href=\"http:\/\/vulnfactory.org\/exploits\/full-nelson.c\">exception<\/a>), subsequent system calls can suddenly start writing into kernel memory via <code>copy_to_user<\/code> (where the &#8220;to user&#8221; really means &#8220;within the <code>addr_limit<\/code> range&#8221;).<\/p>\n<p>Thomas Garnier <a href=\"https:\/\/git.kernel.org\/linus\/5ea0727b163cb5575e36397a12eade68a1f35f24\">implemented USER_DS checking<\/a> at syscall exit time for x86, <a href=\"https:\/\/git.kernel.org\/linus\/e33f8d32677fa4f4f8996ef46748f86aac81ccff\">arm<\/a>, and <a href=\"https:\/\/git.kernel.org\/linus\/cf7de27ab35172a9240f079477cae3146a182998\">arm64<\/a> (with a small <a href=\"https:\/\/git.kernel.org\/linus\/a2048e34d4655c06d31400646ae495bbfeb16b27\">fix<\/a>). This means that a broken <code>set_fs()<\/code> setting will not extend beyond the buggy syscall that fails to set it back to <code>USER_DS<\/code>. Additionally, as part of the discussion on the best way to deal with this feature, Christoph Hellwig and Al Viro (and others) have been making <a href=\"https:\/\/git.kernel.org\/linus\/581bfce969cbfc7ce43ee92273be9cb7c3fdfa61\">extensive changes<\/a> to avoid the need for <code>set_fs()<\/code> being used at all, which should greatly reduce the number of places where it might be possible to introduce such a bug in the future.<\/p>\n<p><strong>SLUB freelist hardening<\/strong><br \/>\nA common class of heap attacks is <a href=\"http:\/\/resources.infosecinstitute.com\/exploiting-linux-kernel-heap-corruptions-slub-allocator\/\">overwriting the freelist pointers<\/a> stored inline in the unallocated SLUB cache objects. PaX\/grsecurity developed an inexpensive defense that XORs the freelist pointer with a global random value (and the storage address). Daniel Micay improved on this by using a per-cache random value, and I refactored the code a bit more. The <a href=\"https:\/\/git.kernel.org\/linus\/2482ddec670fb83717d129012bc558777cb159f7\">resulting feature<\/a>, enabled with <code>CONFIG_SLAB_FREELIST_HARDENED<\/code>, makes freelist pointer overwrites very hard to exploit unless an attacker has found a way to expose both the random value and the pointer location. This should render blind heap overflow bugs much more difficult to exploit.<\/p>\n<p>Additionally, Alexander Popov implemented a <a href=\"https:\/\/git.kernel.org\/linus\/ce6fa91b93630396ca220c33dd38ffc62686d499\">simple double-free defense<\/a>, similar to the <a href=\"https:\/\/sourceware.org\/git\/?p=glibc.git;a=blob;f=malloc\/malloc.c;h=be472b2ba3885b194f55c29474c4ad5d6a61b729;hb=eefa3be8e4c2c721a9f277d8ea2e11180231829f#l3817\">&#8220;fasttop&#8221;<\/a> check in the GNU C library, which will catch sequential <code>free()<\/code>s of the same pointer. (And has already <a href=\"https:\/\/bugzilla.kernel.org\/show_bug.cgi?id=197515\">uncovered a bug<\/a>.)<\/p>\n<p>Future work would be to provide similar metadata protections to the SLAB allocator (though <a href=\"http:\/\/events.linuxfoundation.org\/sites\/events\/files\/slides\/slaballocators.pdf\">SLAB doesn&#8217;t store its freelist within the individual unused objects<\/a>, so it has a different set of exposures compared to SLUB).<\/p>\n<p><strong>setuid-exec stack limitation<\/strong><br \/>\nContinuing the various additional defenses to protect against future problems related to userspace memory layout manipulation (as shown most recently in the <a href=\"https:\/\/blog.qualys.com\/securitylabs\/2017\/06\/19\/the-stack-clash\">Stack Clash<\/a> attacks), I implemented <a href=\"https:\/\/git.kernel.org\/linus\/64701dee4178eb4a771b8b36cd86560f5b0e2460\">an 8MiB stack limit<\/a> for privileged (i.e. setuid) execs, inspired by a similar protection in grsecurity, after reworking the secureexec handling by LSMs. This complements the <a href=\"https:\/\/git.kernel.org\/linus\/da029c11e6b12f321f36dac8771e833b65cec962\">unconditional limit to the size of exec arguments<\/a> that landed in v4.13.<\/p>\n<p><strong>randstruct automatic struct selection<\/strong><br \/>\nWhile the bulk of the port of the <a href=\"\/blog\/archives\/2017\/09\/05\/security-things-in-linux-v4-13\/\">randstruct gcc plugin<\/a> from grsecurity landed in v4.13, the last of the work needed to <a href=\"https:\/\/git.kernel.org\/linus\/9225331b310821760f39ba55b00b8973602adbb5\">enable automatic struct selection<\/a> landed in v4.14. This means that the coverage of randomized structures, via <code>CONFIG_GCC_PLUGIN_RANDSTRUCT<\/code>, now includes one of the major targets of exploits: function pointer structures. Without knowing the build-randomized location of a callback pointer an attacker needs to overwrite in a structure, exploits become much less reliable.<\/p>\n<p><strong>structleak passed-by-reference variable initialization<\/strong><br \/>\nArd Biesheuvel <a href=\"https:\/\/git.kernel.org\/linus\/f7dd2507893cc3425d3ffc2369559619960befb0\">enhanced the structleak gcc plugin<\/a> to initialize all variables on the stack that are passed by reference when built with <code>CONFIG_GCC_PLUGIN_STRUCTLEAK_BYREF_ALL<\/code>. Normally the compiler will yell if a variable is used before being initialized, but it silences this warning if the variable&#8217;s address is passed into a function call first, as it has no way to tell if the function did actually initialize the contents. So the plugin now zero-initializes such variables (if they hadn&#8217;t already been initialized) before the function call that takes their address. Enabling this feature has a small performance impact, but solves many stack content exposure flaws. (In fact at least <a href=\"https:\/\/lkml.org\/lkml\/2017\/10\/31\/609\">one such flaw<\/a> reported during the v4.15 development cycle was mitigated by this plugin.)<\/p>\n<p><strong>improved boot entropy<\/strong><br \/>\nLaura Abbott and Daniel Micay improved early boot entropy available to the stack protector by both <a href=\"https:\/\/git.kernel.org\/linus\/121388a31362b0d3176dc1190ac8064b98a61b20\">moving the stack protector setup later in the boot<\/a>, and including the <a href=\"https:\/\/git.kernel.org\/linus\/33d72f3822d7ff8a9e45bd7413c811085cb87aa5\">kernel command line in boot entropy collection<\/a> (since with some devices it changes on each boot).<\/p>\n<p><strong>eBPF JIT for 32-bit ARM<\/strong><br \/>\nThe ARM BPF JIT had been around a while, but it didn&#8217;t support eBPF (and, as a result, did not provide <a href=\"\/blog\/archives\/2016\/10\/03\/security-things-in-linux-v4-7\/\">constant value blinding<\/a>, which meant it was exposed to being used by an attacker to build arbitrary machine code with BPF constant values). Shubham Bansal spent a bunch of time building a <a href=\"https:\/\/git.kernel.org\/linus\/39c13c204bb1150d401e27d41a9d8b332be47c49\">full eBPF JIT for 32-bit ARM<\/a> which both speeds up eBPF and brings it up to date on JIT exploit defenses in the kernel.<\/p>\n<p><strong>seccomp improvements<\/strong><br \/>\nTyler Hicks addressed a long-standing deficiency in how seccomp could log action results. In addition to creating a way to <a href=\"https:\/\/git.kernel.org\/linus\/e66a39977985b1e69e17c4042cb290768eca9b02\">mark a specific seccomp filter<\/a> as needing to be logged with <code>SECCOMP_FILTER_FLAG_LOG<\/code>, he added a new action result, <a href=\"https:\/\/git.kernel.org\/linus\/59f5cf44a38284eb9e76270c786fb6cc62ef8ac4\"><code>SECCOMP_RET_LOG<\/code><\/a>. With these changes in place, it should be much easier for developers to inspect the results of seccomp filters, and for process launchers to generate logs for their child processes operating under a seccomp filter.<\/p>\n<p>Additionally, I finally found a way to implement an often-requested feature for seccomp, which was to kill an entire process instead of just the offending thread. This was done by creating the <code>SECCOMP_RET_ACTION_FULL<\/code> mask (n\u00c3\u00a9e <code>SECCOMP_RET_ACTION<\/code>) and implementing <a href=\"https:\/\/git.kernel.org\/linus\/0466bdb99e8744bc9befa8d62a317f0fd7fd7421\"><code>SECCOMP_RET_KILL_PROCESS<\/code><\/a>.<\/p>\n<p>That\u00e2\u20ac\u2122s it for now; please let me know if I missed anything. The <a href=\"\/blog\/archives\/2018\/02\/05\/security-things-in-linux-v4-15\/\">v4.15<\/a> merge window is now open!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Previously: v4.13. Linux kernel v4.14 was released this last Sunday, and there&#8217;s a bunch of security things I think are interesting: vmapped kernel stack on arm64 Similar to the same feature on x86, Mark Rutland and Ard Biesheuvel implemented CONFIG_VMAP_STACK for arm64, which moves the kernel stack to an isolated and guard-paged vmap area. With [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20,18,21,6,14,19],"tags":[],"_links":{"self":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/1075"}],"collection":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/comments?post=1075"}],"version-history":[{"count":16,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/1075\/revisions"}],"predecessor-version":[{"id":1339,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/1075\/revisions\/1339"}],"wp:attachment":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/media?parent=1075"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/categories?post=1075"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/tags?post=1075"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}