An attacker could pre-create /tmp/.bubblewrap-$UID and make it a
non-directory, non-symlink (in which case mounting our tmpfs would fail,
causing denial of service), or make it a symlink under their control
(potentially allowing bad things if the protected_symlinks sysctl is
not enabled).
Instead, temporarily mount the tmpfs on a directory that we are sure
exists and is not attacker-controlled. /tmp (the directory itself, not
a subdirectory) will do.
Fixes: #304
Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=923557
Signed-off-by: Simon McVittie <smcv@debian.org>
Closes: #305
Approved by: cgwalters
The exit code is only reported if it exited after a successful exec.
This is accomplished with a pipe, where the write end is closed on exec.
To distinguish between pipe-close pre-exec and at-exec,
data is written to the pipe immediately before calling exec
so if it is closed before exec the pipe is empty
and if it is closed during exec it contains a 1 byte value.
To further distinguish between a successful exec and a failed exec,
on exec failure a second value is written.
Signed-off-by: Richard Maw <richard.maw@codethink.co.uk>
Closes: #257
Closes: #293
Approved by: cgwalters
For the non-suid case, we were assuming that the host system would have
merged /usr (e.g. /bin -> /usr/bin). This isn't yet the case for all
distros, so let's handle both.
Closes: #290
Approved by: smcv
These ignore source files not existing which allows bwrap using
applications to avoid repeatedly checking if files exist.
Closes: #283
Approved by: alexlarsson
Some variables like base_path ("/run/user/%d/.bubblewrap") are
declared with the cleanup attribute in main(), but this cleanup is not
run when in the parent process, since it calls exit() in monitor_child().
Use return statements instead of exit() so that cleanup attributes
will be run.
Closes: #271
Approved by: smcv
Keep a reference to the previous working directory and use it for the
umount.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Closes: #256
Approved by: cgwalters
Skip these mounts when the process will keep CAP_SYS_ADMIN as it will
anyway able to umount them.
This fix the case of running bwrap inside of a bwrap with a new pid
namespace and mount /proc.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Closes: #256
Approved by: cgwalters
This is preparatory work for supporting recursive bwrap. Without this, using
`mount()` on the second `/` won't work, since it won't be a mount point.
Closes: #256
Approved by: cgwalters
This shouldn't matter unless someone wants to run an inadvisably-named
executable, but it's best-practice for commands that pass on some
of their arguments to a subsequent command.
It allows an invocation like:
bwrap --ro-bind /container / -- "$@"
to search PATH in the container for an executable named according to
"$1", even if $1 has a pathological value like
"--this-has-a-stupid-name--", or even a value that might be
deliberately trying to break bwrap's parsing like "--bind".
Fixes: #259
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #261
Approved by: cgwalters
For NFS mounts if we call mkdir() on a read-only mount (such as when
we've created a read-only bind mount) the kernel will nor return EEXIST
even when the directory exists, instead returning EROFS.
So, we add (and use) an ensure_dir() helper that stats before calling
mkdir.
Closes: #258
Approved by: giuseppe
According to PEP 394, the python command is meant to be Python 2
until at least 2020, so in practice this script will be run with
Python 2 for now (except on Arch Linux); but it seems good to be
more future-proof.
In Python 3, os.write() takes a bytestring (bytes object), not a
text string (str/unicode object). In Python 2 ≥ 2.6, the b'' syntax
is supported and gives a str object, because that was a bytestring
in Python 2; either way, b'1' is an acceptable argument to os.write().
In Python ≥ 3.4, the result of os.pipe() is close-on-exec
(non-inheritable) by default, so undo that where needed.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #246
Approved by: giuseppe
This means we can use it with an installed bwrap, which seems a more
common use of a demo script than a just-compiled bwrap, and is
consistent with the shell scripts.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #246
Approved by: giuseppe
On systems without the /usr merge, it's almost certainly in /usr,
so this script would have failed.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #246
Approved by: giuseppe
Per open(2) man page:
When O_PATH is specified in flags, flag bits other than O_CLOEXEC
, O_DIRECTORY, and O_NOFOLLOW are ignored.
Signed-off-by: Marcos Paulo de Souza <marcos.souza.org@gmail.com>
Closes: #244
Approved by: cgwalters
The options --file, --bind-data and --ro-bind-data take a file
descriptor as first argument. This FD is then used to set up the new
root file system. These FDs are then closed after this step. However,
when the privileged mode is used, this step is run in a child process,
hence leaking the FDs in the parent process.
To avoid future omissions, this patch walk through all the file
descriptors tied to an option and try to close them. To avoid a double
close, it marks FDs closed by setup_newroot as such.
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Closes: #243
Approved by: cgwalters
This means we can compile on Debian 8 'jessie', currently the
"oldstable" distribution. It's consistent with what would happen
if we knew PR_CAP_AMBIENT at compile-time but the kernel didn't support
it at runtime.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #242
Approved by: cgwalters
README.md and the demos are documentation that could be useful to
install, the spec file can be used by rpmbuild -ta, and the autogen.sh
and editor and uncrustify configuration could be useful for distro
packagers contributing patches upstream from a tree based on tarball
imports.
I arbitrarily left out CI configuration for PAPR and Travis-CI, since
these always take their source code from git anyway.
git.mk is excluded because it contains comments saying it should be.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #236
Approved by: giuseppe
The first attempt caused a use-after-free because the arguments parsed
from --args are passed to parse_args_recurse(), and the other cases
there may take those pointers (without copying) into SetupOp structures,
which persist after data is freed.
Fix that by treating data more like the argv to main(): an allocation
which exists throughout the life of the program. Do that by hoisting its
declaration out as a global, and then pulling the allocated data into a
cleanup_free variable in main(), to tie its lifecycle to main().
The alternative is to strdup() each one of the argv elements when they
are used in parse_args_recurse(), but that would mean a lot more
allocations and frees, and a lot of code churn.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
https://github.com/projectatomic/bubblewrap/issues/224
Closes: #237
Approved by: smcv
A new test was added in commit c09c1e53, but the total number of tests
wasn’t incremented. Fix that.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Closes: #237
Approved by: smcv
We've got a lot of new features and bugfixes since 0.1.8. Let's cut a new
release before we start landing even more things like the `pivot_root()` PR.
Closes: #232
Approved by: smcv
It may not always be obvious what the source of any particular error
message is. For instance, "Can't find source path" errors could be
perceived as coming from either the shell, loader, bubblewrap, or the
wrapped application, especially when a previously-configured program
stops working due to some external circumstances.
Thus, disambiguate the source of bubblewrap's error messages by
printing them with a "bwrap: " prefix.
Closes: #234
Approved by: cgwalters
I was looking at what fds flatpak injects, and realized this is actually just a
bubblewrap bug; there's no reason for us to leak this to the child, so don't.
It took me a while to work out/remember that our `close_extra_fds()` bits are
only intended to handle processes *other* than the final target, i.e. we want to
close fds in our init process. For the final child process, we need to support
passing arbitrary fds though, so `close_extra_fds()` can't apply to the child.
Closes: #221
Approved by: smcv
bwrap uses F_SETLK, not F_SETLKW, to implement --lock-file.
This means we have to be prepared to retry if another process -
like our own lockf-n.py - might already be holding it.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #227
Approved by: cgwalters
This reverts the actual leak fix from commit
4b8fa95704, which seems to make --args
fail to work.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #230
Approved by: cgwalters
On Debian systems, by default only root has /{usr/,}sbin in PATH.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #228
Approved by: cgwalters
The main thing this gets us is the ability to see when the build-time
test was skipped.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #229
Approved by: cgwalters
If stderr and stdout are going to the same place, it doesn't matter
either way. If they are separated (as they are in the Debian
autopkgtest environment), we want the diagnostic that indicates "this
next warning is OK" to end up in the same place as the warning.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #229
Approved by: cgwalters
Redirecting stderr to a file is unhelpful, if the command fails and we
have no chance to see why.
assert_not_file_has_content seems a little clearer than using grep
directly.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #229
Approved by: cgwalters
Most Linux distributions should have deployed
/proc/sys/fs/protected_symlinks by now, preventing the usual
symlink-traversal vulnerability; but avoiding predictable filenames in
/tmp is a good habit to get into.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Closes: #229
Approved by: cgwalters