-
Notifications
You must be signed in to change notification settings - Fork 21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
blog: add post on capability ptr #109
base: master
Are you sure you want to change the base?
Conversation
_posts/2025-01-16-talking-tock-58.md
Outdated
holder of the pointer can actually use the pointer to access memory. | ||
|
||
Traditionally, a pointer in `unsafe` Rust always has the capability to be | ||
dereferenced. That is, the hardware will access the referenced memory. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Traditionally, a pointer in
unsafe
Rust always has the capability to be dereferenced.
As written, that statement isn't really true:
- The pointer may not point at a valid address (such an access would trap at the hardware level)
- The pointer may point at an address that the MPU/PMP/MMU/etc is blocking access to (hardware trap)
- The pointer may not have provenance that is valid for the dereference (the language's AM does not allow access through the pointer)
CapabilityPtr
just adds one more element to that list (the pointer's data can contain permissions for that pointer).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think "in Rust" is doing a lot of heavy lifting there, the memory access will be compiled into the program by the Rust compiler, and unconditionally executed at runtime. Now, whether or not the dereference succeeds in hardware, is (arguably) a different matter. Perhaps this depends a bit on the particular semantics of "dereference" the reader assumes.
I think I can add a qualifier to make this perhaps a bit more clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that's exactly true either. Given that trying to access a pointer might be UB (if it's not aligned / pointing to an allocated object / so on...) that Rust does not guarantee anything, including that hardware will access the referenced memory.
A compliant implementation of Rust (like MIRI, for instance) might make extra checks and do something like jump to a panic handler and this would be well within the bounds of "undefined behavior".
|
||
The primary driver for adding the `CapabilityPtr` type is the | ||
[CHERI](https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/) extension for | ||
hardware architectures. With CHERI, hardware can track whether a pointer can be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When someone talks about running "Rust on CHERI", they're usually referring to a pure-capability CHERI ABI. However, @LawrenceEsswood is porting the Tock kernel to a hybrid CHERI ABI, which has some different properties. One of those properties is that in hybrid CHERI, a language's default pointer types are not CHERI capabilities -- which is the reason why we need CapabilityPtr
. In purecap CHERI, we don't need CapabilityPtr
, as *mut T
can do the same job.
We should probably clarify that CapabilityPtr
is to support hybrid CHERI, otherwise this may be confusing for readers familiar with the upstream efforts to port Rust to CHERI.
(Lawrence, please correct me if I'm wrong about this).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can try to clarify this, but maybe this indicates this post is helpful as this difference is pretty opaque to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Jonathan is correct. At the end of the day both *const T
and CapabilityPtr
are types in an abstract machine, and what hardware representation they have is always with respect to a given ABI.
"Legacy" CHERI ABI says that these should be lowered to an integer address
Hybrid CHERI ABIs say that *const T
should be lowered to an address but CapabilityPtr
to a CHERI capability.
Purecap CHERI ABIs say that both should be lowered to a CHERI capability.
Try to balance making a blog post which does not capture all complexity while avoiding confusion from incorrect statements.
I added a bit more text, which maybe addresses the concerns. I do want this to remain a reasonably accessible blog post which does not need to capture all complexity, but shouldn't be overtly misleading or confusing. |
I'm probably not the best person to write the technical details in this post, but ideally this is at least technically correct and somewhat accessible to a broader audience.