diff options
-rw-r--r-- | .github/workflows/check.yml | 2 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | bwrap.xml | 26 | ||||
-rw-r--r-- | meson.build | 33 | ||||
-rw-r--r-- | meson_options.txt | 11 | ||||
-rw-r--r-- | tests/meson.build | 1 | ||||
-rwxr-xr-x | tests/test-specifying-pidns.sh | 3 | ||||
-rw-r--r-- | tests/try-syscall.c | 10 | ||||
-rw-r--r-- | utils.h | 4 |
9 files changed, 78 insertions, 14 deletions
diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 34b8771..ceb3b82 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -110,7 +110,7 @@ jobs: ( cd DESTDIR && find -ls ) - name: dist run: | - BWRAP_MUST_WORK=1 CI_MESON_DIST=1 meson dist -C _build + BWRAP_MUST_WORK=1 meson dist -C _build - name: Collect dist test logs on failure if: failure() run: mv _build/meson-private/dist-build/meson-logs/testlog.txt test-logs/disttestlog.txt || true @@ -31,7 +31,7 @@ user namespaces. Emphasis on subset - specifically relevant to the above CVE, bubblewrap does not allow control over iptables. The original bubblewrap code existed before user namespaces - it inherits code from -[xdg-app helper](https://cgit.freedesktop.org/xdg-app/xdg-app/tree/common/xdg-app-helper.c) +[xdg-app helper](https://cgit.freedesktop.org/xdg-app/xdg-app/tree/common/xdg-app-helper.c?id=4c3bf179e2e4a2a298cd1db1d045adaf3f564532) which in turn distantly derives from [linux-user-chroot](https://git.gnome.org/browse/linux-user-chroot). @@ -131,6 +131,10 @@ <listitem><para>Unshare all possible namespaces. Currently equivalent with: <option>--unshare-user-try</option> <option>--unshare-ipc</option> <option>--unshare-pid</option> <option>--unshare-net</option> <option>--unshare-uts</option> <option>--unshare-cgroup-try</option></para></listitem> </varlistentry> <varlistentry> + <term><option>--share-net</option></term> + <listitem><para>Retain the network namespace, overriding an earlier <option>--unshare-all</option> or <option>--unshare-net</option></para></listitem> + </varlistentry> + <varlistentry> <term><option>--userns <arg choice="plain">FD</arg></option></term> <listitem><para>Use an existing user namespace instead of creating a new one. The namespace must fulfil the permission requirements for setns(), which generally means that it must be a descendant of the currently active user namespace, owned by the same user. </para> <para>This is incompatible with --unshare-user, and doesn't work in the setuid version of bubblewrap.</para></listitem> @@ -382,6 +386,28 @@ </para></listitem> </varlistentry> <varlistentry> + <term><option>--json-status-fd <arg choice="plain">FD</arg></option></term> + <listitem><para> + Multiple JSON documents are written to <arg choice="plain">FD</arg>, + one per line (<ulink url="https://jsonlines.org/">"JSON lines" format</ulink>). + Each line is a single JSON object. + After <command>bwrap</command> has started the child process inside the sandbox, + it writes an object with a <literal>child-pid</literal> member to the + <option>--json-status-fd</option> (this duplicates the older <option>--info-fd</option>). + The corresponding value is the process ID of the child process in the pid namespace from + which <command>bwrap</command> was run. + If available, the namespace IDs are also included in the object with the <literal>child-pid</literal>; + again, this duplicates the older <option>--info-fd</option>. + When the child process inside the sandbox exits, <command>bwrap</command> writes an object + with an exit-code member, and then closes the <option>--json-status-fd</option>. The value + corresponding to <literal>exit-code</literal> is the exit status of the child, in the usual + shell encoding (n if it exited normally with status n, or 128+n if it was killed by signal n). + Other members may be added to those objects in future versions of <command>bwrap</command>, + and other JSON objects may be added before or after the current objects, so readers must + ignore members and objects that they do not understand. + </para></listitem> + </varlistentry> + <varlistentry> <term><option>--new-session</option></term> <listitem><para> Create a new terminal session for the sandbox (calls setsid()). This diff --git a/meson.build b/meson.build index 5b63aa6..7d51a85 100644 --- a/meson.build +++ b/meson.build @@ -101,12 +101,14 @@ configure_file( configuration : cdata, ) -if meson.is_subproject() - bwrapdir = get_option('libexecdir') +if meson.is_subproject() and get_option('program_prefix') == '' + error('program_prefix option must be set when bwrap is a subproject') +endif - if get_option('program_prefix') == '' - error('program_prefix option must be set when bwrap is a subproject') - endif +if get_option('bwrapdir') != '' + bwrapdir = get_option('bwrapdir') +elif meson.is_subproject() + bwrapdir = get_option('libexecdir') else bwrapdir = get_option('bindir') endif @@ -124,9 +126,24 @@ bwrap = executable( dependencies : [selinux_dep, libcap_dep], ) +manpages_xsl = 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl' xsltproc = find_program('xsltproc', required : get_option('man')) +build_man_page = false if xsltproc.found() and not meson.is_subproject() + if run_command([ + xsltproc, '--nonet', manpages_xsl, + ], check : false).returncode() == 0 + message('Docbook XSL found, man page enabled') + build_man_page = true + elif get_option('man').enabled() + error('Man page requested, but Docbook XSL stylesheets not found') + else + message('Docbook XSL not found, man page disabled automatically') + endif +endif + +if build_man_page custom_target( 'bwrap.1', output : 'bwrap.1', @@ -140,7 +157,7 @@ if xsltproc.found() and not meson.is_subproject() '--stringparam', 'man.authors.section.enabled', '0', '--stringparam', 'man.copyright.section.enabled', '0', '-o', '@OUTPUT@', - 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl', + manpages_xsl, '@INPUT@', ], install : true, @@ -152,4 +169,6 @@ if not meson.is_subproject() subdir('completions') endif -subdir('tests') +if get_option('tests') + subdir('tests') +endif diff --git a/meson_options.txt b/meson_options.txt index 2fa3a8c..87bac9c 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -11,6 +11,11 @@ option( value : '', ) option( + 'bwrapdir', + type : 'string', + description : 'install bwrap in this directory [default: bindir, or libexecdir in subprojects]', +) +option( 'man', type : 'feature', description : 'generate man pages', @@ -39,6 +44,12 @@ option( value : 'auto', ) option( + 'tests', + type : 'boolean', + description : 'build tests', + value : 'true', +) +option( 'zsh_completion', type : 'feature', description : 'install zsh completion script', diff --git a/tests/meson.build b/tests/meson.build index 0f32a37..87bf709 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -12,6 +12,7 @@ test_programs = [ executable( 'try-syscall', 'try-syscall.c', + override_options: ['b_sanitize=none'], ) test_scripts = [ diff --git a/tests/test-specifying-pidns.sh b/tests/test-specifying-pidns.sh index 5b88af4..de38b97 100755 --- a/tests/test-specifying-pidns.sh +++ b/tests/test-specifying-pidns.sh @@ -10,14 +10,13 @@ echo "1..1" # This test needs user namespaces if test -n "${bwrap_is_suid:-}"; then echo "ok - # SKIP no setuid support for --unshare-user" -elif test -n "${CI_MESON_DIST:-}"; then - echo "not ok - # TODO this test hangs under 'meson dist' during Github Workflow CI" else mkfifo donepipe $RUN --info-fd 42 --unshare-user --unshare-pid sh -c 'readlink /proc/self/ns/pid > sandbox-pidns; cat < donepipe' >/dev/null 42>info.json & while ! test -f sandbox-pidns; do sleep 1; done SANDBOX1PID=$(extract_child_pid info.json) + ASAN_OPTIONS=detect_leaks=0 LSAN_OPTIONS=detect_leaks=0 \ $RUN --userns 11 --pidns 12 readlink /proc/self/ns/pid > sandbox2-pidns 11< /proc/$SANDBOX1PID/ns/user 12< /proc/$SANDBOX1PID/ns/pid echo foo > donepipe diff --git a/tests/try-syscall.c b/tests/try-syscall.c index df35054..6f2f112 100644 --- a/tests/try-syscall.c +++ b/tests/try-syscall.c @@ -24,11 +24,11 @@ #include <sys/types.h> #if defined(_MIPS_SIM) -# if _MIPS_SIM == _MIPS_SIM_ABI32 +# if _MIPS_SIM == _ABIO32 # define MISSING_SYSCALL_BASE 4000 -# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# elif _MIPS_SIM == _ABI64 # define MISSING_SYSCALL_BASE 5000 -# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# elif _MIPS_SIM == _ABIN32 # define MISSING_SYSCALL_BASE 6000 # else # error "Unknown MIPS ABI" @@ -71,6 +71,10 @@ */ #define WRONG_POINTER ((char *) 1) +#ifndef PR_GET_CHILD_SUBREAPER +#define PR_GET_CHILD_SUBREAPER 37 +#endif + int main (int argc, char **argv) { @@ -48,6 +48,10 @@ typedef int bool; #define PIPE_READ_END 0 #define PIPE_WRITE_END 1 +#ifndef PR_SET_CHILD_SUBREAPER +#define PR_SET_CHILD_SUBREAPER 36 +#endif + void warn (const char *format, ...) __attribute__((format (printf, 1, 2))); void die_with_error (const char *format, |