From 53f014c063d5f31f5f1aa3851a45bdd0784cd0eb Mon Sep 17 00:00:00 2001 From: Dapeng Gao Date: Wed, 28 Aug 2024 16:44:19 +0100 Subject: [PATCH 1/2] c18n: Compare pointers by converting them to integers first Strictly speaking, using >= to compare pointers to different trusted frames is undefined behaviour. --- libexec/rtld-elf/rtld_c18n.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libexec/rtld-elf/rtld_c18n.c b/libexec/rtld-elf/rtld_c18n.c index 99395627a166..1eecfac7c9aa 100644 --- a/libexec/rtld-elf/rtld_c18n.c +++ b/libexec/rtld-elf/rtld_c18n.c @@ -944,7 +944,8 @@ unwind_stack(struct jmp_args ret, void *rcsp, struct trusted_frame *target) tf = get_trusted_stk(); - if (!cheri_is_subset(tf, target) || tf->previous >= target) { + if (!cheri_is_subset(tf, target) || + (ptraddr_t)tf->previous >= (ptraddr_t)target) { rtld_fdprintf(STDERR_FILENO, "c18n: Illegal unwind from %#p to %#p\n", tf, target); abort(); @@ -960,7 +961,7 @@ unwind_stack(struct jmp_args ret, void *rcsp, struct trusted_frame *target) cid = index_to_cid(index); ospp = &table->entries[cid].stack; - if (*ospp > cur->osp) { + if ((ptraddr_t)*ospp > (ptraddr_t)cur->osp) { rtld_fdprintf(STDERR_FILENO, "c18n: Cannot unwind %s from %#p to %#p\n", comparts.data[cid].name, *ospp, cur->osp); @@ -969,9 +970,9 @@ unwind_stack(struct jmp_args ret, void *rcsp, struct trusted_frame *target) *ospp = cur->osp; cur = cur->previous; - } while (cur < target); + } while ((ptraddr_t)cur < (ptraddr_t)target); - if (cur != target) { + if ((ptraddr_t)cur != (ptraddr_t)target) { rtld_fdprintf(STDERR_FILENO, "c18n: Illegal unwind from %#p to %#p\n", cur, target); abort(); @@ -982,7 +983,7 @@ unwind_stack(struct jmp_args ret, void *rcsp, struct trusted_frame *target) * topmost trusted frame to restore the untrusted stack when it is * popped. */ - if (rcsp > *ospp) { + if ((ptraddr_t)rcsp > (ptraddr_t)*ospp) { rtld_fdprintf(STDERR_FILENO, "c18n: Cannot complete unwind %s from %#p to %#p, ", "tf: %#p -> %#p\n", comparts.data[cid].name, rcsp, *ospp, From f0c2c5d124b224a09d32d251f4019d658fd8a8dc Mon Sep 17 00:00:00 2001 From: Dapeng Gao Date: Tue, 18 Jun 2024 16:33:34 +0100 Subject: [PATCH 2/2] c18n: Expose unified unwinding APIs to setjmp/longjmp and libunwind Previously, libunwind hard-codes knowledge about the layout of the trusted frame and has read access to the trusted stack. This is fragile and insecure. Now, the task of extracting the relevant registers from the trusted stack is delegated to RTLD, and libunwind no longer has access to the trusted stack. The unified unwinding APIs are declared as dl_c18n_* functions in link.h. setjmp/longjmp have been updated to use them. The previous API has been retained for compatibility with old libunwind. --- lib/libc/aarch64/gen/_setjmp.S | 47 ++++++----- lib/libc/aarch64/gen/setjmp.S | 52 ++++++------ lib/libgcc_s/Makefile | 3 +- lib/libgcc_s/Symbol-c18n.map | 7 +- libexec/rtld-elf/Symbol-c18n.map | 8 +- libexec/rtld-elf/aarch64/rtld_c18n_asm.S | 3 + libexec/rtld-elf/aarch64/rtld_c18n_machdep.h | 34 +------- libexec/rtld-elf/rtld_c18n.c | 88 ++++++++++++++------ libexec/rtld-elf/rtld_c18n.h | 46 +++++++++- libexec/rtld-elf/rtld_c18n_policy.txt | 8 ++ sys/sys/link_elf.h | 6 ++ 11 files changed, 182 insertions(+), 120 deletions(-) diff --git a/lib/libc/aarch64/gen/_setjmp.S b/lib/libc/aarch64/gen/_setjmp.S index 66a239b563a3..624d9ff1430c 100644 --- a/lib/libc/aarch64/gen/_setjmp.S +++ b/lib/libc/aarch64/gen/_setjmp.S @@ -37,6 +37,13 @@ ENTRY(_setjmp) ldr x8, .Lmagic mov REG(9), REGN(sp) stp REG(8), REG(9), [REG(0)], #(REG_WIDTH * 2) +#ifdef CHERI_LIB_C18N + /* Store the trusted stack pointer */ + stp c0, c30, [csp, #-0x20]! + bl dl_c18n_get_trusted_stk + ldp c0, c30, [csp], #0x20 + add c0, c0, #REG_WIDTH +#endif /* Store the general purpose registers and lr */ stp REG(19), REG(20), [REG(0)], #(REG_WIDTH * 2) @@ -55,18 +62,8 @@ ENTRY(_setjmp) #endif /* Return value */ -#ifdef CHERI_LIB_C18N - mov c1, c0 -#endif mov x0, #0 -#ifdef CHERI_LIB_C18N - /* - * Tail-call to save Executive mode state - */ - b _rtld_setjmp -#else RETURN -#endif .align 3 .Lmagic: .quad _JB_MAGIC__SETJMP @@ -79,12 +76,26 @@ ENTRY(_longjmp) cmp x8, x9 b.ne botch +#ifdef CHERI_LIB_C18N + /* + * Preserve the arguments in callee-saved registers instead of pushing + * them onto the stack because stack unwinding will switch the stack. + */ + mov c19, c0 + mov c20, c1 + /* Pass the target untrusted stack pointer and trusted stack pointer */ + ldp c0, c1, [c0] + bl dl_c18n_unwind_trusted_stk + mov c0, c19 + mov c1, c20 +#endif + /* Restore the stack pointer */ ldr REG(8), [REG(0)], #(REG_WIDTH) -#ifdef CHERI_LIB_C18N - mov c2, c8 -#else mov REGN(sp), REG(8) +#ifdef CHERI_LIB_C18N + /* Skip the trusted stack pointer */ + add c0, c0, #REG_WIDTH #endif /* Restore the general purpose registers and lr */ @@ -104,19 +115,9 @@ ENTRY(_longjmp) #endif /* Load the return value */ -#ifdef CHERI_LIB_C18N - mov c3, c0 -#endif cmp x1, #0 csinc x0, x1, xzr, ne -#ifdef CHERI_LIB_C18N - /* - * Tail-call to restore Executive mode state - */ - b _rtld_longjmp -#else RETURN -#endif botch: #ifdef _STANDALONE diff --git a/lib/libc/aarch64/gen/setjmp.S b/lib/libc/aarch64/gen/setjmp.S index 164199ca695a..7931b8c03e24 100644 --- a/lib/libc/aarch64/gen/setjmp.S +++ b/lib/libc/aarch64/gen/setjmp.S @@ -32,11 +32,6 @@ #include #include -#ifdef CHERI_LIB_C18N -.weak _rtld_setjmp -.weak _rtld_longjmp -#endif - ENTRY(setjmp) sub REGN(sp), REGN(sp), #(REG_WIDTH * 2) stp REG(0), REGN(lr), [REGN(sp)] @@ -54,6 +49,13 @@ ENTRY(setjmp) ldr x8, .Lmagic mov REG(9), REGN(sp) stp REG(8), REG(9), [REG(0)], #(REG_WIDTH * 2) +#ifdef CHERI_LIB_C18N + /* Store the trusted stack pointer */ + stp c0, c30, [csp, #-0x20]! + bl dl_c18n_get_trusted_stk + ldp c0, c30, [csp], #0x20 + add c0, c0, #REG_WIDTH +#endif /* Store the general purpose registers and lr */ stp REG(19), REG(20), [REG(0)], #(REG_WIDTH * 2) @@ -70,24 +72,28 @@ ENTRY(setjmp) stp d14, d15, [REG(0)], #16 /* Return value */ -#ifdef CHERI_LIB_C18N - mov c1, c0 -#endif mov x0, #0 -#ifdef CHERI_LIB_C18N - /* - * Tail-call to save Executive mode state - */ - b _rtld_setjmp -#else RETURN -#endif .align 3 .Lmagic: .quad _JB_MAGIC_SETJMP END(setjmp) ENTRY(longjmp) +#ifdef CHERI_LIB_C18N + /* + * Preserve the arguments in callee-saved registers instead of pushing + * them onto the stack because stack unwinding will switch the stack. + */ + mov c19, c0 + mov c20, c1 + /* Pass the target untrusted stack pointer and trusted stack pointer */ + ldp c0, c1, [c0, #(REG_WIDTH * 1)] + bl dl_c18n_unwind_trusted_stk + mov c0, c19 + mov c1, c20 +#endif + sub REGN(sp), REGN(sp), #(REG_WIDTH * 4) stp REG(0), REGN(lr), [REGN(sp)] str REG(1), [REGN(sp), #(REG_WIDTH * 2)] @@ -110,10 +116,10 @@ ENTRY(longjmp) /* Restore the stack pointer */ ldr REG(8), [REG(0)], #(REG_WIDTH) -#ifdef CHERI_LIB_C18N - mov c2, c8 -#else mov REGN(sp), REG(8) +#ifdef CHERI_LIB_C18N + /* Skip the trusted stack pointer */ + add c0, c0, #REG_WIDTH #endif /* Restore the general purpose registers and lr */ @@ -131,19 +137,9 @@ ENTRY(longjmp) ldp d14, d15, [REG(0)], #16 /* Load the return value */ -#ifdef CHERI_LIB_C18N - mov c3, c0 -#endif cmp x1, #0 csinc x0, x1, xzr, ne -#ifdef CHERI_LIB_C18N - /* - * Tail-call to restore Executive mode state - */ - b _rtld_longjmp -#else RETURN -#endif botch: bl _C_LABEL(longjmperror) diff --git a/lib/libgcc_s/Makefile b/lib/libgcc_s/Makefile index 5cc573d2a042..4d46a07b96fb 100644 --- a/lib/libgcc_s/Makefile +++ b/lib/libgcc_s/Makefile @@ -53,10 +53,9 @@ SRCS+= s_logbl.c SRCS+= s_scalbnl.c .endif -# LIBUNWIND_SANDBOX_OTYPES is only supported on aarch64 (Morello). +# c18n is only supported on Morello. .if ${MACHINE_ABI:Mpurecap} && ${MACHINE_CPUARCH} == "aarch64" SYMBOL_MAPS+= ${.CURDIR}/Symbol-c18n.map -CFLAGS+= -D_LIBUNWIND_CHERI_C18N_SUPPORT .endif .include diff --git a/lib/libgcc_s/Symbol-c18n.map b/lib/libgcc_s/Symbol-c18n.map index 6cddda834561..0054a7e586d1 100644 --- a/lib/libgcc_s/Symbol-c18n.map +++ b/lib/libgcc_s/Symbol-c18n.map @@ -1,5 +1,6 @@ FBSDprivate_1.0 { - _rtld_unw_getcontext; - _rtld_unw_setcontext; - _rtld_unw_getsealer; + dl_c18n_get_trusted_stk; + dl_c18n_unwind_trusted_stk; + dl_c18n_is_tramp; + dl_c18n_pop_trusted_stk; }; diff --git a/libexec/rtld-elf/Symbol-c18n.map b/libexec/rtld-elf/Symbol-c18n.map index 3729640162b9..dbbb00ccbc04 100644 --- a/libexec/rtld-elf/Symbol-c18n.map +++ b/libexec/rtld-elf/Symbol-c18n.map @@ -11,10 +11,10 @@ FBSDprivate_1.0 { _rtld_setjmp; _rtld_longjmp; _rtld_unw_getcontext; - _rtld_unw_getcontext_unsealed; _rtld_unw_setcontext; - _rtld_unw_setcontext_unsealed; _rtld_unw_getsealer; - _rtld_safebox_code; - _rtld_sandbox_code; + dl_c18n_get_trusted_stk; + dl_c18n_unwind_trusted_stk; + dl_c18n_is_tramp; + dl_c18n_pop_trusted_stk; }; diff --git a/libexec/rtld-elf/aarch64/rtld_c18n_asm.S b/libexec/rtld-elf/aarch64/rtld_c18n_asm.S index 17b699f5c533..0fe1e076f117 100644 --- a/libexec/rtld-elf/aarch64/rtld_c18n_asm.S +++ b/libexec/rtld-elf/aarch64/rtld_c18n_asm.S @@ -34,6 +34,9 @@ * See rtld_c18n.h for an overview of the design. */ +/* + * XXX: These assembly stubs are kept here for compatibility with old libunwind. + */ /* * The _rtld_unw_{get,set}context_epilogue functions are stack unwinding * helpers. See the 'Stack unwinding' section in rtld_c18n.c. diff --git a/libexec/rtld-elf/aarch64/rtld_c18n_machdep.h b/libexec/rtld-elf/aarch64/rtld_c18n_machdep.h index 5e2607f42f08..4d2f0335d5d3 100644 --- a/libexec/rtld-elf/aarch64/rtld_c18n_machdep.h +++ b/libexec/rtld-elf/aarch64/rtld_c18n_machdep.h @@ -133,7 +133,7 @@ set_untrusted_stk(const void *sp) } #endif -struct trusted_frame { +struct dl_c18n_compart_state { void *fp; void *pc; /* @@ -145,38 +145,6 @@ struct trusted_frame { * caller made the call. */ void *sp; - /* - * INVARIANT: This field contains the top of the caller's stack when the - * caller was last entered. - */ - void *osp; - /* - * Address of the previous trusted frame - */ - struct trusted_frame *previous; - /* - * Compartment ID of the caller - */ - stk_table_index caller; - /* - * Zeros - */ - uint16_t zeros; - /* - * Compartment ID of the callee - */ - stk_table_index callee; - /* - * Number of return value registers, encoded in enum tramp_ret_args - */ - uint8_t ret_args : 2; - uint16_t reserved : 14; - /* - * This field contains the code address in the trampoline that the - * callee should return to. This is used by trampolines to detect cross- - * compartment tail-calls. - */ - ptraddr_t landing; }; #endif #endif diff --git a/libexec/rtld-elf/rtld_c18n.c b/libexec/rtld-elf/rtld_c18n.c index 1eecfac7c9aa..1ebecf5f0fff 100644 --- a/libexec/rtld-elf/rtld_c18n.c +++ b/libexec/rtld-elf/rtld_c18n.c @@ -87,7 +87,7 @@ _Static_assert( TRUSTED_FRAME_SIZE * sizeof(uintptr_t) == sizeof(struct trusted_frame), "Unexpected struct trusted_frame size"); _Static_assert( - TRUSTED_FRAME_SP_OSP == offsetof(struct trusted_frame, sp), + TRUSTED_FRAME_SP_OSP == offsetof(struct trusted_frame, state.sp), "Unexpected struct trusted_frame member offset"); _Static_assert( TRUSTED_FRAME_PREV == offsetof(struct trusted_frame, previous), @@ -117,8 +117,7 @@ _Static_assert( * Sealers for RTLD privileged information */ static uintptr_t sealer_tcb; -static uintptr_t sealer_jmpbuf; -static uintptr_t sealer_unwbuf; +static uintptr_t sealer_trusted_stk; uintptr_t sealer_pltgot, sealer_tramp; @@ -859,6 +858,8 @@ resolve_untrusted_stk_impl(stk_table_index index) /* * Stack unwinding + * + * APIs exposed to stack unwinders (e.g., libc setjmp/longjmp and libunwind) */ /* * Assembly functions that are tail-called when compartmentalisation is @@ -867,8 +868,8 @@ resolve_untrusted_stk_impl(stk_table_index index) uintptr_t _rtld_unw_getcontext_epilogue(uintptr_t, void **); struct jmp_args _rtld_unw_setcontext_epilogue(struct jmp_args, void *, void **); -static void * -unwind_cursor(void) +void +dl_c18n_get_trusted_stk(void **buf) { /* * This helper is used by functions like setjmp. Before setjmp is @@ -882,17 +883,23 @@ unwind_cursor(void) * buffer. */ - return (get_trusted_stk()->previous); + if (C18N_ENABLED) + *buf = cheri_seal(get_trusted_stk()->previous, + sealer_trusted_stk); + else + *buf = NULL; } +/* + * XXX: These functions are kept here for compatibility with old libunwind. + */ uintptr_t _rtld_setjmp(uintptr_t, void **); uintptr_t _rtld_unw_getcontext(uintptr_t, void **); -uintptr_t _rtld_unw_getcontext_unsealed(uintptr_t, void **); uintptr_t _rtld_setjmp(uintptr_t ret, void **buf) { - *buf = cheri_seal(unwind_cursor(), sealer_jmpbuf); + dl_c18n_get_trusted_stk(buf); return (ret); } @@ -903,7 +910,7 @@ _rtld_unw_getcontext(uintptr_t ret, void **buf) __attribute__((musttail)) return (_rtld_unw_getcontext_epilogue(ret, buf)); } - *buf = cheri_seal(unwind_cursor(), sealer_unwbuf); + dl_c18n_get_trusted_stk(buf); return (ret); } @@ -913,8 +920,8 @@ _rtld_unw_getcontext(uintptr_t ret, void **buf) */ struct jmp_args { uintptr_t ret1; uintptr_t ret2; }; -static struct jmp_args -unwind_stack(struct jmp_args ret, void *rcsp, struct trusted_frame *target) +void +dl_c18n_unwind_trusted_stk(void *rcsp, void *target) { /* * This helper is used by functions like longjmp. Before longjmp is @@ -936,6 +943,9 @@ unwind_stack(struct jmp_args ret, void *rcsp, struct trusted_frame *target) struct trusted_frame *cur, *tf; sigset_t nset, oset; + if (!C18N_ENABLED) + return; + /* * Make the function re-entrant by blocking all signals. */ @@ -943,6 +953,7 @@ unwind_stack(struct jmp_args ret, void *rcsp, struct trusted_frame *target) sigprocmask(SIG_SETMASK, &nset, &oset); tf = get_trusted_stk(); + target = cheri_unseal(target, sealer_trusted_stk); if (!cheri_is_subset(tf, target) || (ptraddr_t)tf->previous >= (ptraddr_t)target) { @@ -991,36 +1002,64 @@ unwind_stack(struct jmp_args ret, void *rcsp, struct trusted_frame *target) abort(); } - tf->sp = rcsp; + tf->state.sp = rcsp; tf->osp = *ospp; tf->previous = cur; tf->caller = index; sigprocmask(SIG_SETMASK, &oset, NULL); +} - return (ret); +int +dl_c18n_is_tramp(ptraddr_t pc, void *tfs) +{ + struct trusted_frame *tf; + + if (!C18N_ENABLED) + return (0); + + tf = cheri_unseal(tfs, sealer_trusted_stk); + return (pc == tf->landing); +} + +void * +dl_c18n_pop_trusted_stk(struct dl_c18n_compart_state *state, void *tfs) +{ + struct trusted_frame *tf; + + if (!C18N_ENABLED) + return (NULL); + + tf = cheri_unseal(tfs, sealer_trusted_stk); + *state = tf->state; + return (cheri_seal(tf->previous, sealer_trusted_stk)); } +/* + * XXX: These functions are kept here for compatibility with old libunwind. + */ struct jmp_args _rtld_longjmp(struct jmp_args, void *, void **); struct jmp_args _rtld_unw_setcontext_impl(struct jmp_args, void *, void **); struct jmp_args _rtld_longjmp(struct jmp_args ret, void *rcsp, void **buf) { - return (unwind_stack(ret, rcsp, cheri_unseal(*buf, sealer_jmpbuf))); + dl_c18n_unwind_trusted_stk(rcsp, *buf); + return (ret); } struct jmp_args _rtld_unw_setcontext_impl(struct jmp_args ret, void *rcsp, void **buf) { - return (unwind_stack(ret, rcsp, cheri_unseal(*buf, sealer_unwbuf))); + dl_c18n_unwind_trusted_stk(rcsp, *buf); + return (ret); } uintptr_t _rtld_unw_getsealer(void); uintptr_t _rtld_unw_getsealer(void) { - return (sealer_unwbuf); + return (sealer_trusted_stk); } /* @@ -1210,9 +1249,9 @@ tramp_hook_impl(int event, const struct tramp_header *hdr, memcpy(ut.sig, C18N_UTRACE_SIG, C18N_UTRACE_SIG_SZ); ut.event = event; ut.symnum = hdr->symnum; - ut.fp = tf->fp; - ut.pc = tf->pc; - ut.sp = tf->sp; + ut.fp = tf->state.fp; + ut.pc = tf->state.pc; + ut.sp = tf->state.sp; ut.osp = tf->osp; ut.previous = tf->previous; memcpy(&ut.fsig, &hdr->sig, sizeof(ut.fsig)); @@ -1639,10 +1678,7 @@ c18n_init2(Obj_Entry *obj_rtld) sealer_tcb = cheri_setboundsexact(sealer, 1); sealer += 1; - sealer_jmpbuf = cheri_setboundsexact(sealer, 1); - sealer += 1; - - sealer_unwbuf = cheri_setboundsexact(sealer, 1); + sealer_trusted_stk = cheri_setboundsexact(sealer, 1); sealer += 1; sealer_tramp = cheri_setboundsexact(sealer, C18N_FUNC_SIG_COUNT); @@ -1978,7 +2014,9 @@ _rtld_sighandler_impl(int sig, siginfo_t *info, ucontext_t *ucp, void *nsp) */ ntf = tf - 2; *ntf = (struct trusted_frame) { - .sp = nsp, + .state = (struct dl_c18n_compart_state) { + .sp = nsp + }, .osp = osp, .previous = tf, .caller = intr_idx, @@ -2033,7 +2071,7 @@ _rtld_sighandler_impl(int sig, siginfo_t *info, ucontext_t *ucp, void *nsp) * compartment. */ #ifndef __ARM_MORELLO_PURECAP_BENCHMARK_ABI - set_untrusted_stk(ntf->sp); + set_untrusted_stk(ntf->state.sp); #endif } diff --git a/libexec/rtld-elf/rtld_c18n.h b/libexec/rtld-elf/rtld_c18n.h index 646d48b23779..1c6a17bf7b3d 100644 --- a/libexec/rtld-elf/rtld_c18n.h +++ b/libexec/rtld-elf/rtld_c18n.h @@ -120,6 +120,48 @@ struct stk_table { #include "rtld_c18n_machdep.h" +struct trusted_frame { + /* + * Architecture-specific callee-saved registers, including fp, sp, and + * the return address + */ + struct dl_c18n_compart_state state; + /* + * INVARIANT: This field contains the top of the caller's stack when the + * caller was last entered. + */ + void *osp; + /* + * Pointer to the previous trusted frame + */ + struct trusted_frame *previous; + /* + * Stack table index of the caller, derived from its compartment ID + */ + stk_table_index caller; + /* + * This padding space must be filled with zeros so that an optimised + * trampoline can use a wide load to load multiple fields of the trusted + * frame and then use a word-sized register to extract the caller field. + */ + uint16_t zeros; + /* + * Stack table index of the callee, derived from its compartment ID + */ + stk_table_index callee; + /* + * Number of return value registers, encoded in enum tramp_ret_args + */ + uint8_t ret_args : 2; + uint16_t reserved : 14; + /* + * This field contains the code address in the trampoline that the + * callee should return to. This is used by trampolines to detect cross- + * compartment tail-calls. + */ + ptraddr_t landing; +}; + struct tcb *c18n_allocate_tcb(struct tcb *); void c18n_free_tcb(void); @@ -217,8 +259,8 @@ func_sig_legal(struct func_sig sig) /* * This macro can only be used in a function directly invoked by a trampoline. */ -#define c18n_return_address() \ - (C18N_ENABLED ? get_trusted_stk()->pc : __builtin_return_address(0)) +#define c18n_return_address() (C18N_ENABLED ? \ + get_trusted_stk()->state.pc : __builtin_return_address(0)) void *_rtld_sandbox_code(void *, struct func_sig); void *_rtld_safebox_code(void *, struct func_sig); diff --git a/libexec/rtld-elf/rtld_c18n_policy.txt b/libexec/rtld-elf/rtld_c18n_policy.txt index d373837982ab..4b085a871c31 100644 --- a/libexec/rtld-elf/rtld_c18n_policy.txt +++ b/libexec/rtld-elf/rtld_c18n_policy.txt @@ -59,8 +59,16 @@ export to [TCB] _rtld_setjmp _rtld_longjmp +callee [RTLD] +export to [TCB] +export to [libunwind] + dl_c18n_get_trusted_stk + dl_c18n_unwind_trusted_stk + callee [RTLD] export to [libunwind] _rtld_unw_getcontext _rtld_unw_setcontext _rtld_unw_getsealer + dl_c18n_is_tramp + dl_c18n_pop_trusted_stk diff --git a/sys/sys/link_elf.h b/sys/sys/link_elf.h index f999a296d945..0c1e365acf98 100644 --- a/sys/sys/link_elf.h +++ b/sys/sys/link_elf.h @@ -110,6 +110,12 @@ int _rtld_addr_phdr(const void *, struct dl_phdr_info *); int _rtld_get_stack_prot(void); int _rtld_is_dlopened(void *); +struct dl_c18n_compart_state; +void dl_c18n_get_trusted_stk(void **); +void dl_c18n_unwind_trusted_stk(void *, void *); +int dl_c18n_is_tramp(ptraddr_t, void *); +void *dl_c18n_pop_trusted_stk(struct dl_c18n_compart_state *, void *); + #ifdef __ARM_EABI__ void * dl_unwind_find_exidx(const void *, int *); #endif