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
52 changes: 52 additions & 0 deletions bubblewrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@
#include <sys/signalfd.h>
#include <sys/capability.h>
#include <sys/prctl.h>
#include <sys/syscall.h>
#include <linux/sched.h>
#include <linux/seccomp.h>
#include <linux/filter.h>

#ifdef HAVE_LANDLOCK_H
#include <linux/landlock.h>
Copy link
Collaborator

Choose a reason for hiding this comment

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

What kernel/glibc versions, if any, guarantee to have this header?

The build system should probably check for this header with cc.check_header('linux/landlock.h') and define HAVE_LANDLOCK_H, so that this can become

Suggested change
#include <linux/landlock.h>
#ifdef HAVE_LANDLOCK_H
#include <linux/landlock.h>
#endif

and then the use of Landlock features in the code can be something like (pseudocode)

if (opt_scope_abs_unix_sockets)
  {
#ifdef HAVE_LANDLOCK_H
    do Landlock things;
#else
    die ("Landlock not available at compile time, cannot implement --scope-abstract-unix-sockets");
#endif
  }

Copy link
Author

Choose a reason for hiding this comment

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

Not sure about the exact version, but the header was introduced by Linux in cb2c7d1a1776057c9a1f48ed1250d85e94d4850d on Thu Apr 22 17:41:17 2021. Regardless, I also agree that we should have this as a check and guard it, so I'll wire that up.

#endif

#include "utils.h"
#include "network.h"
#include "bind-mount.h"
Expand Down Expand Up @@ -92,6 +97,7 @@ static int opt_userns_fd = -1;
static int opt_userns2_fd = -1;
static int opt_pidns_fd = -1;
static int opt_tmp_overlay_count = 0;
static bool opt_scope_abstract_unix_sockets = false;
static int next_perms = -1;
static size_t next_size_arg = 0;
static int next_overlay_src_count = 0;
Expand Down Expand Up @@ -373,6 +379,7 @@ 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"
" --scope-abstract-af-unix Scope access to abstract unix sockets to within in the sandbox\n"
);
exit (ecode);
}
Expand Down Expand Up @@ -2736,6 +2743,10 @@ parse_args_recurse (int *argcp,
argv += 2;
argc -= 2;
}
else if (strcmp (arg, "--scope-abstract-af-unix") == 0)
{
opt_scope_abstract_unix_sockets = true;
}
else if (strcmp (arg, "--") == 0)
{
argv += 1;
Expand Down Expand Up @@ -2867,6 +2878,26 @@ namespace_ids_write (int fd,
}
}

#ifdef HAVE_LANDLOCK_H
#ifndef landlock_create_ruleset
static inline int
landlock_create_ruleset (const struct landlock_ruleset_attr *attr,
size_t size,
uint32_t flags)
{
return syscall (SYS_landlock_create_ruleset, attr, size, flags);
}
#endif

#ifndef landlock_restrict_self
static inline int
landlock_restrict_self (int ruleset_fd, uint32_t flags)
{
return syscall (SYS_landlock_restrict_self, ruleset_fd, flags);
}
#endif
#endif

int
main (int argc,
char **argv)
Expand Down Expand Up @@ -3491,6 +3522,27 @@ main (int argc,
die ("creation of new user namespaces was not disabled as requested");
}

if (opt_scope_abstract_unix_sockets)
{
#ifdef HAVE_LANDLOCK_H
static const struct landlock_ruleset_attr ruleset_attr = {
.scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET
};
const int abi = landlock_create_ruleset (NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
if (abi < 0)
die_with_error ("failed to check Landlock compatibility");
if (abi < 6)
die ("supported kernel Landlock ABI too old, version 6 or above required");
const int ruleset_fd = landlock_create_ruleset (&ruleset_attr, sizeof (ruleset_attr), 0);
if (ruleset_fd < 0)
die_with_error ("failed to create Landlock ruleset");
if (landlock_restrict_self (ruleset_fd, 0) < 0)
die_with_error ("failed to enforce Landlock ruleset");
#else
die ("Landlock not available at compile time, cannot implement --scope-abstract-af-unix");
#endif
}

/* All privileged ops are done now, so drop caps we don't need */
drop_privs (!is_privileged, true);

Expand Down
11 changes: 11 additions & 0 deletions bwrap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,17 @@
command line. Please be careful to the order they are specified.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--scope-abstract-af-unix</option></term>
<listitem><para>
Scope access to abstract unix sockets. This option will prevent the newly
created sandbox from talking to any abstract unix sockets, including in the
current net namespace (i.e. in the absence of <option>--unshare-net</option>).

This has the same behaviour as LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET: see
<citerefentry><refentrytitle>landlock</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details.
</para></listitem>
</varlistentry>
</variablelist>
</refsect1>

Expand Down
1 change: 1 addition & 0 deletions completions/bash/bwrap
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ _bwrap() {
--disable-userns
--help
--new-session
--scope-abstract-af-unix
--unshare-all
--unshare-cgroup
--unshare-cgroup-try
Expand Down
1 change: 1 addition & 0 deletions completions/zsh/_bwrap
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ _bwrap_args=(
'--remount-ro[Remount DEST as readonly; does not recursively remount]:mount point to remount read-only:_files'
'--ro-bind-try[Equal to --ro-bind but ignores non-existent SRC]:source:_files:destination:_files'
'--ro-bind[Bind mount the host path SRC readonly on DEST]:source:_files:destination:_files'
'--scope-abstract-af-unix[Scope access to abstract unix sockets to within in the sandbox]'
'--seccomp[Load and use seccomp rules from FD]: :_guard "[0-9]#" "file descriptor to read seccomp rules from"'
'--setenv[Set an environment variable]:variable to set:_parameters -g "*export*":value of variable: :'
'--size[Set size in bytes for next action argument]: :->after_size'
Expand Down
4 changes: 4 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ if (
], language : 'c')
endif

if cc.check_header('linux/landlock.h')
add_project_arguments('-DHAVE_LANDLOCK_H', language : 'c')
endif

bash = find_program('bash', required : false)

if get_option('python') == ''
Expand Down