summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2018-09-24 13:17:51 +0100
committerAtomic Bot <atomic-devel@projectatomic.io>2018-11-05 16:18:37 +0000
commitf6acd3551ec615b6755a9c4bfee6e165f4959b35 (patch)
tree21e86565e6ebf719da7c8e3ff3ead3ffee7e5874
parent8fc5a96b3ef4a8038365059412342f9cccbe2a87 (diff)
downloadbubblewrap-f6acd3551ec615b6755a9c4bfee6e165f4959b35.tar.gz
bwrap: add option json-status-fd to show child exit code
Signed-off-by: Richard Maw <richard.maw@codethink.co.uk> Closes: #293 Approved by: cgwalters
-rw-r--r--bubblewrap.c50
-rwxr-xr-xtests/test-run.sh10
2 files changed, 55 insertions, 5 deletions
diff --git a/bubblewrap.c b/bubblewrap.c
index b319f1c..03abbe5 100644
--- a/bubblewrap.c
+++ b/bubblewrap.c
@@ -73,6 +73,7 @@ int opt_sync_fd = -1;
int opt_block_fd = -1;
int opt_userns_block_fd = -1;
int opt_info_fd = -1;
+int opt_json_status_fd = -1;
int opt_seccomp_fd = -1;
const char *opt_sandbox_hostname = NULL;
char *opt_args_data = NULL; /* owned */
@@ -229,6 +230,7 @@ usage (int ecode, FILE *out)
" --block-fd FD Block on FD until some data to read is available\n"
" --userns-block-fd FD Block on FD until the user namespace is ready\n"
" --info-fd FD Write information about the running container to FD\n"
+ " --json-status-fd FD Write container status to FD as multiple JSON documents\n"
" --new-session Create a new terminal session\n"
" --die-with-parent Kills with SIGKILL child process (COMMAND) when bwrap or bwrap's parent dies.\n"
" --as-pid-1 Do not install a reaper process with PID=1\n"
@@ -314,6 +316,17 @@ propagate_exit_status (int status)
return 255;
}
+static void
+dump_info (int fd, const char *output, bool exit_on_error)
+{
+ size_t len = strlen (output);
+ if (write_to_fd (fd, output, len))
+ {
+ if (exit_on_error)
+ die_with_error ("Write to info_fd");
+ }
+}
+
/* This stays around for as long as the initial process in the app does
* and when that exits it exits, propagating the exit status. We do this
* by having pid 1 in the sandbox detect this exit and tell the monitor
@@ -331,12 +344,18 @@ monitor_child (int event_fd, pid_t child_pid)
struct pollfd fds[2];
int num_fds;
struct signalfd_siginfo fdsi;
- int dont_close[] = { event_fd, -1 };
+ int dont_close[] = {-1, -1, -1};
+ int j = 0;
pid_t died_pid;
int died_status;
/* Close all extra fds in the monitoring process.
Any passed in fds have been passed on to the child anyway. */
+ if (event_fd != -1)
+ dont_close[j++] = event_fd;
+ if (opt_json_status_fd != -1)
+ dont_close[j++] = opt_json_status_fd;
+ assert (j < sizeof(dont_close)/sizeof(*dont_close));
fdwalk (proc_fd, close_extra_fds, dont_close);
sigemptyset (&mask);
@@ -1768,6 +1787,23 @@ parse_args_recurse (int *argcp,
argv += 1;
argc -= 1;
}
+ else if (strcmp (arg, "--json-status-fd") == 0)
+ {
+ int the_fd;
+ char *endptr;
+
+ if (argc < 2)
+ die ("--json-status-fd takes an argument");
+
+ the_fd = strtol (argv[1], &endptr, 10);
+ if (argv[1][0] == 0 || endptr[0] != 0 || the_fd < 0)
+ die ("Invalid fd: %s", argv[1]);
+
+ opt_json_status_fd = the_fd;
+
+ argv += 1;
+ argc -= 1;
+ }
else if (strcmp (arg, "--seccomp") == 0)
{
int the_fd;
@@ -2216,11 +2252,14 @@ main (int argc,
if (opt_info_fd != -1)
{
cleanup_free char *output = xasprintf ("{\n \"child-pid\": %i\n}\n", pid);
- size_t len = strlen (output);
- if (write (opt_info_fd, output, len) != len)
- die_with_error ("Write to info_fd");
+ dump_info (opt_info_fd, output, TRUE);
close (opt_info_fd);
}
+ if (opt_json_status_fd != -1)
+ {
+ cleanup_free char *output = xasprintf ("{ \"child-pid\": %i }\n", pid);
+ dump_info (opt_json_status_fd, output, TRUE);
+ }
if (opt_userns_block_fd != -1)
{
@@ -2255,6 +2294,9 @@ main (int argc,
if (opt_info_fd != -1)
close (opt_info_fd);
+ if (opt_json_status_fd != -1)
+ close (opt_json_status_fd);
+
/* Wait for the parent to init uid/gid maps and drop caps */
res = read (child_wait_fd, &val, 8);
close (child_wait_fd);
diff --git a/tests/test-run.sh b/tests/test-run.sh
index b883b82..b922e3b 100755
--- a/tests/test-run.sh
+++ b/tests/test-run.sh
@@ -80,7 +80,7 @@ if ! $RUN true; then
skip Seems like bwrap is not working at all. Maybe setuid is not working
fi
-echo "1..38"
+echo "1..39"
# Test help
${BWRAP} --help > help.txt
@@ -140,6 +140,14 @@ $RUN --unshare-pid --as-pid-1 --bind / / bash -c 'echo $$' > as_pid_1.txt
assert_file_has_content as_pid_1.txt "1"
echo "ok - can run as pid 1"
+# Test --info-fd and --json-status-fd
+if $RUN --unshare-all --info-fd 42 --json-status-fd 43 -- bash -c 'exit 42' 42>info.json 43>json-status.json 2>err.txt; then
+ fatal "should have been exit 42"
+fi
+assert_file_has_content info.json '"child-pid": [0-9]'
+assert_file_has_content json-status.json '"child-pid": [0-9]'
+echo "ok info and json-status fd"
+
# These tests require --unshare-user
if test -n "${bwrap_is_suid:-}"; then
echo "ok - # SKIP no --cap-add support"