summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-08-25 11:29:32 +0200
committerDjalal Harouni <tixxdz@opendz.org>2016-09-25 10:19:15 +0200
commit7648a565d14dfb5516d93bacf0d87de2de5b5d91 (patch)
tree58cf6af5fe6dcba5bfcd2a6a305104d2362a62bb /src/core
parent6ee1a919cf9013a695da2a01ae67327b996a6ef6 (diff)
namespace: when enforcing fs namespace restrictions suppress redundant mounts
If /foo is marked to be read-only, and /foo/bar too, then the latter may be suppressed as it has no effect.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/namespace.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 74201caa10..72f850b2f2 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -161,6 +161,44 @@ static void drop_inaccessible(BindMount *m, unsigned *n) {
*n = t - m;
}
+static void drop_nop(BindMount *m, unsigned *n) {
+ BindMount *f, *t;
+
+ assert(m);
+ assert(n);
+
+ /* Drops all entries which have an immediate parent that has the same type, as they are redundant. Assumes the
+ * list is ordered by prefixes. */
+
+ for (f = m, t = m; f < m+*n; f++) {
+
+ /* Only suppress such subtrees for READONLY and READWRITE entries */
+ if (IN_SET(f->mode, READONLY, READWRITE)) {
+ BindMount *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(f->path, p->path)) {
+ found = true;
+ break;
+ }
+ }
+
+ /* 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", f->path, p->path);
+ continue;
+ }
+ }
+
+ *t = *f;
+ t++;
+ }
+
+ *n = t - m;
+}
+
static int mount_dev(BindMount *m) {
static const char devnodes[] =
"/dev/null\0"
@@ -515,6 +553,7 @@ int setup_namespace(
drop_duplicates(mounts, &n);
drop_inaccessible(mounts, &n);
+ drop_nop(mounts, &n);
}
if (n > 0 || root_directory) {