Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Morello: Stop using caprelocs for static binaries #2286

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions lib/csu/aarch64/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ CFLAGS+= -I${.CURDIR}

.if ${MACHINE_CPU:Mcheri}
CFLAGS+= -I${.CURDIR:H}/common-cheri

NO_WCAST_ALIGN=
.endif

CRT1SRC= crt1_s.S
Expand Down
93 changes: 93 additions & 0 deletions lib/csu/aarch64/caprel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2024 SRI International
*
* This software was developed by SRI International, the University of
* Cambridge Computer Laboratory (Department of Computer Science and
* Technology), and Capabilities Limited under Defense Advanced Research
* Projects Agency (DARPA) Contract No. FA8750-24-C-B047 ("DEC").
*/

#ifndef __CAPREL_H__
#define __CAPREL_H__

#include <sys/types.h>
#include <machine/elf.h>

#include <cheri/cheric.h>

#define FUNC_PTR_REMOVE_PERMS \
(CHERI_PERM_SEAL | CHERI_PERM_STORE | CHERI_PERM_STORE_CAP | \
CHERI_PERM_STORE_LOCAL_CAP)

#define DATA_PTR_REMOVE_PERMS \
(CHERI_PERM_SEAL | CHERI_PERM_EXECUTE)

#define CAP_RELOC_REMOVE_PERMS \
(CHERI_PERM_SW_VMEM)

/*
* Fragments consist of a 64-bit address followed by a 56-bit length and an
* 8-bit permission field.
*/
static __always_inline uintcap_t
init_cap_from_fragment(const Elf_Addr *fragment, void * __capability data_cap,
const void * __capability text_rodata_cap, Elf_Addr base_addr,

Check failure on line 36 in lib/csu/aarch64/caprel.h

View workflow job for this annotation

GitHub Actions / Style Checker

"foo * bar" should be "foo *bar"
Elf_Size addend)
{
uintcap_t cap;
Elf_Addr address, len;
uint8_t perms;

address = fragment[0];
len = fragment[1] & ((1UL << (8 * sizeof(*fragment) - 8)) - 1);
perms = fragment[1] >> (8 * sizeof(*fragment) - 8);

cap = perms == MORELLO_FRAG_EXECUTABLE ?
(uintcap_t)text_rodata_cap : (uintcap_t)data_cap;
cap = cheri_setaddress(cap, base_addr + address);
cap = cheri_clearperm(cap, CAP_RELOC_REMOVE_PERMS);

if (perms == MORELLO_FRAG_EXECUTABLE || perms == MORELLO_FRAG_RODATA) {
cap = cheri_clearperm(cap, FUNC_PTR_REMOVE_PERMS);
}
if (perms == MORELLO_FRAG_RWDATA || perms == MORELLO_FRAG_RODATA) {
cap = cheri_clearperm(cap, DATA_PTR_REMOVE_PERMS);
cap = cheri_setbounds(cap, len);
}

cap += addend;

if (perms == MORELLO_FRAG_EXECUTABLE) {
/*
* TODO tight bounds: lower bound and len should be set
* with LSB == 0 for C64 code.
*/
cap = cheri_sealentry(cap);
}

return (cap);
}

static __always_inline void
elf_reloc(const Elf_Rela *rela, void * __capability data_cap,
const void * __capability code_cap, Elf_Addr relocbase)

Check failure on line 75 in lib/csu/aarch64/caprel.h

View workflow job for this annotation

GitHub Actions / Style Checker

"foo * bar" should be "foo *bar"
{
Elf_Addr addr;
Elf_Addr *where;

if (ELF_R_TYPE(rela->r_info) != R_MORELLO_RELATIVE)
__builtin_trap();

addr = relocbase + rela->r_offset;
#ifdef __CHERI_PURE_CAPABILITY__
where = cheri_setaddress(data_cap, addr);
#else
where = (Elf_Addr *)addr;
#endif
*(uintcap_t *)(void *)where = init_cap_from_fragment(where, data_cap,
code_cap, relocbase, rela->r_addend);
}

#endif /* __CAPREL_H__ */
6 changes: 6 additions & 0 deletions lib/csu/aarch64/crt1_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,15 @@
* need to include the code here.
*/
#if __has_feature(capabilities) && !defined(PIC)
#define CHERI_INIT_RELA

extern int _DYNAMIC;
#pragma weak _DYNAMIC

#define RODATA_PTR(x) &x

Check failure on line 46 in lib/csu/aarch64/crt1_c.c

View workflow job for this annotation

GitHub Actions / Style Checker

Macros with complex values should be enclosed in parenthesis

#include "caprel.h"

#include "crt_init_globals.c"

void __process_cap_relocs(char *env[]);
Expand Down
4 changes: 3 additions & 1 deletion lib/csu/aarch64c/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

.PATH: ${.CURDIR}/../common-cheri ${.CURDIR}/../common

CFLAGS+= -I${.CURDIR}
CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../aarch64

NO_WCAST_ALIGN=

.include <bsd.lib.mk>
13 changes: 13 additions & 0 deletions lib/csu/aarch64c/crt1_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@
* to include the code here.
*/
#ifndef PIC
#define CHERI_INIT_RELA

