Improve pledge() usability and consistency

- We now kill the program on violations like OpenBSD
- We now print a message explaining which promise is needed
- This change also fixes a linkage bug with thread local storage
- Your sigaction() handlers should now be more thread safe

A new `__pledge_mode` global has been introduced to make pledge() more
customizable on Linux. For example:

    __attribute__((__constructor__)) static void init(void) {
      __pledge_mode = SECCOMP_RET_ERRNO | EPERM;
    }

Can be used to restore our old permissive pledge() behavior.
This commit is contained in:
Justine Tunney 2022-08-07 16:18:33 -07:00
parent 13c1c45075
commit 5546559034
30 changed files with 713 additions and 86 deletions

View file

@ -37,7 +37,6 @@
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/describeflags.internal.h"
#include "libc/intrin/spinlock.h"
#include "libc/limits.h"
#include "libc/log/backtrace.internal.h"
#include "libc/log/log.h"
@ -245,7 +244,7 @@ static int __sigaction(int sig, const struct sigaction *act,
}
/**
* Installs handler for kernel interrupt, e.g.:
* Installs handler for kernel interrupt to thread, e.g.:
*
* void GotCtrlC(int sig, siginfo_t *si, ucontext_t *ctx);
* struct sigaction sa = {.sa_sigaction = GotCtrlC,
@ -445,6 +444,7 @@ static int __sigaction(int sig, const struct sigaction *act,
* @return 0 on success or -1 w/ errno
* @see xsigaction() for a much better api
* @asyncsignalsafe
* @threadsafe
* @vforksafe
*/
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) {
@ -452,9 +452,7 @@ int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) {
if (sig == SIGKILL || sig == SIGSTOP) {
rc = einval();
} else {
__sig_lock();
rc = __sigaction(sig, act, oldact);
__sig_unlock();
}
STRACE("sigaction(%G, %s, [%s]) → %d% m", sig, DescribeSigaction(0, act),
DescribeSigaction(rc, oldact), rc);