CHERI and Existing Software
CHERI can strengthen established C and C++ codebases, but compatibility depends on software mode, interfaces, and pointer assumptions.
Most organisations cannot replace a mature software stack solely to gain a new security property. Important products contain proven C and C++ components, third-party libraries, device drivers, file formats, network protocols, and operational tooling. A practical security architecture needs a path for that software.
CHERI was designed to support incremental adoption as well as more complete conversion. The amount of work depends on the platform and on how the code uses pointers.
Three broad software modes
Conventional binaries
Some CHERI-capable processors and operating systems can continue to run conventional binaries. Those binaries retain their existing application binary interface, or ABI, and do not automatically gain fine-grained CHERI memory protection.
This can help with transition, but compatibility should not be confused with protection. The exact mixing rules depend on the platform.
Hybrid code
Hybrid code uses a conventional ABI while selected code and interfaces use capabilities explicitly. This is useful for experiments, protected handles, and staged migration. It lets developers introduce capability-aware boundaries without changing every pointer at once.
The trade-off is coverage. Ordinary pointers in hybrid code do not carry the same object bounds as capabilities, so teams must be clear about which paths are protected.
Pure-capability code
In a pure-capability ABI, language-visible pointers are represented as capabilities. This applies CHERI checks broadly across compiled code and makes pointer assumptions visible during porting.
Pure-capability conversion generally provides the strongest memory-safety coverage, but it can expose more compatibility issues and changes the ABI. Libraries passed across the same interface normally need compatible builds.
Code that often builds cleanly
Well-structured C and C++ code commonly needs little or no source change. Code is easier to port when it:
- uses pointer types for pointers rather than storing them in integers
- keeps array lengths with the arrays they describe
- uses standard allocation and library interfaces
- avoids relying on object layout outside the language rules
- separates serialised data formats from in-memory pointers
The compiler and runtime can then create capabilities with appropriate permissions and bounds.
Assumptions that need attention
Porting work often finds code that treats pointers and integers as interchangeable. Examples include:
uint32_t saved = (uint32_t)pointer;
This may truncate a pointer even on conventional 64-bit systems. On CHERI it also discards protected capability metadata. A pointer-sized integer type such as uintptr_t can preserve an address for permitted conversions, but integer manipulation should not be assumed to preserve authority or validity.
Other common issues include:
- custom allocators that do not set useful object bounds
- unions or packed structures that assume a particular pointer size
- pointer values stored in files or sent across a network
- code that deliberately accesses one allocation through a pointer to another
- inline assembly that does not handle capability registers
- callbacks and foreign-function interfaces with mismatched ABIs
These are not all security vulnerabilities, but each deserves an explicit design decision.
Port one boundary at a time
A useful migration starts with a defined workload rather than an entire product:
- Build the component with a CHERI-aware compiler.
- Run its existing tests in a simulator or development platform.
- Classify warnings and capability faults by root cause.
- Replace pointer-integer assumptions and unclear object boundaries.
- Add tests for malformed input and interface limits.
- Measure performance, memory use, and operational behaviour.
- Decide whether the next step is a wider pure-capability port or a compartment boundary.
CheriBSD and CHERI Linux provide operating-system environments for larger software stacks. CHERIoT provides a hardware-software platform aimed at embedded systems and compartmentalised firmware. Their build systems and compatibility models differ, so platform documentation is the source of truth for exact commands and supported targets.
What remains the same
CHERI does not require a new application protocol, algorithm, or user interface. Most source-level program logic remains familiar. Teams still use compilers, linkers, debuggers, tests, package dependencies, and version control. The difference is that pointer authority becomes explicit enough for hardware to enforce.
Start with Choose a Platform and then use Port Existing Software for a practical workflow.