#define RODATA_PTR(x) ({ \
__typeof__(x) *_p; \
\
__asm__ ( \
"adrp %0, " __STRING(x) "\n\t" \
"add %0, %0, :lo12:" __STRING(x) "\n\t" \
: "=C" (_p)); \
_p; })

#include "caprel.h"

#include "crt_init_globals.c"
#endif

Expand Down
32 changes: 32 additions & 0 deletions lib/csu/common-cheri/crt_init_globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,34 @@
#error "PIEs never need to initialise their own globals"
#endif

#ifdef CHERI_INIT_RELA
extern const Elf_Rela __weak_symbol __rela_dyn_start __hidden;

Check failure on line 43 in lib/csu/common-cheri/crt_init_globals.c

View workflow job for this annotation

GitHub Actions / Style Checker

externs should be avoided in .c files
extern const Elf_Rela __weak_symbol __rela_dyn_end __hidden;

Check failure on line 44 in lib/csu/common-cheri/crt_init_globals.c

View workflow job for this annotation

GitHub Actions / Style Checker

externs should be avoided in .c files

static __always_inline void
crt_init_rela(const Elf_Phdr *phdr __unused)
{
const Elf_Rela *rela, *relalim;
void * __capability data_cap;

Check failure on line 50 in lib/csu/common-cheri/crt_init_globals.c

View workflow job for this annotation

GitHub Actions / Style Checker

"foo * bar" should be "foo *bar"
const void * __capability code_cap;

Check failure on line 51 in lib/csu/common-cheri/crt_init_globals.c

View workflow job for this annotation

GitHub Actions / Style Checker

"foo * bar" should be "foo *bar"

#ifdef __CHERI_PURE_CAPABILITY__
data_cap = __DECONST(void *, phdr);
#else
data_cap = cheri_getdefault();
#endif
data_cap = cheri_clearperm(data_cap,
CHERI_PERM_EXECUTE | CHERI_PERM_SW_VMEM);

code_cap = cheri_getpcc();

rela = RODATA_PTR(__rela_dyn_start);
relalim = RODATA_PTR(__rela_dyn_end);
for (; rela < relalim; rela++)
elf_reloc(rela, data_cap, code_cap, 0);
}
#endif

#define CHERI_INIT_GLOBALS_GDC_ONLY
#include <cheri_init_globals.h>
#if !defined(CHERI_INIT_GLOBALS_VERSION) || CHERI_INIT_GLOBALS_VERSION < 4
Expand Down Expand Up @@ -66,6 +94,10 @@
const void * __capability code_cap;
const void * __capability rodata_cap;

#ifdef CHERI_INIT_RELA
crt_init_rela(phdr);
#endif

/* Attempt to bound the data capability to only the writable segment */
for (const Elf_Phdr *ph = phdr; ph < phlimit; ph++) {
if (ph->p_type != PT_LOAD && ph->p_type != PT_GNU_RELRO) {
Expand Down
10 changes: 10 additions & 0 deletions libexec/rtld-elf/rtld.c
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,11 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
break;

case DT_JMPREL:
#ifdef __aarch64__
/* Ignore empty PLT entries for Morello. */
if (dynp->d_un.d_ptr == 0)
break;
#endif
obj->pltrel = (const Elf_Rel *)
(obj->relocbase + dynp->d_un.d_ptr);
break;
Expand Down Expand Up @@ -1643,6 +1648,11 @@ digest_dynamic1(Obj_Entry *obj, int early, const Elf_Dyn **dyn_rpath,
break;

case DT_PLTGOT:
#ifdef __aarch64__
/* Ignore empty PLT entries for Morello. */
if (dynp->d_un.d_ptr == 0)
break;
#endif
obj->pltgot = (uintptr_t *)(obj->relocbase + dynp->d_un.d_ptr);
break;

Expand Down
4 changes: 4 additions & 0 deletions share/mk/bsd.lib.mk
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ LDFLAGS+= -Wl,-zbti-report=error
.endif
.endif

.if ${MACHINE_CPUARCH} == "aarch64" && ${MACHINE_CPU:Mcheri}
LDFLAGS+= -Wl,--local-caprelocs=elf
.endif

# Initialize stack variables on function entry
.if ${OPT_INIT_ALL} != "none"
.if ${COMPILER_FEATURES:Minit-all}
Expand Down
4 changes: 4 additions & 0 deletions share/mk/bsd.prog.mk
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,13 @@
.endif
.endif

.if ${MACHINE_CPUARCH} == "aarch64" && ${MACHINE_CPU:Mcheri}
LDFLAGS+= -Wl,--local-caprelocs=elf
.endif

# Initialize stack variables on function entry
.if ${OPT_INIT_ALL} != "none"
.if ${COMPILER_FEATURES:Minit-all}

Check warning on line 93 in share/mk/bsd.prog.mk

View workflow job for this annotation

GitHub Actions / Style Checker

Missing Signed-off-by: line
CFLAGS+= -ftrivial-auto-var-init=${OPT_INIT_ALL}
CXXFLAGS+= -ftrivial-auto-var-init=${OPT_INIT_ALL}
.if ${OPT_INIT_ALL} == "zero" && ${COMPILER_TYPE} == "clang" && ${COMPILER_VERSION} < 160000
Expand Down
Loading