Skip to content

Commit b1d5af4

Browse files
committed
sys: Adjust support for bounded code pointers
Prepare for preferring the bounds from cap relocs and relative ELF relocations when PT_CHERI_PCC is present. For now the bounds are always disabled, but this provides the hooks to enable this in the future when support for PT_CHERI_PCC is added to the kernel linker.
1 parent 2c4897e commit b1d5af4

File tree

5 files changed

+19
-24
lines changed

5 files changed

+19
-24
lines changed

sys/arm64/arm64/elf_machdep.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -396,13 +396,16 @@ decode_fragment(Elf_Addr *fragment, Elf_Addr relocbase, Elf_Addr *addrp,
396396

397397
static uintcap_t __nosanitizecoverage
398398
build_reloc_cap(Elf_Addr addr, Elf_Addr size, uint8_t perms, Elf_Addr offset,
399-
void * __capability data_cap, const void * __capability code_cap)
399+
void * __capability data_cap, const void * __capability code_cap,
400+
bool use_code_bounds)
400401
{
401402
uintcap_t cap;
402403

403404
cap = perms == MORELLO_FRAG_EXECUTABLE ?
404405
(uintcap_t)code_cap : (uintcap_t)data_cap;
405406
cap = cheri_setaddress(cap, addr);
407+
if (perms != MORELLO_FRAG_EXECUTABLE || use_code_bounds)
408+
cap = cheri_setbounds(cap, size);
406409

407410
if (perms == MORELLO_FRAG_EXECUTABLE ||
408411
perms == MORELLO_FRAG_RODATA) {
@@ -414,7 +417,6 @@ build_reloc_cap(Elf_Addr addr, Elf_Addr size, uint8_t perms, Elf_Addr offset,
414417
perms == MORELLO_FRAG_RODATA) {
415418
cap = cheri_clearperm(cap, CHERI_PERM_SEAL |
416419
CHERI_PERM_EXECUTE);
417-
cap = cheri_setbounds(cap, size);
418420
}
419421
cap += offset;
420422
if (perms == MORELLO_FRAG_EXECUTABLE) {
@@ -429,13 +431,15 @@ build_reloc_cap(Elf_Addr addr, Elf_Addr size, uint8_t perms, Elf_Addr offset,
429431
#ifdef __CHERI_PURE_CAPABILITY__
430432
static uintcap_t __nosanitizecoverage
431433
build_cap_from_fragment(Elf_Addr *fragment, Elf_Addr relocbase, Elf_Addr offset,
432-
void * __capability data_cap, const void * __capability code_cap)
434+
void * __capability data_cap, const void * __capability code_cap,
435+
bool use_code_bounds)
433436
{
434437
Elf_Addr addr, size;
435438
uint8_t perms;
436439

437440
decode_fragment(fragment, relocbase, &addr, &size, &perms);
438-
return (build_reloc_cap(addr, size, perms, offset, data_cap, code_cap));
441+
return (build_reloc_cap(addr, size, perms, offset, data_cap, code_cap,
442+
use_code_bounds));
439443
}
440444
#endif
441445
#endif
@@ -516,7 +520,7 @@ elf_reloc_internal(linker_file_t lf, char *relocbase, const void *data,
516520
(val == addr1 ? relocbase :
517521
linker_kernel_file->address);
518522
*(uintcap_t *)(void *)where = build_reloc_cap(addr1,
519-
size, perms, addend, base, base);
523+
size, perms, addend, base, base, false);
520524
}
521525
#endif
522526
return (0);
@@ -618,7 +622,7 @@ elf_reloc_internal(linker_file_t lf, char *relocbase, const void *data,
618622
} else
619623
addr = build_cap_from_fragment(where,
620624
(Elf_Addr)relocbase, rela->r_addend,
621-
relocbase, relocbase);
625+
relocbase, relocbase, false);
622626
addr = ((uintptr_t (*)(void))addr)();
623627
*(uintptr_t *)where = addr;
624628
break;
@@ -785,7 +789,7 @@ elf_reloc_self(const Elf_Dyn *dynp, void *data_cap, const void *code_cap)
785789
fragment = (Elf_Addr *)cheri_setaddress(data_cap,
786790
rela->r_offset);
787791
cap = build_cap_from_fragment(fragment, 0,
788-
rela->r_addend, data_cap, code_cap);
792+
rela->r_addend, data_cap, code_cap, false);
789793
*((uintptr_t *)fragment) = cap;
790794
break;
791795
}

