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
9 changes: 9 additions & 0 deletions bind-mount.c
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,15 @@ bind_mount (int proc_fd,
be safe to ignore because its not something the user can access. */
if (errno != EACCES)
{
/* And if we don't need a security boundary, we can also
* ignore other remount errors for submounts. */
if (options & BIND_FAIL_OPEN)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I verified that having the check under the for loop that start with i = 1 seem to be enough:

  if (recursive)
    {
      for (i = 1; mount_tab[i].mountpoint != NULL; i++)
        {
           ...

This seems to cover also host mount points like /hdd directly under /, because even when --bind / / is used mount_tab[0].mountpoint will be /newroot, and so the code will handle /newroot/hdd

And we can assume that /newroot is not on an automount?

So we shouldn't nee to add the check also for mount_tab[0].mountpoint.

{
warn ("Can't remount %s submount (%s), ignoring error",
mount_tab[i].mountpoint, strerror (errno));
continue;
}

if (failing_path != NULL)
*failing_path = xstrdup (mount_tab[i].mountpoint);

Expand Down
1 change: 1 addition & 0 deletions bind-mount.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ typedef enum {
BIND_READONLY = (1 << 0),
BIND_DEVICES = (1 << 2),
BIND_RECURSIVE = (1 << 3),
BIND_FAIL_OPEN = (1 << 4),
} bind_option_t;

typedef enum
Expand Down
22 changes: 19 additions & 3 deletions bubblewrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ static int opt_tmp_overlay_count = 0;
static int next_perms = -1;
static size_t next_size_arg = 0;
static int next_overlay_src_count = 0;
static bool opt_not_a_security_boundary = false;

#define CAP_TO_MASK_0(x) (1L << ((x) & 31))
#define CAP_TO_MASK_1(x) CAP_TO_MASK_0(x - 32)
Expand Down Expand Up @@ -350,6 +351,8 @@ usage (int ecode, FILE *out)
" --perms OCTAL Set permissions of next argument (--bind-data, --file, etc.)\n"
" --size BYTES Set size of next argument (only for --tmpfs)\n"
" --chmod OCTAL PATH Change permissions of PATH (must already exist)\n"
" --not-a-security-boundary Do not fail hard when some sandbox setup steps fail;\n"
" use only when the sandbox is not a security boundary\n"
);
exit (ecode);
}
Expand Down Expand Up @@ -1003,9 +1006,18 @@ setup_newroot (bool unshare_pid)
else if (ensure_file (dest, 0444) != 0)
die_with_error ("Can't create file at %s", op->dest);

setup_op_bind_mount ((op->type == SETUP_RO_BIND_MOUNT ? BIND_READONLY : 0) |
(op->type == SETUP_DEV_BIND_MOUNT ? BIND_DEVICES : 0),
source, dest);
bind_option_t bind_flags = 0;

if (opt_not_a_security_boundary)
bind_flags |= BIND_FAIL_OPEN;

if (op->type == SETUP_RO_BIND_MOUNT)
bind_flags |= BIND_READONLY;

if (op->type == SETUP_DEV_BIND_MOUNT)
bind_flags |= BIND_DEVICES;

setup_op_bind_mount (bind_flags, source, dest);

if (op->fd >= 0)
{
Expand Down Expand Up @@ -2427,6 +2439,10 @@ parse_args_recurse (int *argcp,
argv += 2;
argc -= 2;
}
else if (strcmp (arg, "--not-a-security-boundary") == 0)
{
opt_not_a_security_boundary = true;
}
else if (strcmp (arg, "--") == 0)
{
argv += 1;
Expand Down
27 changes: 27 additions & 0 deletions bwrap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,33 @@
command line. Please be careful to the order they are specified.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--not-a-security-boundary</option></term>
<listitem>
<para>
Declare that this invocation of <command>bwrap</command> is not
intended to create a security boundary between the sandbox and the
host system. When this option is given, certain non-fatal sandbox
setup failures (such as a bind mount failing because an automounter
did not respond in time) will produce a warning and will be skipped,
rather than causing <command>bwrap</command> to exit with an error.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps worthwhile to say something like

Suggested change
rather than causing <command>bwrap</command> to exit with an error.
rather than causing <command>bwrap</command> to exit with an error.
The effect of this option might be extended to make other sandbox
setup operations non-fatal in future releases of bubblewrap.

to give us space to make more operations fail open if we find that it's desirable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in the latest version.

The effect of this option might be extended to make other sandbox
setup operations non-fatal in future releases of bubblewrap.
</para>
<para>
This option is intended for callers such as
<application>xdg-dbus-proxy</application> or Steam that use
<command>bwrap</command> to adjust the filesystem layout for a
process, but do not rely on it to create a security boundary.
</para>
<para>
Other operations that are fundamental to establishing the sandbox
(creating namespaces, <function>pivot_root</function>,
dropping capabilities) will still cause a hard failure
regardless of this option.
</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

Expand Down
9 changes: 9 additions & 0 deletions tests/test-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -689,4 +689,13 @@ else
fi
fi

# Smoke-test --not-a-security-boundary
#
# Setting up an unavailable automount and triggering the right conditions is
# complicated to do here, but we can at least check that the option is there,
# and that it stays there.

$RUN --not-a-security-boundary true
ok "Accepts --not-a-security-boundary"

done_testing
Loading