{"id":1494,"date":"2021-02-08T16:47:47","date_gmt":"2021-02-09T00:47:47","guid":{"rendered":"https:\/\/outflux.net\/blog\/?p=1494"},"modified":"2022-04-04T15:50:02","modified_gmt":"2022-04-04T22:50:02","slug":"security-things-in-linux-v5-8","status":"publish","type":"post","link":"https:\/\/outflux.net\/blog\/archives\/2021\/02\/08\/security-things-in-linux-v5-8\/","title":{"rendered":"security things in Linux v5.8"},"content":{"rendered":"<p>Previously: <a href=\"\/blog\/archives\/2020\/09\/21\/security-things-in-linux-v5-7\/\">v5.7<\/a><\/p>\n<p>Linux <a href=\"https:\/\/lore.kernel.org\/lkml\/CAHk-=wj+mDPbj8hXspXRAksh+1TmPjubc9RNEbu8EVpYyypX=w@mail.gmail.com\">v5.8 was released in August, 2020<\/a>. Here\u2019s my summary of various security things that caught my attention:<\/p>\n<p><strong id=\"v5.8-bti\">arm64 Branch Target Identification<\/strong><br \/>\nDave Martin <a href=\"https:\/\/git.kernel.org\/linus\/8ef8f360cf30be12382f89ff48a57fbbd9b31c14\">added support for ARMv8.5&#8217;s Branch Target Instructions<\/a> (<a href=\"https:\/\/developer.arm.com\/architectures\/learn-the-architecture\/providing-protection-for-complex-software\/single-page\">BTI<\/a>), which are enabled in <a href=\"https:\/\/git.kernel.org\/linus\/ab7876a98a2160092133de4c648e94b18bc3f139\">userspace at execve()<\/a> time, and all the time <a href=\"https:\/\/git.kernel.org\/linus\/92e2294d870bc9e77592c2454f565c3bd6bb79ad\">in the kernel<\/a> (which required manually marking up a lot of non-C code, like assembly and <a href=\"https:\/\/git.kernel.org\/linus\/fa76cfe65c1d748ef418e930a4b631a03b28f04c\">JIT code<\/a>).<\/p>\n<p>With this in place, Jump-Oriented Programming (JOP, where code gadgets are chained together with jumps and calls) is no longer available to the attacker. An attacker&#8217;s code must make direct function calls. This basically reduces the &#8220;usable&#8221; code available to an attacker from every word in the kernel text to only function entries (or jump targets). This is a &#8220;low granularity&#8221; forward-edge Control Flow Integrity (CFI) feature, which is important (since it greatly reduces the potential targets that can be used in an attack) and cheap (implemented in hardware). It&#8217;s a good first step to strong CFI, but (as we&#8217;ve seen with things like CFG) it isn&#8217;t usually strong enough to stop a motivated attacker. &#8220;High granularity&#8221; CFI (which uses a more specific branch-target characteristic, like function prototypes, to track expected call sites) is not yet a hardware supported feature, but the software version will be coming in the future by way of <a href=\"https:\/\/github.com\/samitolvanen\/linux\/commits\/clang-cfi\">Clang&#8217;s CFI implementation<\/a>.<\/p>\n<p><strong>arm64 Shadow Call Stack<\/strong><br \/>\nSami Tolvanen landed the <a href=\"https:\/\/git.kernel.org\/linus\/5287569a790d2546a06db07e391bf84b8bd6cf51\">kernel implementation of Clang&#8217;s Shadow Call Stack<\/a> (<a href=\"https:\/\/clang.llvm.org\/docs\/ShadowCallStack.html\">SCS<\/a>), which protects the kernel against Return-Oriented Programming (ROP) attacks (where code gadgets are chained together with returns). This backward-edge CFI protection is implemented by keeping a second dedicated stack pointer register (<code>x18<\/code>) and keeping a copy of the return addresses stored in a separate &#8220;shadow stack&#8221;. In this way, manipulating the regular stack&#8217;s return addresses will have no effect. (And since a copy of the return address continues to live in the regular stack, no changes are needed for back trace dumps, etc.)<\/p>\n<p>It&#8217;s worth noting that unlike BTI (which is hardware based), this is a software defense that relies on the location of the Shadow Stack (i.e. the value of <code>x18<\/code>) staying secret, since the memory could be written to directly. Intel&#8217;s hardware ROP defense (CET) uses a hardware shadow stack that isn&#8217;t directly writable. ARM&#8217;s hardware defense against ROP is <a href=\"\/blog\/archives\/2020\/09\/21\/security-things-in-linux-v5-7\/#v5.7-pac\">PAC<\/a> (which is actually designed as an arbitrary CFI defense &#8212; it can be used for forward-edge too), but that depends on having ARMv8.3 hardware. The expectation is that SCS will be used until PAC is available.<\/p>\n<p><strong>Kernel Concurrency Sanitizer infrastructure added<\/strong><br \/>\nMarco Elver landed support for the <a href=\"https:\/\/git.kernel.org\/linus\/dfd402a4c4baae42398ce9180ff424d589b8bffc\">Kernel Concurrency Sanitizer<\/a>, which is a new debugging infrastructure to find data races in the kernel, via <code>CONFIG_KCSAN<\/code>. This immediately found real bugs, with some fixes having <a href=\"https:\/\/git.kernel.org\/linus\/d6c1f098f2a7ba62627c9bc17cda28f534ef9e4a\">already<\/a> <a href=\"https:\/\/git.kernel.org\/linus\/68ace460c5b2a96a82ee49ab0b589ceed8abd000\">landed<\/a> too. For more details, see the <a href=\"https:\/\/www.kernel.org\/doc\/html\/latest\/dev-tools\/kcsan.html\">KCSAN documentation<\/a>.<\/p>\n<p><strong>new capabilities<\/strong><br \/>\nAlexey Budankov <a href=\"https:\/\/git.kernel.org\/linus\/980737282232b752bb14dab96d77665c15889c36\/\">added <code>CAP_PERFMON<\/code><\/a>, which is designed to allow access to <code>perf()<\/code>. The idea is that this capability gives a process access to only read aspects of the running kernel and system. No longer will access be needed through the much more powerful abilities of <code>CAP_SYS_ADMIN<\/code>, which has many ways to change kernel internals. This allows for a split between controls over the confidentiality (read access via CAP_PERFMON) of the kernel vs control over integrity (write access via CAP_SYS_ADMIN).<\/p>\n<p>Alexei Starovoitov <a href=\"https:\/\/git.kernel.org\/linus\/a17b53c4a4b55ec322c132b6670743612229ee9c\/\">added <code>CAP_BPF<\/code><\/a>, which is designed to separate BPF access from the all-powerful <code>CAP_SYS_ADMIN<\/code>. It is designed to be used in combination with <code>CAP_PERFMON<\/code> for tracing-like activities and <code>CAP_NET_ADMIN<\/code> for networking-related activities. For things that could change kernel integrity (i.e. write access), <code>CAP_SYS_ADMIN<\/code> is still required.<\/p>\n<p><strong id=\"v5.8-network-rng\">network random number generator improvements<\/strong><br \/>\nWilly Tarreau made the <a href=\"https:\/\/git.kernel.org\/linus\/f227e3ec3b5cad859ad15666874405e8c1bbc1d4\">network code&#8217;s random number generator less predictable<\/a>. This will further frustrate any attacker&#8217;s attempts to recover the state of the RNG externally, which might lead to the ability to hijack network sessions (by correctly guessing packet states).<\/p>\n<p><strong>fix various kernel address exposures to non-<code>CAP_SYSLOG<\/code><\/strong><br \/>\nI fixed several situations where kernel addresses were still being exposed to unprivileged (i.e. non-<code>CAP_SYSLOG<\/code>) users, though usually only through odd corner cases. After <a href=\"https:\/\/git.kernel.org\/linus\/60f7bb66b88b649433bf700acfc60c3f24953871\">refactoring how capabilities were being checked<\/a> for files in <code>\/sys<\/code> and <code>\/proc<\/code>, the <a href=\"https:\/\/git.kernel.org\/linus\/b25a7c5af9051850d4f3d93ca500056ab6ec724b\">kernel modules sections<\/a>, <a href=\"https:\/\/git.kernel.org\/linus\/60f7bb66b88b649433bf700acfc60c3f24953871\">kprobes<\/a>, and <a href=\"https:\/\/git.kernel.org\/linus\/63960260457a02af2a6cb35d75e6bdb17299c882\">BPF<\/a> exposures got fixed. (Though in doing so, I briefly made things much worse before getting it <a href=\"https:\/\/git.kernel.org\/linus\/11990a5bd7e558e9203c1070fc52fb6f0488e75b\">properly fixed<\/a>. Yikes!)<\/p>\n<p><strong>RISCV W^X detection<\/strong><br \/>\nFollowing up on his recent work to <a href=\"\/blog\/archives\/2020\/09\/21\/security-things-in-linux-v5-7\/#v5.7-wx-riscv\">enable strict kernel memory protections on RISCV<\/a>, Zong Li has now added <a href=\"https:\/\/git.kernel.org\/linus\/b422d28b21773bbfc9e84dbb5579a8ce355279ca\">support for <code>CONFIG_DEBUG_WX<\/code><\/a> as seen for other architectures. Any writable and executable memory regions in the kernel (which are lovely targets for attackers) will be loudly noted at boot so they can get corrected.<\/p>\n<p><strong><code>execve()<\/code> refactoring continues<\/strong><br \/>\nEric W. Biederman continued working on <a href=\"https:\/\/git.kernel.org\/linus\/56305aa9b6fab91a5555a45796b79c1b0a6353d1\"><code>execve()<\/code> refactoring<\/a>, including getting rid of the <a href=\"https:\/\/git.kernel.org\/linus\/bc2bf338d54b7aadaed49bb45b9e10d4592b2a46\">frequently problematic recursion<\/a> used to locate binary handlers. I used the opportunity to dust off some old <a href=\"https:\/\/git.kernel.org\/linus\/b081320f0693cce0394f7c8bad9fba0b25982186\"><code>binfmt_script<\/code> regression tests<\/a> and get them into the kernel selftests.<\/p>\n<p><strong>multiple <code>\/proc<\/code> instances<\/strong><br \/>\nAlexey Gladkov modernized <code>\/proc<\/code> internals and provided a way to have <a href=\"https:\/\/git.kernel.org\/linus\/fa10fed30f2550313a8284365b3e2398526eb42c\">multiple <code>\/proc<\/code> instances<\/a> mounted in the same PID namespace. This allows for having multiple views of <code>\/proc<\/code>, with different features enabled. (Including the newly added <a href=\"https:\/\/git.kernel.org\/linus\/24a71ce5c47f6b1b3cdacf544cb24220f5c3b7ef\">hidepid=4<\/a> and <a href=\"https:\/\/git.kernel.org\/linus\/6814ef2d992af09451bbeda4770daa204461329e\">subset=pid<\/a> mount <a href=\"https:\/\/www.kernel.org\/doc\/html\/latest\/filesystems\/proc.html#mount-options\">options<\/a>.)<\/p>\n<p><strong id=\"v5.8-set_fs\"><code>set_fs()<\/code> removal continues<\/strong><br \/>\nChristoph Hellwig, with Eric W. Biederman, Arnd Bergmann, and others, have been diligently working to entirely remove the kernel&#8217;s <code>set_fs()<\/code> interface, which has long been a source of security flaws due to weird confusions about which address space the kernel thought it should be accessing. Beyond things like the lower-level per-architecture <a href=\"https:\/\/git.kernel.org\/linus\/c3b3f52476412a3899f2c65b220075aceb18dd2c\">signal handling<\/a> code, this has needed to touch various <a href=\"https:\/\/git.kernel.org\/linus\/fa4751f454e6b51ef93babfd8b6c8b43a65c9db2\">parts<\/a> of the <a href=\"https:\/\/git.kernel.org\/linus\/d2530b436f114dfbd1adc70c59d8d31038318726\">ELF<\/a> loader, and <a href=\"https:\/\/git.kernel.org\/linus\/1f466e1f15cf1dac7c86798d694649fc42cd868a\">networking<\/a> code too.<\/p>\n<p><strong><code>READ_IMPLIES_EXEC<\/code> is no more for native 64-bit<\/strong><br \/>\nThe <code>READ_IMPLIES_EXEC<\/code> flag was a work-around for dealing with the addition of non-executable (NX) memory when x86_64 was introduced. It was designed as a way to mark a memory region as &#8220;well, since we don&#8217;t know if this memory region was expected to be executable, we must assume that if we need to read it, we need to be allowed to execute it too&#8221;. It was designed mostly for stack memory (where trampoline code might live), but it would carry over into all <code>mmap()<\/code> allocations, which would mean sometimes exposing a large attack surface to an attacker looking to find executable memory. While normally this didn&#8217;t cause problems on modern systems that correctly marked their ELF sections as NX, there were still some awkward corner-cases. I fixed this by splitting <code>READ_IMPLIES_EXEC<\/code> from the ELF <code>PT_GNU_STACK<\/code> marking on <a href=\"https:\/\/git.kernel.org\/linus\/122306117afe4ba202b5e57c61dfbeffc5c41387\">x86<\/a> and <a href=\"https:\/\/git.kernel.org\/linus\/eaf3f9e61887332d5097dbf0b327b8377546adc5\">arm\/arm64<\/a>, and declaring that a native 64-bit process would never gain <code>READ_IMPLIES_EXEC<\/code> on <a href=\"https:\/\/git.kernel.org\/linus\/9fccc5c0c99f238aa1b0460fccbdb30a887e7036\">x86_64<\/a> and <a href=\"https:\/\/git.kernel.org\/linus\/6e0d6ac5f3d9d90271899f6d340872360fe1caee\">arm64<\/a>, which matches the behavior of other native 64-bit architectures that correctly didn&#8217;t ever implement <code>READ_IMPLIES_EXEC<\/code> in the first place.<\/p>\n<p><strong id=\"v5.8-flex-array\">array index bounds checking continues<\/strong><br \/>\nAs part of the ongoing work to use modern flexible arrays in the kernel, Gustavo A. R. Silva added the <a href=\"https:\/\/git.kernel.org\/linus\/b19d57d0f3cc6f1022edf94daf1d70506a09e3c2\"><code>flex_array_size()<\/code> helper<\/a> (as a cousin to <code>struct_size()<\/code>). The <a href=\"https:\/\/git.kernel.org\/pub\/scm\/linux\/kernel\/git\/torvalds\/linux.git\/log\/?h=v5.8&#038;qt=grep&#038;q=with+flexible-array\">zero\/one-member into flex array conversions<\/a> continue with over a hundred commits as we slowly get closer to being able to build with <code>-Warray-bounds<\/code>.<\/p>\n<p><strong><code>scnprintf()<\/code> replacement continues<\/strong><br \/>\nChen Zhou joined Takashi Iwai in <a href=\"\/blog\/archives\/2020\/09\/21\/security-things-in-linux-v5-7\/#v5.7-scnprintf\">continuing<\/a> to replace potentially unsafe uses of <code>sprintf()<\/code> with <code>scnprintf()<\/code>. Fixing all of these will make sure the kernel avoids nasty buffer concatenation surprises.<\/p>\n<p>That&#8217;s it for now! Let me know if there is anything else you think I should mention here. Next up: Linux <a href=\"\/blog\/archives\/2021\/04\/05\/security-things-in-linux-v5-9\/\">v5.9<\/a>.<\/p>\n<p style='text-align:left'>&copy; 2021 &#8211; 2022, <a href=\"https:\/\/outflux.net\/blog\/\">Kees Cook<\/a>. This work is licensed under a <a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\">Creative Commons Attribution-ShareAlike 4.0 License<\/a>.<br \/><a rel=\"license\" href=\"http:\/\/creativecommons.org\/licenses\/by-sa\/4.0\/\"><img decoding=\"async\" alt=\"CC BY-SA 4.0\" style=\"border-width:0\" src=\"https:\/\/i.creativecommons.org\/l\/by-sa\/4.0\/88x31.png\" \/><\/a> <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Previously: v5.7 Linux v5.8 was released in August, 2020. Here\u2019s my summary of various security things that caught my attention: arm64 Branch Target Identification Dave Martin added support for ARMv8.5&#8217;s Branch Target Instructions (BTI), which are enabled in userspace at execve() time, and all the time in the kernel (which required manually marking up a [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,20,18,21,6,14,19],"tags":[],"_links":{"self":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/1494"}],"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=1494"}],"version-history":[{"count":35,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/1494\/revisions"}],"predecessor-version":[{"id":1573,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/posts\/1494\/revisions\/1573"}],"wp:attachment":[{"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/media?parent=1494"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/categories?post=1494"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/outflux.net\/blog\/wp-json\/wp\/v2\/tags?post=1494"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}