Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions bin/cheribsdtest/cheribsdtest_registers.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,11 @@ check_initreg_data_full_addrspace(void * __capability c)

/* Permissions. */
v = cheri_perms_get(c);
if (v != (CHERI_CAP_USER_DATA_PERMS | CHERI_PERM_SW_VMEM))
if (v != (CHERI_CAP_USER_DATA_PERMS | CHERI_PERM_SW_VMEM |
CHERI_PERM_SYSCALL))
cheribsdtest_failure_errx("perms %jx (expected %jx)", v,
(uintmax_t)CHERI_CAP_USER_DATA_PERMS |
CHERI_PERM_SW_VMEM);
CHERI_PERM_SW_VMEM | CHERI_PERM_SYSCALL);

/*
* More overt tests for permissions that should -- or should not -- be
Expand Down Expand Up @@ -315,18 +316,18 @@ CHERIBSDTEST(initregs_default, "Test initial value of default capability")
*/

#define CHERI_STACK_USE_MAX (256 * 1024)
#define CHERI_STACK_SWPERMS \
(CHERI_PERMS_SWALL & ~(CHERI_PERM_SW_VMEM | CHERI_PERM_SYSCALL))

CHERIBSDTEST(initregs_stack_user_perms,
"Test user permissions of stack capability")
{
register_t v;

v = cheri_perms_get(cheri_stack_get());
if ((v & CHERI_PERMS_SWALL) !=
(CHERI_PERMS_SWALL & ~CHERI_PERM_SW_VMEM))
if ((v & CHERI_PERMS_SWALL) != CHERI_STACK_SWPERMS)
cheribsdtest_failure_errx("swperms %jx (expected swperms %x)",
v & CHERI_PERMS_SWALL,
(CHERI_PERMS_SWALL & ~CHERI_PERM_SW_VMEM));
v & CHERI_PERMS_SWALL, CHERI_STACK_SWPERMS);
cheribsdtest_success();
}

Expand Down
11 changes: 7 additions & 4 deletions sys/arm64/arm64/pmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2541,12 +2541,15 @@ pmap_kremove_device(vm_offset_t sva, vm_size_t size)
vm_pointer_t
pmap_map(vm_pointer_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
{
vm_pointer_t p;

p = PHYS_TO_DMAP(start);
#ifdef __CHERI_PURE_CAPABILITY__
return cheri_perms_and(cheri_bounds_set(PHYS_TO_DMAP(start), end - start),
vm_map_prot2perms(prot));
#else
return PHYS_TO_DMAP(start);
p = cheri_bounds_set(p, end - start);
p = cheri_perms_and(p, vm_prot2perms(cheri_perms_get(p), prot));
#endif

return (p);
}

/*
Expand Down
33 changes: 32 additions & 1 deletion sys/arm64/cheri/cheri_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <sys/kernel.h>
#include <sys/devmap.h>
#include <sys/proc.h>
#include <vm/vm.h>

#include <cheri/cheri.h>
#include <cheri/cheric.h>
Expand Down Expand Up @@ -118,7 +119,7 @@ hybridabi_thread_setregs(struct thread *td, unsigned long entry_addr)

/* Set DDC to full user privilege. */
tf->tf_ddc = (uintcap_t)cheri_capability_build_user_rwx(
CHERI_CAP_USER_DATA_PERMS | CHERI_PERM_SW_VMEM,
CHERI_CAP_USER_DATA_PERMS | CHERI_PERMS_SWALL,
CHERI_CAP_USER_DATA_BASE, CHERI_CAP_USER_DATA_LENGTH,
CHERI_CAP_USER_DATA_OFFSET);

Expand All @@ -127,3 +128,33 @@ hybridabi_thread_setregs(struct thread *td, unsigned long entry_addr)
td, CHERI_CAP_USER_CODE_PERMS, CHERI_CAP_USER_CODE_BASE,
CHERI_CAP_USER_CODE_LENGTH, entry_addr));
}

