diff --git a/ape/apeuninstall.sh b/ape/apeuninstall.sh index 986ce4805..e4abe5406 100755 --- a/ape/apeuninstall.sh +++ b/ape/apeuninstall.sh @@ -21,4 +21,4 @@ set -ex if [ -f /proc/sys/fs/binfmt_misc/APE ]; then $SUDO sh -c 'echo -1 >/proc/sys/fs/binfmt_misc/APE' || exit fi -$SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape /tmp/.ape || exit +$SUDO rm -f /usr/bin/ape ~/.ape o/tmp/.ape o/tmp/ape /tmp/.ape /tmp/ape || exit diff --git a/build/bootstrap/apetest.com b/build/bootstrap/apetest.com deleted file mode 100755 index f19ee992d..000000000 Binary files a/build/bootstrap/apetest.com and /dev/null differ diff --git a/build/bootstrap/ar.com b/build/bootstrap/ar.com index 0f1dc30ec..0baefcb08 100755 Binary files a/build/bootstrap/ar.com and b/build/bootstrap/ar.com differ diff --git a/build/bootstrap/cocmd.com b/build/bootstrap/cocmd.com index 98f715ff4..ddbaac8b6 100755 Binary files a/build/bootstrap/cocmd.com and b/build/bootstrap/cocmd.com differ diff --git a/build/bootstrap/compile.com b/build/bootstrap/compile.com index bae9d2683..6d0dcb1b3 100755 Binary files a/build/bootstrap/compile.com and b/build/bootstrap/compile.com differ diff --git a/build/bootstrap/cp.com b/build/bootstrap/cp.com index 421917e28..d9df41618 100755 Binary files a/build/bootstrap/cp.com and b/build/bootstrap/cp.com differ diff --git a/build/bootstrap/echo.com b/build/bootstrap/echo.com index 7e2cb9852..db7ea23aa 100755 Binary files a/build/bootstrap/echo.com and b/build/bootstrap/echo.com differ diff --git a/build/bootstrap/fixupobj.com b/build/bootstrap/fixupobj.com index 6c4851d7d..28bc765a2 100755 Binary files a/build/bootstrap/fixupobj.com and b/build/bootstrap/fixupobj.com differ diff --git a/build/bootstrap/gzip.com b/build/bootstrap/gzip.com index 2e1c78976..cc3a1cfa5 100755 Binary files a/build/bootstrap/gzip.com and b/build/bootstrap/gzip.com differ diff --git a/build/bootstrap/make.com b/build/bootstrap/make.com index f6117dfd5..c8725e772 100755 Binary files a/build/bootstrap/make.com and b/build/bootstrap/make.com differ diff --git a/build/bootstrap/mkdeps.com b/build/bootstrap/mkdeps.com index d5f61fc27..4884076fd 100755 Binary files a/build/bootstrap/mkdeps.com and b/build/bootstrap/mkdeps.com differ diff --git a/build/bootstrap/mkdir.com b/build/bootstrap/mkdir.com index 2307febea..e71d0e503 100755 Binary files a/build/bootstrap/mkdir.com and b/build/bootstrap/mkdir.com differ diff --git a/build/bootstrap/package.com b/build/bootstrap/package.com index 974798411..44043f74a 100755 Binary files a/build/bootstrap/package.com and b/build/bootstrap/package.com differ diff --git a/build/bootstrap/pwd.com b/build/bootstrap/pwd.com index dc562bf51..603df4de9 100755 Binary files a/build/bootstrap/pwd.com and b/build/bootstrap/pwd.com differ diff --git a/build/bootstrap/rm.com b/build/bootstrap/rm.com index a99f8296b..be89f8c0f 100755 Binary files a/build/bootstrap/rm.com and b/build/bootstrap/rm.com differ diff --git a/build/bootstrap/touch.com b/build/bootstrap/touch.com index 3a9630ce5..aaa95f8df 100755 Binary files a/build/bootstrap/touch.com and b/build/bootstrap/touch.com differ diff --git a/build/bootstrap/unbundle.com b/build/bootstrap/unbundle.com index e3ddc7d8f..25cd06475 100755 Binary files a/build/bootstrap/unbundle.com and b/build/bootstrap/unbundle.com differ diff --git a/build/bootstrap/zipobj.com b/build/bootstrap/zipobj.com index c4702c1f8..04bb49920 100755 Binary files a/build/bootstrap/zipobj.com and b/build/bootstrap/zipobj.com differ diff --git a/build/sanitycheck b/build/sanitycheck index 3bd95062f..7808571f4 100755 --- a/build/sanitycheck +++ b/build/sanitycheck @@ -31,8 +31,7 @@ if [ ! -f /proc/sys/fs/binfmt_misc/status ]; then exit 0 fi -STATUS="$(build/bootstrap/apetest.com)" -if [ x"$STATUS" != xsuccess ]; then +if ! build/bootstrap/echo.com -n; then cat <<'EOF' >&2 ERROR diff --git a/libc/calls/execve-sysv.c b/libc/calls/execve-sysv.c index 7852ae1a4..dd4ed9038 100644 --- a/libc/calls/execve-sysv.c +++ b/libc/calls/execve-sysv.c @@ -77,7 +77,9 @@ int sys_execve(const char *prog, char *const argv[], char *const envp[]) { (CanExecute((ape = "/usr/bin/ape")) || CanExecute((ape = Join(firstnonnull(getenv("TMPDIR"), firstnonnull(getenv("HOME"), ".")), - ".ape", buf))))) { + ".ape", buf))) || + CanExecute( + (ape = Join(firstnonnull(getenv("HOME"), "."), ".ape", buf))))) { shargs[0] = ape; shargs[1] = "-"; shargs[2] = prog; diff --git a/libc/calls/g_sighandrvas.c b/libc/calls/g_sighandrvas.c index 51020cbe1..df628bc0e 100644 --- a/libc/calls/g_sighandrvas.c +++ b/libc/calls/g_sighandrvas.c @@ -19,5 +19,7 @@ #include "libc/calls/state.internal.h" #include "libc/intrin/pthread.h" -_Thread_local unsigned __sighandrvas[NSIG]; -_Thread_local unsigned __sighandflags[NSIG]; +// TODO(jart): These should be _Thread_local but doing that currently +// causes a regression with runitd.com on Windows. +unsigned __sighandrvas[NSIG]; +unsigned __sighandflags[NSIG]; diff --git a/libc/calls/ioctl_tcsets.c b/libc/calls/ioctl_tcsets.c index 77fc8b76e..339912b37 100644 --- a/libc/calls/ioctl_tcsets.c +++ b/libc/calls/ioctl_tcsets.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/bits/weaken.h" #include "libc/calls/internal.h" #include "libc/calls/ioctl.h" #include "libc/calls/strace.internal.h" @@ -28,6 +29,7 @@ #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" +void __on_ioctl_tcsets(void); int ioctl_tcsets_nt(int, uint64_t, const struct termios *); static int ioctl_tcsets_metal(int fd, uint64_t request, @@ -65,10 +67,17 @@ static int ioctl_tcsets_sysv(int fd, uint64_t request, int ioctl_tcsets(int fd, uint64_t request, ...) { int rc; va_list va; + static bool once; const struct termios *tio; va_start(va, request); tio = va_arg(va, const struct termios *); va_end(va); + if (weaken(__on_ioctl_tcsets)) { + if (!once) { + weaken(__on_ioctl_tcsets)(); + once = true; + } + } if (!tio || (IsAsan() && !__asan_is_valid(tio, sizeof(*tio)))) { rc = efault(); } else if (fd >= 0) { diff --git a/libc/calls/sig2.c b/libc/calls/sig2.c index 47b009644..f25858a7e 100644 --- a/libc/calls/sig2.c +++ b/libc/calls/sig2.c @@ -99,6 +99,7 @@ static bool __sig_deliver(bool restartable, int sig, int si_code, STRACE("delivering %G", sig); // enter the signal + __sig_lock(); rva = __sighandrvas[sig]; flags = __sighandflags[sig]; if ((~flags & SA_NODEFER) || (flags & SA_RESETHAND)) { @@ -109,6 +110,7 @@ static bool __sig_deliver(bool restartable, int sig, int si_code, // signal handler. in that case you must use SA_NODEFER. __sighandrvas[sig] = (int32_t)(intptr_t)SIG_DFL; } + __sig_unlock(); // setup the somewhat expensive information args // only if they're requested by the user in sigaction() diff --git a/libc/calls/sigaction.c b/libc/calls/sigaction.c index 096652a58..77478f01e 100644 --- a/libc/calls/sigaction.c +++ b/libc/calls/sigaction.c @@ -452,7 +452,9 @@ 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); diff --git a/libc/calls/state.internal.h b/libc/calls/state.internal.h index 955d83b78..0759ad91c 100644 --- a/libc/calls/state.internal.h +++ b/libc/calls/state.internal.h @@ -7,8 +7,8 @@ COSMOPOLITAN_C_START_ hidden extern int __vforked; hidden extern bool __time_critical; -hidden _Thread_local extern unsigned __sighandrvas[NSIG]; -hidden _Thread_local extern unsigned __sighandflags[NSIG]; +hidden extern unsigned __sighandrvas[NSIG]; +hidden extern unsigned __sighandflags[NSIG]; hidden extern const struct NtSecurityAttributes kNtIsInheritable; void __fds_lock(void); diff --git a/libc/intrin/restoretty.c b/libc/intrin/restoretty.c index 26d6668ba..527bc2bb1 100644 --- a/libc/intrin/restoretty.c +++ b/libc/intrin/restoretty.c @@ -16,18 +16,12 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" #include "libc/calls/struct/metatermios.internal.h" -#include "libc/calls/struct/termios.h" #include "libc/calls/syscall-sysv.internal.h" -#include "libc/calls/termios.h" -#include "libc/dce.h" #include "libc/errno.h" -#include "libc/intrin/promises.internal.h" -#include "libc/log/color.internal.h" #include "libc/log/internal.h" #include "libc/log/libfatal.internal.h" -#include "libc/runtime/internal.h" +#include "libc/runtime/runtime.h" #include "libc/sysv/consts/termios.h" /** @@ -45,22 +39,19 @@ static bool __isrestorable; static union metatermios __oldtermios; -static textstartup void __oldtermios_init() { +// called weakly by libc/calls/ioctl_tcsets.c to avoid pledge("tty") +void __on_ioctl_tcsets(void) { int e; e = errno; - if (PLEDGED(TTY) && sys_ioctl(0, TCGETS, &__oldtermios) != -1) { + if (sys_ioctl(0, TCGETS, &__oldtermios) != -1) { __isrestorable = true; } errno = e; } -const void *const __oldtermios_ctor[] initarray = { - __oldtermios_init, -}; - void __restore_tty(void) { int e; - if (__isrestorable && PLEDGED(TTY) && !__isworker && !__nocolor) { + if (__isrestorable && !__isworker && !__nocolor) { e = errno; sys_write(0, ANSI_RESTORE, __strlen(ANSI_RESTORE)); sys_ioctl(0, TCSETSF, &__oldtermios); diff --git a/third_party/make/job.c b/third_party/make/job.c index a435abf6f..40a5a0920 100644 --- a/third_party/make/job.c +++ b/third_party/make/job.c @@ -1714,7 +1714,9 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv) if (argv[0][0] == '/' && IsDynamicExecutable (argv[0])) { - /* weaken sandbox if user is using dynamic shared lolbjects */ + /* + * weaken sandbox if user is using dynamic shared lolbjects + */ Unveil ("/bin", "rx"); Unveil ("/lib", "rx"); Unveil ("/lib64", "rx"); @@ -1733,13 +1735,25 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv) Unveil ("/usr/share/locale-langpack", "r"); } else - /* permit launching actually portable executables */ - if (!Unveil ("/usr/bin/ape", "rx")) - Unveil (xjoinpaths (firstnonnull (getenv ("TMPDIR"), - firstnonnull (getenv ("HOME"), - ".")), - ".ape"), - "rx"); + { + /* + * permit launching actually portable executables + * + * we assume launching make.com already did the expensive + * work of extracting the ape loader program, via /bin/sh + * and we won't need to do that again, since sys_execve() + * will pass ape binaries directly to the ape loader, but + * only if the ape loader exists on a well-known path. + */ + if (!Unveil ("/usr/bin/ape", "rx")) + { + char *s; + if ((s = getenv ("TMPDIR"))) + Unveil (xjoinpaths (s, ".ape"), "rx"); + if ((s = getenv ("HOME"))) + Unveil (xjoinpaths (s, ".ape"), "rx"); + } + } /* unveil executable */ Unveil (argv[0], "rx"); diff --git a/tool/build/pledge.c b/tool/build/pledge.c index 576024f97..e8cdd3f30 100644 --- a/tool/build/pledge.c +++ b/tool/build/pledge.c @@ -22,6 +22,7 @@ #include "libc/calls/landlock.h" #include "libc/calls/struct/rlimit.h" #include "libc/calls/struct/sched_param.h" +#include "libc/calls/struct/seccomp.h" #include "libc/calls/struct/stat.h" #include "libc/calls/struct/sysinfo.h" #include "libc/calls/syscall-sysv.internal.h" @@ -666,6 +667,12 @@ int main(int argc, char *argv[]) { g_promises = xstrcat(g_promises, ' ', "exec"); } + // pledge.com uses the return eperm instead of killing the process + // model. we do this becasue it's only possible to have sigsys print + // crash messages if we're not pledging exec, which is what this tool + // always has to do currently. + __pledge_mode = SECCOMP_RET_ERRNO | EPERM; + // apply sandbox if (pledge(g_promises, g_promises) == -1) { kprintf("error: pledge(%#s) failed: %m\n", g_promises);