This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Use of Auxiliary Vector Capabilities in Linux Purecap

Hi

As previously advised, I am using getauxptr(AT_CHERI_SEAL_CAP) to obtain a sealer capability.  However I don't understand how this can provide any security, because all processes can obtain a root capability from which they can derive any valid object ID.

Given the object ID can be read from a sealed capability, this surely means any sealed capability can always be unsealed even without access to the original sealing capability?  At least in the same process, this is possible.

My understanding of capability sealing is it prevents use of the memory referenced by the sealed capability by a 3rd party, so how does use of deriving a capability from the aux vector like this provide security?

I presume that (when this feature gets implemented) if the PE is in restricted state then it should not be possible to obtain the AT_CHERI_SEAL_CAP capability - so is this the only mechanism by which the security is provided?

Please correct me if I am wrong - and provide links to appropriate media (if applicable) to explain this further for the Morello implementation of CHERI, so that I can increase my understanding.

Additionally, AT_CHERI_EXEC_RW_CAP and AT_CHERI_EXEC_RX_CAP seem to be effectively unbound (as if they were the to-be-deprecated DDC) - should these not instead be bound to not more than the memory range of the loaded ELF image?

Thanks
Pete

Parents
  • Hi Pete,

    As a general rule, the root capabilities in the auxiliary vector should be considered as privileged. So far we have focused on the base mechanisms, to provide a common interface for all code that requires such capabilities (e.g. dynamic linker for AT_CHERI_{EXEC,INTERP}*CAP). As you rightly point out, the policy aspects are however missing as things stand. For instance, it would be desirable for libc to restrict access to AT_CHERI_{EXEC,INTERP}*CAP to prevent application code from tampering with these early mappings.

    Regarding sealing capabilities, there is a general understanding that application code should obtain them through some sort of allocator. Here as well, AT_CHERI_SEAL_CAP provides a coarse mechanism, but no policy. libc could provide such allocator (and prevent direct access to the root capability), but a kernel allocator could be preferred as it may be desirable to share some object types between processes (and that would also avoid adding such an allocator in every libc).

    Finally it is indeed correct that most AT_CHERI_*_CAP entries are currently unbounded capabilities. To put this in context, our initial focus on the kernel side was to functionally support the pure-capability ABI in userspace - in other words make things work. On the other hand, we started working on security aspects, such as narrowing down capabilities, just a few months ago. We are making good progress but this particular aspect hasn't been taken care of yet. Note that all these tasks are tracked as issues on GitLab, specifically https://git.morello-project.org/morello/kernel/linux/-/issues/19 for this aspect. It will take us some more time to restrict the bounds of AT_CHERI_*_CAP as this requires reservations to be deployed, which is a work in progress (initial patches on the list).

    Hope that clarifies the situation!

    Cheers,
    Kevin

Reply
  • Hi Pete,

    As a general rule, the root capabilities in the auxiliary vector should be considered as privileged. So far we have focused on the base mechanisms, to provide a common interface for all code that requires such capabilities (e.g. dynamic linker for AT_CHERI_{EXEC,INTERP}*CAP). As you rightly point out, the policy aspects are however missing as things stand. For instance, it would be desirable for libc to restrict access to AT_CHERI_{EXEC,INTERP}*CAP to prevent application code from tampering with these early mappings.

    Regarding sealing capabilities, there is a general understanding that application code should obtain them through some sort of allocator. Here as well, AT_CHERI_SEAL_CAP provides a coarse mechanism, but no policy. libc could provide such allocator (and prevent direct access to the root capability), but a kernel allocator could be preferred as it may be desirable to share some object types between processes (and that would also avoid adding such an allocator in every libc).

    Finally it is indeed correct that most AT_CHERI_*_CAP entries are currently unbounded capabilities. To put this in context, our initial focus on the kernel side was to functionally support the pure-capability ABI in userspace - in other words make things work. On the other hand, we started working on security aspects, such as narrowing down capabilities, just a few months ago. We are making good progress but this particular aspect hasn't been taken care of yet. Note that all these tasks are tracked as issues on GitLab, specifically https://git.morello-project.org/morello/kernel/linux/-/issues/19 for this aspect. It will take us some more time to restrict the bounds of AT_CHERI_*_CAP as this requires reservations to be deployed, which is a work in progress (initial patches on the list).

    Hope that clarifies the situation!

    Cheers,
    Kevin

Children