In 2020, Linus Torvalds said he was “not a huge fan of Rust” in the context of kernel development. In 2022, Linux 6.1 merged the initial Rust infrastructure. By 2025, the first Rust-written kernel driver was part of the mainline kernel. By 2026, Apple GPU support, certain networking components, and portions of the Android kernel use Rust.
The shift from skepticism to adoption by arguably the world’s most important C codebase is worth understanding.
The Problem With C in a Kernel
Kernel code runs with the highest privileges on the machine. A bug in kernel code doesn’t crash a process - it crashes the entire system, causes data corruption, or creates a security vulnerability exploitable by any application running on the system.
The Linux kernel has around 30 million lines of C code. C’s memory management model - manual allocation, manual deallocation, raw pointers - has a well-documented failure mode: memory safety bugs. Buffer overflows, use-after-free errors, null pointer dereferences, and double-free bugs have been responsible for a significant fraction of serious Linux kernel CVEs (Common Vulnerabilities and Exposures).
The NSA, Microsoft, and Google have all published research pointing to memory unsafety as the source of 60-70% of security vulnerabilities in large C/C++ codebases. This is not unique to Linux - Windows, Android, Chrome, and iOS have similar distributions.
The Linux Security Module (LSM) framework, which implements security policies, is particularly vulnerable to this class of bug because it sits between applications and the kernel’s core operations. A mistake here has maximum blast radius.
Why Rust Specifically
Rust’s ownership and borrowing system catches the entire class of memory safety bugs at compile time. This is not runtime checking (which has overhead) - it’s the compiler refusing to compile code that could produce use-after-free, buffer overflow, or data race bugs.
fn bad_code() -> &str {
let s = String::from("hello");
&s // ERROR: s is dropped at end of function, reference would be dangling
} // Compiler catches this - this never compiles
In C, the equivalent code compiles and runs, producing undefined behavior that may or may not manifest as a bug depending on memory layout.
Rust guarantees:
- No use-after-free (lifetime system prevents dangling references)
- No buffer overflows (bounds checking, slice types)
- No data races (ownership rules prevent shared mutable state)
- No null pointer dereferences (no null in the type system - use
Option<T>)
These guarantees hold in safe Rust. Kernel code does need unsafe blocks for hardware interaction, interrupt handlers, and inline assembly - but the goal is to minimize and isolate unsafe code so that safety invariants can be reasoned about locally.
What Actually Landed
Linux 6.1 (December 2022): Rust infrastructure merged - the toolchain, the basic abstractions, the ability to write a kernel module in Rust.
Linux 6.8 (2024): First significant Rust abstractions for device drivers.
Linux 6.11+ (2024-2025): Nova GPU driver for NVIDIA hardware written in Rust. Apple AGX GPU driver components. Memory management bindings enabling Rust code to safely interact with kernel memory.
The Android kernel has been more aggressive - Google has been writing new kernel components for Android in Rust since 2021, citing security improvements in Bluetooth stack rewrites and other networking components.
The trajectory is clear: new kernel subsystems and drivers are increasingly being written in Rust. The 30 million lines of existing C won’t be rewritten, but the marginal line of new kernel code is increasingly likely to be Rust.
The C Developer Resistance
The resistance from established kernel developers has been real and, in some cases, principled. The objections worth taking seriously:
Toolchain complexity: The Linux kernel now requires both GCC and the Rust toolchain (LLVM-based) to build fully. This is a maintenance burden.
Abstraction overhead: Rust’s abstractions have zero-cost guarantees in theory. In practice, some kernel developers have found that Rust code is harder to reason about in terms of generated assembly compared to equivalent C.
Integration friction: Writing Rust code that calls C kernel APIs and C code that calls Rust functions requires bridging code. The bindings are improving but add surface area.
Cultural fit: The Linux kernel has a specific, demanding code review culture built around C idioms. Rust idioms and patterns don’t always map cleanly.
These objections don’t argue that Rust is wrong for the kernel. They argue that the transition has costs. Those costs are real and the kernel community is paying them.
What This Means for the Industry
When Linux ships Rust in the kernel, it signals three things:
-
The safety guarantees are taken seriously at the highest level of systems programming. If it’s good enough for the kernel, it’s good enough for your application.
-
The tooling is mature enough. The Rust toolchain can produce correct, performant kernel code. The language is not a toy.
-
Memory safety is treated as an engineering requirement, not a preference. The era of “C is fine if you’re careful” as the default assumption is ending.
For engineers deciding whether to invest time in Rust: the kernel adoption is the strongest possible endorsement that the language has solved the problems it was designed to solve.
Bottom Line
Rust is in the Linux kernel because memory safety bugs in C have been a persistent source of serious security vulnerabilities, and Rust provably eliminates the most common classes of those bugs at compile time. The migration is slow, deliberate, and incremental - exactly right for a 30-million-line safety-critical codebase. The long-term direction is unmistakable: new systems code will increasingly be written in Rust, and the Linux kernel is where that future is being built today.
Comments