int
vm_prot2perms(int base, vm_prot_t prot)
{
int perms = 0;

if (prot & (VM_PROT_CAP | VM_PROT_NO_IMPLY_CAP)) {
if (prot & (VM_PROT_READ | VM_PROT_COPY))
perms |= CHERI_PERM_LOAD;
if (VM_PROT_HAS_READ_CAP(prot))
perms |= CHERI_PERM_LOAD_CAP | CHERI_PERM_MUTABLE_LOAD;
if (prot & VM_PROT_WRITE)
perms |= CHERI_PERM_STORE;
if (VM_PROT_HAS_WRITE_CAP(prot))
perms |= CHERI_PERM_STORE_CAP |
CHERI_PERM_STORE_LOCAL_CAP;
} else {
if (prot & (VM_PROT_READ | VM_PROT_COPY))
perms |= CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP |
CHERI_PERM_MUTABLE_LOAD;
if (prot & VM_PROT_WRITE)
perms |= CHERI_PERM_STORE | CHERI_PERM_STORE_CAP |
CHERI_PERM_STORE_LOCAL_CAP;
}
if (prot & VM_PROT_EXECUTE)
perms |= CHERI_PERM_EXECUTE | CHERI_PERM_EXECUTIVE |
CHERI_PERM_LOAD | CHERI_PERM_SYSCALL;

return ((base & ~CHERI_PERMS_RWX_MASK) | perms);
}
32 changes: 15 additions & 17 deletions sys/arm64/include/cherireg.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,21 +112,6 @@

/* TODO #define CHERI_PERMS_HWALL_CID (CHERI_PERM_SETCID) */

/*
* vm_prot_t to capability permission bits
*/
#define CHERI_PERMS_PROT2PERM_READ \
CHERI_PERM_LOAD
#define CHERI_PERMS_PROT2PERM_READ_CAP \
(CHERI_PERM_LOAD_CAP | CHERI_PERM_MUTABLE_LOAD)
#define CHERI_PERMS_PROT2PERM_WRITE \
CHERI_PERM_STORE
#define CHERI_PERMS_PROT2PERM_WRITE_CAP \
(CHERI_PERM_STORE_CAP | CHERI_PERM_STORE_LOCAL_CAP)
#define CHERI_PERMS_PROT2PERM_EXEC \
(CHERI_PERM_EXECUTE | CHERI_PERM_EXECUTIVE | \
CHERI_PERMS_PROT2PERM_READ)

/*
* Basic userspace permission mask; CHERI_PERM_EXECUTE will be added for
* executable capabilities (pcc); CHERI_PERM_STORE, CHERI_PERM_STORE_CAP,
Expand All @@ -135,14 +120,15 @@
#define CHERI_PERMS_USERSPACE \
(CHERI_PERM_GLOBAL | CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP | \
CHERI_PERM_BRANCH_SEALED_PAIR | \
(CHERI_PERMS_SWALL & ~CHERI_PERM_SW_VMEM))
(CHERI_PERMS_SWALL & ~(CHERI_PERM_SW_VMEM | CHERI_PERM_SYSCALL)))

#define CHERI_PERMS_USERSPACE_CIDCAP \
(CHERI_PERM_COMPARTMENT_ID)

#define CHERI_PERMS_USERSPACE_CODE \
(CHERI_PERMS_USERSPACE | CHERI_PERM_EXECUTE | \
CHERI_PERM_EXECUTIVE | CHERI_PERM_MUTABLE_LOAD)
CHERI_PERM_EXECUTIVE | CHERI_PERM_MUTABLE_LOAD | \
CHERI_PERM_SYSCALL)

#define CHERI_PERMS_USERSPACE_SEALCAP \
(CHERI_PERM_GLOBAL | CHERI_PERM_SEAL | CHERI_PERM_UNSEAL)
Expand Down Expand Up @@ -187,6 +173,18 @@
#define CHERI_PERMS_KERNEL_DATA_NOCAP \
(CHERI_PERM_GLOBAL | CHERI_PERM_LOAD | CHERI_PERM_STORE)

/*
* Permission mask that encodes the permission bits associated to
* the RWX memory access control.
* These are separate from the permission bits that encode other
* properties of capabilities (e.g. sealing or ASR).
*/
#define CHERI_PERMS_RWX_MASK \
(CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP | CHERI_PERM_STORE | \
CHERI_PERM_STORE_CAP |CHERI_PERM_MUTABLE_LOAD | \

Check failure on line 184 in sys/arm64/include/cherireg.h

View workflow job for this annotation

GitHub Actions / Style Checker

spaces required around that '|' (ctx:WxV)
CHERI_PERM_STORE_LOCAL_CAP | CHERI_PERM_EXECUTE | \
CHERI_PERM_EXECUTIVE | CHERI_PERM_SYSCALL)

