Capability Revocation and Indirection
Capability Revocation and Indirection
Posted Sep 24, 2025 22:49 UTC (Wed) by wahern (subscriber, #37304)Parent article: CHERI with a Linux on top
CHERI is great for spatial safety, but the cost of avoiding indirection means temporal safety requires more work. Perhaps the next evolution will be exploring how linear or affine typing in application languages such as Rust could be leveraged to minimize the sweeping work, e.g. by automatically clearing capabilities as they're copied through the application from malloc through free. Or evolving allocation APIs and page table permission schemes so memory that doesn't need to store a capability/pointer can be skipped from sweeping entirely.
[1] https://www.cl.cam.ac.uk/research/security/ctsrd/pdfs/202...
Posted Sep 26, 2025 0:29 UTC (Fri)
by cpatulea (subscriber, #87498)
[Link] (1 responses)
Any chance you might have a deeper reference for this?
Posted Sep 26, 2025 12:24 UTC (Fri)
by wahern (subscriber, #37304)
[Link]
Also worthwhile to read the core papers on CHERI, especially papers about and subsequent to the ARM Morello implementation. Once you understand the basic architecture, in particular the hidden 129th bit that tags a word (i.e. C pointer) in memory as a valid capability and which is copied along with the visible 128-bit value (e.g. in `char *b = *a;`), it's easy to see understand the problem space regarding revocation. Most of the early work in CHERI was finding and verifying the minimum software and hardware requirements for guaranteed spatial safety that was also maximally performant in hardware and practical to incorporate into existing platforms (language standards, ABIs, kernels, etc). Temporal safety, especially performant revocation, didn't receive as much attention until later, after the shape of capability pointers (i.e. 129-bit compressed pointers) had already largely been settled. But it's still an active area of research and may yet result in some design changes or at least suggest additional hardware facilities for future implementations.
Posted Sep 27, 2025 23:15 UTC (Sat)
by NYKevin (subscriber, #129325)
[Link]
1. Every "regular" capability is really a double indirection (a pointer-to-a-pointer) in disguise. I will use the term "outer pointer" to refer to the first layer of indirection (exposed to user code) and "inner pointer" to refer to the second layer (the pointee of the outer pointer).
I know that double indirection is significantly more expensive than single indirection... but sweeping address space not only seems like it should be similarly expensive, it gets slower the more memory we allocate (whereas double indirection is a fixed cost per dereference). How much memory do you have to allocate before you hit the break-even point?
The other obvious question is how much of this you can hardware-accelerate, and to what extent.
Posted Oct 2, 2025 13:03 UTC (Thu)
by Vorpal (guest, #136011)
[Link] (2 responses)
Oof, that seems like a complete deal breaker to me. My main interests are in low latency hard realtime code, and that would completely kill any RT guarantees.
I don't see it scaling well to large workloads either. Imagine a database server with hundreds of GB of memory mapped into the process, no way that you want to sweep through all the pointers in that either. And even if you do it in the background concurrently, you will eat a lot of memory bandwidth, and you risk falling behind.
Which means we are left with a small niche: small systems with no RT guarantees.
> during the pendency of a concurrent background sweep, a CoW-like scheme temporarily traps all reads to sweep specific pages on demand, permitting forward progress before the concurrent sweep completes.
Isn't there a race condition in that: if you copy the capability around you may be able to copy it from a yet-to-be-swept page to an already swept page while the sweep is somewhere in between those pages? Or maybe I'm misunderstanding you.
Posted Oct 2, 2025 17:19 UTC (Thu)
by Wol (subscriber, #4433)
[Link] (1 responses)
Then you're using the wrong database server :-)
Cheers,
Posted Oct 2, 2025 17:25 UTC (Thu)
by jake (editor, #205)
[Link]
Please do not continue down this path, Wol. You have been asked before. Your favorite hobby horse is off-topic on this article (and many, many others).
thanks,
jake
Capability Revocation and Indirection
Capability Revocation and Indirection
Capability Revocation and Indirection
2. When an allocation is created, we create an inner pointer for it. When an allocation is deallocated, we mark its inner pointer as invalid.
3. Inner pointers live in a special region of address space. When it fills up with dead pointers, you unmap the whole region, and map a fresh one somewhere else. The region is not allowed to contain any object other than an inner pointer (no "real" allocations).
4. A region that has ever been mapped for inner pointers during the lifetime of a process can never again be remapped to contain inner pointers (but it can be remapped for any other purpose, so this is not a pervasive restriction and should not break anything else). malloc or its equivalent would be responsible for the necessary bookkeeping, which might involve mapping regions at some fixed or regular pattern of offsets to reduce the amount of data that you need to track.
5. When an outer pointer is dereferenced by user code, you first check the validity of the outer pointer, then check that it points to a region currently mapped for inner pointers, and finally check the validity of the inner pointer.
6. In principle, you could run out of address space doing this, but that ought to take a rather long time if we're using 64-bit addresses. If we really insist on reusing inner pointer regions, one option could be to give each mapping and each outer pointer a generation number, but CHERI pointers are already wider than standard pointers, and I'm not sure this is worth it. Besides, then you're just running out of generation numbers instead.
Capability Revocation and Indirection
Capability Revocation and Indirection
Wol
Capability Revocation and Indirection
