diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-08-25 11:29:32 +0200 |
---|---|---|
committer | Djalal Harouni <tixxdz@opendz.org> | 2016-09-25 10:19:15 +0200 |
commit | 7648a565d14dfb5516d93bacf0d87de2de5b5d91 (patch) | |
tree | 58cf6af5fe6dcba5bfcd2a6a305104d2362a62bb /src | |
parent | 6ee1a919cf9013a695da2a01ae67327b996a6ef6 (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')
-rw-r--r-- | src/core/namespace.c | 39 |
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) { |