11 permission bits are hardware defined in CHERI ISA.
//file:
// ./sys/mips/include/cherireg.h
/*
* CHERI ISA-defined constants for capabilities -- suitable for inclusion from
* assembly source code.
*
* XXXRW: CHERI_UNSEALED is not currently considered part of the perms word,
* but perhaps it should be.
*/
#define CHERI_PERM_GLOBAL (1 << 0) /* 0x00000001 */
#define CHERI_PERM_EXECUTE (1 << 1) /* 0x00000002 */
#define CHERI_PERM_LOAD (1 << 2) /* 0x00000004 */
#define CHERI_PERM_STORE (1 << 3) /* 0x00000008 */
#define CHERI_PERM_LOAD_CAP (1 << 4) /* 0x00000010 */
#define CHERI_PERM_STORE_CAP (1 << 5) /* 0x00000020 */
#define CHERI_PERM_STORE_LOCAL_CAP (1 << 6) /* 0x00000040 */
#define CHERI_PERM_SEAL (1 << 7) /* 0x00000080 */
#define CHERI_PERM_CCALL (1 << 8) /* 0x00000100 */
#define CHERI_PERM_UNSEAL (1 << 9) /* 0x00000200 */
#define CHERI_PERM_SYSTEM_REGS (1 << 10) /* 0x00000400 */
./sys/mips/include/cherireg.h CHERI_PERM_SYSTEM_REGS, or Permit_Access_System_Registers in 3.3.5 of ISAv71, can be used to restrict the access of special capability registers, such as $PCC, $DDC, $EPCC, $KCC, $KDC, $CULR (User Thread Local Storage), $CPLR (Privileged Thread-Local Storage), and other architectural specific registers.
15 permission bits for 256-bit CHERI; 4 permission bits for 128-bit CHERI.
CHERIxxx_PERMI_SWx:
// file:
// ./sys/mips/include/cherireg.h
/*
* User-defined permission bits.
*
* 256-bit CHERI has a substantially larger number of software-defined
* permissions.
*/
#define CHERI256_PERM_SW0 (1 << 15) /* 0x00008000 */
#define CHERI256_PERM_SW1 (1 << 16) /* 0x00010000 */
#define CHERI256_PERM_SW2 (1 << 17) /* 0x00020000 */
#define CHERI256_PERM_SW3 (1 << 18) /* 0x00040000 */
#define CHERI256_PERM_SW4 (1 << 19) /* 0x00080000 */
#define CHERI256_PERM_SW5 (1 << 20) /* 0x00100000 */
#define CHERI256_PERM_SW6 (1 << 21) /* 0x00200000 */
#define CHERI256_PERM_SW7 (1 << 22) /* 0x00400000 */
#define CHERI256_PERM_SW8 (1 << 23) /* 0x00800000 */
//...
#define CHERI256_PERM_SW15 (1 << 30) /* 0x40000000 */
#define CHERI128_PERM_SW0 (1 << 15) /* 0x00008000 */
#define CHERI128_PERM_SW1 (1 << 16) /* 0x00010000 */
#define CHERI128_PERM_SW2 (1 << 17) /* 0x00020000 */
#define CHERI128_PERM_SW3 (1 << 18) /* 0x00040000 */
#if (CHERICAP_SIZE == 32)
#define CHERI_PERM_SW0 CHERI256_PERM_SW0
#define CHERI_PERM_SW1 CHERI256_PERM_SW1
#define CHERI_PERM_SW2 CHERI256_PERM_SW2
//...
#define CHERI_PERM_SW15 CHERI256_PERM_SW15
#else /* (!(CHERICAP_SIZE == 32)) */
#define CHERI_PERM_SW0 CHERI128_PERM_SW0
#define CHERI_PERM_SW1 CHERI128_PERM_SW1
#define CHERI_PERM_SW2 CHERI128_PERM_SW2
#define CHERI_PERM_SW3 CHERI128_PERM_SW3
#endif /* (!(CHERICAP_SIZE == 32)) */
One of user permission bits, CHERI_PERMI_SW0
, is used as CHERI_PERM_SYSCALL
for authorising system calls from $pcc
.
// file:
// ./sys/mips/include/cherireg.h
/*
* The kernel snags one for the software-defined permissions for the purposes
* of authorising system calls from $pcc. This is a bit of an oddity:
* normally, we check permissions on data capabilities, not code capabilities,
* but aligns with 'privilege' checks: e.g., $epcc access. We may wish to
* switch to another model, such as having userspace register one or more
* class capabilities as suitable for system-call use.
*/
#define CHERI_PERM_SYSCALL CHERI_PERM_SW0
Another user defined permission bit, CHERI_PERM_SW1
is used to restrict
the ability to change the page mapping underlying a capability.
“This can’t be the same permission bit as CHERI_PERM_SYSCALL because $pcc
should not confer the right rewrite or remap executable memory.”
// file:
// ./sys/mips/include/cherireg.h
#define CHERI_PERM_CHERIABI_VMMAP CHERI_PERM_SW1
Initial permission sets for various scenarios are defined in macros, different between 256-bit and 128-bit CHERI.
CHERI_PERMS_SWALL
: Mask of all available software-defined permissions; From CHERI_PERM_SW0
to CHERI_PERM_SW15
for 256 bits, or to CHERI_PERM_SW3
for 128 bits;CHERI_PERMS_HWALL
: Mask of all available hardware-defined permissions; From CHERI_PERM_GLOBAL
to CHERI_PERM_SYSTEM_REGS
;Global + Seal + Unseal: Root “object-type” capability for the kernel. This can be used neither as a data nor code capability.
CHERI_PERM_GLOBAL (LLM: what is permission for? Global variables ???)
// file:
// ./sys/mips/include/cherireg.h
#define CHERI_PERM_KERN_TYPE (CHERI_PERM_GLOBAL | CHERI_PERM_SEAL | \
CHERI_PERM_UNSEAL)
The following defines “the permission masks for kernel code and data; these are currently a bit broad, and should be narrowed over time as the kernel becomes more capability-aware”.
// file:
// ./sys/mips/include/cherireg.h
#define CHERI_PERMS_KERNEL \
(CHERI_PERM_GLOBAL | CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP) \
#define CHERI_PERMS_KERNEL_CODE \
(CHERI_PERMS_KERNEL | CHERI_PERM_EXECUTE | CHERI_PERM_SYSTEM_REGS)
#define CHERI_PERMS_KERNEL_DATA \
(CHERI_PERMS_KERNEL | CHERI_PERM_STORE | CHERI_PERM_STORE_CAP | \
CHERI_PERM_STORE_LOCAL_CAP)
#define CHERI_PERMS_KERNEL_SEALCAP \
(CHERI_PERM_GLOBAL | CHERI_PERM_SEAL | CHERI_PERM_UNSEAL)
“The following definition is a highly privileged kernel capability able to name the entire address space, and is suitable to derive all other kernel-related capabilities from, including sealing capabilities.”
#define CHERI_CAP_KERN_PERMS \
(CHERI_PERMS_SWALL | CHERI_PERMS_HWALL)
#define CHERI_CAP_KERN_BASE 0x0
#define CHERI_CAP_KERN_LENGTH 0xffffffffffffffff
#define CHERI_CAP_KERN_OFFSET 0x0
#define CHERI_SEALCAP_KERNEL_PERMS CHERI_PERMS_KERNEL_SEALCAP
#define CHERI_SEALCAP_KERNEL_BASE CHERI_OTYPE_KERN_MIN
#define CHERI_SEALCAP_KERNEL_LENGTH \
(CHERI_OTYPE_KERN_MAX - CHERI_OTYPE_KERN_MIN + 1)
#define CHERI_SEALCAP_KERNEL_OFFSET 0x0
CHERI_PERM_EXECUTE
for executable capabilities ($pcc);
CHERI_PERM_STORE
, CHERI_PERM_STORE_CAP
,
and CHERI_PERM_STORE_LOCAL_CAP
for data permissions ($c0).
“No variation required between 256-bit and 128-bit CHERI.”
// file:
// ./sys/mips/include/cherireg.h
#define CHERI_PERMS_USERSPACE \
(CHERI_PERM_GLOBAL | CHERI_PERM_LOAD | CHERI_PERM_LOAD_CAP | \
CHERI_PERM_CCALL | (CHERI_PERMS_SWALL & ~CHERI_PERM_CHERIABI_VMMAP))
#define CHERI_PERMS_USERSPACE_CODE \
(CHERI_PERMS_USERSPACE | CHERI_PERM_EXECUTE)
#define CHERI_PERMS_USERSPACE_SEALCAP \
(CHERI_PERM_GLOBAL | CHERI_PERM_SEAL | CHERI_PERM_UNSEAL)
/*
* _DATA includes _VMMAP so that we can derive the MMAP cap from it.
*
* XXX: Should it include "unallocated" user permissions so
* userspace can use them?
*/
#define CHERI_PERMS_USERSPACE_DATA \
(CHERI_PERMS_USERSPACE | \
CHERI_PERM_STORE | \
CHERI_PERM_STORE_CAP | \
CHERI_PERM_STORE_LOCAL_CAP | \
CHERI_PERM_CHERIABI_VMMAP)
Definition for userspace “unprivileged” capability able to name the user portion of the address space:
// file:
// ./sys/mips/include/cherireg.h
#define CHERI_CAP_USER_CODE_PERMS CHERI_PERMS_USERSPACE_CODE
#define CHERI_CAP_USER_CODE_BASE VM_MINUSER_ADDRESS
#define CHERI_CAP_USER_CODE_LENGTH (VM_MAXUSER_ADDRESS - VM_MINUSER_ADDRESS)
#define CHERI_CAP_USER_CODE_OFFSET 0x0
#define CHERI_CAP_USER_DATA_PERMS CHERI_PERMS_USERSPACE_DATA
#define CHERI_CAP_USER_DATA_BASE VM_MINUSER_ADDRESS
#define CHERI_CAP_USER_DATA_LENGTH (VM_MAXUSER_ADDRESS - VM_MINUSER_ADDRESS)
#define CHERI_CAP_USER_DATA_OFFSET 0x0
#define CHERI_CAP_USER_MMAP_PERMS \
(CHERI_PERMS_USERSPACE_DATA | CHERI_PERMS_USERSPACE_CODE | \
CHERI_PERM_CHERIABI_VMMAP)
/* Start at 256MB to avoid low PC values in sandboxes */
#define CHERI_CAP_USER_MMAP_BASE (VM_MINUSER_ADDRESS + 0x10000000)
#define CHERI_CAP_USER_MMAP_LENGTH \
(VM_MAXUSER_ADDRESS - CHERI_CAP_USER_MMAP_BASE)
#define CHERI_CAP_USER_MMAP_OFFSET 0x0
Root sealing capability for all userspace object capabilities. This is made available to userspace via a sysarch(2).
#define CHERI_SEALCAP_USERSPACE_PERMS CHERI_PERMS_USERSPACE_SEALCAP
#define CHERI_SEALCAP_USERSPACE_BASE CHERI_OTYPE_USER_MIN
#define CHERI_SEALCAP_USERSPACE_LENGTH \
(CHERI_OTYPE_USER_MAX - CHERI_OTYPE_USER_MIN + 1)
#define CHERI_SEALCAP_USERSPACE_OFFSET 0x0
If you could revise
the fundmental principles of
computer system design
to improve security...
... what would you change?