/*
* The CHERI object-type space is split between userspace and kernel,
* permitting kernel object references to be delegated to userspace (if
Expand Down
13 changes: 0 additions & 13 deletions sys/cheri/cherireg.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,19 +104,6 @@
(CHERI_OTYPE_USER_MAX - CHERI_OTYPE_USER_MIN + 1)
#define CHERI_SEALCAP_USERSPACE_OFFSET 0x0

/*
* Definition for mapping vm_prot_t to capability permission
*/
#define CHERI_PROT2PERM_READ_PERMS CHERI_PERMS_PROT2PERM_READ
#define CHERI_PROT2PERM_READ_CAP_PERMS CHERI_PERMS_PROT2PERM_READ_CAP
#define CHERI_PROT2PERM_WRITE_PERMS CHERI_PERMS_PROT2PERM_WRITE
#define CHERI_PROT2PERM_WRITE_CAP_PERMS CHERI_PERMS_PROT2PERM_WRITE_CAP
#define CHERI_PROT2PERM_EXEC_PERMS CHERI_PERMS_PROT2PERM_EXEC
#define CHERI_PROT2PERM_MASK \
(CHERI_PROT2PERM_READ_PERMS | CHERI_PROT2PERM_WRITE_PERMS | \
CHERI_PROT2PERM_READ_CAP_PERMS | CHERI_PROT2PERM_WRITE_CAP_PERMS | \
CHERI_PROT2PERM_EXEC_PERMS)

/*
* Root sealing capability for kernel managed objects.
*/
Expand Down
2 changes: 1 addition & 1 deletion sys/compat/linuxkpi/common/src/linux_page.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ __get_user_pages_fast(void * __capability addr, int nr_pages, int write,
prot = write ? (VM_PROT_READ | VM_PROT_WRITE) : VM_PROT_READ;
len = ptoa((vm_offset_t)nr_pages);
#if __has_feature(capabilities)
if (!cheri_can_access(addr, vm_map_prot2perms(prot), len))
if (!cheri_can_access(addr, vm_prot2perms(0, prot), len))
return (-1);
#endif
MPASS(pages != NULL);
Expand Down
2 changes: 1 addition & 1 deletion sys/dev/pci/pci_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,7 @@ pci_bar_mmap(device_t pcidev, struct pci_bar_mmap *pbm)
}
#if __has_feature(capabilities) && !defined(__CHERI_PURE_CAPABILITY__)
pbm->pbm_map_base = cheri_capability_build_user_data(
vm_map_prot2perms(prot), addr, plen, 0);
vm_prot2perms(0, prot), addr, plen, 0);
#else
pbm->pbm_map_base = (void *)addr;
#endif
Expand Down
3 changes: 1 addition & 2 deletions sys/kern/kern_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1311,8 +1311,7 @@ exec_map_stack(struct image_params *imgp)
}

#if __has_feature(capabilities)
perms = (~CHERI_PROT2PERM_MASK | vm_map_prot2perms(stack_prot)) &
CHERI_CAP_USER_DATA_PERMS;
perms = vm_prot2perms(CHERI_CAP_USER_DATA_PERMS, stack_prot);
#ifdef __CHERI_PURE_CAPABILITY__
imgp->stack = (void *)cheri_perms_and(stack_top, perms);
#else
Expand Down
32 changes: 31 additions & 1 deletion sys/riscv/cheri/cheri_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <sys/kernel.h>
#include <sys/devmap.h>
#include <sys/proc.h>
#include <vm/vm.h>

