summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-11-23 01:09:14 +0100
committerLennart Poettering <lennart@poettering.net>2016-12-14 00:42:01 +0100
commitcfbeb4ef8d836ad33572527b63eea383101d9aba (patch)
tree0c95e618b807127057ca3cfa47485be60d116119
parentddbe041277a2b363364304ba03884e8458a882ca (diff)
namespace: add explicit read-only flag
This reworks handling of the read-only management for mount points. This will become handy as soon as we add arbitrary bind mount support (which comes in a later commit).
-rw-r--r--src/core/namespace.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/src/core/namespace.c b/src/core/namespace.c
index ee705af6b8..e9702ae448 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -59,9 +59,10 @@ typedef enum MountMode {
typedef struct BindMount {
const char *path_const; /* Memory allocated on stack or static */
- MountMode mode:6;
+ 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;
@@ -159,6 +160,12 @@ 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) {
+ assert(p);
+
+ return p->read_only || IN_SET(p->mode, READONLY, INACCESSIBLE);
+}
+
static int append_access_mounts(BindMount **p, char **strv, MountMode mode) {
char **i;
@@ -314,6 +321,7 @@ static void drop_duplicates(BindMount *m, unsigned *n) {
* 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 */
f->path_malloc = mfree(f->path_malloc);
continue;
}
@@ -634,7 +642,7 @@ static int make_read_only(BindMount *m, char **blacklist) {
assert(m);
- if (IN_SET(m->mode, INACCESSIBLE, READONLY))
+ if (bind_mount_read_only(m))
r = bind_remount_recursive(bind_mount_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)
@@ -749,12 +757,13 @@ int setup_namespace(
if (mount_flags == 0)
mount_flags = MS_SHARED;
- n_mounts = namespace_calculate_mounts(ns_info,
- read_write_paths,
- read_only_paths,
- inaccessible_paths,
- tmp_dir, var_tmp_dir,
- protect_home, protect_system);
+ n_mounts = namespace_calculate_mounts(
+ ns_info,
+ read_write_paths,
+ read_only_paths,
+ inaccessible_paths,
+ tmp_dir, var_tmp_dir,
+ protect_home, protect_system);
/* Set mount slave mode */
if (root_directory || n_mounts > 0)