There is gathering momentum around the idea of adding Rust to the Linux kernel. Why exactly is that a big deal, and what does this mean for the rest of us? The Linux kernel has been just C and assembly for its entire lifetime. A big project like the kernel has a great deal of shared tooling around making its languages work, so adding another one is quite an undertaking. There’s also the project culture developed around the language choice. So why exactly are the grey-beards of kernel development even entertaining the idea of adding Rust? To answer in a single line, it’s because C was designed in 1971, to run on the minicomputers at Bell Labs. If you want to shoot yourself in the foot, C will hand you the loaded firearm.
On the other hand, if you want to write a kernel, C is a great language for doing low-level coding. Direct memory access? Yep. Inline assembly? Sure. Runs directly on the metal, with no garbage collection or virtual machines in the way? Absolutely. But all the things that make C great for kernel programming also make C dangerous for kernel programming.
Now I hear your collective keyboards clacking in consternation: “It’s possible to write safe C code!” Yes, yes it is possible. It’s just very easy to mess up, and when you mess up in a kernel, you have security vulnerabilities. There’s also some things that are objectively terrible about C, like undefined behavior. C compilers do their best to do the right thing with cursed code like
i++ + i++; or
a[i] = i++;. But that’s almost certainly not going to do what you want it to, and even worse, it may sometimes do the right thing.
Rust seems to be gaining popularity. There are some ambitious projects out there, like rewriting coreutils in Rust. Many other standard applications are getting a Rust rewrite. It’s fairly inevitable that the collection of Rust developers started to ask, could we invade the kernel next? This was pitched for a Linux Plumbers Conference, and the mailing list response was cautiously optimistic. If Rust could be added without breaking things, and without losing the very things that makes Rust useful, then yes it would be interesting.
So what makes Rust so interesting? There are two main answers here. First, it’s a modern language with a strong memory-safety guarantee. (There’s a caveat here, and we’ll cover unsafe code later.) Something around two thirds of all security vulnerabilities are a result of memory handling bugs, and Rust pretty much eliminates those. A second bonus, Rust has some of the niceties we’ve come to appreciate in modern languages, like an easy-to-use
STRING type built-in to the standard library, and some handy functions for common scenarios like string comparison.
The other answer is that Rust is an easy fit with C code and kernel programming. Rust does it’s magic in the compiler. The code you write is what actually runs, without an interpreter or garbage collection trying to be helpful. Rust hasn’t overdosed on Object Oriented patterns, but meshes nicely with the C-style structs already used in the kernel. Even the stack model is very similar to C.
There’s one problem with Rust’s memory-safe guarantee — it’s impossible to write a kernel that is formally memory-safe. A kernel has to write to unallocated memory, do weird pointer math, and other seemingly bizarre things to actually make our computers work. This doesn’t work well with a language that tries to guarantee that memory manipulations are safe. How do you write kernel code with Rust, then? Rust has added the
unsafe keyword, allowing use of direct memory access and other such techniques that don’t work with Rusts’s memory guarantees. Keep the potential problems together, and it makes auditing easier.
There’s at least one other language that may come to mind as an incremental update to C that tries to do some of these things: C++. Surely this would have been even a better fit, right? Kernel devs have some strong feelings about that idea. To put it gently, none of the improvements in C++ are useful in the context of the kernel, and some of the other changes just get in the way.
What’s the Plan?
So are we about to see the kernel completely rewritten in Rust? Not likely. The kernel development process is painstakingly conservative, so the initial introduction of Rust is going to be done in the least obtrusive way possible — driver code. As kernel second-in-command [Greg Kroah-Hartman] put it, “drivers are probably the first place for an attempt like this as they are the ‘end leafs’ of the tree of dependencies in the kernel source. They depend on core kernel functionality, but nothing depends on them.”
In practice, this would mean that tooling, documentation, and example code would be merged into the kernel right away. At some point in the future, one of the interested parties, like Google, would start writing new drivers in Rust. Google seems to be very interested in converting parts of Android to Rust, likely in an attempt to thwart the continued pwnage of their OS from the likes of the NSO group. There’s a useful example driver in Rust on the Google Security Blog. Another interesting connection is that [Miguel Ojeda], lead developer of the Rust for Linux effort, is now employed full time by Prossimo for that purpose. Prossimo is an arm of the Internet Security Research Group, which is also famous for leading Let’s Encrypt. Funding for [Ojeda]’s work was provided by Google.
So where are we now? Version 6 of the Rust patches were just sent to the kernel mailing list. There have been a couple of very minor change requests, but most notably developers have begun calling for the patches to be pulled into the 5.19 kernel once its merge window opens. 5.18-rc6 was just released, so in two to three weeks we should see that kernel mint a final release, and the 5.19 merge window open. That’s right, there’s a very good chance we’ll see Rust added to the Linux kernel in about three weeks!
Once it finally lands, expect to see a simple driver that actually makes use of the support in the following version. So if 5.19 sees Rust support, a driver written in rust will probably happen in 5.20. As hinted at above, Google is one of the very interested parties in the Rust for Linux effort. It’s likely that some Android related code will be ported to Rust, as a part of Google’s continual effort to improve the security of their mobile ecosystem.
What Could Possibly Go Wrong?
Rust in Linux is almost certainly going to happen, but is that guaranteed to be a good thing? There are a few possible downsides to consider. First off, the interface between C and Rust is a likely place for unanticipated bugs to crop up. It’s new code, some of it generated automatically, doing something novel — there will certainly be surprises. That’s not really any more of a problem than any other new code. Bugs get fixed, problems get ironed out.
What may be more of an issue is the added complexity of debugging problems when there is another language to consider. Until now, the kernel has enjoyed the advantage that it’s all in C and all the programmers working on it are familiar with that language. Add a second language, and now there’s C programmers, Rust programmers, and the few that are actually proficient in both. There’s yet another compiler that could possibly introduce errors, and another toolchain to manage.
Lastly, there’s the danger that it just doesn’t catch on. It may be that the kernel community collectively shrugs, and goes on writing code in C, and the Rust support bit-rots. This is the least problematic issue, because the backing of big players like Google make this unlikely, and even if Rust dies on the vine, it’s easy to remove the code.
Are any of the above issues likely to be deal breakers? Probably not. The addition of Rust will change the way kernel development happens a bit, and kernel maintainers will have to brush up on their Rust knowledge. The potential benefits seem to outweigh the downsides. Torvalds seems to have accepted the idea of Rust in the kernel, once the last few wrinkles are ironed out. We’re looking forward to seeing Rust in Linux mature, and we’ll bring you the rest of the story once that happens.