Fix some regressions with execution

This commit is contained in:
Justine Tunney 2022-08-07 22:10:18 -07:00
parent 5546559034
commit b77cae2d57
28 changed files with 58 additions and 30 deletions

View file

@ -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

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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

View file

@ -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;

View file

@ -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];

View file

@ -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) {

View file

@ -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()

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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");

View file

@ -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);