-
Notifications
You must be signed in to change notification settings - Fork 60
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: New {get,set}context APIs for libunwind #2123
base: dev
Are you sure you want to change the base?
Conversation
This makes changes in setjmp/longjmp as well and the commit message should probably reflect that. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certainly some text in the commit log explaining why setjmp/longjmp are changing would be good.
lib/libc/aarch64/gen/_setjmp.S
Outdated
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX) | ||
mov c2, c8 | ||
#else | ||
#if !defined(__CHERI_PURE_CAPABILITY__) || !defined(RTLD_SANDBOX) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find it easier to read as !(purecap && sandbox) rather than !purecap || !sandbox.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, is RTLD_SANDBOX ever true for !purecap? That is, can we simplify some of the #ifdef's to #ifdef RTLD_SANDBOX
or #ifndef RTLD_SANDBOX
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, is RTLD_SANDBOX ever true for !purecap? That is, can we simplify some of the #ifdef's to
#ifdef RTLD_SANDBOX
or#ifndef RTLD_SANDBOX
?
The purecap check is indeed redundant. I'll do a find-and-replace once the libsys is merged. (libsys renames RTLD_SANDBOX to CHERI_LIB_C18N.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Security fixes: CTSRD-CHERI#2135 rar: Fix OOB in rar e8 filter (CVE-2024-26256) CTSRD-CHERI#2145 zip: Fix out of boundary access Important bugfixes: CTSRD-CHERI#2131 7zip: Limit amount of properties CTSRD-CHERI#2110 bsdtar: Fix error handling around strtol() usages CTSRD-CHERI#2116 passphrase: Never allow empty passwords CTSRD-CHERI#2124 rar: Fix "File CRC Error" when extracting specific rar4 archives CTSRD-CHERI#2123 xar: Avoid infinite link loop CTSRD-CHERI#2108 zip: Update AppleDouble support for directories CTSRD-CHERI#2071 zstd: Implement core detection Obained from: libarchive Libarchive commit: 313aa1fa10b657de791e3202c168a6c833bc3543
Libarchive 3.7.4 + three fixes from master Security fixes: CTSRD-CHERI#2135 rar: Fix OOB in rar e8 filter (CVE-2024-26256) CTSRD-CHERI#2145 zip: Fix out of boundary access CTSRD-CHERI#2148 rar: Fix OOB in rar delta filter CTSRD-CHERI#2149 rar: Fix OOB in rar audio filter Important bugfixes: CTSRD-CHERI#2131 7zip: Limit amount of properties CTSRD-CHERI#2110 bsdtar: Fix error handling around strtol() usages CTSRD-CHERI#2116 passphrase: Never allow empty passwords CTSRD-CHERI#2124 rar: Fix "File CRC Error" when extracting specific rar4 archives CTSRD-CHERI#2123 xar: Avoid infinite link loop CTSRD-CHERI#2150 xar: Fix another infinite loop and expat error handling CTSRD-CHERI#2108 zip: Update AppleDouble support for directories CTSRD-CHERI#2071 zstd: Implement core detectiongit PR: 278588 (exp-run) MFC after: 1 day
Libarchive 3.7.4 + three fixes from master Security fixes: CTSRD-CHERI#2135 rar: Fix OOB in rar e8 filter (CVE-2024-26256) CTSRD-CHERI#2145 zip: Fix out of boundary access CTSRD-CHERI#2148 rar: Fix OOB in rar delta filter CTSRD-CHERI#2149 rar: Fix OOB in rar audio filter Important bugfixes: CTSRD-CHERI#2131 7zip: Limit amount of properties CTSRD-CHERI#2110 bsdtar: Fix error handling around strtol() usages CTSRD-CHERI#2116 passphrase: Never allow empty passwords CTSRD-CHERI#2124 rar: Fix "File CRC Error" when extracting specific rar4 archives CTSRD-CHERI#2123 xar: Avoid infinite link loop CTSRD-CHERI#2150 xar: Fix another infinite loop and expat error handling CTSRD-CHERI#2108 zip: Update AppleDouble support for directories CTSRD-CHERI#2071 zstd: Implement core detectiongit PR: 278588 (exp-run) MFC after: 1 day
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Builds & runs fine, similar to CTSRD-CHERI/llvm-project#740 just a few nits.
libexec/rtld-elf/rtld_c18n.c
Outdated
|
||
static void * | ||
unwind_cursor(void) | ||
bool c18n_is_enabled(void); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should probably be in sys/sys/link_elf.h with dl_iterate_phdr and friends.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Although I guess it would require renaming struct trusted_frame
etc. to have a dl_
prefix?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm, since a struct trusted_frame *
only ever leaves RTLD as a sealed capability, a void *
should be sufficient.
@@ -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 ? \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should probably be a non-c18n fallback implementation of this so you don't need to ifdef every use.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will do in another PR
@@ -936,13 +913,17 @@ 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 (ret); | |||
|
|||
/* | |||
* Make the function re-entrant by blocking all signals. | |||
*/ | |||
SIGFILLSET(nset); | |||
sigprocmask(SIG_SETMASK, &nset, &oset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could expose functions from rtld_lock.c that use sigfastblock when available, saves having to do syscalls here for single-threaded applications. In theory one could also register a per-thread mask just for c18n to use, given rtld unregisters its locking one when a thread is created. But not for this PR.
@jrtc27 I've changed how setjmp/longjmp invokes the RTLD's unwinding APIs such that it is very simple to remove the ifdefs in a future PR (essentially we just need a noop ASM stub like in libunwind). I also added |
The |
Can we keep the old interfaces implemented as compatibility shims so upgrades work when c18n is enabled? |
It seems that preserving the old interfaces implies retaining much of the old implementation as well (including the assembly stubs), but that's fine. |
libexec/rtld-elf/rtld_c18n.c
Outdated
} | ||
|
||
/* | ||
* XXX: These functions are kept here for compatibility with old libunwind. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
libc and libunwind (ditto for the other instance below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And maybe group all the compat interfaces together at the end?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is possible to move all the function definitions to the end, but the declaration of _rtld_unw_setcontext_impl
has to stay in front because of the function-pointer workaround employed in the previous release. _rtld_unw_setcontext_impl
has to be wrapped into _rtld_unw_setcontext_ptr
in c18n_init2
.
b36ee3e
to
7d7f130
Compare
41d8ed3
to
7574483
Compare
Be very careful about git subrepo commits in a PR, the parent commit is recorded so rebasing breaks them for next time someone uses git subrepo. |
I'm in the middle of another FreeBSD merge, but I can do an update of libunwind after that so long as the new libunwind will still work fine with the current |
Yeah, it would be easiest if we decoupled rtld and libunwind changes. Because this PR keeps the old rtld interfaces (and they’ll stay for one release) we don’t need to import libunwind in this PR, we can just merge the new interfaces ready for a future import. |
(But note that updating libunwind in dev now would break) |
I see. I've removed the subrepo pull commit. |
Using relational operators to compare pointers to different trusted frames is undefined behaviour.
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.
See also #2122 for a draft of this PR.
_rtld_unw_getcontext_epilogue is removed because when c18n is not enabled, the trusted stack field of the context is unused anyway, so there's no need to fill it.
The assembly stub in _rtld_unw_setcontext is removed because _rtld_unw_setcontext is now expected to be called before all registers are restored, so it does not need to restore any register anymore.