summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2014-06-04 18:07:55 +0200
committerLennart Poettering <lennart@poettering.net>2014-06-04 18:12:55 +0200
commit1b8689f94983b47bf190e77ddb03a8fc6af15fb3 (patch)
tree7bb1324b3b882adaa0b8bf786f8848ccec156a94 /src
parent4c02dd7153f970244950b5e00f7bdfea8d2ff0be (diff)
core: rename ReadOnlySystem= to ProtectSystem= and add a third value for also mounting /etc read-only
Also, rename ProtectedHome= to ProtectHome=, to simplify things a bit. With this in place we now have two neat options ProtectSystem= and ProtectHome= for protecting the OS itself (and optionally its configuration), and for protecting the user's data.
Diffstat (limited to 'src')
-rw-r--r--src/core/dbus-execute.c7
-rw-r--r--src/core/execute.c16
-rw-r--r--src/core/execute.h4
-rw-r--r--src/core/load-fragment-gperf.gperf.m44
-rw-r--r--src/core/load-fragment.c57
-rw-r--r--src/core/load-fragment.h3
-rw-r--r--src/core/namespace.c35
-rw-r--r--src/core/namespace.h33
-rw-r--r--src/test/test-ns.c4
9 files changed, 114 insertions, 49 deletions
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
index 2aa08c1435..cb9a077d0e 100644
--- a/src/core/dbus-execute.c
+++ b/src/core/dbus-execute.c
@@ -45,7 +45,8 @@ BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutp
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
-static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protected_home, protected_home, ProtectedHome);
+static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_home, protect_home, ProtectHome);
+static BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_protect_system, protect_system, ProtectSystem);
static int property_get_environment_files(
sd_bus *bus,
@@ -629,8 +630,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ProtectedHome", "s", bus_property_get_protected_home, offsetof(ExecContext, protected_home), SD_BUS_VTABLE_PROPERTY_CONST),
- SD_BUS_PROPERTY("ReadOnlySystem", "b", bus_property_get_bool, offsetof(ExecContext, read_only_system), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("ProtectHome", "s", bus_property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
+ SD_BUS_PROPERTY("ProtectSystem", "s", bus_property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
diff --git a/src/core/execute.c b/src/core/execute.c
index ce8b9bcb8b..78fb81f726 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -1570,8 +1570,8 @@ int exec_spawn(ExecCommand *command,
context->mount_flags != 0 ||
(context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir)) ||
context->private_devices ||
- context->read_only_system ||
- context->protected_home != PROTECTED_HOME_NO) {
+ context->protect_system != PROTECT_SYSTEM_NO ||
+ context->protect_home != PROTECT_HOME_NO) {
char *tmp = NULL, *var = NULL;
@@ -1595,8 +1595,8 @@ int exec_spawn(ExecCommand *command,
tmp,
var,
context->private_devices,
- context->protected_home,
- context->read_only_system,
+ context->protect_home,
+ context->protect_system,
context->mount_flags);
if (err < 0) {
r = EXIT_NAMESPACE;
@@ -2114,8 +2114,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
"%sPrivateTmp: %s\n"
"%sPrivateNetwork: %s\n"
"%sPrivateDevices: %s\n"
- "%sProtectedHome: %s\n"
- "%sReadOnlySystem: %s\n"
+ "%sProtectHome: %s\n"
+ "%sProtectSystem: %s\n"
"%sIgnoreSIGPIPE: %s\n",
prefix, c->umask,
prefix, c->working_directory ? c->working_directory : "/",
@@ -2124,8 +2124,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
prefix, yes_no(c->private_tmp),
prefix, yes_no(c->private_network),
prefix, yes_no(c->private_devices),
- prefix, protected_home_to_string(c->protected_home),
- prefix, yes_no(c->read_only_system),
+ prefix, protect_home_to_string(c->protect_home),
+ prefix, protect_system_to_string(c->protect_system),
prefix, yes_no(c->ignore_sigpipe));
STRV_FOREACH(e, c->environment)
diff --git a/src/core/execute.h b/src/core/execute.h
index 3d6f77c8ef..9d05d3a9de 100644
--- a/src/core/execute.h
+++ b/src/core/execute.h
@@ -157,8 +157,8 @@ struct ExecContext {
bool private_tmp;
bool private_network;
bool private_devices;
- bool read_only_system;
- ProtectedHome protected_home;
+ ProtectSystem protect_system;
+ ProtectHome protect_home;
bool no_new_privileges;
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index 95f59f55d9..089c32a81e 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -80,8 +80,8 @@ $1.InaccessibleDirectories, config_parse_namespace_path_strv, 0,
$1.PrivateTmp, config_parse_bool, 0, offsetof($1, exec_context.private_tmp)
$1.PrivateNetwork, config_parse_bool, 0, offsetof($1, exec_context.private_network)
$1.PrivateDevices, config_parse_bool, 0, offsetof($1, exec_context.private_devices)
-$1.ReadOnlySystem, config_parse_bool, 0, offsetof($1, exec_context.read_only_system)
-$1.ProtectedHome, config_parse_protected_home, 0, offsetof($1, exec_context)
+$1.ProtectSystem, config_parse_protect_system, 0, offsetof($1, exec_context.protect_system)
+$1.ProtectHome, config_parse_protect_home, 0, offsetof($1, exec_context.protect_home)
$1.MountFlags, config_parse_exec_mount_flags, 0, offsetof($1, exec_context)
$1.Personality, config_parse_personality, 0, offsetof($1, exec_context.personality)
$1.RuntimeDirectoryMode, config_parse_mode, 0, offsetof($1, exec_context.runtime_directory_mode)
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index 64d4c2f639..54d3af1a99 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -3101,7 +3101,7 @@ int config_parse_no_new_privileges(
return 0;
}
-int config_parse_protected_home(
+int config_parse_protect_home(
const char* unit,
const char *filename,
unsigned line,
@@ -3126,19 +3126,62 @@ int config_parse_protected_home(
k = parse_boolean(rvalue);
if (k > 0)
- c->protected_home = PROTECTED_HOME_YES;
+ c->protect_home = PROTECT_HOME_YES;
else if (k == 0)
- c->protected_home = PROTECTED_HOME_NO;
+ c->protect_home = PROTECT_HOME_NO;
else {
- ProtectedHome h;
+ ProtectHome h;
- h = protected_home_from_string(rvalue);
+ h = protect_home_from_string(rvalue);
if (h < 0){
- log_syntax(unit, LOG_ERR, filename, line, -h, "Failed to parse protected home value, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, -h, "Failed to parse protect home value, ignoring: %s", rvalue);
return 0;
}
- c->protected_home = h;
+ c->protect_home = h;
+ }
+
+ return 0;
+}
+
+int config_parse_protect_system(
+ const char* unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ ExecContext *c = data;
+ int k;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ /* Our enum shall be a superset of booleans, hence first try
+ * to parse as as boolean, and then as enum */
+
+ k = parse_boolean(rvalue);
+ if (k > 0)
+ c->protect_system = PROTECT_SYSTEM_YES;
+ else if (k == 0)
+ c->protect_system = PROTECT_SYSTEM_NO;
+ else {
+ ProtectSystem s;
+
+ s = protect_system_from_string(rvalue);
+ if (s < 0){
+ log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse protect system value, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ c->protect_system = s;
}
return 0;
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 9e4494cf98..1c21c466d2 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -98,7 +98,8 @@ int config_parse_set_status(const char *unit, const char *filename, unsigned lin
int config_parse_namespace_path_strv(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_no_new_privileges(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_cpu_quota(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
-int config_parse_protected_home(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_protect_home(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_protect_system(const char* unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
/* gperf prototypes */
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 1f987a4b9d..080c086fd4 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -337,8 +337,8 @@ int setup_namespace(
char* tmp_dir,
char* var_tmp_dir,
bool private_dev,
- ProtectedHome protected_home,
- bool read_only_system,
+ ProtectHome protect_home,
+ ProtectSystem protect_system,
unsigned mount_flags) {
BindMount *m, *mounts = NULL;
@@ -356,8 +356,9 @@ int setup_namespace(
strv_length(read_only_dirs) +
strv_length(inaccessible_dirs) +
private_dev +
- (protected_home != PROTECTED_HOME_NO ? 2 : 0) +
- (read_only_system ? 2 : 0);
+ (protect_home != PROTECT_HOME_NO ? 2 : 0) +
+ (protect_system != PROTECT_SYSTEM_NO ? 2 : 0) +
+ (protect_system == PROTECT_SYSTEM_FULL ? 1 : 0);
if (n > 0) {
m = mounts = (BindMount *) alloca(n * sizeof(BindMount));
@@ -391,14 +392,14 @@ int setup_namespace(
m++;
}
- if (protected_home != PROTECTED_HOME_NO) {
- r = append_mounts(&m, STRV_MAKE("-/home", "-/run/user"), protected_home == PROTECTED_HOME_READ_ONLY ? READONLY : INACCESSIBLE);
+ if (protect_home != PROTECT_HOME_NO) {
+ r = append_mounts(&m, STRV_MAKE("-/home", "-/run/user"), protect_home == PROTECT_HOME_READ_ONLY ? READONLY : INACCESSIBLE);
if (r < 0)
return r;
}
- if (read_only_system) {
- r = append_mounts(&m, STRV_MAKE("/usr", "-/boot"), READONLY);
+ if (protect_system != PROTECT_SYSTEM_NO) {
+ r = append_mounts(&m, protect_system == PROTECT_SYSTEM_FULL ? STRV_MAKE("/usr", "/etc", "-/boot") : STRV_MAKE("/usr", "-/boot"), READONLY);
if (r < 0)
return r;
}
@@ -604,10 +605,18 @@ fail:
return r;
}
-static const char *const protected_home_table[_PROTECTED_HOME_MAX] = {
- [PROTECTED_HOME_NO] = "no",
- [PROTECTED_HOME_YES] = "yes",
- [PROTECTED_HOME_READ_ONLY] = "read-only",
+static const char *const protect_home_table[_PROTECT_HOME_MAX] = {
+ [PROTECT_HOME_NO] = "no",
+ [PROTECT_HOME_YES] = "yes",
+ [PROTECT_HOME_READ_ONLY] = "read-only",
};
-DEFINE_STRING_TABLE_LOOKUP(protected_home, ProtectedHome);
+DEFINE_STRING_TABLE_LOOKUP(protect_home, ProtectHome);
+
+static const char *const protect_system_table[_PROTECT_SYSTEM_MAX] = {
+ [PROTECT_SYSTEM_NO] = "no",
+ [PROTECT_SYSTEM_YES] = "yes",
+ [PROTECT_SYSTEM_FULL] = "full",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(protect_system, ProtectSystem);
diff --git a/src/core/namespace.h b/src/core/namespace.h
index b985bdf512..9343fe3264 100644
--- a/src/core/namespace.h
+++ b/src/core/namespace.h
@@ -25,13 +25,21 @@
#include "macro.h"
-typedef enum ProtectedHome {
- PROTECTED_HOME_NO,
- PROTECTED_HOME_YES,
- PROTECTED_HOME_READ_ONLY,
- _PROTECTED_HOME_MAX,
- _PROTECTED_HOME_INVALID = -1
-} ProtectedHome;
+typedef enum ProtectHome {
+ PROTECT_HOME_NO,
+ PROTECT_HOME_YES,
+ PROTECT_HOME_READ_ONLY,
+ _PROTECT_HOME_MAX,
+ _PROTECT_HOME_INVALID = -1
+} ProtectHome;
+
+typedef enum ProtectSystem {
+ PROTECT_SYSTEM_NO,
+ PROTECT_SYSTEM_YES,
+ PROTECT_SYSTEM_FULL,
+ _PROTECT_SYSTEM_MAX,
+ _PROTECT_SYSTEM_INVALID = -1
+} ProtectSystem;
int setup_namespace(char **read_write_dirs,
char **read_only_dirs,
@@ -39,8 +47,8 @@ int setup_namespace(char **read_write_dirs,
char *tmp_dir,
char *var_tmp_dir,
bool private_dev,
- ProtectedHome protected_home,
- bool read_only_system,
+ ProtectHome protect_home,
+ ProtectSystem protect_system,
unsigned mount_flags);
int setup_tmp_dirs(const char *id,
@@ -49,5 +57,8 @@ int setup_tmp_dirs(const char *id,
int setup_netns(int netns_storage_socket[2]);
-const char* protected_home_to_string(ProtectedHome p) _const_;
-ProtectedHome protected_home_from_string(const char *s) _pure_;
+const char* protect_home_to_string(ProtectHome p) _const_;
+ProtectHome protect_home_from_string(const char *s) _pure_;
+
+const char* protect_system_to_string(ProtectSystem p) _const_;
+ProtectSystem protect_system_from_string(const char *s) _pure_;
diff --git a/src/test/test-ns.c b/src/test/test-ns.c
index 71581934cb..acad725899 100644
--- a/src/test/test-ns.c
+++ b/src/test/test-ns.c
@@ -60,8 +60,8 @@ int main(int argc, char *argv[]) {
tmp_dir,
var_tmp_dir,
true,
- PROTECTED_HOME_NO,
- false,
+ PROTECT_HOME_NO,
+ PROTECT_SYSTEM_NO,
0);
if (r < 0) {
log_error("Failed to setup namespace: %s", strerror(-r));