10 ms·
Towards Linux Kernel Memory Safety
- empath75 9y agoLong term, the solution has to be switching to an OS that’s written in a memory safe language.
- adrianN 9y agoIf by long-term you mean at least fifty years, then maybe.
- alphaalpha101 9y agoGiven that it hasn't even been around for that long, I rather doubt it. If the same amount of effort that has gone into the Linux kernel went into another Unix kernel written in some memory-safe version of C, I'm sure it could be just as successful. It might even take less time, though I doubt it.
- StudentStuff 9y agoSo Rust it is then, eh? Could work through the kernel module by module to rewrite it in rust, but it'd be a multi-year process (like Firefox's rewrite has been).
- DigitalJack 9y agoit's 20 million lines of code.
- monocasa 9y agoYou could triage. Zorro bus support can probably wait until someone has a specific itch to scratch.
- vilhelm_s 9y agoFirefox is 17 million!
- alphaalpha101 9y agoAnd is not written in Rust, and won't be written in Rust any time soon.
- mundanevoice 9y agoThe whole Firefox codebase has not been ported to Rust and will not be anytime soon. So your argument doesn't hold true.
- daveFNbuck 9y agoIsn't that a point in the rewrite's favor? You don't have to port everything to gain a lot of the benefits.
- mundanevoice 9y ago> You don't have to port everything to gain a lot of the benefits. I agree with this. But just saying Firefox has X millions of lines of code doesn't say anything about the possibility for Linux to be ported to Rust.
- craftyguy 9y agoyou're comparing apples and rutabagas. code line count is a hilariously inaccurate way to measure the complexity required for a portable OS kernel vs a userspace application.
- mundanevoice 9y ago> code line count is a hilariously inaccurate way to measure the complexity required for a portable OS kernel vs a userspace application I never said that. My whole premise is that you can't say anything like this by just saying code count on two very different projects. Maybe you didn't read my comments properly.
- staticassertion 9y agoRight, but you don't have to rewrite it at once. There are certain areas of the kernel that have historically had more issues, are at higher risk of attack, etc. Those will make up far less code than 20 million lines, and you can start there.
- ynezz 9y agoYou mean rewriting unsafe C code to Rust by annotating it with `unsafe` keyword? :-) Try to write in Rust something which would touch bare metal hardware. It would be PITA, it would be full of unsafe keywords and assembler code so it would possibly result in similar amount of bugs in the end, just in different parts.
- dikaiosune 9y agoThis is empirically not true if you look at the usage of unsafe in pure Rust kernels. Yes, there is assembly needed, and some unsafe Rust code, but it's very possible to wrap up unsafe operations in safe APIs. For example, the kernel repository for Redox (a written-in-Rust OS project) appears to have 242 usages of the unsafe keyword (including comments bc lazy), out of 18205 lines of Rust source.
- red75prime 9y agoI can't come up with a situation where C doesn't need inline assembly, while Rust does. Do you have some specific example on your mind?
- zaarn 9y agoIt's actually not that much unsafe. You can wrap most unsafe operations to be safe with proper checks, I've done it myself and it's much less than you would expect since a lot of the memory accesses can be made safe trivially.
- pjmlp 9y agoNot necessarily, Google's approach has been to forbid kernel access (ChromeOS), to make a big pain to use native code only for specific use cases (Android) or to develop a new microkernel in a mix of C++/Rust/Go/Dart (Fuchsia).
- IcePic 9y ago..and of course Rust needs to be ported and have its .. "runtime" fixed for all platforms linux runs on. Otherwise this will be a decent way to kill off a bunch of platforms.
- koffiezet 9y agoWas going to point this out too... Having the Rust compiler support all platforms GCC is able to target is going to be a massive task - nevermind maintaining them. That's one of the main advantages of C - it runs on pretty much everything.
- Varriount 9y agoSeriously? What is it worth people thinking that Rust is the only choice for such things? Memory safety is nothing new. Languages like D, Nim, and Swift all allow for the possibility of both memory safety and low-level access.
- mkesper 9y agoMemory safety without GC and with zero-cost abstractions is the combination rust enables. Nim and swift (and Go) strictly require a GC and D without GC doesn't work without heavy lifting.
- dom96 9y ago> Nim and swift (and Go) strictly require a GC and D without GC doesn't work without heavy lifting. I think Nim belongs with D here. You can freely disable the GC in Nim. Full disclosure: I'm a Nim core dev.
- Varriount 9y agoWhat's wrong with garbage collectors? Depending on the type, you can get performance characteristics better than or similar to destructor-based management. Even current operating systems use forms of garbage collection (such as refcounting) to track resources.
- ksec 9y agoWell at least someone is already trying to write an OS with Rust. https://github.com/redox-os/redox https://github.com/redox-os/redox
- Santosh83 9y agoJust to turn this discussion towards the practical aspect: does anyone know if a concrete effort has been made to sound out Torvalds and the other senior kernel devs about accepting Rust into the kernel? I would imagine that initially as PoC one can start by implementing a simple module... obviously a small portion of the Rust stdlib and runtime needs to be ported and of course rustc needs to be integrated into the kernel toolchain... Perhaps someone has done it privately (i.e., without attempting to submit patches back to source)?
- steeleduncan 9y agoIn [1] (from 2016) he says I don't think you actually solve any of the really hard kernel problems with your choice of programming language. The big problems tend to be about hardware support (all those drivers, all the odd details about different platforms, all the subtleties in memory management and resource accounting) I think what he is saying is that rewriting c->(e.g.) rust doesn't improve make progress on any of the design problems in the linux kernel. In [2] (2013) he expands on that, essentially explaining how well C maps to machine instructions, and how that helps optimise the kernel. Personally I think Rust maps very well to machine code, and although it doesn't solve design problems, I do think it saves a lot of time debugging the security flaws and bugs that can result from memory bugs. [1] https://www.infoworld.com/article/3109150/linux/linux-at-25-linus-torvalds-on-the-evolution-and-future-of-linux.html https://www.infoworld.com/article/3109150/linux/linux-at-25-... [2] https://www.reddit.com/r/programming/comments/1t0gfy/linus_torvalds_on_the_question_if_there_is_a/ https://www.reddit.com/r/programming/comments/1t0gfy/linus_t...
- Santosh83 9y agoI tend to agree with his point that you may perhaps not solve design and driver problems just changing language, but can anyone dispute that a memory-safe language can at least help eliminate routine programming pitfalls like off-by-one, null deferences, double-free and so on? And these are the types of innocuous and inadvertent errors that are exploited by black-hats, sometimes with costly consequences. I don't see a strong argument against a memory-safe language, although granted it won't solve architectural and hardware issues. Perhaps the effort to support, say Rust, in the kernel is just not worth the trade-off at this point? Perhaps no one has taken on the mantle for doing so? But I can't see how one can categorically argue against it...
- rurban 9y agoRust is not safe. ATS, Pony, C#, Java, lisp come to my mind. But maybe even D, Nim, swift, crystal. Singularity/Midori or the LispM were good candidates. And it cannot be a monolithic kernel of course.
- Nokinside 9y agoIt's possible to program in C in a way that is memory safe and verify it programmatically (even with memory allocations and recursion). It's even do static verification of the absence of runtime errors, arithmetic overflows, inconsistent locking, etc. Best tools are commercial unfortunately.
- pcwalton 9y agoCan you elaborate as to how to prevent use-after-free statically in C without forbidding dynamic memory allocation?
- Nokinside 9y agoBy proving that memory references don't live longer than the allocated memory. The use of dynamic allocation must be carefully restricted and programmer may need to provide provide assertions or modify the code to pass verification. There is two ways tho think static verification: 1. Language level verification. All valid programs are verified to be correct in respect of safety guarantees the language gives. 2. Verification of safety features that can't be proved in general. In most cases it's possible to write program in a way that it can be verified to be correct, but finding a way to write provably correct program may need some work.
- pjmlp 9y agoNow try to use that in the presence of commercial libraries.
- jhasse 9y agoTry to use Rust in the presence of commercial libraries.
- pjmlp 9y agoEasy just like any compiler for a memory safe language. There might exist logical bugs, but the language semantics allow for a higher thrust of code quality, assuming the binaries haven't been tampered with. Every line of C code is unsafe, specially if the binary was compiled with -O3. Regarding Rust, the only issue is lack of support for binary libraries in Cargo, one needs to call rustc directly.
- akkartik 9y agoNot necessarily: http://www.cl.cam.ac.uk/~srk31/research/papers/kell17some-preprint.pdf http://www.cl.cam.ac.uk/~srk31/research/papers/kell17some-pr... HN discussion: https://news.ycombinator.com/item?id=15179188 https://news.ycombinator.com/item?id=15179188
- pcwalton 9y agoIf someone was going to deploy a version of the Linux kernel with SoftBound (which is among other things what this paper suggests), they would have done so by now. It hasn't happened, because (a) contrary to what that paper suggests, performance really is a concern; (b) the entire ecosystem of C is what makes it so popular, not the language itself. Replacing the runtime is a huge amount of work.
- pjmlp 9y agoC performance is a result of 40 years taking advantage of UB optimizations.
- johncolanduoni 9y agoI think they were talking about SoftBound vs vanilla C performance, not Rust vs C.
- StreamBright 9y agoOr it has to run on a memory safe architecture. http://phrack.org/issues/64/6.html http://phrack.org/issues/64/6.html "- separated kernel and process address space (both can use the whole address space). Such an implementation, to be efficient, requires a dedicated support from the underlaining architecture. It is the case of the primary and secondary context register used in conjunction with the ASI identifiers on the UltraSPARC (sun4u/sun4v) architecture. The only limitation to kernel (and processes) virtual space on systems implementing an userland/kerneland separated address space is given by the architecture (UltraSPARC I and II can reference only 44bit of the whole 64bit addressable space. This VA-hole is placed among 0x0000080000000000 and 0xFFFFF7FFFFFFFFFF). This memory model makes explotation indeed harder, because we can't directly dereference the userspace. The previously cited NULL pointer dereferences are pretty much un-exploitable. Moreover, we can't rely on "valid" userland addresses as a place to store our shellcode (or any other kernel emulation data), neither we can "return to userspace"."
- lunixbochs 9y ago> separated kernel and process address space This already exists on x86_64 Linux in the form of SMEP and SMAP. > With SMEP enabled, it’s no longer possible to map exploit payloads in userland, as the CPU will trigger a fault if it attempts to execute those user pages in kernel mode http://vulnfactory.org/blog/2011/06/05/smep-what-is-it-and-how-to-beat-it-on-linux/ http://vulnfactory.org/blog/2011/06/05/smep-what-is-it-and-h... > SMEP can be used to prevent supervisor-mode code from unintentionally executing user-space code. SMAP extends this protection to reads and writes https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevention https://en.wikipedia.org/wiki/Supervisor_Mode_Access_Prevent... These mitigations aren't overly novel at this point and don't prevent exploits (just complicates them). Here's a recent CVE PoC containing an SMEP and KASLR bypass: https://github.com/xairy/kernel-exploits/blob/master/CVE-2017-1000112/poc.c https://github.com/xairy/kernel-exploits/blob/master/CVE-201... Full memory safety takes this much further, and should be far harder to bypass.
- StreamBright 9y agoGood to know. I think there is no silver bullet in security so anything making exploitation harder is good.
- zaarn 9y agoLong term the solution is to switch to an OS that is memory safe and has a safe architecture that simply forbids exploits from working. Memory safe languages are not panacea, not even close, and especially not in an operating system.
- anameaname 9y agoSource for those interested: https://github.com/torvalds/linux/blob/master/lib/refcount.c https://github.com/torvalds/linux/blob/master/lib/refcount.c I'm kind of surprised that the authors went with compare-and-exchange for their ref count, rather than get-and-increment. Even if the counter does overflow, it's usually detectable, and reversible. This is true even in the face of concurrent updates. The benefit is that there is only one atomic operation in the fast path.
- Someone 9y ago”usually detectable” isn’t good enough. You must assume attackers will try to hit your code zillions of times until they hit the ‘unusual’ case.
- fulafel 9y agoThe MPX part was a good excuse to look around at the status of MPX support. It seems GCC is the major compiler to support it, but it's under threat of depreciation because the bootsrap build with MPX has been broken for so long. Also the lack of AMD buy-in (patents?) seems like a big hinderance compared to more compatible compiler-based approaches for C memory safety, like SoftBound, CCured, etc.
- pjmlp 9y agoThe problem with any of such approaches, versus safer languages, is that they only work properly if 100% of the source code is available.
- zvrba 9y agoWhich it is for most of internet infrastructure.
- AstralStorm 9y agoBut not vulnerable embedded devices, cell phones and IoT hardware.
- zvrba 9y agoHow many of these even run on the latest Intel CPUs?
- joosters 9y agoI don't understand your point. If you haven't got all the source code (e.g. random drivers), you're unlikely to have any say in the language that the binary code blobs were written in either.
- pjmlp 9y agoLanguages like Ada just forbid many of the errors that lead to memory corruption in C, by default. So it would only happen with a binary Ada library in two ways: - the binary was manipulated and thus does not map to the original source code - the code was compiled with permission for Uncheked packages enabled In C, 100% of the source code is unsafe, specially when compiled with -O3.
- lima 9y agoIs this PAX_REFCOUNT or something entirely new?
- DSingularity 9y agoCan anyone here comment on the races in MPX and whether this will prevent deployment? https://intel-mpx.github.io/microbenchmarks/#multithreading https://intel-mpx.github.io/microbenchmarks/#multithreading
- youdontknowtho 9y agoThis is really cool. I would love to hear more about this. Those bounds checking instructions will hopefully make a big difference.