Skip to content
Open
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
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,12 @@ test: $(BIN)
$(call run_test, ./nsjail --config tests/basic.cfg -q -t 2 -- /bin/bash -c 'strace -o /dev/null /bin/true && exit 77', 77)
$(call run_test, ./nsjail --config tests/pasta-nat.cfg -q -t 3 -- /bin/bash -c 'sleep 0.2; ping -W 1 -c 1 8.8.8.8 && exit 77', 77)
$(call run_test, ./nsjail --config tests/pasta-port-mappings.cfg -q -t 3 -- /bin/bash -c 'sleep 0.2; { netstat -tan | grep LISTEN; } && exit 77', 77)
rm -f /tmp/nsjail_pasta_env_test /tmp/nsjail_fake_pasta
printf '#!/bin/sh\necho env-path-executed > /tmp/nsjail_pasta_env_test\nexit 0\n' > /tmp/nsjail_fake_pasta
chmod +x /tmp/nsjail_fake_pasta
NSJAIL_PASTA_PATH=/tmp/nsjail_fake_pasta ./nsjail --config tests/pasta-nat.cfg -q -t 1 -- /bin/true >/dev/null 2>&1 || true
test ! -e /tmp/nsjail_pasta_env_test
rm -f /tmp/nsjail_pasta_env_test /tmp/nsjail_fake_pasta

ifeq ($(NL3_EXISTS), yes)
# --- Traffic rules tests ---
Expand Down
42 changes: 32 additions & 10 deletions net.cc
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@
#define F_SEAL_FUTURE_WRITE 0x0010
#endif /* !defined(F_SEAL_FUTURE_WRITE) */

static char* const kPastaEnv[] = {const_cast<char*>("PATH=/usr/sbin:/usr/bin:/sbin:/bin"), nullptr};

static const char* const kPastaPaths[] = {
"/usr/bin/pasta",
"/usr/local/bin/pasta",
"/bin/pasta",
"/sbin/pasta",
nullptr,
};

/* Embed pasta inside this binary */
// clang-format off
__asm__("\n"
Expand Down Expand Up @@ -121,7 +131,24 @@ static int getPastaFd() {
return fd;
}

extern char** environ;
static int openPastaFd() {
int fd = getPastaFd();
if (fd != -1) {
return fd;
}

for (const char* const* path = kPastaPaths; *path != nullptr; path++) {
fd = open(*path, O_PATH | O_CLOEXEC);
if (fd != -1) {
return fd;
}
if (errno != ENOENT && errno != ENOTDIR) {
PLOG_D("open('%s', O_PATH | O_CLOEXEC)", *path);
}
}

return -1;
}

namespace net {

Expand Down Expand Up @@ -353,26 +380,21 @@ static void pastaProcess(nsj_t* nsj, int pid, int err_pipe) {
close(nullfd);
}

int pasta_fd = getPastaFd();
const char* pasta_path = getenv("NSJAIL_PASTA_PATH");
if (pasta_path == NULL) {
pasta_path = argv[0];
}
int pasta_fd = openPastaFd();

util::makeRangeCOE(STDERR_FILENO + 1, ~0U);

/* LOG doesn't use STDERR_FILENO so it's fine to use it */
int err = 0;
if (pasta_fd != -1) {
util::syscall(__NR_execveat, pasta_fd, (uintptr_t)"", (uintptr_t)argv.data(),
(uintptr_t)environ, AT_EMPTY_PATH);
(uintptr_t)kPastaEnv, AT_EMPTY_PATH);
err = errno;
PLOG_W("execveat(pasta_fd=%d, AT_EMPTY_PATH)", pasta_fd);

} else {
execvpe(pasta_path, (char* const*)argv.data(), environ);
err = errno;
PLOG_W("execvpe('%s')", pasta_path);
err = ENOENT;
LOG_W("Cannot find pasta binary in trusted system paths");
}

util::writeToFd(err_pipe, &err, sizeof(err));
Expand Down