Skip to content

mmap PROT_CAP and PROT_NO_CAP support#23

Open
scosu wants to merge 3 commits into
CHERI-Alliance:codasip-cheri-riscv-7.0from
scosu:topic/mmap-cap-prot/v7.0
Open

mmap PROT_CAP and PROT_NO_CAP support#23
scosu wants to merge 3 commits into
CHERI-Alliance:codasip-cheri-riscv-7.0from
scosu:topic/mmap-cap-prot/v7.0

Conversation

@scosu
Copy link
Copy Markdown

@scosu scosu commented May 21, 2026

In most cases PROT_CAP is automatically applied. PROT_NO_CAP removes the ability to store pointers and will create a segfault with SEGV_STORETAG.

This Pull Request also adds a self test, testing the assumptions of how it should work.

See the individual commit messages for more details.

Closes: #10

scosu added 3 commits May 20, 2026 20:52
Support flags PROT_CAP and PROT_NO_CAP in mmap. PROT_CAP is implied by
PROT_READ and PROT_WRITE for most mmap calls. PROT_NO_CAP forbids the
use of capabilities in this mapping. Storing a tag in this mapping will
cause a fault.

Note that CHERI on riscv needs additional setting of
CHERI_PERMS_LOAD_CAP or CHERI_PERMS_STORE_CAP, otherwise PROT_NO_CAP
is not enforced.

Signed-off-by: Markus Schneider-Pargmann (The Capable Hub) <msp@baylibre.com>
Implement Zcheripte 0.9.3 tval2 encoding support for CHERI PTE faults.
Return SEGV_STORETAG when there is a PTE fault.

Signed-off-by: Markus Schneider-Pargmann (The Capable Hub) <msp@baylibre.com>
Add selftests for mmap PROT_CAP and PROT_NO_CAP behavior.

Signed-off-by: Markus Schneider-Pargmann (The Capable Hub) <msp@baylibre.com>
perms |= CHERI_PERMS_LOAD_CAP;
if (prot & PROT_WRITE)
perms |= CHERI_PERMS_STORE_CAP;
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but this and the related text in the commit message is bogus. I somewhat see why you are doing this but we really shouldn't add additional permissions to the capability with an explicitly given PROT_NO_CAP. Yes, you will get a CHERI fault instead of a capability fault but I don't think we care. If this fails tests adjust the tests.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that it is even more bogus than that if the CW bit is not supported, either because the hardware does not have it or because for some reason the arch decided to not make use of it.

Comment thread mm/mmap.c
return -EINVAL;
/*
* PROT_CAP is not supported with file-backed MAP_SHARED mapping
*/
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this? Isn't it the whole point to allow just that?

Comment thread arch/riscv/mm/fault.c
local_flush_tlb_page(addr);
}

static inline bool access_error(unsigned long cause, struct vm_area_struct *vma)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is quite right. First, you are introducing quite a large diff in a function with subtle logic. This is bound to introduce merge errors when the upstream code changes.
But more importantly, you are now saying that a cheri PTE fault on a VMA with VM_CAP_WRITE is ok. That will trigger standard fault handling which is then trying to fix an ordinary page fault and will fail to do so. So I think that all cheri PTE faults should be bad_area_nosemaphore. This also simpifies things because you can just handle those before even calling access_ok().

Comment thread arch/riscv/mm/fault.c
@@ -351,11 +366,12 @@ void handle_page_fault(struct pt_regs *regs)
if (!vma)
goto lock_mmap;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above: Handle cheri_pte_faults here and always do an access error.

perms |= CHERI_PERMS_LOAD_CAP;
if (prot & PROT_WRITE)
perms |= CHERI_PERMS_STORE_CAP;
}
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that it is even more bogus than that if the CW bit is not supported, either because the hardware does not have it or because for some reason the arch decided to not make use of it.

#define SEGV_CAPACCESSERR 14 /* Capability access fault */
#define NSIGSEGV 14
#define SEGV_STORETAG 15 /* Capability tag store fault */
#define NSIGSEGV 15
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the CI run: This breaks build on other archs.

Copy link
Copy Markdown
Collaborator

@chrehrhardt chrehrhardt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See inline comments. At the very least the arch_user_ptr_owning_perms_from_prot needs to go

@brooksdavis
Copy link
Copy Markdown

This implementation doesn't appear to square with the design in CheriBSD https://man.cheribsd.org/cgi-bin/man.cgi/mmap. The key thing is that PROT_NO_CAP means "don't imply PROT_CAP" not prot &= ~PROT_CAP. The reason for this construction is that we feel we need to imply PROT_CAP for MAP_ANON or too much will break so we need a way to disable that implication when we don't want capabilities. This leads to a slightly awkward construction.

PROT_CAP|PROT_NO_CAP is a reasonable set of permissions if you're constructing permissions through a series of decisions. (Inside CheriBSD VM permissions always end up that way as VM_PROT_NO_IMPLY_CAP is used to finalizes the constructed set of permissions.)

In the original implementation (see CTSRD-CHERI/cheribsd#2191), I had PROT_READ_CAP, PROT_WRITE_CAP, and PROT_NO_IMPLY_CAP. Because it became clear RVY wasn't going to have separate READ_CAP and WRITE_CAP permissions (and because they aren't obviously useful), we consolidated down to the two permissions today. It could certainly be argued that PROT_NO_CAP should still be PROT_NO_IMPLY_CAP for clarity (or some of these other options in CTSRD-CHERI/cheribsd#2191 (comment) (note that github's UI for resolved or outdated comments is terrible so after following this link you'll need to expand comments on mmap.2 until you find a highlighted one)).

It would be super helpful if @paul-metzger could update his cheribsdtest port and test this branch with it to see how things align.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants