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: Rework implementation to be interrupt-safe #2090

Merged
merged 3 commits into from
Jun 1, 2024
Merged
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
36 changes: 4 additions & 32 deletions lib/libc/sys/sigaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,43 +37,15 @@
__weak_reference(sigaction, __libc_sigaction);
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
/*
* These weak symbols will always be resolved at runtime.
* This weak symbol will always be resolved at runtime.
*/
/*
* 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 *);

#pragma weak _rtld_sigaction_end
void _rtld_sigaction_end(int, void *, const struct sigaction *,
struct sigaction *);
#pragma weak _rtld_sigaction
int _rtld_sigaction(int, const struct sigaction *, struct sigaction *);

Check failure on line 43 in lib/libc/sys/sigaction.c

View workflow job for this annotation

GitHub Actions / Style Checker

externs should be avoided in .c files

int
sigaction_c18n(int sig, const struct sigaction *act, struct sigaction *oact)
{
int ret;
void *context = 0;
struct sigaction newact;
const struct sigaction *newactp = act;

if (act &&
act->sa_handler != SIG_DFL && act->sa_handler != SIG_IGN) {
newact = *act;
newactp = &newact;

context = _rtld_sigaction_begin(sig, &newact);
newact.sa_sigaction = _rtld_sighandler;
}

ret = __sys_sigaction(sig, newactp, oact);

if (ret == 0)
_rtld_sigaction_end(sig, context, act, oact);

return (ret);
return (_rtld_sigaction(sig, act, oact));
}
#endif

Expand Down
38 changes: 28 additions & 10 deletions lib/libsysdecode/utrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,29 @@ print_utrace_mrs(FILE *fp, void *p)
}
return (1);
}

static int
print_utrace_c18n(FILE *fp, void *p)
{
struct utrace_c18n *ut = p;

switch (ut->event) {
case UTRACE_COMPARTMENT_ENTER:
fprintf(fp, "RTLD: c18n: %s -> %s at [%zu] %s (%02hhx)",
ut->caller, ut->callee, ut->symnum, ut->symbol, ut->fsig);
break;
case UTRACE_COMPARTMENT_LEAVE:
fprintf(fp, "RTLD: c18n: %s <- %s at [%zu] %s (%02hhx)",
ut->caller, ut->callee, ut->symnum, ut->symbol, ut->fsig);
break;
default:
return (0);
}
fprintf(fp, "\nnsp = %#p\nosp = %#p, previous = %#p\n"
"fp = %#p, pc = %#p", ut->sp, ut->osp, ut->previous,
ut->fp, ut->pc);
return (1);
}
#endif

#ifdef __LP64__
Expand Down Expand Up @@ -200,16 +223,6 @@ print_utrace_rtld(FILE *fp, void *p)
case UTRACE_RTLD_ERROR:
fprintf(fp, "RTLD: error: %s\n", ut->name);
break;
case UTRACE_COMPARTMENT_ENTER:
fprintf(fp,
"RTLD: c18n: enter %s from %s at [%zu] %s (%p)",
ut->callee, ut->caller, ut->mapsize, ut->symbol, ut->handle);
break;
case UTRACE_COMPARTMENT_LEAVE:
fprintf(fp,
"RTLD: c18n: leave %s to %s at [%zu] %s",
ut->callee, ut->caller, ut->mapsize, ut->symbol);
break;

default:
return (0);
Expand Down Expand Up @@ -279,10 +292,15 @@ sysdecode_utrace(FILE *fp, void *p, size_t len)
static const char rtld_utrace_sig[RTLD_UTRACE_SIG_SZ] = RTLD_UTRACE_SIG;
#ifdef __CHERI_PURE_CAPABILITY__
static const char mrs_utrace_sig[MRS_UTRACE_SIG_SZ] = MRS_UTRACE_SIG;
static const char c18n_utrace_sig[C18N_UTRACE_SIG_SZ] = C18N_UTRACE_SIG;

if (len == sizeof(struct utrace_mrs) && bcmp(p, mrs_utrace_sig,
sizeof(mrs_utrace_sig)) == 0)
return (print_utrace_mrs(fp, p));

if (len == sizeof(struct utrace_c18n) && bcmp(p, c18n_utrace_sig,
sizeof(c18n_utrace_sig)) == 0)
return (print_utrace_c18n(fp, p));
#endif

if (len == sizeof(struct utrace_rtld) && bcmp(p, rtld_utrace_sig,
Expand Down
48 changes: 22 additions & 26 deletions lib/libthr/thread/thr_sig.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,22 +76,14 @@
/*
* These weak symbols will always be resolved at runtime.
*/
/*
* XXX: Explicit function pointer used so that RTLD can wrap it in trampoline.
*/
extern void (*_rtld_sighandler)(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_sighandler
void _rtld_sighandler(int, siginfo_t *, void *);

Check failure on line 80 in lib/libthr/thread/thr_sig.c

View workflow job for this annotation

GitHub Actions / Style Checker

externs should be avoided in .c files

#pragma weak _rtld_sigaction_begin
void *_rtld_sigaction_begin(int, struct sigaction *);
#pragma weak _rtld_sigaction
int _rtld_sigaction(int, const struct sigaction *, struct sigaction *);

Check failure on line 83 in lib/libthr/thread/thr_sig.c

View workflow job for this annotation

GitHub Actions / Style Checker

externs should be avoided in .c files

#pragma weak _rtld_sigaction_end
void _rtld_sigaction_end(int, void *, const struct sigaction *,
struct sigaction *);
#pragma weak _rtld_siginvoke
void _rtld_siginvoke(int, siginfo_t *, void *, const struct sigaction *);

Check failure on line 86 in lib/libthr/thread/thr_sig.c

View workflow job for this annotation

GitHub Actions / Style Checker

externs should be avoided in .c files
#endif

int _sigtimedwait(const sigset_t *set, siginfo_t *info,
Expand Down Expand Up @@ -305,10 +297,14 @@
if (!cancel_async)
curthread->cancel_enable = 0;

#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
(void)sigfunc;
#else
/* restore correct mask before calling user handler */
__sys_sigprocmask(SIG_SETMASK, &actp->sa_mask, NULL);

sigfunc = actp->sa_sigaction;
#endif

/*
* We have already reset cancellation point flags, so if user's code
Expand All @@ -318,13 +314,17 @@
* so after setjmps() returns once more, the user code may need to
* re-set cancel_enable flag by calling pthread_setcancelstate().
*/
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
_rtld_siginvoke(sig, info, ucp, actp);
#else
if ((actp->sa_flags & SA_SIGINFO) != 0) {
sigfunc(sig, info, ucp);
} else {
((ohandler)sigfunc)(sig, info->si_code,
(struct sigcontext *)ucp, info->si_addr,
(__sighandler_t *)sigfunc);
}
#endif
err = errno;

curthread->in_sigsuspend = in_sigsuspend;
Expand Down Expand Up @@ -501,7 +501,11 @@
for (sig = 1; sig <= _SIG_MAXSIG; sig++) {
if (sig == SIGCANCEL)
continue;
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
error = _rtld_sigaction(sig, NULL, &oact);
#else
error = __sys_sigaction(sig, NULL, &oact);
#endif
if (error == -1 || oact.sa_handler == SIG_DFL ||
oact.sa_handler == SIG_IGN)
continue;
Expand All @@ -512,6 +516,8 @@
nact.sa_flags &= ~SA_NODEFER;
nact.sa_flags |= SA_SIGINFO;
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
/* XXX: Ignore sigaltstack for now */
nact.sa_flags &= ~SA_ONSTACK;
nact.sa_sigaction = _rtld_sighandler;
#else
nact.sa_sigaction = thr_sighandler;
Expand Down Expand Up @@ -615,9 +621,6 @@
sigset_t oldset;
struct usigaction *usa;
int ret, err;
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
void *context = NULL;
#endif

if (!_SIG_VALID(sig) || sig == SIGCANCEL) {
errno = EINVAL;
Expand All @@ -644,15 +647,13 @@
*/
if (newact.sa_handler != SIG_DFL &&
newact.sa_handler != SIG_IGN) {
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
context = _rtld_sigaction_begin(sig, &newact);
newact.sa_sigaction = _rtld_dispatch_signal;
#endif
usa->sigact = newact;
remove_thr_signals(&usa->sigact.sa_mask);
newact.sa_flags &= ~SA_NODEFER;
newact.sa_flags |= SA_SIGINFO;
#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
/* XXX: Ignore sigaltstack for now */
newact.sa_flags &= ~SA_ONSTACK;
newact.sa_sigaction = _rtld_sighandler;
#else
newact.sa_sigaction = thr_sighandler;
Expand All @@ -676,11 +677,6 @@
oldact = usa->sigact;
}

#if defined(__CHERI_PURE_CAPABILITY__) && defined(RTLD_SANDBOX)
if (ret == 0)
_rtld_sigaction_end(sig, context, act, &oldact);
#endif

_thr_rwl_unlock(&usa->lock);
__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);

Expand Down
5 changes: 2 additions & 3 deletions libexec/rtld-elf/Symbol-c18n.map
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ FBSDprivate_1.0 {
_rtld_thread_start_init;
_rtld_thread_start;
_rtld_thr_exit;
_rtld_dispatch_signal;
_rtld_sigaction_begin;
_rtld_sigaction_end;
_rtld_sighandler_init;
_rtld_sighandler;
_rtld_siginvoke;
_rtld_sigaction;
_rtld_setjmp;
_rtld_longjmp;
_rtld_unw_getcontext;
Expand Down
Loading
Loading