#include <cheri/cheri.h>
#include <cheri/cheric.h>
Expand Down Expand Up @@ -91,7 +92,7 @@ hybridabi_thread_setregs(struct thread *td, unsigned long entry_addr)

/* Set DDC to full user privilege. */
tf->tf_ddc = (uintcap_t)cheri_capability_build_user_rwx(
CHERI_CAP_USER_DATA_PERMS | CHERI_PERM_SW_VMEM,
CHERI_CAP_USER_DATA_PERMS | CHERI_PERMS_SWALL,
CHERI_CAP_USER_DATA_BASE, CHERI_CAP_USER_DATA_LENGTH,
CHERI_CAP_USER_DATA_OFFSET);

Expand All @@ -100,6 +101,35 @@ hybridabi_thread_setregs(struct thread *td, unsigned long entry_addr)
td, CHERI_CAP_USER_CODE_PERMS, CHERI_CAP_USER_CODE_BASE,
CHERI_CAP_USER_CODE_LENGTH, entry_addr);
}

int
vm_prot2perms(int base, vm_prot_t prot)
{
int perms = 0;

if (prot & (VM_PROT_CAP | VM_PROT_NO_IMPLY_CAP)) {
if (prot & (VM_PROT_READ | VM_PROT_COPY))
perms |= CHERI_PERM_LOAD;
if (VM_PROT_HAS_READ_CAP(prot))
perms |= CHERI_PERM_LOAD_CAP;
if (prot & VM_PROT_WRITE)
perms |= CHERI_PERM_STORE;
if (VM_PROT_HAS_WRITE_CAP(prot))
perms |= CHERI_PERM_STORE_CAP |
CHERI_PERM_STORE_LOCAL_CAP;
} else {
if (prot & (VM_PROT_READ | VM_PROT_COPY))
perms |= CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP;
if (prot & VM_PROT_WRITE)
perms |= CHERI_PERM_STORE | CHERI_PERM_STORE_CAP |
CHERI_PERM_STORE_LOCAL_CAP;
}
if (prot & VM_PROT_EXECUTE)
perms |= CHERI_PERM_EXECUTE | CHERI_PERM_LOAD |
CHERI_PERM_SYSCALL;

return ((base & ~CHERI_PERMS_RWX_MASK) | perms);
}
// CHERI CHANGES START
// {
// "updated": 20230509,
Expand Down
30 changes: 14 additions & 16 deletions sys/riscv/include/cherireg.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,6 @@
CHERI_PERM_SEAL | CHERI_PERM_INVOKE | CHERI_PERM_UNSEAL | \
CHERI_PERM_SYSTEM_REGS | CHERI_PERM_SET_CID)

/*
* vm_prot_t to capability permission bits
*/
#define CHERI_PERMS_PROT2PERM_READ \
CHERI_PERM_LOAD
#define CHERI_PERMS_PROT2PERM_READ_CAP \
CHERI_PERM_LOAD_CAP
#define CHERI_PERMS_PROT2PERM_WRITE \
CHERI_PERM_STORE
#define CHERI_PERMS_PROT2PERM_WRITE_CAP \
(CHERI_PERM_STORE_CAP | CHERI_PERM_STORE_LOCAL_CAP)
#define CHERI_PERMS_PROT2PERM_EXEC \
(CHERI_PERM_EXECUTE | CHERI_PERMS_PROT2PERM_READ)

/*
* Hardware defines a kind of tripartite taxonomy: memory, type, and CID.
* They're all squished together in the permission bits, so define masks
Expand All @@ -135,10 +121,11 @@
*/
#define CHERI_PERMS_USERSPACE \
(CHERI_PERM_GLOBAL | CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP | \
CHERI_PERM_INVOKE | (CHERI_PERMS_SWALL & ~CHERI_PERM_SW_VMEM))
CHERI_PERM_INVOKE | \
(CHERI_PERMS_SWALL & ~(CHERI_PERM_SW_VMEM | CHERI_PERM_SYSCALL)))

