Rust and CHERI

(and why not Rust vs. CHERI!)

Since both Rust and CHERI tackle memory safety issues, it might be confusing and people might think that the two technologies compete… they are not, and here is why. 

CHERI Alliance logo

The core distinction: compile-time vs. hardware-runtime guarantees

Rust reduces bugs at the source; CHERI limits the blast radius when bugs exist and prevents supply-chain attacks.

Rust

  • Checks the code at compile-time
  • Helps prevent programmers from making mistakes
  • Requires trusting the compiler

CHERI

  • Controls execution of code during runtime
  • Protects memory from bugs and malicious attacks
  • Security does not depend on compiler

Use Rust for new code – CHERI brings memory safety to existing code

Writing new code in Rust is desirable because it helps to minimize mistakes during development. However, it is impossible to rewrite all legacy code, economically (opportunity cost, risk of introducing new issues) and practically (Rust requires “unsafe” FFI code)… CHERI can protect existing code, including libraries that Rust assumes to be OK. CHERI is a better platform to run Rust programs!

So we need the two, and this is why we have a Rust+CHERI working group!

CHERI brings security by design

Even developers taking great care in developing code usually only write a very small part of the end application. Most of the code comes from operating systems, libraries, or drivers, that are either developed by 3rd parties, come from open-source repositories or are even developed by “vibe coding”.

As we see a surge in software supply chain attacks, with repositories being infected by malicious contributors, it becomes increasingly difficult to blindly trust these elements. CHERI helps protect your system by isolating various elements in compartments, and operating systems can even be optimised for CHERI. This is the work we do in the related working groups (Linux, FreeRTOS, Zephyr, seL4…) but also that commercial vendors do, e.g. VxWorks by Wind River.

In particular, CHERIoT builds on CHERI with a rich compartmentalisation model that makes least-privilege isolation practical for embedded and IoT software.

Comparing both technologies – the full table

The table below shows that Rust and CHERI are complementary, not competitors.

Takeaway: use Rust to prevent the most common memory-safety bugs in new code (by design, at compile time), and use CHERI to enforce strong, hardware-backed bounds and isolation at runtime — including across unsafe Rust, FFI calls, and legacy C/C++ dependencies. In practice, the strongest systems combine both.

Legend: ● Covered, ○ Partial, (blank) Not covered

PROPERTYRUSTCHERIRUST + CHERINOTES
Buffer overflow preventionOnly in safe Rust, via bounds checks on slices; CHERI via hardware capability bounds on every pointer
Out-of-bounds readThis is catched in safe Rust; CHERI also catches it in inline assembly and FFI code
Bounds on heap allocationsRust checks bounds only in safe code; CHERI tags every allocation with hardware bounds regardless of language
Pointer integer confusionCHERI capabilities cannot be forged from integers — hardware tag bit enforces this; Rust's type system allows raw pointer casts via unsafe
Pointer provenance enforcementSafe Rust tracks provenance conceptually; CHERI enforces it in silicon — no capability without derivation from a valid source
Use-after-free preventionRust's ownership model statically prevents this in safe code. CHERI provides use-after-free protection with capability revocation
Dangling pointer preventionRust's borrow checker statically prevents dangling pointers; CHERI requires revocation support for equivalent temporal safety
Double-free preventionRust's ownership enforces single deallocation; Handled by CHERI memory allocator
Memory leak preventionRust eliminates many causes of leaks with RAII. Still requires programmer’s care, or dedicated tooling
Type confusion (same-size structs)Rust's type system distinguishes structs of the same size; CHERI only tracks bounds and provenance
Data race preventionRust's Send/Sync traits enforce thread safety at compile time; CHERI has no concurrency model, but guarantees relaxed atomicity for all pointer loads and stores
Uninitialized reads & arithmetic errorsRust requires initialization before use and panics on integer overflow in debug builds; Out of scope for CHERI
Cross-component memory isolationCHERI compartmentalisation enforces that objects in one compartment cannot be accessed by another. Rust has no equivalent at the process/component boundary
C/C++ code cannot corrupt Rust objects Without CHERI, a bug in linked C code can corrupt any Rust object in the same process. CHERI enforces bounds on all code in a compartment regardless of language
Supply-chain isolationCHERI provides tools to build compartments to isolate third-party or malicious library code
Least-privilege enforcementCHERI capabilities are monotonically non-increasing — a component can only delegate a subset of its own permissions
Protects unsafe Rust blocksEven though tools can help, Rust waives its own guarantees in unsafe blocks. CHERI hardware checks apply regardless — this is the most critical complementarity
Protects assembly / non-Rust codeCHERI hardware protects all code including inline assembly, OS kernels, and bootloaders that Rust cannot touch
No compiler trust requiredRust's guarantees depend entirely on compiler correctness. CHERI enforces its properties in silicon — a buggy or malicious compiler cannot bypass hardware capabilities
Reuse existing softwareRust requires a complete code re-write. CHERI requires recompilation and fixing a few issues (max 0.5% of lines of code)
Works on existing hardwareRust requires only a compiler. CHERI requires hardware support
Zero runtime overhead (safe code) Safe Rust has near-zero overhead. CHERI's show less than 3% overhead, but runtime protection enables further optimisations to significantly improve performance at the same security level
Protects legacy codebases without rewriteCHERI requires only a recompile of most C/C++ code. Rust requires a full rewrite — economically infeasible for the world's existing C/C++ codebase
Capability sealing (object authority)CHERI supports sealing capabilities so they can be held but not dereferenced except by the designated unsealer — enabling secure object references and cross-compartment handles
Embedded / bare-metal systems supportBoth support embedded systems without an OS

The active convergence: Rust on CHERI

The bottom line: Rust secures the code you write; CHERI secures the memory environment that code runs in — including its dependencies, its unsafe blocks, and the legacy C code it inevitably touches. Opposing them is a category error.