Skip to content

Commit cd0d48d

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 f838244 commit cd0d48d

File tree

4 files changed

+18
-29
lines changed

4 files changed

+18
-29
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
@@ -180,7 +180,7 @@ typedef void (cap_relocs_cb)(void *arg, bool function, bool constant,
180180

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

sys/cheri/cheri_cap_relocs.c

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,10 @@ init_cap_relocs(void *data_cap, void *code_cap)
4646
stop_relocs = CHERI_RODATA_PTR(__stop___cap_relocs);
4747

4848
/*
49-
* Set code bounds if the ABI allows it.
50-
* When building for hybrid or with the pc-relative captable ABI we do
51-
* not further constrain the given code_cap.
49+
* TODO: Set code bounds if the ABI allows it (presence of
50+
* PT_CHERI_PCC)
5251
*/
53-
#if !defined(__CHERI_PURE_CAPABILITY__) || __CHERI_CAPABILITY_TABLE__ == 3
5452
bool can_set_code_bounds = false;
55-
#else
56-
bool can_set_code_bounds = true;
57-
#endif
5853

5954
for (const struct capreloc *reloc = start_relocs; reloc < stop_relocs;
6055
reloc++) {
@@ -112,23 +107,13 @@ typedef void (cap_relocs_cb)(void *arg, bool function, bool constant,
112107

113108
void init_linker_file_cap_relocs(const void *start_relocs,
114109
const void *stop_relocs, void *data_cap, ptraddr_t base_addr,
115-
cap_relocs_cb *cb, void *cb_arg);
110+
bool can_set_code_bounds, cap_relocs_cb *cb, void *cb_arg);
116111

117112
void
118113
init_linker_file_cap_relocs(const void *start_relocs, const void *stop_relocs,
119-
void *data_cap, ptraddr_t base_addr, cap_relocs_cb *cb, void *cb_arg)
114+
void *data_cap, ptraddr_t base_addr, bool can_set_code_bounds,
115+
cap_relocs_cb *cb, void *cb_arg)
120116
{
121-
/*
122-
* Set code bounds if the ABI allows it.
123-
* When building for hybrid or with the pc-relative captable ABI we do
124-
* not further constrain the given code_cap.
125-
*/
126-
#if !defined(__CHERI_PURE_CAPABILITY__) || __CHERI_CAPABILITY_TABLE__ == 3
127-
bool can_set_code_bounds = false;
128-
#else
129-
bool can_set_code_bounds = true;
130-
#endif
131-
132117
/*
133118
* This cannot use cheri_init_globals_impl directly as symbols
134119
* 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
@@ -2150,7 +2150,7 @@ link_elf_reloc_local(linker_file_t lf)
21502150
data_cap = cheri_andperm(ef->mapbase, CHERI_PERMS_KERNEL_DATA);
21512151
init_linker_file_cap_relocs(ef->caprelocs,
21522152
(char *)ef->caprelocs + ef->caprelocssize, data_cap,
2153-
(ptraddr_t)ef->address, resolve_cap_reloc, ef);
2153+
(ptraddr_t)ef->address, false, resolve_cap_reloc, ef);
21542154
}
21552155
#endif
21562156

0 commit comments

Comments
 (0)