#define CHERI_PERMS_USERSPACE_CODE \
(CHERI_PERMS_USERSPACE | CHERI_PERM_EXECUTE)
(CHERI_PERMS_USERSPACE | CHERI_PERM_EXECUTE | CHERI_PERM_SYSCALL)

#define CHERI_PERMS_USERSPACE_SEALCAP \
(CHERI_PERM_GLOBAL | CHERI_PERM_SEAL | CHERI_PERM_UNSEAL)
Expand Down Expand Up @@ -171,6 +158,17 @@
#define CHERI_PERMS_KERNEL_SEALCAP \
(CHERI_PERM_GLOBAL | CHERI_PERM_SEAL | CHERI_PERM_UNSEAL)

/*
* Permission mask that encodes the permission bits associated to
* the RWX memory access control.
* These are separate from the permission bits that encode other
* properties of capabilities (e.g. sealing or ASR).
*/
#define CHERI_PERMS_RWX_MASK \
(CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP | CHERI_PERM_STORE | \
CHERI_PERM_STORE_CAP | CHERI_PERM_STORE_LOCAL_CAP | \
CHERI_PERM_EXECUTE | CHERI_PERM_SYSCALL)

#define CHERI_FLAGS_CAP_MODE 0x1

/*
Expand Down
7 changes: 4 additions & 3 deletions sys/riscv/riscv/pmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1375,9 +1375,10 @@ pmap_map(vm_pointer_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
vm_pointer_t p;

p = PHYS_TO_DMAP(start);
p = cheri_kern_bounds_set(p, end - start);
p = cheri_kern_perms_and(p, vm_map_prot2perms(prot) |
~CHERI_PROT2PERM_MASK);
#ifdef __CHERI_PURE_CAPABILITY__
p = cheri_bounds_set(p, end - start);
p = cheri_perms_and(p, vm_prot2perms(cheri_perms_get(p), prot));
#endif

return (p);
}
Expand Down
4 changes: 4 additions & 0 deletions sys/vm/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ extern struct kva_md_info kmi;
extern int old_mlock;
extern int vm_ndomains;
extern int vm_overcommit;

#if __has_feature(capabilities)
int vm_prot2perms(int base, vm_prot_t prot);
#endif
#endif /* _KERNEL */

#endif /* VM_H */
Expand Down
2 changes: 1 addition & 1 deletion sys/vm/vm_fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -2366,7 +2366,7 @@ vm_fault_quick_hold_pages(vm_map_t map, void * __capability addr, vm_size_t len,
if (len == 0)
return (0);
#if __has_feature(capabilities)
if (!cheri_can_access(addr, vm_map_prot2perms(prot), len))
if (!cheri_can_access(addr, vm_prot2perms(0, prot), len))
return (-1);
#endif
start = (__cheri_addr vm_offset_t)trunc_page(addr);
Expand Down
4 changes: 2 additions & 2 deletions sys/vm/vm_glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ useracc(void * __capability cap, int len, int rw)
("illegal ``rw'' argument to useracc (%x)\n", rw));
prot = rw;
#if __has_feature(capabilities)
if (!cheri_can_access(cap, vm_map_prot2perms(prot), len))
if (!cheri_can_access(cap, vm_prot2perms(0, prot), len))
return (false);
#endif
addr = (__cheri_addr vm_offset_t)cap;
Expand All @@ -195,7 +195,7 @@ vslock(void * __capability addr, size_t len, vm_prot_t prot __unused)

#if __has_feature(capabilities)
if (!cheri_can_access(addr,
vm_map_prot2perms(prot | VM_PROT_NO_IMPLY_CAP), len))
vm_prot2perms(0, prot | VM_PROT_NO_IMPLY_CAP), len))
return (EPROT);
#endif
vaddr = (__cheri_addr vm_offset_t)addr;
Expand Down
Loading
Loading