Tasks & Compartments

Compartments

A compartment is the Cheriette isolation domain.

To cross the boundaries between compartments Tasks use Secure Calls.

CHERI isolation

Cheriette is designed to isolate compartments and implement secure calls between them using CHERI hardware capabilities.

VM isolation

While currently not supported, Cheriette compartments can also be implemented using normal MMU-based isolation techniques.

Privilege

For architectural reasons, see Exception Levels, some services that would in other systems be associated with the kernel, must run in privileged exception levels.

Cheriette makes a clear distinction between compartments in unprivileged EL0 and privileged EL1. All interactions between compartments use secure calls, but their implementations differ.

Secure calls within exception levels use CHERI sealed capabilities and cinvoke to call directly into the target compartment.

Secure calls between exception levels first call into another service compartment, which then handles the switch between exception levels. The compartment on the different exception level receives a call on a handler. This ensures isolation between the caller and callee compartments across exception levels, and preserves the secure call interface.

For more details see Linking secure calls.

Practical Limitations for CHERI isolation enforcement

In current practice, a compartment is a compilation unit within which the compiler generates PC-relative assembly. PC-relative accesses require a PCC with access to the entire range of addresses from the minimum address the compiler may want to access, to the maximum address that may be accessed in a PC-relative fashion. This compilation unit is equivalent to a linked ELF.

With a clever linker script, the range of these PC-relative accesses can be reduced, but all code sections that share a global object table and either contain PC-relative addresses or happen to be located in-between other code sections that do must be within PCC’s range. The same applies to data sections that are addressed PC-relative.

                    ------
+--------------+         |
| GOT          |         |
+--------------+         |
                         |
    ...                  |
                         |  PCC range must include all possible
+--------------+         |  PC-relative accesses.
| Code Section |         |
+--------------+         |
                         |
    ...                  |
                         |
+--------------+         |
| Code Section |         |
+--------------+         |
                         |
    ...                  |
                         |
+--------------+         |
| Code Section |         |
+--------------+         |
                    ------

Tasks

A task is the schedulable unit in Cheriette.

Every task has an associated stack and register file, including a program counter.

A task is a stream of execution, and by design not confined to a particular compartment. Using Secure Calls, tasks can securely switch between compartments.

Tasks are either created when a compartment is initialized, or at runtime by interacting with the scheduler.

Dynamically created tasks may never be initialized with a set of registers from the caller, instead their registers must be filled with trusted caps or caps loaded from memory. This is to avoid “copying” of one threads stack into another one, which would allow implementing the exploit in Securing the stack.

Service Model

Most services in Cheriette are provided by dormant compartments that are not associated with any schedulable task. These dormant compartments function like objects: They expose secure-callable handler functions and keep private state within the compartment’s isolation domain.

services may also register to receive interrupts or other events not associated with another task. In this case, the registration requires the donation of a task context that is then used to call the handler.

Cheriette also allows the creation of daemons, which are compartments that have their own schedulable task.