Linux kernel modules in safe Rust
This is a framework for writing loadable Linux kernel modules in Rust, using safe abstractions around kernel interfaces and primitives.
For more information on the motivation and goals for this project, check out our presentation at Linux Security Summit North America 2019 (recording coming soon on LSSNA's website). We're immediately focusing on making this project viable for out-of-tree modules, but we also see this project as a testing ground for whether in-tree components could be written in Rust.
There is a simple demo module in the hello-world directory, as well as various other examples in the tests/ directory.
We run bindgen on the
kernel headers to generate automatic Rust FFI bindings. bindgen is
powered by Clang, so we use use the kernel's
own build system to determine the appropriate CFLAGS (see
kernel-cflags-finder) and pass them to bindgen (see
build.rs). Then we
write safe bindings to these types (see the various files inside
Each kernel module in Rust lives in a
staticlib crate, which generates
.a file. We pass this object to the Linux kernel's own module build
system for linking into a
The kernel is inherently multi-threaded: kernel resources can be
accessed from multiple userspace processes at once, which causes
multiple threads of execution inside the kernel to handle system calls
(or interrupts). Therefore, the
KernelModule type is
so all data shared by a kernel module must be safe to access
concurrently (such as by implementing locking).
We're currently only running CI on Linux 4.15 (Ubuntu Xenial) on amd64, although we try to keep support for newer (and perhaps older) kernels working. Other architectures should work but are untested - see #112 for expected status.
You'll need to have Rust - in particular
Rust nightly, as we use some unstable
and Clang installed. You need LLVM/Clang 3.9
or higher to bind constants
you're running kernel 5.0 or newer, you'll need Clang
(currently the development release). You may need to set the
environment variable appropriately, e.g.,
- Install clang, kernel headers,
cargo-xbuild, and the
apt-get install llvm clang linux-headers-"$(uname -r)" # or the equivalent for your OS cargo install cargo-xbuild rustup component add --toolchain=nightly rust-src rustfmt
- cd to one of the examples
- Build the static object with cargo xbuild, pointing it at our custom target
cargo xbuild --target $(pwd)/../x86_64-linux-kernel-module.json
- Build the kernel module using the Linux kernel build system (kbuild)
- Load and unload the module!
sudo insmod helloworld.ko sudo rmmod helloworld dmesg | tail