sys/cheri/cheri.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ typedef void (cap_relocs_cb)(void *arg, bool function, bool constant,
179179

180180
int init_linker_file_cap_relocs(const void *start_relocs,
181181
const void *stop_relocs, void *data_cap, ptraddr_t base_addr,
182-
cap_relocs_cb *cb, void *cb_arg);
182+
bool can_set_code_bounds, cap_relocs_cb *cb, void *cb_arg);
183183
#endif
184184
#endif /* !_KERNEL */
185185

sys/cheri/cheri_cap_relocs.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,26 +64,16 @@ typedef void (cap_relocs_cb)(void *arg, bool function, bool constant,
6464

6565
int init_linker_file_cap_relocs(const void *start_relocs,
6666
const void *stop_relocs, void *data_cap, ptraddr_t base_addr,
67-
cap_relocs_cb *cb, void *cb_arg);
67+
bool can_set_code_bounds, cap_relocs_cb *cb, void *cb_arg);
6868

6969
/* Can't include <sys/systm.h>. */
7070
int printf(const char *, ...) __printflike(1, 2);
7171

7272
int
7373
init_linker_file_cap_relocs(const void *start_relocs, const void *stop_relocs,
74-
void *data_cap, ptraddr_t base_addr, cap_relocs_cb *cb, void *cb_arg)
74+
void *data_cap, ptraddr_t base_addr, bool can_set_code_bounds,
75+
cap_relocs_cb *cb, void *cb_arg)
7576
{
76-
/*
77-
* Set code bounds if the ABI allows it.
78-
* When building for hybrid or with the pc-relative captable ABI we do
79-
* not further constrain the given code_cap.
80-
*/
81-
#if !defined(__CHERI_PURE_CAPABILITY__) || __CHERI_CAPABILITY_TABLE__ == 3
82-
bool can_set_code_bounds = false;
83-
#else
84-
bool can_set_code_bounds = true;
85-
#endif
86-
8777
/*
8878
* This cannot use cheri_init_globals_impl directly as symbols
8979
* for kernel modules in the vnet and dpcpu sets need to use

sys/kern/link_elf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2194,7 +2194,7 @@ link_elf_reloc_local(linker_file_t lf)
21942194
data_cap = cheri_andperm(ef->mapbase, CHERI_PERMS_KERNEL_DATA);
21952195
if (init_linker_file_cap_relocs(ef->caprelocs,
21962196
(char *)ef->caprelocs + ef->caprelocssize, data_cap,
2197-
(ptraddr_t)ef->address, resolve_cap_reloc, ef) != 0)
2197+
(ptraddr_t)ef->address, false, resolve_cap_reloc, ef) != 0)
21982198
return (ENOEXEC);
21992199
}
22002200
#endif

sys/riscv/riscv/locore.S

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -404,8 +404,9 @@ va:
404404
cincoffset ca1, ca0, t1
405405
candperm ca2, cs0, t0
406406
mv a3,zero
407-
cllc ca4, _C_LABEL(kernel_cap_relocs_cb)
408-
csetflags ca5, ca4, zero
407+
mv a4,zero /* TODO: true for PT_CHERI_PCC */
408+
cllc ca5, _C_LABEL(kernel_cap_relocs_cb)
409+
csetflags ca6, ca5, zero
409410
cllc cra, _C_LABEL(init_linker_file_cap_relocs)
410411
cjalr cra
411412
cincoffset csp, csp, (2 * 16)

0 commit comments

Comments
 (0)