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

c18n: Fix various implementation bugs #2072

Closed
wants to merge 4 commits into from
Closed
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
9 changes: 0 additions & 9 deletions bin/cheribsdtest/cheribsdtest.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,15 +151,6 @@ extern struct cheribsdtest_child_state *ccsp;
#endif
#endif

#ifndef XFAIL_C18N_FPTR_CANON
#ifdef CHERIBSD_C18N_TESTS
#define XFAIL_C18N_FPTR_CANON \
"function pointers are currently non-canonical with library-based compartmentalisation"
#else
#define XFAIL_C18N_FPTR_CANON NULL
#endif
#endif

struct cheri_test {
const char *ct_name;
const char *ct_desc;
Expand Down
9 changes: 3 additions & 6 deletions bin/cheribsdtest/cheribsdtest_fptr_canon.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@
#include "cheribsdtest.h"

CHERIBSDTEST(fptr_canon_cross,
"Check that function pointers are canonical across objects",
.ct_xfail_reason = XFAIL_C18N_FPTR_CANON)
"Check that function pointers are canonical across objects")
{
void (* volatile fptr_inside)(void);
void (* volatile fptr_outside)(void);
Expand All @@ -53,8 +52,7 @@ CHERIBSDTEST(fptr_canon_cross,
}

CHERIBSDTEST(fptr_canon_dlsym,
"Check that function pointers are canonical for dlsym",
.ct_xfail_reason = XFAIL_C18N_FPTR_CANON)
"Check that function pointers are canonical for dlsym")
{
void (* volatile fptr_inside)(void);
void (* volatile fptr_dlsym)(void);
Expand All @@ -70,8 +68,7 @@ CHERIBSDTEST(fptr_canon_dlsym,
}

CHERIBSDTEST(fptr_canon_dlfunc,
"Check that function pointers are canonical for dlfunc",
.ct_xfail_reason = XFAIL_C18N_FPTR_CANON)
"Check that function pointers are canonical for dlfunc")
{
void (* volatile fptr_inside)(void);
void (* volatile fptr_dlfunc)(void);
Expand Down
6 changes: 4 additions & 2 deletions lib/libc/sys/sigaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ __weak_reference(sigaction, __libc_sigaction);
/*
* These weak symbols will always be resolved at runtime.
*/
#pragma weak _rtld_sighandler
void _rtld_sighandler(int, siginfo_t *, void *);
/*
* XXX: Explicit function pointer used so that RTLD can wrap it in trampoline.
*/
extern void (*_rtld_sighandler)(int, siginfo_t *, void *);

#pragma weak _rtld_sigaction_begin
void *_rtld_sigaction_begin(int, struct sigaction *);
Expand Down
12 changes: 8 additions & 4 deletions lib/libthr/thread/thr_sig.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,15 @@ static void check_cancel(struct pthread *curthread, ucontext_t *ucp);
/*
* These weak symbols will always be resolved at runtime.
*/
#pragma weak _rtld_sighandler
void _rtld_sighandler(int, siginfo_t *, void *);
/*
* XXX: Explicit function pointer used so that RTLD can wrap it in trampoline.
*/
extern void (*_rtld_sighandler)(int, siginfo_t *, void *);

#pragma weak _rtld_dispatch_signal
void _rtld_dispatch_signal(int, siginfo_t *, void *);
/*
* XXX: Explicit function pointer used so that RTLD can wrap it in trampoline.
*/
extern void (*_rtld_dispatch_signal)(int, siginfo_t *, void *);

#pragma weak _rtld_sigaction_begin
void *_rtld_sigaction_begin(int, struct sigaction *);
Expand Down
8 changes: 4 additions & 4 deletions libexec/rtld-elf/aarch64/rtld_c18n_asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ END(_rtld_thread_start)
* is only ever invoked via a trampoline by the kernel when a signal is
* delivered.
*/
ENTRY(_rtld_sighandler)
ENTRY(_rtld_sighandler_unsafe)
#ifndef __ARM_MORELLO_PURECAP_BENCHMARK_ABI
/*
* The sigframe is pushed onto the trusted stack, disrupting the linked-
Expand Down Expand Up @@ -116,7 +116,7 @@ ENTRY(_rtld_sighandler)
mov c30, c19
b sighandler_unfix_link
#endif
END(_rtld_sighandler)
END(_rtld_sighandler_unsafe)

/*
* void _rtld_dispatch_signal(int, siginfo_t *, void *);
Expand All @@ -125,7 +125,7 @@ END(_rtld_sighandler)
* is only ever invoked by either RTLD code that is aware of this behaviour or
* external code via a trampoline.
*/
ENTRY(_rtld_dispatch_signal)
ENTRY(_rtld_dispatch_signal_unsafe)
mov c24, c30
mov w25, w0
mov c26, c1
Expand All @@ -151,7 +151,7 @@ ENTRY(_rtld_dispatch_signal)
mov c1, c27
mov c30, c24
b dispatch_signal_end
END(_rtld_dispatch_signal)
END(_rtld_dispatch_signal_unsafe)

ENTRY(allocate_rstk)
/*
Expand Down
8 changes: 0 additions & 8 deletions libexec/rtld-elf/cheri/cheri_reloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,6 @@ process_r_cheri_capability(Obj_Entry *obj, Elf_Word r_symndx,
}
/* Remove write permissions and set bounds */
symval = make_function_cap_with_addend(def, defobj, addend);
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
symval = tramp_intern(obj, &(struct tramp_data) {
.target = __DECONST(void *, symval),
.defobj = defobj,
.def = def,
.sig = sigtab_get(obj, r_symndx)
});
#endif
if (__predict_false(symval == NULL)) {
_rtld_error("Could not create function pointer for %s "
"(in %s)\n",
Expand Down
43 changes: 20 additions & 23 deletions libexec/rtld-elf/rtld.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ static bool ld_skip_init_funcs = false; /* XXXAR: debug environment variable to
static struct obj_entry_q obj_list; /* Queue of all loaded objects */
static Obj_Entry *obj_main; /* The main program shared object */
static Obj_Entry obj_rtld; /* The dynamic linker shared object */
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
Obj_Entry *obj_rtld_p = &obj_rtld;
#endif
static unsigned int obj_count; /* Number of objects in obj_list */
static unsigned int obj_loads; /* Number of loads of objects (gen count) */
size_t ld_static_tls_extra = /* Static TLS extra space (bytes) */
Expand Down Expand Up @@ -1228,12 +1231,21 @@ _rtld_bind(Obj_Entry *obj, Elf_Size reloff)
rtld_die();
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC)
target = (uintptr_t)rtld_resolve_ifunc(defobj, def);
else
else {
#ifdef __CHERI_PURE_CAPABILITY__
target = (uintptr_t)make_function_pointer(def, defobj);
#ifdef RTLD_SANDBOX
target = (uintptr_t)tramp_intern(obj, &(struct tramp_data) {
.target = (void *)target,
.defobj = defobj,
.def = def,
.sig = sigtab_get(obj, ELF_R_SYM(rel->r_info))
});
#endif
#else
target = (uintptr_t)(defobj->relocbase + def->st_value);
#endif
}

dbg("\"%s\" in \"%s\" ==> %p in \"%s\"",
defobj->strtab + def->st_name,
Expand All @@ -1248,14 +1260,6 @@ _rtld_bind(Obj_Entry *obj, Elf_Size reloff)
* address. The value returned from reloc_jmpslot() is the value
* that the trampoline needs.
*/
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
target = (uintptr_t)tramp_intern(obj, &(struct tramp_data) {
.target = (void *)target,
.defobj = defobj,
.def = def,
.sig = sigtab_get(obj, ELF_R_SYM(rel->r_info))
});
#endif
target = reloc_jmpslot(where, target, defobj, obj, rel);
lock_release(rtld_bind_lock, &lockstate);
return (target);
Expand Down Expand Up @@ -3293,6 +3297,13 @@ Obj_Entry *
obj_from_addr(const void *addr)
{
Obj_Entry *obj;
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
struct tramp_header *header;

header = tramp_reflect(__DECONST(void *, addr));
if (header != NULL)
return (__DECONST(Obj_Entry *, header->defobj));
#endif

TAILQ_FOREACH(obj, &obj_list, next) {
if (obj->marker)
Expand Down Expand Up @@ -4394,23 +4405,9 @@ do_dlsym(void *handle, const char *name, void *retaddr, const Ver_Entry *ve,
*/
if (ELF_ST_TYPE(def->st_info) == STT_FUNC) {
sym = __DECONST(void*, make_function_pointer(def, defobj));
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
sym = tramp_intern(obj, &(struct tramp_data) {
.target = sym,
.defobj = defobj,
.def = def
});
#endif
dbg("dlsym(%s) is function: " PTR_FMT, name, sym);
} else if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
sym = rtld_resolve_ifunc(defobj, def);
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
sym = tramp_intern(obj, &(struct tramp_data) {
.target = sym,
.defobj = defobj,
.def = def
});
#endif
dbg("dlsym(%s) is ifunc. Resolved to: " PTR_FMT, name, sym);
} else if (ELF_ST_TYPE(def->st_info) == STT_TLS) {
ti.ti_module = defobj->tlsindex;
Expand Down
Loading
Loading