summaryrefslogtreecommitdiff
path: root/src/core/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/namespace.c')
-rw-r--r--src/core/namespace.c148
1 files changed, 74 insertions, 74 deletions
diff --git a/src/core/namespace.c b/src/core/namespace.c
index e9702ae448..1b4bcd5ba4 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -57,14 +57,14 @@ typedef enum MountMode {
READWRITE,
} MountMode;
-typedef struct BindMount {
+typedef struct MountEntry {
const char *path_const; /* Memory allocated on stack or static */
MountMode mode:5;
bool ignore:1; /* Ignore if path does not exist? */
bool has_prefix:1; /* Already is prefixed by the root dir? */
bool read_only:1; /* Shall this mount point be read-only? */
char *path_malloc; /* Use this instead of 'path' if we had to allocate memory */
-} BindMount;
+} MountEntry;
/*
* The following Protect tables are to protect paths and mark some of them
@@ -75,7 +75,7 @@ typedef struct BindMount {
*/
/* ProtectKernelTunables= option and the related filesystem APIs */
-static const BindMount protect_kernel_tunables_table[] = {
+static const MountEntry protect_kernel_tunables_table[] = {
{ "/proc/sys", READONLY, false },
{ "/proc/sysrq-trigger", READONLY, true },
{ "/proc/latency_stats", READONLY, true },
@@ -94,7 +94,7 @@ static const BindMount protect_kernel_tunables_table[] = {
};
/* ProtectKernelModules= option */
-static const BindMount protect_kernel_modules_table[] = {
+static const MountEntry protect_kernel_modules_table[] = {
#ifdef HAVE_SPLIT_USR
{ "/lib/modules", INACCESSIBLE, true },
#endif
@@ -105,28 +105,28 @@ static const BindMount protect_kernel_modules_table[] = {
* ProtectHome=read-only table, protect $HOME and $XDG_RUNTIME_DIR and rest of
* system should be protected by ProtectSystem=
*/
-static const BindMount protect_home_read_only_table[] = {
+static const MountEntry protect_home_read_only_table[] = {
{ "/home", READONLY, true },
{ "/run/user", READONLY, true },
{ "/root", READONLY, true },
};
/* ProtectHome=yes table */
-static const BindMount protect_home_yes_table[] = {
+static const MountEntry protect_home_yes_table[] = {
{ "/home", INACCESSIBLE, true },
{ "/run/user", INACCESSIBLE, true },
{ "/root", INACCESSIBLE, true },
};
/* ProtectSystem=yes table */
-static const BindMount protect_system_yes_table[] = {
+static const MountEntry protect_system_yes_table[] = {
{ "/usr", READONLY, false },
{ "/boot", READONLY, true },
{ "/efi", READONLY, true },
};
/* ProtectSystem=full includes ProtectSystem=yes */
-static const BindMount protect_system_full_table[] = {
+static const MountEntry protect_system_full_table[] = {
{ "/usr", READONLY, false },
{ "/boot", READONLY, true },
{ "/efi", READONLY, true },
@@ -141,7 +141,7 @@ static const BindMount protect_system_full_table[] = {
* (And of course /home and friends are also left writable, as ProtectHome=
* shall manage those, orthogonally).
*/
-static const BindMount protect_system_strict_table[] = {
+static const MountEntry protect_system_strict_table[] = {
{ "/", READONLY, false },
{ "/proc", READWRITE, false }, /* ProtectKernelTunables= */
{ "/sys", READWRITE, false }, /* ProtectKernelTunables= */
@@ -151,7 +151,7 @@ static const BindMount protect_system_strict_table[] = {
{ "/root", READWRITE, true }, /* ProtectHome= */
};
-static const char *bind_mount_path(const BindMount *p) {
+static const char *mount_entry_path(const MountEntry *p) {
assert(p);
/* Returns the path of this bind mount. If the malloc()-allocated ->path_buffer field is set we return that,
@@ -160,13 +160,13 @@ static const char *bind_mount_path(const BindMount *p) {
return p->path_malloc ?: p->path_const;
}
-static bool bind_mount_read_only(const BindMount *p) {
+static bool mount_entry_read_only(const MountEntry *p) {
assert(p);
return p->read_only || IN_SET(p->mode, READONLY, INACCESSIBLE);
}
-static int append_access_mounts(BindMount **p, char **strv, MountMode mode) {
+static int append_access_mounts(MountEntry **p, char **strv, MountMode mode) {
char **i;
assert(p);
@@ -190,7 +190,7 @@ static int append_access_mounts(BindMount **p, char **strv, MountMode mode) {
if (!path_is_absolute(e))
return -EINVAL;
- *((*p)++) = (BindMount) {
+ *((*p)++) = (MountEntry) {
.path_const = e,
.mode = mode,
.ignore = ignore,
@@ -201,7 +201,7 @@ static int append_access_mounts(BindMount **p, char **strv, MountMode mode) {
return 0;
}
-static int append_static_mounts(BindMount **p, const BindMount *mounts, unsigned n, bool ignore_protect) {
+static int append_static_mounts(MountEntry **p, const MountEntry *mounts, unsigned n, bool ignore_protect) {
unsigned i;
assert(p);
@@ -210,8 +210,8 @@ static int append_static_mounts(BindMount **p, const BindMount *mounts, unsigned
/* Adds a list of static pre-defined entries */
for (i = 0; i < n; i++)
- *((*p)++) = (BindMount) {
- .path_const = bind_mount_path(mounts+i),
+ *((*p)++) = (MountEntry) {
+ .path_const = mount_entry_path(mounts+i),
.mode = mounts[i].mode,
.ignore = mounts[i].ignore || ignore_protect,
};
@@ -219,7 +219,7 @@ static int append_static_mounts(BindMount **p, const BindMount *mounts, unsigned
return 0;
}
-static int append_protect_home(BindMount **p, ProtectHome protect_home, bool ignore_protect) {
+static int append_protect_home(MountEntry **p, ProtectHome protect_home, bool ignore_protect) {
assert(p);
switch (protect_home) {
@@ -238,7 +238,7 @@ static int append_protect_home(BindMount **p, ProtectHome protect_home, bool ign
}
}
-static int append_protect_system(BindMount **p, ProtectSystem protect_system, bool ignore_protect) {
+static int append_protect_system(MountEntry **p, ProtectSystem protect_system, bool ignore_protect) {
assert(p);
switch (protect_system) {
@@ -261,11 +261,11 @@ static int append_protect_system(BindMount **p, ProtectSystem protect_system, bo
}
static int mount_path_compare(const void *a, const void *b) {
- const BindMount *p = a, *q = b;
+ const MountEntry *p = a, *q = b;
int d;
/* If the paths are not equal, then order prefixes first */
- d = path_compare(bind_mount_path(p), bind_mount_path(q));
+ d = path_compare(mount_entry_path(p), mount_entry_path(q));
if (d != 0)
return d;
@@ -279,7 +279,7 @@ static int mount_path_compare(const void *a, const void *b) {
return 0;
}
-static int prefix_where_needed(BindMount *m, unsigned n, const char *root_directory) {
+static int prefix_where_needed(MountEntry *m, unsigned n, const char *root_directory) {
unsigned i;
/* Prefixes all paths in the bind mount table with the root directory if it is specified and the entry needs
@@ -294,7 +294,7 @@ static int prefix_where_needed(BindMount *m, unsigned n, const char *root_direct
if (m[i].has_prefix)
continue;
- s = prefix_root(root_directory, bind_mount_path(m+i));
+ s = prefix_root(root_directory, mount_entry_path(m+i));
if (!s)
return -ENOMEM;
@@ -307,8 +307,8 @@ static int prefix_where_needed(BindMount *m, unsigned n, const char *root_direct
return 0;
}
-static void drop_duplicates(BindMount *m, unsigned *n) {
- BindMount *f, *t, *previous;
+static void drop_duplicates(MountEntry *m, unsigned *n) {
+ MountEntry *f, *t, *previous;
assert(m);
assert(n);
@@ -319,9 +319,9 @@ static void drop_duplicates(BindMount *m, unsigned *n) {
/* The first one wins (which is the one with the more restrictive mode), see mount_path_compare()
* above. */
- if (previous && path_equal(bind_mount_path(f), bind_mount_path(previous))) {
- log_debug("%s is duplicate.", bind_mount_path(f));
- previous->read_only = previous->read_only || bind_mount_read_only(f); /* Propagate the read-only flag to the remaining entry */
+ if (previous && path_equal(mount_entry_path(f), mount_entry_path(previous))) {
+ log_debug("%s is duplicate.", mount_entry_path(f));
+ previous->read_only = previous->read_only || mount_entry_read_only(f); /* Propagate the read-only flag to the remaining entry */
f->path_malloc = mfree(f->path_malloc);
continue;
}
@@ -334,8 +334,8 @@ static void drop_duplicates(BindMount *m, unsigned *n) {
*n = t - m;
}
-static void drop_inaccessible(BindMount *m, unsigned *n) {
- BindMount *f, *t;
+static void drop_inaccessible(MountEntry *m, unsigned *n) {
+ MountEntry *f, *t;
const char *clear = NULL;
assert(m);
@@ -348,13 +348,13 @@ static void drop_inaccessible(BindMount *m, unsigned *n) {
/* If we found a path set for INACCESSIBLE earlier, and this entry has it as prefix we should drop
* it, as inaccessible paths really should drop the entire subtree. */
- if (clear && path_startswith(bind_mount_path(f), clear)) {
- log_debug("%s is masked by %s.", bind_mount_path(f), clear);
+ if (clear && path_startswith(mount_entry_path(f), clear)) {
+ log_debug("%s is masked by %s.", mount_entry_path(f), clear);
f->path_malloc = mfree(f->path_malloc);
continue;
}
- clear = f->mode == INACCESSIBLE ? bind_mount_path(f) : NULL;
+ clear = f->mode == INACCESSIBLE ? mount_entry_path(f) : NULL;
*t = *f;
t++;
@@ -363,8 +363,8 @@ static void drop_inaccessible(BindMount *m, unsigned *n) {
*n = t - m;
}
-static void drop_nop(BindMount *m, unsigned *n) {
- BindMount *f, *t;
+static void drop_nop(MountEntry *m, unsigned *n) {
+ MountEntry *f, *t;
assert(m);
assert(n);
@@ -376,12 +376,12 @@ static void drop_nop(BindMount *m, unsigned *n) {
/* Only suppress such subtrees for READONLY and READWRITE entries */
if (IN_SET(f->mode, READONLY, READWRITE)) {
- BindMount *p;
+ MountEntry *p;
bool found = false;
/* Now let's find the first parent of the entry we are looking at. */
for (p = t-1; p >= m; p--) {
- if (path_startswith(bind_mount_path(f), bind_mount_path(p))) {
+ if (path_startswith(mount_entry_path(f), mount_entry_path(p))) {
found = true;
break;
}
@@ -389,7 +389,7 @@ static void drop_nop(BindMount *m, unsigned *n) {
/* We found it, let's see if it's the same mode, if so, we can drop this entry */
if (found && p->mode == f->mode) {
- log_debug("%s is redundant by %s", bind_mount_path(f), bind_mount_path(p));
+ log_debug("%s is redundant by %s", mount_entry_path(f), mount_entry_path(p));
f->path_malloc = mfree(f->path_malloc);
continue;
}
@@ -402,8 +402,8 @@ static void drop_nop(BindMount *m, unsigned *n) {
*n = t - m;
}
-static void drop_outside_root(const char *root_directory, BindMount *m, unsigned *n) {
- BindMount *f, *t;
+static void drop_outside_root(const char *root_directory, MountEntry *m, unsigned *n) {
+ MountEntry *f, *t;
assert(m);
assert(n);
@@ -416,8 +416,8 @@ static void drop_outside_root(const char *root_directory, BindMount *m, unsigned
for (f = m, t = m; f < m + *n; f++) {
- if (!path_startswith(bind_mount_path(f), root_directory)) {
- log_debug("%s is outside of root directory.", bind_mount_path(f));
+ if (!path_startswith(mount_entry_path(f), root_directory)) {
+ log_debug("%s is outside of root directory.", mount_entry_path(f));
f->path_malloc = mfree(f->path_malloc);
continue;
}
@@ -429,7 +429,7 @@ static void drop_outside_root(const char *root_directory, BindMount *m, unsigned
*n = t - m;
}
-static int mount_dev(BindMount *m) {
+static int mount_dev(MountEntry *m) {
static const char devnodes[] =
"/dev/null\0"
"/dev/zero\0"
@@ -534,11 +534,11 @@ static int mount_dev(BindMount *m) {
* missing when the service is started with RootDirectory. This is
* consistent with mount units creating the mount points when missing.
*/
- (void) mkdir_p_label(bind_mount_path(m), 0755);
+ (void) mkdir_p_label(mount_entry_path(m), 0755);
/* Unmount everything in old /dev */
- umount_recursive(bind_mount_path(m), 0);
- if (mount(dev, bind_mount_path(m), NULL, MS_MOVE, NULL) < 0) {
+ umount_recursive(mount_entry_path(m), 0);
+ if (mount(dev, mount_entry_path(m), NULL, MS_MOVE, NULL) < 0) {
r = -errno;
goto fail;
}
@@ -569,7 +569,7 @@ fail:
}
static int apply_mount(
- BindMount *m,
+ MountEntry *m,
const char *tmp_dir,
const char *var_tmp_dir) {
@@ -578,7 +578,7 @@ static int apply_mount(
assert(m);
- log_debug("Applying namespace mount on %s", bind_mount_path(m));
+ log_debug("Applying namespace mount on %s", mount_entry_path(m));
switch (m->mode) {
@@ -588,10 +588,10 @@ static int apply_mount(
/* First, get rid of everything that is below if there
* is anything... Then, overmount it with an
* inaccessible path. */
- (void) umount_recursive(bind_mount_path(m), 0);
+ (void) umount_recursive(mount_entry_path(m), 0);
- if (lstat(bind_mount_path(m), &target) < 0)
- return log_debug_errno(errno, "Failed to lstat() %s to determine what to mount over it: %m", bind_mount_path(m));
+ if (lstat(mount_entry_path(m), &target) < 0)
+ return log_debug_errno(errno, "Failed to lstat() %s to determine what to mount over it: %m", mount_entry_path(m));
what = mode_to_inaccessible_node(target.st_mode);
if (!what) {
@@ -604,13 +604,13 @@ static int apply_mount(
case READONLY:
case READWRITE:
- r = path_is_mount_point(bind_mount_path(m), NULL, 0);
+ r = path_is_mount_point(mount_entry_path(m), NULL, 0);
if (r < 0)
- return log_debug_errno(r, "Failed to determine whether %s is already a mount point: %m", bind_mount_path(m));
+ return log_debug_errno(r, "Failed to determine whether %s is already a mount point: %m", mount_entry_path(m));
if (r > 0) /* Nothing to do here, it is already a mount. We just later toggle the MS_RDONLY bit for the mount point if needed. */
return 0;
/* This isn't a mount point yet, let's make it one. */
- what = bind_mount_path(m);
+ what = mount_entry_path(m);
break;
case PRIVATE_TMP:
@@ -630,22 +630,22 @@ static int apply_mount(
assert(what);
- if (mount(what, bind_mount_path(m), NULL, MS_BIND|MS_REC, NULL) < 0)
- return log_debug_errno(errno, "Failed to mount %s to %s: %m", what, bind_mount_path(m));
+ if (mount(what, mount_entry_path(m), NULL, MS_BIND|MS_REC, NULL) < 0)
+ return log_debug_errno(errno, "Failed to mount %s to %s: %m", what, mount_entry_path(m));
- log_debug("Successfully mounted %s to %s", what, bind_mount_path(m));
+ log_debug("Successfully mounted %s to %s", what, mount_entry_path(m));
return 0;
}
-static int make_read_only(BindMount *m, char **blacklist) {
+static int make_read_only(MountEntry *m, char **blacklist) {
int r = 0;
assert(m);
- if (bind_mount_read_only(m))
- r = bind_remount_recursive(bind_mount_path(m), true, blacklist);
+ if (mount_entry_read_only(m))
+ r = bind_remount_recursive(mount_entry_path(m), true, blacklist);
else if (m->mode == PRIVATE_DEV) { /* Can be readonly but the submounts can't*/
- if (mount(NULL, bind_mount_path(m), NULL, MS_REMOUNT|DEV_MOUNT_OPTIONS|MS_RDONLY, NULL) < 0)
+ if (mount(NULL, mount_entry_path(m), NULL, MS_REMOUNT|DEV_MOUNT_OPTIONS|MS_RDONLY, NULL) < 0)
r = -errno;
} else
return 0;
@@ -658,8 +658,8 @@ static int make_read_only(BindMount *m, char **blacklist) {
}
/* Chase symlinks and remove failed paths from mounts */
-static int chase_all_symlinks(const char *root_directory, BindMount *m, unsigned *n) {
- BindMount *f, *t;
+static int chase_all_symlinks(const char *root_directory, MountEntry *m, unsigned *n) {
+ MountEntry *f, *t;
int r = 0;
assert(m);
@@ -673,20 +673,20 @@ static int chase_all_symlinks(const char *root_directory, BindMount *m, unsigned
_cleanup_free_ char *chased = NULL;
int k;
- k = chase_symlinks(bind_mount_path(f), root_directory, 0, &chased);
+ k = chase_symlinks(mount_entry_path(f), root_directory, 0, &chased);
if (k < 0) {
/* Get only real errors */
if (r >= 0 && (k != -ENOENT || !f->ignore))
r = k;
/* Doesn't exist or failed? Then remove it and continue! */
- log_debug_errno(k, "Failed to chase symlinks for %s: %m", bind_mount_path(f));
+ log_debug_errno(k, "Failed to chase symlinks for %s: %m", mount_entry_path(f));
f->path_malloc = mfree(f->path_malloc);
continue;
}
- if (!path_equal(bind_mount_path(f), chased)) {
- log_debug("Chased %s → %s", bind_mount_path(f), chased);
+ if (!path_equal(mount_entry_path(f), chased)) {
+ log_debug("Chased %s → %s", mount_entry_path(f), chased);
free(f->path_malloc);
f->path_malloc = chased;
@@ -749,7 +749,7 @@ int setup_namespace(
ProtectSystem protect_system,
unsigned long mount_flags) {
- BindMount *m, *mounts = NULL;
+ MountEntry *m, *mounts = NULL;
bool make_slave = false;
unsigned n_mounts;
int r = 0;
@@ -770,7 +770,7 @@ int setup_namespace(
make_slave = true;
if (n_mounts > 0) {
- m = mounts = (BindMount *) alloca0(n_mounts * sizeof(BindMount));
+ m = mounts = (MountEntry *) alloca0(n_mounts * sizeof(MountEntry));
r = append_access_mounts(&m, read_write_paths, READWRITE);
if (r < 0)
goto finish;
@@ -784,21 +784,21 @@ int setup_namespace(
goto finish;
if (tmp_dir) {
- *(m++) = (BindMount) {
+ *(m++) = (MountEntry) {
.path_const = "/tmp",
.mode = PRIVATE_TMP,
};
}
if (var_tmp_dir) {
- *(m++) = (BindMount) {
+ *(m++) = (MountEntry) {
.path_const = "/var/tmp",
.mode = PRIVATE_VAR_TMP,
};
}
if (ns_info->private_dev) {
- *(m++) = (BindMount) {
+ *(m++) = (MountEntry) {
.path_const = "/dev",
.mode = PRIVATE_DEV,
};
@@ -817,7 +817,7 @@ int setup_namespace(
}
if (ns_info->protect_control_groups) {
- *(m++) = (BindMount) {
+ *(m++) = (MountEntry) {
.path_const = "/sys/fs/cgroup",
.mode = READONLY,
};
@@ -845,7 +845,7 @@ int setup_namespace(
if (r < 0)
goto finish;
- qsort(mounts, n_mounts, sizeof(BindMount), mount_path_compare);
+ qsort(mounts, n_mounts, sizeof(MountEntry), mount_path_compare);
drop_duplicates(mounts, &n_mounts);
drop_outside_root(root_directory, mounts, &n_mounts);
@@ -894,7 +894,7 @@ int setup_namespace(
/* Create a blacklist we can pass to bind_mount_recursive() */
blacklist = newa(char*, n_mounts+1);
for (j = 0; j < n_mounts; j++)
- blacklist[j] = (char*) bind_mount_path(mounts+j);
+ blacklist[j] = (char*) mount_entry_path(mounts+j);
blacklist[j] = NULL;
/* Second round, flip the ro bits if necessary. */