aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2020-04-28 20:26:06 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2020-04-28 20:26:06 +0000
commit176b03abf8e6baf728dcbdbba6f43c21b6b40ae1 (patch)
tree78e86640c6d23a6fb5e69a659077d9f5d56d5514
parent346049c5ce31736f66837d3aadc6514b5569793a (diff)
parent68abb5c01306acf16296fc5edfc44bc30145311e (diff)
downloadplatform_external_minijail-android10-mainline-tzdata-release.tar.gz
platform_external_minijail-android10-mainline-tzdata-release.tar.bz2
platform_external_minijail-android10-mainline-tzdata-release.zip
Snap for 6439596 from 68abb5c01306acf16296fc5edfc44bc30145311e to qt-aml-tzdata-releaseandroid-mainline-10.0.0_r11android10-mainline-tzdata-release
Change-Id: I6562d49398a4e1a8a5423ab3fde42505c602f40f
-rw-r--r--Makefile6
-rw-r--r--bpf.h4
-rw-r--r--examples/cat.policy2
-rw-r--r--gen_constants-inl.h4
-rw-r--r--libminijail.c241
-rw-r--r--libminijail.h38
-rw-r--r--libminijail_unittest.cc262
-rw-r--r--minijail0.119
-rw-r--r--minijail0_cli.c53
-rw-r--r--minijail0_cli_unittest.cc4
-rw-r--r--parse_seccomp_policy.cc8
-rw-r--r--syscall_filter.c95
-rw-r--r--syscall_filter.h19
-rw-r--r--syscall_filter_unittest.cc198
-rw-r--r--syscall_filter_unittest_macros.h14
-rw-r--r--system.c67
-rw-r--r--system.h5
-rw-r--r--system_unittest.cc15
-rw-r--r--util.h33
19 files changed, 192 insertions, 895 deletions
diff --git a/Makefile b/Makefile
index 4bfa8203..b2c5569e 100644
--- a/Makefile
+++ b/Makefile
@@ -46,10 +46,8 @@ ifeq ($(USE_SYSTEM_GTEST),no)
GTEST_CXXFLAGS := -std=gnu++14
GTEST_LIBS := gtest.a
else
-GTEST_CXXFLAGS := $(shell gtest-config --cxxflags 2>/dev/null || \
- echo "-pthread")
-GTEST_LIBS := $(shell gtest-config --libs 2>/dev/null || \
- echo "-lgtest -pthread -lpthread")
+GTEST_CXXFLAGS := $(shell gtest-config --cxxflags)
+GTEST_LIBS := $(shell gtest-config --libs)
endif
CORE_OBJECT_FILES := libminijail.o syscall_filter.o signal_handler.o \
diff --git a/bpf.h b/bpf.h
index 9404c949..db66223b 100644
--- a/bpf.h
+++ b/bpf.h
@@ -48,7 +48,6 @@ enum {
#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */
#define SECCOMP_RET_TRAP 0x00030000U /* return SIGSYS */
#define SECCOMP_RET_ERRNO 0x00050000U /* return -1 and set errno */
-#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
#define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */
#define SECCOMP_RET_DATA 0x0000ffffU /* mask for return value */
@@ -173,9 +172,6 @@ static inline size_t set_bpf_instr(struct sock_filter *instr,
set_bpf_stmt((_block), BPF_RET+BPF_K, \
SECCOMP_RET_ERRNO | ((_errno) & SECCOMP_RET_DATA))
-#define set_bpf_ret_log(_block) \
- set_bpf_stmt((_block), BPF_RET+BPF_K, SECCOMP_RET_LOG)
-
#define set_bpf_ret_allow(_block) \
set_bpf_stmt((_block), BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
diff --git a/examples/cat.policy b/examples/cat.policy
index 25b4c29b..dea3dd37 100644
--- a/examples/cat.policy
+++ b/examples/cat.policy
@@ -5,12 +5,10 @@
read: 1
write: 1
-restart_syscall: 1
rt_sigreturn: 1
exit_group: 1
open: 1
-openat: 1
close: 1
fstat: 1
# Enforce W^X.
diff --git a/gen_constants-inl.h b/gen_constants-inl.h
index d2c1ec08..0ea710d3 100644
--- a/gen_constants-inl.h
+++ b/gen_constants-inl.h
@@ -3,9 +3,7 @@
#endif // __i386__ || __x86_64__
#include <errno.h>
#include <fcntl.h>
-#include <linux/fd.h>
#include <linux/fs.h>
-#include <linux/loop.h>
#include <linux/mman.h>
#include <linux/net.h>
#include <linux/prctl.h>
@@ -13,8 +11,8 @@
#include <linux/serial.h>
#include <linux/sockios.h>
#include <linux/termios.h>
-#include <signal.h>
#include <stddef.h>
+#include <signal.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sys/socket.h>
diff --git a/libminijail.c b/libminijail.c
index 6d6b2dc4..482d6bd9 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -163,7 +163,6 @@ struct minijail {
int close_open_fds : 1;
int new_session_keyring : 1;
int forward_signals : 1;
- int setsid : 1;
} flags;
uid_t uid;
gid_t gid;
@@ -238,7 +237,6 @@ void minijail_preenter(struct minijail *j)
j->flags.pid_file = 0;
j->flags.cgroups = 0;
j->flags.forward_signals = 0;
- j->flags.setsid = 0;
j->remount_mode = 0;
}
@@ -382,17 +380,6 @@ void API minijail_set_seccomp_filter_tsync(struct minijail *j)
die("minijail_set_seccomp_filter_tsync() must be called "
"before minijail_parse_seccomp_filters()");
}
-
- if (j->flags.seccomp_filter_logging && !seccomp_ret_log_available()) {
- /*
- * If SECCOMP_RET_LOG is not available, we don't want to use
- * SECCOMP_RET_TRAP to both kill the entire process and report
- * failing syscalls, since it will be brittle. Just bail.
- */
- die("SECCOMP_RET_LOG not available, cannot use logging with "
- "thread sync at the same time");
- }
-
j->flags.seccomp_filter_tsync = 1;
}
@@ -402,23 +389,11 @@ void API minijail_log_seccomp_filter_failures(struct minijail *j)
die("minijail_log_seccomp_filter_failures() must be called "
"before minijail_parse_seccomp_filters()");
}
-
- if (j->flags.seccomp_filter_tsync && !seccomp_ret_log_available()) {
- /*
- * If SECCOMP_RET_LOG is not available, we don't want to use
- * SECCOMP_RET_TRAP to both kill the entire process and report
- * failing syscalls, since it will be brittle. Just bail.
- */
- die("SECCOMP_RET_LOG not available, cannot use thread sync with "
- "logging at the same time");
- }
-
- if (debug_logging_allowed()) {
- j->flags.seccomp_filter_logging = 1;
- } else {
- warn("non-debug build: ignoring request to enable seccomp "
- "logging");
- }
+#ifdef ALLOW_DEBUG_LOGGING
+ j->flags.seccomp_filter_logging = 1;
+#else
+ warn("non-debug build: ignoring request to enable seccomp logging");
+#endif
}
void API minijail_use_caps(struct minijail *j, uint64_t capmask)
@@ -758,11 +733,6 @@ int API minijail_forward_signals(struct minijail *j)
return 0;
}
-int API minijail_create_session(struct minijail *j) {
- j->flags.setsid = 1;
- return 0;
-}
-
int API minijail_mount_with_data(struct minijail *j, const char *src,
const char *dest, const char *type,
unsigned long flags, const char *data)
@@ -955,17 +925,12 @@ static int seccomp_should_use_filters(struct minijail *j)
}
static int set_seccomp_filters_internal(struct minijail *j,
- const struct sock_fprog *filter,
- bool owned)
+ struct sock_fprog *filter, bool owned)
{
struct sock_fprog *fprog;
if (owned) {
- /*
- * If |owned| is true, it's OK to cast away the const-ness since
- * we'll own the pointer going forward.
- */
- fprog = (struct sock_fprog *)filter;
+ fprog = filter;
} else {
fprog = malloc(sizeof(struct sock_fprog));
if (!fprog)
@@ -990,48 +955,45 @@ static int set_seccomp_filters_internal(struct minijail *j,
return 0;
}
-static int parse_seccomp_filters(struct minijail *j, const char *filename,
- FILE *policy_file)
+void API minijail_set_seccomp_filters(struct minijail *j,
+ const struct sock_fprog *filter)
{
- struct sock_fprog *fprog = malloc(sizeof(struct sock_fprog));
- if (!fprog)
- return -ENOMEM;
+ if (!seccomp_should_use_filters(j))
+ return;
- struct filter_options filteropts;
+ if (j->flags.seccomp_filter_logging) {
+ die("minijail_log_seccomp_filter_failures() is incompatible "
+ "with minijail_set_seccomp_filters()");
+ }
/*
- * Figure out filter options.
- * Allow logging?
+ * set_seccomp_filters_internal() can only fail with ENOMEM.
+ * Furthermore, since we won't own the incoming filter, it will not be
+ * modified.
*/
- filteropts.allow_logging =
- debug_logging_allowed() && j->flags.seccomp_filter_logging;
-
- /* What to do on a blocked system call? */
- if (filteropts.allow_logging) {
- if (seccomp_ret_log_available())
- filteropts.action = ACTION_RET_LOG;
- else
- filteropts.action = ACTION_RET_TRAP;
- } else {
- if (j->flags.seccomp_filter_tsync)
- filteropts.action = ACTION_RET_TRAP;
- else
- filteropts.action = ACTION_RET_KILL;
+ if (set_seccomp_filters_internal(j, (struct sock_fprog *)filter,
+ false) < 0) {
+ die("failed to copy seccomp filter");
}
+}
- /*
- * If SECCOMP_RET_LOG is not available, need to allow extra syscalls
- * for logging.
- */
- filteropts.allow_syscalls_for_logging =
- filteropts.allow_logging && !seccomp_ret_log_available();
+static int parse_seccomp_filters(struct minijail *j, const char *filename,
+ FILE *policy_file)
+{
+ struct sock_fprog *fprog = malloc(sizeof(struct sock_fprog));
+ if (!fprog)
+ return -ENOMEM;
+ int use_ret_trap =
+ j->flags.seccomp_filter_tsync || j->flags.seccomp_filter_logging;
+ int allow_logging = j->flags.seccomp_filter_logging;
- if (compile_filter(filename, policy_file, fprog, &filteropts)) {
+ if (compile_filter(filename, policy_file, fprog, use_ret_trap,
+ allow_logging)) {
free(fprog);
return -1;
}
- return set_seccomp_filters_internal(j, fprog, true /* owned */);
+ return set_seccomp_filters_internal(j, fprog, true);
}
void API minijail_parse_seccomp_filters(struct minijail *j, const char *path)
@@ -1079,27 +1041,6 @@ void API minijail_parse_seccomp_filters_from_fd(struct minijail *j, int fd)
fclose(file);
}
-void API minijail_set_seccomp_filters(struct minijail *j,
- const struct sock_fprog *filter)
-{
- if (!seccomp_should_use_filters(j))
- return;
-
- if (j->flags.seccomp_filter_logging) {
- die("minijail_log_seccomp_filter_failures() is incompatible "
- "with minijail_set_seccomp_filters()");
- }
-
- /*
- * set_seccomp_filters_internal() can only fail with ENOMEM.
- * Furthermore, since we won't own the incoming filter, it will not be
- * modified.
- */
- if (set_seccomp_filters_internal(j, filter, false /* owned */) < 0) {
- die("failed to set seccomp filter");
- }
-}
-
int API minijail_use_alt_syscall(struct minijail *j, const char *table)
{
j->alt_syscall_table = strdup(table);
@@ -1542,9 +1483,7 @@ static int mount_one(const struct minijail *j, struct mountpoint *m,
/* We assume |dest| has a leading "/". */
if (dev_path && strncmp("/dev/", m->dest, 5) == 0) {
- /*
- * Since the temp path is rooted at /dev, skip that dest part.
- */
+ /* Since the temp path is rooted at /dev, skip that dest part. */
if (asprintf(&dest, "%s%s", dev_path, m->dest + 4) < 0)
return -ENOMEM;
} else {
@@ -1794,17 +1733,14 @@ static void write_ugid_maps_or_die(const struct minijail *j)
if (j->uidmap && write_proc_file(j->initpid, j->uidmap, "uid_map") != 0)
kill_child_and_die(j, "failed to write uid_map");
if (j->gidmap && j->flags.disable_setgroups) {
- /*
- * Older kernels might not have the /proc/<pid>/setgroups files.
- */
+ /* Older kernels might not have the /proc/<pid>/setgroups files. */
int ret = write_proc_file(j->initpid, "deny", "setgroups");
if (ret != 0) {
if (ret == -ENOENT) {
/* See http://man7.org/linux/man-pages/man7/user_namespaces.7.html. */
warn("could not disable setgroups(2)");
} else
- kill_child_and_die(
- j, "failed to disable setgroups(2)");
+ kill_child_and_die(j, "failed to disable setgroups(2)");
}
}
if (j->gidmap && write_proc_file(j->initpid, j->gidmap, "gid_map") != 0)
@@ -2016,16 +1952,13 @@ static void set_seccomp_filter(const struct minijail *j)
if (j->flags.seccomp_filter) {
if (j->flags.seccomp_filter_logging) {
+ /*
+ * If logging seccomp filter failures,
+ * install the SIGSYS handler first.
+ */
+ if (install_sigsys_handler())
+ pdie("failed to install SIGSYS handler");
warn("logging seccomp filter failures");
- if (!seccomp_ret_log_available()) {
- /*
- * If SECCOMP_RET_LOG is not available,
- * install the SIGSYS handler first.
- */
- if (install_sigsys_handler())
- pdie(
- "failed to install SIGSYS handler");
- }
} else if (j->flags.seccomp_filter_tsync) {
/*
* If setting thread sync,
@@ -2164,15 +2097,12 @@ void API minijail_enter(const struct minijail *j)
pdie("unshare(CLONE_NEWNS) failed");
/*
* By default, remount all filesystems as private, unless
- * - Passed a specific remount mode, in which case remount with
- * that,
- * - Asked not to remount at all, in which case skip the
- * mount(2) call.
+ * - Passed a specific remount mode, in which case remount with that,
+ * - Asked not to remount at all, in which case skip the mount(2) call.
* https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
*/
if (j->remount_mode) {
- if (mount(NULL, "/", NULL, MS_REC | j->remount_mode,
- NULL))
+ if (mount(NULL, "/", NULL, MS_REC | j->remount_mode, NULL))
pdie("mount(NULL, /, NULL, MS_REC | MS_PRIVATE,"
" NULL) failed");
}
@@ -2743,12 +2673,11 @@ static int minijail_run_internal(struct minijail *j,
}
/*
- * If the parent process needs to configure the child's runtime
- * environment after forking, create a pipe(2) to block the child until
- * configuration is done.
+ * If we want to set up a new uid/gid map in the user namespace,
+ * or if we need to add the child process to cgroups, create the pipe(2)
+ * to sync between parent and child.
*/
- if (j->flags.forward_signals || j->flags.pid_file || j->flags.cgroups ||
- j->rlimit_count || j->flags.userns) {
+ if (j->flags.userns || j->flags.cgroups) {
sync_child = 1;
if (pipe(child_sync_pipe_fds))
return -EFAULT;
@@ -2808,11 +2737,7 @@ static int minijail_run_internal(struct minijail *j,
if (use_preload) {
free(oldenv_copy);
}
- if (pid_namespace && errno == EPERM) {
- warn("clone(CLONE_NEWPID) failed with EPERM, maybe "
- "this process is not running with CAP_SYS_ADMIN?");
- }
- pdie("failed to fork child");
+ die("failed to fork child");
}
if (child_pid) {
@@ -2952,17 +2877,6 @@ static int minijail_run_internal(struct minijail *j,
inheritable_fds[size++] = stderr_fds[0];
inheritable_fds[size++] = stderr_fds[1];
}
-
- /*
- * Preserve namespace file descriptors over the close_open_fds()
- * call. These are closed in minijail_enter() so they won't leak
- * into the child process.
- */
- if (j->flags.enter_vfs)
- minijail_preserve_fd(j, j->mountns_fd, j->mountns_fd);
- if (j->flags.enter_net)
- minijail_preserve_fd(j, j->netns_fd, j->netns_fd);
-
for (i = 0; i < j->preserved_fd_count; i++) {
/*
* Preserve all parent_fds. They will be dup2(2)-ed in
@@ -2989,8 +2903,8 @@ static int minijail_run_internal(struct minijail *j,
* set up the read end of the pipe.
*/
if (status_out->pstdin_fd) {
- if (dupe_and_close_fd(stdin_fds, 0 /* read end */,
- STDIN_FILENO) < 0)
+ if (setup_and_dupe_pipe_end(stdin_fds, 0 /* read end */,
+ STDIN_FILENO) < 0)
die("failed to set up stdin pipe");
}
@@ -2999,8 +2913,8 @@ static int minijail_run_internal(struct minijail *j,
* set up the write end of the pipe.
*/
if (status_out->pstdout_fd) {
- if (dupe_and_close_fd(stdout_fds, 1 /* write end */,
- STDOUT_FILENO) < 0)
+ if (setup_and_dupe_pipe_end(stdout_fds, 1 /* write end */,
+ STDOUT_FILENO) < 0)
die("failed to set up stdout pipe");
}
@@ -3009,21 +2923,21 @@ static int minijail_run_internal(struct minijail *j,
* set up the write end of the pipe.
*/
if (status_out->pstderr_fd) {
- if (dupe_and_close_fd(stderr_fds, 1 /* write end */,
- STDERR_FILENO) < 0)
+ if (setup_and_dupe_pipe_end(stderr_fds, 1 /* write end */,
+ STDERR_FILENO) < 0)
die("failed to set up stderr pipe");
}
/*
- * If any of stdin, stdout, or stderr are TTYs, or setsid flag is
- * set, create a new session. This prevents the jailed process from
- * using the TIOCSTI ioctl to push characters into the parent process
- * terminal's input buffer, therefore escaping the jail.
+ * If any of stdin, stdout, or stderr are TTYs, create a new session.
+ * This prevents the jailed process from using the TIOCSTI ioctl
+ * to push characters into the parent process terminal's input buffer,
+ * therefore escaping the jail.
*
* Since it has just forked, the child will not be a process group
* leader, and this call to setsid() should always succeed.
*/
- if (j->flags.setsid || isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) ||
+ if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) ||
isatty(STDERR_FILENO)) {
if (setsid() < 0) {
pdie("setsid() failed");
@@ -3102,37 +3016,28 @@ static int minijail_run_internal(struct minijail *j,
* -> init()-ing process
* -> execve()-ing process
*/
- execve(config->filename, config->argv, child_env);
-
- ret = (errno == ENOENT ? MINIJAIL_ERR_NO_COMMAND : MINIJAIL_ERR_NO_ACCESS);
- pwarn("execve(%s) failed", config->filename);
+ ret = execve(config->filename, config->argv, child_env);
+ if (ret == -1) {
+ pwarn("execve(%s) failed", config->filename);
+ }
_exit(ret);
}
int API minijail_kill(struct minijail *j)
{
- if (j->initpid <= 0)
- return -ECHILD;
-
+ int st;
if (kill(j->initpid, SIGTERM))
return -errno;
-
- return minijail_wait(j);
+ if (waitpid(j->initpid, &st, 0) < 0)
+ return -errno;
+ return st;
}
int API minijail_wait(struct minijail *j)
{
- if (j->initpid <= 0)
- return -ECHILD;
-
int st;
- while (true) {
- const int ret = waitpid(j->initpid, &st, 0);
- if (ret >= 0)
- break;
- if (errno != EINTR)
- return -errno;
- }
+ if (waitpid(j->initpid, &st, 0) < 0)
+ return -errno;
if (!WIFEXITED(st)) {
int error_status = st;
@@ -3150,7 +3055,7 @@ int API minijail_wait(struct minijail *j)
if (signum == SIGSYS) {
error_status = MINIJAIL_ERR_JAIL;
} else {
- error_status = MINIJAIL_ERR_SIG_BASE + signum;
+ error_status = 128 + signum;
}
}
return error_status;
diff --git a/libminijail.h b/libminijail.h
index 3da845c3..0853c179 100644
--- a/libminijail.h
+++ b/libminijail.h
@@ -23,22 +23,9 @@
extern "C" {
#endif
-/* Possible exit status codes returned by minijail_wait(). */
enum {
- /* Command can be found but cannot be run */
- MINIJAIL_ERR_NO_ACCESS = 126,
-
- /* Command cannot be found */
- MINIJAIL_ERR_NO_COMMAND = 127,
-
- /* (MINIJAIL_ERR_SIG_BASE + n) if process killed by signal n != SIGSYS */
- MINIJAIL_ERR_SIG_BASE = 128,
-
MINIJAIL_ERR_PRELOAD = 252,
-
- /* Process killed by SIGSYS */
MINIJAIL_ERR_JAIL = 253,
-
MINIJAIL_ERR_INIT = 254,
};
@@ -173,9 +160,6 @@ int minijail_add_to_cgroup(struct minijail *j, const char *path);
*/
int minijail_forward_signals(struct minijail *j);
-/* The jailed child process should call setsid() to create a new session. */
-int minijail_create_session(struct minijail *j);
-
/*
* minijail_enter_chroot: enables chroot() restriction for @j
* @j minijail to apply restriction to
@@ -404,28 +388,14 @@ int minijail_run_env_pid_pipes_no_preload(struct minijail *j,
pid_t minijail_fork(struct minijail *j);
/*
- * Send SIGTERM to the process in the minijail and wait for it to terminate.
- *
- * Return the same nonnegative exit status as minijail_wait(), or a negative
- * error code (eg -ESRCH if the process has already been waited for).
- *
- * This is most useful if the minijail has been created with PID namespacing
- * since, in this case, all processes inside it are atomically killed.
+ * Kill the specified minijail. The minijail must have been created with pid
+ * namespacing; if it was, all processes inside it are atomically killed.
*/
int minijail_kill(struct minijail *j);
/*
- * Wait for the first process spawned in the specified minijail to exit, and
- * return its exit status. A process can only be waited once.
- *
- * Return:
- * A negative error code if the process cannot be waited for (eg -ECHILD if no
- * process has been started or if the process has already been waited for).
- * MINIJAIL_ERR_NO_COMMAND if command cannot be found.
- * MINIJAIL_ERR_NO_ACCESS if command cannot be run.
- * MINIJAIL_ERR_JAIL if process was killed by SIGSYS.
- * (MINIJAIL_ERR_SIG_BASE + n) if process was killed by signal n != SIGSYS.
- * (n & 0xFF) if process finished by returning code n.
+ * Wait for all processes in the specified minijail to exit. Returns the exit
+ * status of the _first_ process spawned in the jail.
*/
int minijail_wait(struct minijail *j);
diff --git a/libminijail_unittest.cc b/libminijail_unittest.cc
index d8ffc381..25aa76e5 100644
--- a/libminijail_unittest.cc
+++ b/libminijail_unittest.cc
@@ -217,189 +217,19 @@ TEST_F(MarshalTest, 0xff) {
EXPECT_EQ(-EINVAL, minijail_unmarshal(j_, buf_, sizeof(buf_)));
}
-TEST(KillTest, running_process) {
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"sh", "-c", "sleep 1000", nullptr};
- EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0);
- EXPECT_EQ(minijail_kill(j.get()), 128 + SIGTERM);
- EXPECT_EQ(minijail_kill(j.get()), -ESRCH);
-}
-
-TEST(KillTest, process_already_awaited) {
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"sh", "-c", "sleep 1; exit 42", nullptr};
- EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0);
- EXPECT_EQ(minijail_wait(j.get()), 42);
- EXPECT_EQ(minijail_kill(j.get()), -ESRCH);
-}
-
-TEST(KillTest, process_already_finished_but_not_awaited) {
- int fds[2];
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"sh", "-c", "exit 42", nullptr};
- ASSERT_EQ(pipe(fds), 0);
- EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0);
- ASSERT_EQ(close(fds[1]), 0);
- // Wait for process to finish.
- char buf[PIPE_BUF];
- EXPECT_EQ(read(fds[0], buf, PIPE_BUF), 0);
- EXPECT_EQ(minijail_kill(j.get()), 42);
- EXPECT_EQ(minijail_wait(j.get()), -ECHILD);
-}
-
-TEST(KillTest, process_not_started) {
- const ScopedMinijail j(minijail_new());
- EXPECT_EQ(minijail_kill(j.get()), -ECHILD);
-}
-
-TEST(WaitTest, return_zero) {
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"sh", "-c", "exit 0", nullptr};
- EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0);
- EXPECT_EQ(minijail_wait(j.get()), 0);
-}
-
-TEST(WaitTest, return_max) {
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"sh", "-c", "exit 255", nullptr};
- EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0);
- EXPECT_EQ(minijail_wait(j.get()), 255);
-}
-
-TEST(WaitTest, return_modulo) {
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"sh", "-c", "exit 256", nullptr};
- EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0);
- EXPECT_EQ(minijail_wait(j.get()), 0);
-}
-
-TEST(WaitTest, killed_by_sigkill) {
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"sh", "-c", "kill -KILL $$; sleep 1000", nullptr};
- EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0);
- EXPECT_EQ(minijail_wait(j.get()), MINIJAIL_ERR_SIG_BASE + SIGKILL);
-}
-
-TEST(WaitTest, killed_by_sigsys) {
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"sh", "-c", "kill -SYS $$; sleep 1000", nullptr};
- EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0);
- EXPECT_EQ(minijail_wait(j.get()), MINIJAIL_ERR_JAIL);
-}
-
-TEST(WaitTest, command_not_found) {
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"whatever", nullptr};
- EXPECT_EQ(minijail_run(j.get(), "command that cannot be found", argv), 0);
- EXPECT_EQ(minijail_wait(j.get()), MINIJAIL_ERR_NO_COMMAND);
-}
-
-TEST(WaitTest, command_not_run) {
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"whatever", nullptr};
- EXPECT_EQ(minijail_run(j.get(), "/dev/null", argv), 0);
- EXPECT_EQ(minijail_wait(j.get()), MINIJAIL_ERR_NO_ACCESS);
-}
-
-TEST(WaitTest, no_process) {
- const ScopedMinijail j(minijail_new());
- EXPECT_EQ(minijail_wait(j.get()), -ECHILD);
-}
-
-TEST(WaitTest, can_wait_only_once) {
- const ScopedMinijail j(minijail_new());
- char* const argv[] = {"sh", "-c", "exit 0", nullptr};
- EXPECT_EQ(minijail_run(j.get(), kShellPath, argv), 0);
- EXPECT_EQ(minijail_wait(j.get()), 0);
- EXPECT_EQ(minijail_wait(j.get()), -ECHILD);
-}
-
-TEST(Test, close_original_pipes_after_dup2) {
- // Pipe used by child process to signal that it continued after reading from
- // stdin.
- int to_wait[2];
- ASSERT_EQ(pipe(to_wait), 0);
-
- const ScopedMinijail j(minijail_new());
- char* program;
- ASSERT_GT(asprintf(&program, R"(
- echo Hi >&1;
- echo There >&2;
- exec 1>&-;
- exec 2>&-;
- read line1;
- read line2;
- echo "$line1$line2 and Goodbye" >&%d;
- exit 42;
- )", to_wait[1]), 0);
- char* const argv[] = {"sh", "-c", program, nullptr};
-
- int in = -1;
- int out = -1;
- int err = -1;
- EXPECT_EQ(minijail_run_pid_pipes_no_preload(j.get(), kShellPath, argv,
- nullptr, &in, &out, &err),
- 0);
- free(program);
-
- EXPECT_GT(in, 0);
- EXPECT_GT(out, 0);
- EXPECT_GT(err, 0);
-
- char buf[PIPE_BUF];
- ssize_t n;
-
- // Check that stdout and stderr pipes work.
- n = read(out, buf, PIPE_BUF);
- ASSERT_GT(n, 0);
- EXPECT_EQ(std::string(buf, n), "Hi\n");
-
- n = read(err, buf, PIPE_BUF);
- ASSERT_GT(n, 0);
- EXPECT_EQ(std::string(buf, n), "There\n");
-
- // Check that the write ends of stdout and stderr pipes got closed by the
- // child process. If the child process kept other file descriptors connected
- // to stdout and stderr, then the parent process wouldn't be able to detect
- // that all write ends of these pipes are closed and it would block here.
- EXPECT_EQ(read(out, buf, PIPE_BUF), 0);
- EXPECT_EQ(read(err, buf, PIPE_BUF), 0);
-
- // Check that stdin pipe works.
- const std::string s = "Greetings\n";
- EXPECT_EQ(write(in, s.data(), s.size()), s.size());
-
- // Close write end of pipe connected to child's stdin. If there was another
- // file descriptor connected to this write end, then the child wouldn't be
- // able to detect that this write end is closed and it would block.
- ASSERT_EQ(close(in), 0);
-
- // Check that child process continued and ended.
- n = read(to_wait[0], buf, PIPE_BUF);
- ASSERT_GT(n, 0);
- EXPECT_EQ(std::string(buf, n), "Greetings and Goodbye\n");
- EXPECT_EQ(minijail_wait(j.get()), 42);
-}
-
TEST(Test, minijail_run_pid_pipes) {
- // TODO(crbug.com/895875): The preload library interferes with ASan since they
- // both need to use LD_PRELOAD.
- if (running_with_asan()) {
- SUCCEED();
- return;
- }
constexpr char teststr[] = "test\n";
- ScopedMinijail j(minijail_new());
- minijail_set_preload_path(j.get(), kPreloadPath);
+ struct minijail* j = minijail_new();
+ minijail_set_preload_path(j, kPreloadPath);
char* argv[4];
argv[0] = const_cast<char*>(kCatPath);
argv[1] = nullptr;
pid_t pid;
int child_stdin, child_stdout;
- int mj_run_ret = minijail_run_pid_pipes(j.get(), argv[0], argv, &pid,
- &child_stdin, &child_stdout, nullptr);
+ int mj_run_ret = minijail_run_pid_pipes(j, argv[0], argv, &pid, &child_stdin,
+ &child_stdout, nullptr);
EXPECT_EQ(mj_run_ret, 0);
const size_t teststr_len = strlen(teststr);
@@ -423,9 +253,8 @@ TEST(Test, minijail_run_pid_pipes) {
argv[2] = "echo test >&2";
argv[3] = nullptr;
int child_stderr;
- mj_run_ret = minijail_run_pid_pipes(j.get(), argv[0], argv, &pid,
- &child_stdin, &child_stdout,
- &child_stderr);
+ mj_run_ret = minijail_run_pid_pipes(j, argv[0], argv, &pid, &child_stdin,
+ &child_stdout, &child_stderr);
EXPECT_EQ(mj_run_ret, 0);
read_ret = read(child_stderr, buf, sizeof(buf));
@@ -434,6 +263,8 @@ TEST(Test, minijail_run_pid_pipes) {
waitpid(pid, &status, 0);
ASSERT_TRUE(WIFEXITED(status));
EXPECT_EQ(WEXITSTATUS(status), 0);
+
+ minijail_destroy(j);
}
TEST(Test, minijail_run_pid_pipes_no_preload) {
@@ -449,7 +280,7 @@ TEST(Test, minijail_run_pid_pipes_no_preload) {
struct minijail *j = minijail_new();
- argv[0] = const_cast<char*>(kCatPath);
+ argv[0] = (char*)kCatPath;
argv[1] = NULL;
mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv,
&pid,
@@ -470,7 +301,7 @@ TEST(Test, minijail_run_pid_pipes_no_preload) {
ASSERT_TRUE(WIFSIGNALED(status));
EXPECT_EQ(WTERMSIG(status), SIGTERM);
- argv[0] = const_cast<char*>(kShellPath);
+ argv[0] = (char*)kShellPath;
argv[1] = "-c";
argv[2] = "echo test >&2";
argv[3] = NULL;
@@ -503,7 +334,7 @@ TEST(Test, minijail_run_env_pid_pipes_no_preload) {
struct minijail *j = minijail_new();
- argv[0] = const_cast<char*>(kShellPath);
+ argv[0] = (char*)kShellPath;
argv[1] = "-c";
argv[2] = "echo \"${TEST_PARENT+set}|${TEST_VAR}\"";
argv[3] = NULL;
@@ -519,9 +350,9 @@ TEST(Test, minijail_run_env_pid_pipes_no_preload) {
EXPECT_EQ(mj_run_ret, 0);
read_ret = read(child_stdout, buf, sizeof(buf));
- EXPECT_EQ(read_ret, (int)testvar_len + 2);
+ EXPECT_GE(read_ret, (int)testvar_len);
- EXPECT_EQ("|test\n", std::string(buf, 0, testvar_len + 2));
+ EXPECT_EQ("|test\n", std::string(buf));
EXPECT_EQ(waitpid(pid, &status, 0), pid);
ASSERT_TRUE(WIFEXITED(status));
@@ -549,7 +380,7 @@ TEST(Test, test_minijail_no_fd_leaks) {
struct minijail *j = minijail_new();
- argv[0] = const_cast<char*>(kShellPath);
+ argv[0] = (char*)kShellPath;
argv[1] = "-c";
argv[2] = script;
argv[3] = NULL;
@@ -591,17 +422,18 @@ TEST(Test, test_minijail_fork) {
int pipe_fds[2];
ssize_t pid_size = sizeof(mj_fork_ret);
- ScopedMinijail j(minijail_new());
+ struct minijail *j = minijail_new();
ASSERT_EQ(pipe(pipe_fds), 0);
- mj_fork_ret = minijail_fork(j.get());
+ mj_fork_ret = minijail_fork(j);
ASSERT_GE(mj_fork_ret, 0);
if (mj_fork_ret == 0) {
pid_t pid_in_parent;
// Wait for the parent to tell us the pid in the parent namespace.
ASSERT_EQ(read(pipe_fds[0], &pid_in_parent, pid_size), pid_size);
ASSERT_EQ(pid_in_parent, getpid());
+ minijail_destroy(j);
exit(0);
}
@@ -609,6 +441,8 @@ TEST(Test, test_minijail_fork) {
waitpid(mj_fork_ret, &status, 0);
ASSERT_TRUE(WIFEXITED(status));
EXPECT_EQ(WEXITSTATUS(status), 0);
+
+ minijail_destroy(j);
}
static int early_exit(void* payload) {
@@ -629,7 +463,7 @@ TEST(Test, test_minijail_callback) {
MINIJAIL_HOOK_EVENT_PRE_DROP_CAPS);
EXPECT_EQ(status, 0);
- argv[0] = const_cast<char*>(kCatPath);
+ argv[0] = (char*)kCatPath;
argv[1] = NULL;
mj_run_ret = minijail_run_pid_pipes_no_preload(j, argv[0], argv, &pid, NULL,
NULL, NULL);
@@ -664,7 +498,7 @@ TEST(Test, test_minijail_preserve_fd) {
ASSERT_EQ(status, 0);
minijail_close_open_fds(j);
- argv[0] = const_cast<char*>(kCatPath);
+ argv[0] = (char*)kCatPath;
argv[1] = NULL;
mj_run_ret = minijail_run_no_preload(j, argv[0], argv);
EXPECT_EQ(mj_run_ret, 0);
@@ -818,7 +652,7 @@ TEST_F(NamespaceTest, test_tmpfs_userns) {
minijail_gidmap(j, gidmap);
minijail_namespace_user_disable_setgroups(j);
- argv[0] = const_cast<char*>(kShellPath);
+ argv[0] = (char*)kShellPath;
argv[1] = "-c";
argv[2] = "exec touch /tmp/foo";
argv[3] = NULL;
@@ -834,9 +668,7 @@ TEST_F(NamespaceTest, test_tmpfs_userns) {
TEST_F(NamespaceTest, test_namespaces) {
constexpr char teststr[] = "test\n";
- // TODO(crbug.com/895875): The preload library interferes with ASan since they
- // both need to use LD_PRELOAD.
- if (!userns_supported_ || running_with_asan()) {
+ if (!userns_supported_) {
SUCCEED();
return;
}
@@ -881,11 +713,11 @@ TEST_F(NamespaceTest, test_namespaces) {
minijail_close_open_fds(j.get());
test_function(j.get());
- char* const argv[] = {const_cast<char*>(kCatPath), nullptr};
+ const char* argv[] = {kCatPath, nullptr};
pid_t container_pid;
int child_stdin, child_stdout;
int mj_run_ret =
- run_function(j.get(), argv[0], argv,
+ run_function(j.get(), argv[0], const_cast<char* const*>(argv),
&container_pid, &child_stdin, &child_stdout, nullptr);
EXPECT_EQ(mj_run_ret, 0);
@@ -1041,47 +873,3 @@ TEST(Test, parse_size) {
ASSERT_EQ(-EINVAL, parse_size(&size, "-1G"));
ASSERT_EQ(-EINVAL, parse_size(&size, "; /bin/rm -- "));
}
-
-void TestCreateSession(bool create_session) {
- int status;
- int pipe_fds[2];
- pid_t child_pid;
- pid_t parent_sid = getsid(0);
- ssize_t pid_size = sizeof(pid_t);
-
- ScopedMinijail j(minijail_new());
- // stdin/stdout/stderr might be attached to TTYs. Close them to avoid creating
- // a new session because of that.
- minijail_close_open_fds(j.get());
-
- if (create_session)
- minijail_create_session(j.get());
-
- ASSERT_EQ(pipe(pipe_fds), 0);
- minijail_preserve_fd(j.get(), pipe_fds[0], pipe_fds[0]);
-
- child_pid = minijail_fork(j.get());
- ASSERT_GE(child_pid, 0);
- if (child_pid == 0) {
- pid_t sid_in_parent;
- ASSERT_EQ(read(pipe_fds[0], &sid_in_parent, pid_size), pid_size);
- if (create_session)
- ASSERT_NE(sid_in_parent, getsid(0));
- else
- ASSERT_EQ(sid_in_parent, getsid(0));
- exit(0);
- }
-
- EXPECT_EQ(write(pipe_fds[1], &parent_sid, pid_size), pid_size);
- waitpid(child_pid, &status, 0);
- ASSERT_TRUE(WIFEXITED(status));
- EXPECT_EQ(WEXITSTATUS(status), 0);
-}
-
-TEST(Test, default_no_new_session) {
- TestCreateSession(/*create_session=*/false);
-}
-
-TEST(Test, create_new_session) {
- TestCreateSession(/*create_session=*/true);
-}
diff --git a/minijail0.1 b/minijail0.1
index b8a7752b..0fbf38e0 100644
--- a/minijail0.1
+++ b/minijail0.1
@@ -18,8 +18,6 @@ The \fIsrc\fR path must be an absolute path.
If \fIdest\fR is not specified, it will default to \fIsrc\fR.
If the destination does not exist, it will be created as a file or directory
based on the \fIsrc\fR type (including missing parent directories).
-To create a writable bind-mount set \fIwritable\fR to \fB1\fR. If not specified
-it will default to \fB0\fR (read-only).
.TP
\fB-B <mask>\fR
Skip setting securebits in \fImask\fR when restricting capabilities (\fB-c\fR).
@@ -157,13 +155,9 @@ Run inside a new IPC namespace. This option makes the program's System V IPC
namespace independent.
.TP
\fB-L\fR
-Report blocked syscalls when using a seccomp filter. On kernels with support for
-SECCOMP_RET_LOG, every blocked syscall will be reported through the audit
-subsystem (see \fBseccomp\fR(2) for more details on SECCOMP_RET_LOG
-availability.) On all other kernels, the first failing syscall will be logged to
-syslog. This latter case will also force certain syscalls to be allowed in order
-to write to syslog. Note: this option is disabled and ignored for release
-builds.
+Report blocked syscalls to syslog when using seccomp filter. This option will
+force certain syscalls to be allowed in order to achieve this, depending on the
+system.
.TP
\fB-m[<uid> <loweruid> <count>[,<uid> <loweruid> <count>]]\fR
Set the uid mapping of a user namespace (implies \fB-pU\fR). Same arguments as
@@ -282,10 +276,7 @@ namespace to \fIhostname\fR.
.TP
\fB--logging=<system>\fR
Use \fIsystem\fR as the logging system. \fIsystem\fR must be one of
-\fBauto\fR (the default), \fBsyslog\fR, or \fBstderr\fR.
-
-\fBauto\fR will use \fBstderr\fR if connected to a tty (e.g. run directly by a
-user), otherwise it will use \fBsyslog\fR.
+\fBsyslog\fR (the default) or \fBstderr\fR.
.TP
\fB--profile <profile>\fR
Choose from one of the available sandboxing profiles, which are simple way to
@@ -352,4 +343,4 @@ The Chromium OS Authors <chromiumos-dev@chromium.org>
Copyright \(co 2011 The Chromium OS Authors
License BSD-like.
.SH "SEE ALSO"
-\fBlibminijail.h\fR \fBminijail0\fR(5) \fBseccomp\fR(2)
+\fBlibminijail.h\fR \fBminijail0\fR(5)
diff --git a/minijail0_cli.c b/minijail0_cli.c
index 277c2224..807e567c 100644
--- a/minijail0_cli.c
+++ b/minijail0_cli.c
@@ -139,16 +139,9 @@ static void add_binding(struct minijail *j, char *arg)
}
if (dest == NULL || dest[0] == '\0')
dest = src;
- int writable;
- if (flags == NULL || flags[0] == '\0' || !strcmp(flags, "0"))
- writable = 0;
- else if (!strcmp(flags, "1"))
- writable = 1;
- else {
- fprintf(stderr, "Bad value for <writable>: %s\n", flags);
- exit(1);
- }
- if (minijail_bind(j, src, dest, writable)) {
+ if (flags == NULL || flags[0] == '\0')
+ flags = "0";
+ if (minijail_bind(j, src, dest, atoi(flags))) {
fprintf(stderr, "minijail_bind failed.\n");
exit(1);
}
@@ -505,9 +498,8 @@ static void usage(const char *progn)
" -K: Do not change share mode of any existing mounts.\n"
" -K<mode>: Mark all existing mounts as <mode> instead of MS_PRIVATE.\n"
" -l: Enter new IPC namespace.\n"
- " -L: Report blocked syscalls when using seccomp filter.\n"
- " If the kernel does not support SECCOMP_RET_LOG,\n"
- " forces the following syscalls to be allowed:\n"
+ " -L: Report blocked syscalls to syslog when using seccomp filter.\n"
+ " Forces the following syscalls to be allowed:\n"
" ", progn);
/* clang-format on */
for (i = 0; i < log_syscalls_len; i++)
@@ -547,7 +539,7 @@ static void usage(const char *progn)
" --ambient: Raise ambient capabilities. Requires -c.\n"
" --uts[=name]: Enter a new UTS namespace (and set hostname).\n"
" --logging=<s>:Use <s> as the logging system.\n"
- " <s> must be 'auto' (default), 'syslog', or 'stderr'.\n"
+ " <s> must be 'syslog' (default) or 'stderr'.\n"
" --profile <p>:Configure minijail0 to run with the <p> sandboxing profile,\n"
" which is a convenient way to express multiple flags\n"
" that are typically used together.\n"
@@ -582,7 +574,7 @@ int parse_args(struct minijail *j, int argc, char *const argv[],
int forward = 1;
int binding = 0;
int chroot = 0, pivot_root = 0;
- int mount_ns = 0, change_remount = 0;
+ int mount_ns = 0, skip_remount = 0;
int inherit_suppl_gids = 0, keep_suppl_gids = 0;
int caps = 0, ambient_caps = 0;
int seccomp = -1;
@@ -593,7 +585,7 @@ int parse_args(struct minijail *j, int argc, char *const argv[],
int set_uidmap = 0, set_gidmap = 0;
size_t tmp_size = 0;
const char *filter_path = NULL;
- int log_to_stderr = -1;
+ int log_to_stderr = 0;
const char *optstring =
"+u:g:sS:c:C:P:b:B:V:f:m::M::k:a:e::R:T:vrGhHinNplLt::IUK::wyYzd";
@@ -681,12 +673,11 @@ int parse_args(struct minijail *j, int argc, char *const argv[],
add_mount(j, optarg);
break;
case 'K':
- if (optarg) {
+ if (optarg)
set_remount_mode(j, optarg);
- } else {
+ else
minijail_skip_remount_private(j);
- }
- change_remount = 1;
+ skip_remount = 1;
break;
case 'P':
use_pivot_root(j, optarg, &pivot_root, chroot);
@@ -830,11 +821,9 @@ int parse_args(struct minijail *j, int argc, char *const argv[],
minijail_namespace_set_hostname(j, optarg);
break;
case 130: /* Logging. */
- if (!strcmp(optarg, "auto")) {
- log_to_stderr = -1;
- } else if (!strcmp(optarg, "syslog")) {
+ if (!strcmp(optarg, "syslog"))
log_to_stderr = 0;
- } else if (!strcmp(optarg, "stderr")) {
+ else if (!strcmp(optarg, "stderr")) {
log_to_stderr = 1;
} else {
fprintf(stderr, "--logger must be 'syslog' or "
@@ -866,10 +855,6 @@ int parse_args(struct minijail *j, int argc, char *const argv[],
}
}
- if (log_to_stderr == -1) {
- /* Autodetect default logging output. */
- log_to_stderr = isatty(STDIN_FILENO) ? 1 : 0;
- }
if (log_to_stderr) {
init_logging(LOG_TO_FD, STDERR_FILENO, LOG_INFO);
/*
@@ -910,14 +895,12 @@ int parse_args(struct minijail *j, int argc, char *const argv[],
}
/*
- * / is only remounted when entering a new mount namespace, so unless
- * that's set there is no need for the -K/-K<mode> flags.
+ * Remounting / as MS_PRIVATE only happens when entering a new mount
+ * namespace, so skipping it only applies in that case.
*/
- if (change_remount && !mount_ns) {
- fprintf(stderr, "No need to use -K (skip remounting '/') or "
- "-K<mode> (remount '/' as <mode>)\n"
- "without -v (new mount namespace).\n"
- "Do you need to add '-v' explicitly?\n");
+ if (skip_remount && !mount_ns) {
+ fprintf(stderr, "Can't skip marking mounts as MS_PRIVATE"
+ " without mount namespaces.\n");
exit(1);
}
diff --git a/minijail0_cli_unittest.cc b/minijail0_cli_unittest.cc
index 0d6a07d4..a00541a8 100644
--- a/minijail0_cli_unittest.cc
+++ b/minijail0_cli_unittest.cc
@@ -405,10 +405,6 @@ TEST_F(CliTest, invalid_binding) {
// Missing mount namespace/etc...
argv = {"-b", "/", "/bin/sh"};
ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
-
- // Bad value for <writable>.
- argv = {"-b", "/,,writable", "/bin/sh"};
- ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
}
// Valid calls to the mount option.
diff --git a/parse_seccomp_policy.cc b/parse_seccomp_policy.cc
index 38fcbee1..c563a4a1 100644
--- a/parse_seccomp_policy.cc
+++ b/parse_seccomp_policy.cc
@@ -78,14 +78,8 @@ int main(int argc, char** argv) {
if (!f)
pdie("fopen(%s) failed", argv[1]);
- struct filter_options fopts {
- .action = ACTION_RET_KILL,
- .allow_logging = 0,
- .allow_syscalls_for_logging = 0,
- };
-
struct sock_fprog fp;
- int res = compile_filter(argv[1], f, &fp, &fopts);
+ int res = compile_filter(argv[1], f, &fp, 0, 0);
fclose(f);
if (res != 0)
die("compile_filter failed");
diff --git a/syscall_filter.c b/syscall_filter.c
index 3b78f97f..049797a6 100644
--- a/syscall_filter.c
+++ b/syscall_filter.c
@@ -137,13 +137,6 @@ void append_ret_errno(struct filter_block *head, int errno_val)
append_filter_block(head, filter, ONE_INSTR);
}
-void append_ret_log(struct filter_block *head)
-{
- struct sock_filter *filter = new_instr_buf(ONE_INSTR);
- set_bpf_ret_log(filter);
- append_filter_block(head, filter, ONE_INSTR);
-}
-
void append_allow_syscall(struct filter_block *head, int nr)
{
struct sock_filter *filter = new_instr_buf(ALLOW_SYSCALL_LEN);
@@ -276,7 +269,7 @@ int compile_atom(struct parser_state *state, struct filter_block *head,
}
int compile_errno(struct parser_state *state, struct filter_block *head,
- char *ret_errno, enum block_action action)
+ char *ret_errno, int use_ret_trap)
{
char *errno_ptr = NULL;
@@ -299,17 +292,10 @@ int compile_errno(struct parser_state *state, struct filter_block *head,
append_ret_errno(head, errno_val);
} else {
- switch (action) {
- case ACTION_RET_KILL:
+ if (!use_ret_trap)
append_ret_kill(head);
- break;
- case ACTION_RET_TRAP:
+ else
append_ret_trap(head);
- break;
- case ACTION_RET_LOG:
- compiler_warn(state, "invalid action: ACTION_RET_LOG");
- return -1;
- }
}
return 0;
}
@@ -318,7 +304,7 @@ struct filter_block *compile_policy_line(struct parser_state *state, int nr,
const char *policy_line,
unsigned int entry_lbl_id,
struct bpf_labels *labels,
- enum block_action action)
+ int use_ret_trap)
{
/*
* |policy_line| should be an expression of the form:
@@ -382,7 +368,7 @@ struct filter_block *compile_policy_line(struct parser_state *state, int nr,
/* Checks whether we're unconditionally blocking this syscall. */
if (strncmp(line, "return", strlen("return")) == 0) {
- if (compile_errno(state, head, line, action) < 0) {
+ if (compile_errno(state, head, line, use_ret_trap) < 0) {
free_block_list(head);
free(line);
return NULL;
@@ -437,23 +423,16 @@ struct filter_block *compile_policy_line(struct parser_state *state, int nr,
* otherwise just kill the task.
*/
if (ret_errno) {
- if (compile_errno(state, head, ret_errno, action) < 0) {
+ if (compile_errno(state, head, ret_errno, use_ret_trap) < 0) {
free_block_list(head);
free(line);
return NULL;
}
} else {
- switch (action) {
- case ACTION_RET_KILL:
+ if (!use_ret_trap)
append_ret_kill(head);
- break;
- case ACTION_RET_TRAP:
+ else
append_ret_trap(head);
- break;
- case ACTION_RET_LOG:
- append_ret_log(head);
- break;
- }
}
/*
@@ -556,13 +535,12 @@ static ssize_t getmultiline(char **lineptr, size_t *n, FILE *stream)
memcpy(&line[ret + 1], next_line, next_ret + 1);
free(next_line);
*lineptr = line;
- return *n - 1;
+ return ret;
}
int compile_file(const char *filename, FILE *policy_file,
struct filter_block *head, struct filter_block **arg_blocks,
- struct bpf_labels *labels,
- const struct filter_options *filteropts,
+ struct bpf_labels *labels, int use_ret_trap, int allow_logging,
unsigned int include_level)
{
/* clang-format off */
@@ -616,7 +594,8 @@ int compile_file(const char *filename, FILE *policy_file,
goto free_line;
}
if (compile_file(filename, included_file, head,
- arg_blocks, labels, filteropts,
+ arg_blocks, labels, use_ret_trap,
+ allow_logging,
include_level + 1) == -1) {
compiler_warn(&state, "'@include %s' failed",
filename);
@@ -652,7 +631,7 @@ int compile_file(const char *filename, FILE *policy_file,
if (nr < 0) {
compiler_warn(&state, "nonexistent syscall '%s'",
syscall_name);
- if (filteropts->allow_logging) {
+ if (allow_logging) {
/*
* If we're logging failures, assume we're in a
* debugging case and continue.
@@ -690,16 +669,14 @@ int compile_file(const char *filename, FILE *policy_file,
append_filter_block(head, nr_comp, ALLOW_SYSCALL_LEN);
/* Build the arg filter block. */
- struct filter_block *block =
- compile_policy_line(&state, nr, policy_line, id,
- labels, filteropts->action);
+ struct filter_block *block = compile_policy_line(
+ &state, nr, policy_line, id, labels, use_ret_trap);
if (!block) {
if (*arg_blocks) {
free_block_list(*arg_blocks);
*arg_blocks = NULL;
}
- warn("could not allocate filter block");
ret = -1;
goto free_line;
}
@@ -718,7 +695,6 @@ int compile_file(const char *filename, FILE *policy_file,
free_block_list(*arg_blocks);
*arg_blocks = NULL;
}
- warn("getmultiline() failed");
ret = -1;
}
@@ -728,8 +704,7 @@ free_line:
}
int compile_filter(const char *filename, FILE *initial_file,
- struct sock_fprog *prog,
- const struct filter_options *filteropts)
+ struct sock_fprog *prog, int use_ret_trap, int allow_logging)
{
int ret = 0;
struct bpf_labels labels;
@@ -753,48 +728,26 @@ int compile_filter(const char *filename, FILE *initial_file,
len = bpf_load_syscall_nr(load_nr);
append_filter_block(head, load_nr, len);
- /*
- * On kernels without SECCOMP_RET_LOG, Minijail can attempt to write the
- * first failing syscall to syslog(3). In order for syslog(3) to work,
- * some syscalls need to be unconditionally allowed.
- */
- if (filteropts->allow_syscalls_for_logging)
+ /* If logging failures, allow the necessary syscalls first. */
+ if (allow_logging)
allow_logging_syscalls(head);
if (compile_file(filename, initial_file, head, &arg_blocks, &labels,
- filteropts, 0 /* include_level */) != 0) {
+ use_ret_trap, allow_logging,
+ 0 /* include_level */) != 0) {
warn("compile_filter: compile_file() failed");
ret = -1;
goto free_filter;
}
/*
- * If none of the syscalls match, either fall through to LOG, TRAP, or
- * KILL.
+ * If none of the syscalls match, either fall through to KILL,
+ * or return TRAP.
*/
- switch (filteropts->action) {
- case ACTION_RET_KILL:
+ if (!use_ret_trap)
append_ret_kill(head);
- break;
- case ACTION_RET_TRAP:
+ else
append_ret_trap(head);
- break;
- case ACTION_RET_LOG:
- if (filteropts->allow_logging) {
- append_ret_log(head);
- } else {
- warn("compile_filter: cannot use RET_LOG without "
- "allowing logging");
- ret = -1;
- goto free_filter;
- }
- break;
- default:
- warn("compile_filter: invalid log action %d",
- filteropts->action);
- ret = -1;
- goto free_filter;
- }
/* Allocate the final buffer, now that we know its size. */
size_t final_filter_len =
diff --git a/syscall_filter.h b/syscall_filter.h
index 019f3f09..737ef499 100644
--- a/syscall_filter.h
+++ b/syscall_filter.h
@@ -29,31 +29,20 @@ struct parser_state {
size_t line_number;
};
-enum block_action { ACTION_RET_KILL = 0, ACTION_RET_TRAP, ACTION_RET_LOG };
-
-struct filter_options {
- enum block_action action;
- int allow_logging;
- int allow_syscalls_for_logging;
-};
-
struct bpf_labels;
struct filter_block *compile_policy_line(struct parser_state *state, int nr,
const char *policy_line,
unsigned int label_id,
struct bpf_labels *labels,
- enum block_action action);
-
+ int do_ret_trap);
int compile_file(const char *filename, FILE *policy_file,
struct filter_block *head, struct filter_block **arg_blocks,
- struct bpf_labels *labels,
- const struct filter_options *filteropts,
+ struct bpf_labels *labels, int use_ret_trap, int allow_logging,
unsigned int include_level);
-
int compile_filter(const char *filename, FILE *policy_file,
- struct sock_fprog *prog,
- const struct filter_options *filteropts);
+ struct sock_fprog *prog, int do_ret_trap,
+ int add_logging_syscalls);
struct filter_block *new_filter_block(void);
int flatten_block_list(struct filter_block *head, struct sock_filter *filter,
diff --git a/syscall_filter_unittest.cc b/syscall_filter_unittest.cc
index 95b38f49..aca5f54b 100644
--- a/syscall_filter_unittest.cc
+++ b/syscall_filter_unittest.cc
@@ -38,23 +38,18 @@ enum ret_trap {
};
enum use_logging {
- NO_LOGGING = 0,
- USE_SIGSYS_LOGGING = 1,
- USE_RET_LOG_LOGGING = 2,
+ NO_LOGGING = 0,
+ USE_LOGGING = 1,
};
int test_compile_filter(
std::string filename,
FILE* policy_file,
struct sock_fprog* prog,
- enum block_action action = ACTION_RET_KILL,
- enum use_logging allow_logging = NO_LOGGING) {
- struct filter_options filteropts {
- .action = action,
- .allow_logging = allow_logging != NO_LOGGING,
- .allow_syscalls_for_logging = allow_logging == USE_SIGSYS_LOGGING,
- };
- return compile_filter(filename.c_str(), policy_file, prog, &filteropts);
+ enum ret_trap do_ret_trap = USE_RET_KILL,
+ enum use_logging add_logging_syscalls = NO_LOGGING) {
+ return compile_filter(filename.c_str(), policy_file, prog, do_ret_trap,
+ add_logging_syscalls);
}
int test_compile_file(
@@ -63,16 +58,11 @@ int test_compile_file(
struct filter_block* head,
struct filter_block** arg_blocks,
struct bpf_labels* labels,
- enum block_action action = ACTION_RET_KILL,
+ enum ret_trap use_ret_trap = USE_RET_KILL,
enum use_logging allow_logging = NO_LOGGING,
unsigned int include_level = 0) {
- struct filter_options filteropts {
- .action = action,
- .allow_logging = allow_logging != NO_LOGGING,
- .allow_syscalls_for_logging = allow_logging == USE_SIGSYS_LOGGING,
- };
return compile_file(filename.c_str(), policy_file, head, arg_blocks, labels,
- &filteropts, include_level);
+ use_ret_trap, allow_logging, include_level);
}
struct filter_block* test_compile_policy_line(
@@ -81,9 +71,9 @@ struct filter_block* test_compile_policy_line(
std::string policy_line,
unsigned int label_id,
struct bpf_labels* labels,
- enum block_action action = ACTION_RET_KILL) {
- return compile_policy_line(state, nr, policy_line.c_str(), label_id,
- labels, action);
+ enum ret_trap do_ret_trap = USE_RET_KILL) {
+ return compile_policy_line(state, nr, policy_line.c_str(), label_id, labels,
+ do_ret_trap);
}
} // namespace
@@ -532,86 +522,6 @@ TEST_F(ArgFilterTest, arg0_equals) {
free_block_list(block);
}
-TEST_F(ArgFilterTest, arg0_equals_trap) {
- std::string fragment = "arg0 == 0";
-
- struct filter_block* block = test_compile_policy_line(
- &state_, nr_, fragment, id_, &labels_, ACTION_RET_TRAP);
-
- ASSERT_NE(block, nullptr);
- size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
- EXPECT_EQ(block->total_len, exp_total_len);
-
- /* First block is a label. */
- struct filter_block* curr_block = block;
- ASSERT_NE(curr_block, nullptr);
- EXPECT_EQ(curr_block->len, 1U);
- EXPECT_LBL(curr_block->instrs);
-
- /* Second block is a comparison. */
- curr_block = curr_block->next;
- EXPECT_COMP(curr_block);
-
- /* Third block is a jump and a label (end of AND group). */
- curr_block = curr_block->next;
- ASSERT_NE(curr_block, nullptr);
- EXPECT_GROUP_END(curr_block);
-
- /* Fourth block is SECCOMP_RET_TRAP. */
- curr_block = curr_block->next;
- ASSERT_NE(curr_block, nullptr);
- EXPECT_TRAP(curr_block);
-
- /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
- curr_block = curr_block->next;
- ASSERT_NE(curr_block, nullptr);
- EXPECT_ALLOW(curr_block);
-
- EXPECT_EQ(curr_block->next, nullptr);
-
- free_block_list(block);
-}
-
-TEST_F(ArgFilterTest, arg0_equals_log) {
- std::string fragment = "arg0 == 0";
-
- struct filter_block* block = test_compile_policy_line(
- &state_, nr_, fragment, id_, &labels_, ACTION_RET_LOG);
-
- ASSERT_NE(block, nullptr);
- size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
- EXPECT_EQ(block->total_len, exp_total_len);
-
- /* First block is a label. */
- struct filter_block* curr_block = block;
- ASSERT_NE(curr_block, nullptr);
- EXPECT_EQ(curr_block->len, 1U);
- EXPECT_LBL(curr_block->instrs);
-
- /* Second block is a comparison. */
- curr_block = curr_block->next;
- EXPECT_COMP(curr_block);
-
- /* Third block is a jump and a label (end of AND group). */
- curr_block = curr_block->next;
- ASSERT_NE(curr_block, nullptr);
- EXPECT_GROUP_END(curr_block);
-
- /* Fourth block is SECCOMP_RET_LOG. */
- curr_block = curr_block->next;
- ASSERT_NE(curr_block, nullptr);
- EXPECT_LOG(curr_block);
-
- /* Fifth block is "SUCCESS" label and SECCOMP_RET_ALLOW. */
- curr_block = curr_block->next;
- ASSERT_NE(curr_block, nullptr);
- EXPECT_ALLOW(curr_block);
-
- EXPECT_EQ(curr_block->next, nullptr);
-
- free_block_list(block);
-}
-
TEST_F(ArgFilterTest, arg0_short_gt_ge_comparisons) {
for (std::string fragment :
{"arg1 < 0xff", "arg1 <= 0xff", "arg1 > 0xff", "arg1 >= 0xff"}) {
@@ -1018,7 +928,7 @@ TEST_F(ArgFilterTest, log_no_ret_error) {
struct filter_block* block =
test_compile_policy_line(&state_, nr_, fragment, id_, &labels_,
- ACTION_RET_TRAP);
+ USE_RET_TRAP);
ASSERT_NE(block, nullptr);
size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
@@ -1102,7 +1012,7 @@ TEST_F(ArgFilterTest, no_log_bad_ret_error) {
struct filter_block* block =
test_compile_policy_line(&state_, nr_, fragment, id_, &labels_,
- ACTION_RET_TRAP);
+ USE_RET_TRAP);
ASSERT_NE(block, nullptr);
size_t exp_total_len = 1 + (BPF_ARG_COMP_LEN + 1) + 2 + 1 + 2;
EXPECT_EQ(block->total_len, exp_total_len);
@@ -1354,7 +1264,7 @@ TEST_F(FileTest, seccomp_read) {
TEST_F(FileTest, multiline) {
std::string policy =
"read:\\\n1\n"
- "openat:arg0 \\\nin\\\n \\\n5";
+ "openat:arg0 in\\\n5";
const int LABEL_ID = 0;
@@ -1434,8 +1344,7 @@ TEST(FilterTest, seccomp_mode1_trap) {
FILE* policy_file = write_policy_to_pipe(policy);
ASSERT_NE(policy_file, nullptr);
- int res =
- test_compile_filter("policy", policy_file, &actual, ACTION_RET_TRAP);
+ int res = test_compile_filter("policy", policy_file, &actual, USE_RET_TRAP);
fclose(policy_file);
/*
@@ -1462,66 +1371,6 @@ TEST(FilterTest, seccomp_mode1_trap) {
free(actual.filter);
}
-TEST(FilterTest, seccomp_mode1_log) {
- struct sock_fprog actual;
- std::string policy =
- "read: 1\n"
- "write: 1\n"
- "rt_sigreturn: 1\n"
- "exit: 1\n";
-
- FILE* policy_file = write_policy_to_pipe(policy);
- ASSERT_NE(policy_file, nullptr);
-
- int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_LOG,
- USE_RET_LOG_LOGGING);
- fclose(policy_file);
-
- /*
- * Checks return value, filter length, and that the filter
- * validates arch, loads syscall number, and
- * only allows expected syscalls.
- */
- ASSERT_EQ(res, 0);
- EXPECT_EQ(actual.len, 13);
- EXPECT_ARCH_VALIDATION(actual.filter);
- EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN,
- BPF_LD+BPF_W+BPF_ABS, syscall_nr);
- EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 1,
- __NR_read);
- EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 3,
- __NR_write);
- EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 5,
- __NR_rt_sigreturn);
- EXPECT_ALLOW_SYSCALL(actual.filter + ARCH_VALIDATION_LEN + 7,
- __NR_exit);
- EXPECT_EQ_STMT(actual.filter + ARCH_VALIDATION_LEN + 9, BPF_RET+BPF_K,
- SECCOMP_RET_LOG);
-
- free(actual.filter);
-}
-
-TEST(FilterTest, seccomp_mode1_log_fails) {
- struct sock_fprog actual;
- std::string policy =
- "read: 1\n"
- "write: 1\n"
- "rt_sigreturn: 1\n"
- "exit: 1\n";
-
- FILE* policy_file = write_policy_to_pipe(policy);
- ASSERT_NE(policy_file, nullptr);
-
- int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_LOG,
- NO_LOGGING);
- fclose(policy_file);
-
- /*
- * ACTION_RET_LOG should never be used without allowing logging.
- */
- ASSERT_EQ(res, -1);
-}
-
TEST(FilterTest, seccomp_read_write) {
struct sock_fprog actual;
std::string policy =
@@ -1662,8 +1511,8 @@ TEST(FilterTest, log) {
FILE* policy_file = write_policy_to_pipe(policy);
ASSERT_NE(policy_file, nullptr);
- int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_TRAP,
- USE_SIGSYS_LOGGING);
+ int res = test_compile_filter("policy", policy_file, &actual, USE_RET_TRAP,
+ USE_LOGGING);
fclose(policy_file);
size_t i;
@@ -1709,8 +1558,8 @@ TEST(FilterTest, allow_log_but_kill) {
FILE* policy_file = write_policy_to_pipe(policy);
ASSERT_NE(policy_file, nullptr);
- int res = test_compile_filter("policy", policy_file, &actual, ACTION_RET_KILL,
- USE_SIGSYS_LOGGING);
+ int res = test_compile_filter("policy", policy_file, &actual, USE_RET_KILL,
+ USE_LOGGING);
fclose(policy_file);
size_t i;
@@ -1718,7 +1567,7 @@ TEST(FilterTest, allow_log_but_kill) {
/*
* Checks return value, filter length, and that the filter
* validates arch, loads syscall number, only allows expected syscalls,
- * and kills on failure.
+ * and returns TRAP on failure.
* NOTE(jorgelo): the filter is longer since we add the syscalls needed
* for logging.
*/
@@ -1863,7 +1712,7 @@ TEST(FilterTest, include) {
FILE* file_plain = write_policy_to_pipe(policy_plain);
ASSERT_NE(file_plain, nullptr);
int res_plain = test_compile_filter("policy", file_plain, &compiled_plain,
- ACTION_RET_KILL);
+ USE_RET_KILL);
fclose(file_plain);
std::string policy_with_include =
@@ -1871,8 +1720,9 @@ TEST(FilterTest, include) {
FILE* file_with_include = write_policy_to_pipe(policy_with_include);
ASSERT_NE(file_with_include, nullptr);
- int res_with_include = test_compile_filter(
- "policy", file_with_include, &compiled_with_include, ACTION_RET_KILL);
+ int res_with_include =
+ test_compile_filter("policy", file_with_include, &compiled_with_include,
+ USE_RET_KILL);
fclose(file_with_include);
/*
diff --git a/syscall_filter_unittest_macros.h b/syscall_filter_unittest_macros.h
index 3972cb41..4923fc4c 100644
--- a/syscall_filter_unittest_macros.h
+++ b/syscall_filter_unittest_macros.h
@@ -3,11 +3,6 @@
* found in the LICENSE file.
*/
-#ifndef SYSCALL_FILTER_UNITTEST_MACROS_H
-#define SYSCALL_FILTER_UNITTEST_MACROS_H
-
-#include "bpf.h"
-
/* BPF testing macros. */
#define EXPECT_EQ_BLOCK(_block, _code, _k, _jt, _jf) \
do { \
@@ -81,13 +76,6 @@ do { \
BPF_RET+BPF_K, SECCOMP_RET_TRAP); \
} while (0)
-#define EXPECT_LOG(_block) \
-do { \
- EXPECT_EQ((_block)->len, 1U); \
- EXPECT_EQ_STMT((_block)->instrs, \
- BPF_RET+BPF_K, SECCOMP_RET_LOG); \
-} while (0)
-
#define EXPECT_ALLOW(_block) \
do { \
EXPECT_EQ((_block)->len, 2U); \
@@ -119,5 +107,3 @@ do { \
EXPECT_EQ_BLOCK(&(_filter)[1], \
BPF_JMP+BPF_JA, (_id), (_jt), (_jf)); \
} while (0)
-
-#endif // SYSCALL_FILTER_UNITTEST_MACROS_H
diff --git a/system.c b/system.c
index 118daf43..2dcf1527 100644
--- a/system.c
+++ b/system.c
@@ -222,17 +222,14 @@ int setup_pipe_end(int fds[2], size_t index)
return fds[index];
}
-int dupe_and_close_fd(int fds[2], size_t index, int fd)
+int setup_and_dupe_pipe_end(int fds[2], size_t index, int fd)
{
if (index > 1)
return -1;
+ close(fds[1 - index]);
/* dup2(2) the corresponding end of the pipe into |fd|. */
- fd = dup2(fds[index], fd);
-
- close(fds[0]);
- close(fds[1]);
- return fd;
+ return dup2(fds[index], fd);
}
int write_pid_to_path(pid_t pid, const char *path)
@@ -467,61 +464,3 @@ int lookup_group(const char *group, gid_t *gid)
*gid = pgr->gr_gid;
return 0;
}
-
-static int seccomp_action_is_available(const char *wanted)
-{
- if (is_android()) {
- /*
- * Accessing |actions_avail| is generating SELinux denials, so
- * skip for now.
- * TODO(crbug.com/978022, jorgelo): Remove once the denial is
- * fixed.
- */
- return 0;
- }
- const char actions_avail_path[] =
- "/proc/sys/kernel/seccomp/actions_avail";
- FILE *f = fopen(actions_avail_path, "re");
-
- if (!f) {
- pwarn("fopen(%s) failed", actions_avail_path);
- return 0;
- }
-
- char *actions_avail = NULL;
- size_t buf_size = 0;
- if (getline(&actions_avail, &buf_size, f) < 0) {
- pwarn("getline() failed");
- free(actions_avail);
- return 0;
- }
-
- /*
- * This is just substring search, which means that partial matches will
- * match too (e.g. "action" would match "longaction"). There are no
- * seccomp actions which include other actions though, so we're good for
- * now. Eventually we might want to split the string by spaces.
- */
- return strstr(actions_avail, wanted) != NULL;
-}
-
-int seccomp_ret_log_available(void)
-{
- static int ret_log_available = -1;
-
- if (ret_log_available == -1)
- ret_log_available = seccomp_action_is_available("log");
-
- return ret_log_available;
-}
-
-int seccomp_ret_kill_process_available(void)
-{
- static int ret_kill_process_available = -1;
-
- if (ret_kill_process_available == -1)
- ret_kill_process_available =
- seccomp_action_is_available("kill_process");
-
- return ret_kill_process_available;
-}
diff --git a/system.h b/system.h
index c9e04d5a..cd1a98a8 100644
--- a/system.h
+++ b/system.h
@@ -47,7 +47,7 @@ int cap_ambient_supported(void);
int config_net_loopback(void);
int setup_pipe_end(int fds[2], size_t index);
-int dupe_and_close_fd(int fds[2], size_t index, int fd);
+int setup_and_dupe_pipe_end(int fds[2], size_t index, int fd);
int write_pid_to_path(pid_t pid, const char *path);
int write_proc_file(pid_t pid, const char *content, const char *basename);
@@ -60,9 +60,6 @@ int setup_mount_destination(const char *source, const char *dest, uid_t uid,
int lookup_user(const char *user, uid_t *uid, gid_t *gid);
int lookup_group(const char *group, gid_t *gid);
-int seccomp_ret_log_available(void);
-int seccomp_ret_kill_process_available(void);
-
#ifdef __cplusplus
}; /* extern "C" */
#endif
diff --git a/system_unittest.cc b/system_unittest.cc
index e13630ab..36d8dc3b 100644
--- a/system_unittest.cc
+++ b/system_unittest.cc
@@ -187,10 +187,10 @@ TEST(setup_pipe_end, index1) {
}
// Invalid indexes should return errors, not crash.
-TEST(dupe_and_close_fd, bad_index) {
- EXPECT_LT(dupe_and_close_fd(nullptr, 2, -1), 0);
- EXPECT_LT(dupe_and_close_fd(nullptr, 3, -1), 0);
- EXPECT_LT(dupe_and_close_fd(nullptr, 4, -1), 0);
+TEST(setup_and_dupe_pipe_end, bad_index) {
+ EXPECT_LT(setup_and_dupe_pipe_end(nullptr, 2, -1), 0);
+ EXPECT_LT(setup_and_dupe_pipe_end(nullptr, 3, -1), 0);
+ EXPECT_LT(setup_and_dupe_pipe_end(nullptr, 4, -1), 0);
}
// An invalid path should return an error.
@@ -260,7 +260,7 @@ TEST(setup_mount_destination, dest_exists) {
EXPECT_EQ(0, setup_mount_destination(nullptr, "/dev", 0, 0, false, nullptr));
}
-// Mount flags should be obtained for bind-mounts.
+// Mount flags should be obtained for bind-mounts
TEST(setup_mount_destination, mount_flags) {
struct statvfs stvfs_buf;
ASSERT_EQ(0, statvfs("/proc", &stvfs_buf));
@@ -362,8 +362,3 @@ TEST(setup_mount_destination, create_char_dev) {
// We check it's a directory by deleting it as such.
EXPECT_EQ(0, rmdir(child_dev.c_str()));
}
-
-TEST(seccomp_actions_available, smoke) {
- seccomp_ret_log_available();
- seccomp_ret_kill_process_available();
-}
diff --git a/util.h b/util.h
index a71fd29f..b77826ea 100644
--- a/util.h
+++ b/util.h
@@ -9,7 +9,6 @@
#ifndef _UTIL_H_
#define _UTIL_H_
-#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -106,40 +105,12 @@ static inline int is_android(void)
#endif
}
-static inline bool compiled_with_asan(void)
-{
-#if defined(__SANITIZE_ADDRESS__)
- /* For gcc. */
- return true;
-#elif defined(__has_feature)
- /* For clang. */
- return __has_feature(address_sanitizer) ||
- __has_feature(hwaddress_sanitizer);
-#else
- return false;
-#endif
-}
-
void __asan_init(void) attribute_weak;
void __hwasan_init(void) attribute_weak;
-static inline bool running_with_asan(void)
+static inline int running_with_asan(void)
{
- /*
- * There are some configurations under which ASan needs a dynamic (as
- * opposed to compile-time) test. Some Android processes that start
- * before /data is mounted run with non-instrumented libminijail.so, so
- * the symbol-sniffing code must be present to make the right decision.
- */
- return compiled_with_asan() || &__asan_init != 0 || &__hwasan_init != 0;
-}
-
-static inline bool debug_logging_allowed(void) {
-#if defined(ALLOW_DEBUG_LOGGING)
- return true;
-#else
- return false;
-#endif
+ return &__asan_init != 0 || &__hwasan_init != 0;
}
int lookup_syscall(const char *name);