Rust-based Alternative to BPF
- Idea
- Practical Software Fault Isolation for Device Drivers, Policy-, and
Tracing-Programs in the Linux Kernel using Rust (no unsafe), DKMS (Trusted
Compilation), Kernel Preemption, and Secure Interfaces (e.g., for Locking).
Goal is to build an expressive, high-performance plug-in alternative to BPF.
- Background
- Related work
- Design and Challenges
- Wind up a preemption-timer when the Rust program executes in a non-IRQ context (where it can block)
- Return ETIMEOUT from Kernel Interface after 1 time slice
- Send SIGKILL to Rust program after 2 time slices
- Then unwind the Rust stack to the caller and return -1 to the caller
- Can we verify IRQ-safety?
- Related work
- Bounded execution time / nr. of instructions
- Can we use Rust Macros to check for (unbounded) loops?
- No blocking calls
- Write compiler pass to analyze call graph, like Maximilian Ott did for alloc() in Jitty.
- Complicated and unstable, but would work.
- Mark IRQ handlers as async to prevent them from calling sync functions? (suggested by Simon Schuster)
const
has a similar restriction.
- No blocking calls actually means we must not touch the scheduler’s
active thread pointer (that’s how blocking works under the hood)
- Can we turn this into a sync. problem?
- Must not attempt to re-lock shared data when it is already locked
- Active pointer’s guard type should
panic!
when it is accessed by non-timer IRQs
- Guard type that is required by all blocking calls?
- Guard type require for things that are only available in IRQ context.
- How to ensure a bounded stack size?
- LLVM can do stack usage analysis, but it’s not as well integrated into Rust as it is for C.
- You likely need a third party project that extends LLVM.
- In priniciple, it’s possible.
- Alternative: Guard Page + Page Fault Handler
- Can we achieve deterministic run-to-completion?
- Problem: The time may trigger on one CPU, but not on another depending on
DVFS and CPU model. That’s a bad experience for the user.
- Use instruction counter?
- Can not preempt program while it holds kernel-owned lock (would poison the
lock), must not allow it to take those.
- Can we link against the kernel using only BTF, without requiring a whole
vmlinux?
- Put unsafe code into another address space?
- Prototype
- Script to compile (only) safe Rust kernel modules and load them into the kernel
- Safe Rust interface to replace some application of BPF (in non-irq context, because easier)
- Benchmark Rust-based program and compare to BPF program
- Implementation
- Userspace tool to load a semi-privileged, safe Rust Kernel Module
- Can link module to a privileged library that provides the safe interfaces (the lib can use unsafe)
- Build Rust wrappers for some BPF kernel interfaces (helper functions and/or BPF context pointers)
- Build a prototype that invokes the Rust program in a place where a BPF
program would have been used traditionally and compar the performance