summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/namespace.c75
1 files changed, 53 insertions, 22 deletions
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 985e343096..43a2f4ba6e 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -97,6 +97,23 @@ static const TargetMount protect_kernel_tunables_table[] = {
{ "/sys/fs/cgroup", READWRITE, false }, /* READONLY is set by ProtectControlGroups= option */
};
+/*
+ * ProtectHome=read-only table, protect $HOME and $XDG_RUNTIME_DIR and rest of
+ * system should be protected by ProtectSystem=
+ */
+static const TargetMount protect_home_read_only_table[] = {
+ { "/home", READONLY, true },
+ { "/run/user", READONLY, true },
+ { "/root", READONLY, true },
+};
+
+/* ProtectHome=yes table */
+static const TargetMount protect_home_yes_table[] = {
+ { "/home", INACCESSIBLE, true },
+ { "/run/user", INACCESSIBLE, true },
+ { "/root", INACCESSIBLE, true },
+};
+
/* ProtectSystem=yes table */
static const TargetMount protect_system_yes_table[] = {
{ "/usr", READONLY, false },
@@ -190,6 +207,31 @@ static int append_protect_kernel_tunables(BindMount **p, const char *root_direct
ELEMENTSOF(protect_kernel_tunables_table));
}
+static int append_protect_home(BindMount **p, const char *root_directory, ProtectHome protect_home) {
+ int r = 0;
+
+ assert(p);
+
+ if (protect_home == PROTECT_HOME_NO)
+ return 0;
+
+ switch (protect_home) {
+ case PROTECT_HOME_READ_ONLY:
+ r = append_target_mounts(p, root_directory, protect_home_read_only_table,
+ ELEMENTSOF(protect_home_read_only_table));
+ break;
+ case PROTECT_HOME_YES:
+ r = append_target_mounts(p, root_directory, protect_home_yes_table,
+ ELEMENTSOF(protect_home_yes_table));
+ break;
+ default:
+ r = -EINVAL;
+ break;
+ }
+
+ return r;
+}
+
static int append_protect_system(BindMount **p, const char *root_directory, ProtectSystem protect_system) {
int r = 0;
@@ -629,6 +671,7 @@ static unsigned namespace_calculate_mounts(
ProtectHome protect_home,
ProtectSystem protect_system) {
+ unsigned protect_home_cnt;
unsigned protect_system_cnt =
(protect_system == PROTECT_SYSTEM_STRICT ?
ELEMENTSOF(protect_system_strict_table) :
@@ -637,6 +680,12 @@ static unsigned namespace_calculate_mounts(
((protect_system == PROTECT_SYSTEM_YES) ?
ELEMENTSOF(protect_system_yes_table) : 0)));
+ protect_home_cnt =
+ (protect_home == PROTECT_HOME_YES ?
+ ELEMENTSOF(protect_home_yes_table) :
+ ((protect_home == PROTECT_HOME_READ_ONLY) ?
+ ELEMENTSOF(protect_home_read_only_table) : 0));
+
return !!tmp_dir + !!var_tmp_dir +
strv_length(read_write_paths) +
strv_length(read_only_paths) +
@@ -644,8 +693,7 @@ static unsigned namespace_calculate_mounts(
private_dev +
(protect_sysctl ? ELEMENTSOF(protect_kernel_tunables_table) : 0) +
(protect_cgroups ? 1 : 0) +
- (protect_home != PROTECT_HOME_NO || protect_system == PROTECT_SYSTEM_STRICT ? 3 : 0) +
- protect_system_cnt;
+ protect_home_cnt + protect_system_cnt;
}
int setup_namespace(
@@ -723,26 +771,9 @@ int setup_namespace(
m++;
}
- if (protect_home != PROTECT_HOME_NO || protect_system == PROTECT_SYSTEM_STRICT) {
- const char *home_dir, *run_user_dir, *root_dir;
-
- /* If protection of $HOME and $XDG_RUNTIME_DIR is requested, then go for it. If we are in
- * strict system protection mode, then also add entries for these directories, but mark them
- * writable. This is because we want ProtectHome= and ProtectSystem= to be fully orthogonal. */
-
- home_dir = prefix_roota(root_directory, "/home");
- home_dir = strjoina("-", home_dir);
- run_user_dir = prefix_roota(root_directory, "/run/user");
- run_user_dir = strjoina("-", run_user_dir);
- root_dir = prefix_roota(root_directory, "/root");
- root_dir = strjoina("-", root_dir);
-
- r = append_mounts(&m, STRV_MAKE(home_dir, run_user_dir, root_dir),
- protect_home == PROTECT_HOME_READ_ONLY ? READONLY :
- protect_home == PROTECT_HOME_YES ? INACCESSIBLE : READWRITE);
- if (r < 0)
- return r;
- }
+ r = append_protect_home(&m, root_directory, protect_home);
+ if (r < 0)
+ return r;
r = append_protect_system(&m, root_directory, protect_system);
if (r < 0)