Zbigniew Jędrzejewski-Szmek 03e93e
From 6075c25fa4c1411b072955445f0f4a2418f54b0c Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 03e93e
From: Djalal Harouni <tixxdz@opendz.org>
Zbigniew Jędrzejewski-Szmek 03e93e
Date: Thu, 10 Nov 2016 18:11:37 +0100
Zbigniew Jędrzejewski-Szmek 03e93e
Subject: [PATCH] core:namespace: count and free failed paths inside
Zbigniew Jędrzejewski-Szmek 03e93e
 chase_all_symlinks() (#4619)
Zbigniew Jędrzejewski-Szmek 03e93e
Zbigniew Jędrzejewski-Szmek 03e93e
This certainly fixes a bug that was introduced by PR
Zbigniew Jędrzejewski-Szmek 03e93e
https://github.com/systemd/systemd/pull/4594 that intended to fix
Zbigniew Jędrzejewski-Szmek 03e93e
https://github.com/systemd/systemd/issues/4567.
Zbigniew Jędrzejewski-Szmek 03e93e
Zbigniew Jędrzejewski-Szmek 03e93e
The fix was not complete. This patch makes sure that we count and free
Zbigniew Jędrzejewski-Szmek 03e93e
all paths that fail inside chase_all_symlinks().
Zbigniew Jędrzejewski-Szmek 03e93e
Zbigniew Jędrzejewski-Szmek 03e93e
Fixes https://github.com/systemd/systemd/issues/4567
Zbigniew Jędrzejewski-Szmek 03e93e
(cherry picked from commit 1d54cd5d255065c8659ca68d2591e810e6104714)
Zbigniew Jędrzejewski-Szmek 03e93e
---
Zbigniew Jędrzejewski-Szmek 03e93e
 src/core/namespace.c | 32 ++++++++++++++++++--------------
Zbigniew Jędrzejewski-Szmek 03e93e
 1 file changed, 18 insertions(+), 14 deletions(-)
Zbigniew Jędrzejewski-Szmek 03e93e
Zbigniew Jędrzejewski-Szmek 03e93e
diff --git a/src/core/namespace.c b/src/core/namespace.c
Zbigniew Jędrzejewski-Szmek 03e93e
index b18fcf3e29..49a50c7b61 100644
Zbigniew Jędrzejewski-Szmek 03e93e
--- a/src/core/namespace.c
Zbigniew Jędrzejewski-Szmek 03e93e
+++ b/src/core/namespace.c
Zbigniew Jędrzejewski-Szmek 03e93e
@@ -322,7 +322,7 @@ static void drop_duplicates(BindMount *m, unsigned *n) {
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
         /* Drops duplicate entries. Expects that the array is properly ordered already. */
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
-        for (f = m, t = m, previous = NULL; f < m+*n; f++) {
Zbigniew Jędrzejewski-Szmek 03e93e
+        for (f = m, t = m, previous = NULL; f < m + *n; f++) {
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
                 /* The first one wins (which is the one with the more restrictive mode), see mount_path_compare()
Zbigniew Jędrzejewski-Szmek 03e93e
                  * above. */
Zbigniew Jędrzejewski-Szmek 03e93e
@@ -350,7 +350,7 @@ static void drop_inaccessible(BindMount *m, unsigned *n) {
Zbigniew Jędrzejewski-Szmek 03e93e
         /* Drops all entries obstructed by another entry further up the tree. Expects that the array is properly
Zbigniew Jędrzejewski-Szmek 03e93e
          * ordered already. */
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
-        for (f = m, t = m; f < m+*n; f++) {
Zbigniew Jędrzejewski-Szmek 03e93e
+        for (f = m, t = m; f < m + *n; f++) {
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
                 /* If we found a path set for INACCESSIBLE earlier, and this entry has it as prefix we should drop
Zbigniew Jędrzejewski-Szmek 03e93e
                  * it, as inaccessible paths really should drop the entire subtree. */
Zbigniew Jędrzejewski-Szmek 03e93e
@@ -378,7 +378,7 @@ static void drop_nop(BindMount *m, unsigned *n) {
Zbigniew Jędrzejewski-Szmek 03e93e
         /* Drops all entries which have an immediate parent that has the same type, as they are redundant. Assumes the
Zbigniew Jędrzejewski-Szmek 03e93e
          * list is ordered by prefixes. */
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
-        for (f = m, t = m; f < m+*n; f++) {
Zbigniew Jędrzejewski-Szmek 03e93e
+        for (f = m, t = m; f < m + *n; f++) {
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
                 /* Only suppress such subtrees for READONLY and READWRITE entries */
Zbigniew Jędrzejewski-Szmek 03e93e
                 if (IN_SET(f->mode, READONLY, READWRITE)) {
Zbigniew Jędrzejewski-Szmek 03e93e
@@ -414,12 +414,13 @@ static void drop_outside_root(const char *root_directory, BindMount *m, unsigned
Zbigniew Jędrzejewski-Szmek 03e93e
         assert(m);
Zbigniew Jędrzejewski-Szmek 03e93e
         assert(n);
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
+        /* Nothing to do */
Zbigniew Jędrzejewski-Szmek 03e93e
         if (!root_directory)
Zbigniew Jędrzejewski-Szmek 03e93e
                 return;
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
         /* Drops all mounts that are outside of the root directory. */
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
-        for (f = m, t = m; f < m+*n; f++) {
Zbigniew Jędrzejewski-Szmek 03e93e
+        for (f = m, t = m; f < m + *n; f++) {
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
                 if (!path_startswith(f->path, root_directory)) {
Zbigniew Jędrzejewski-Szmek 03e93e
                         log_debug("%s is outside of root directory.", f->path);
Zbigniew Jędrzejewski-Szmek 03e93e
@@ -663,9 +664,10 @@ static int make_read_only(BindMount *m, char **blacklist) {
Zbigniew Jędrzejewski-Szmek 03e93e
         return r;
Zbigniew Jędrzejewski-Szmek 03e93e
 }
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
+/* Chase symlinks and remove failed paths from mounts */
Zbigniew Jędrzejewski-Szmek 03e93e
 static int chase_all_symlinks(const char *root_directory, BindMount *m, unsigned *n) {
Zbigniew Jędrzejewski-Szmek 03e93e
         BindMount *f, *t;
Zbigniew Jędrzejewski-Szmek 03e93e
-        int r;
Zbigniew Jędrzejewski-Szmek 03e93e
+        int r = 0;
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
         assert(m);
Zbigniew Jędrzejewski-Szmek 03e93e
         assert(n);
Zbigniew Jędrzejewski-Szmek 03e93e
@@ -675,22 +677,24 @@ static int chase_all_symlinks(const char *root_directory, BindMount *m, unsigned
Zbigniew Jędrzejewski-Szmek 03e93e
          * can't resolve the path, and which have been marked for such removal. */
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
         for (f = m, t = m; f < m + *n; f++) {
Zbigniew Jędrzejewski-Szmek 03e93e
+                int k;
Zbigniew Jędrzejewski-Szmek 03e93e
                 _cleanup_free_ char *chased = NULL;
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
-                r = chase_symlinks(f->path, root_directory, &chased);
Zbigniew Jędrzejewski-Szmek 03e93e
-                if (r == -ENOENT && f->ignore) {
Zbigniew Jędrzejewski-Szmek 03e93e
-                        /* Doesn't exist? Then remove it! */
Zbigniew Jędrzejewski-Szmek 03e93e
+                k = chase_symlinks(f->path, root_directory, &chased);
Zbigniew Jędrzejewski-Szmek 03e93e
+                if (k < 0) {
Zbigniew Jędrzejewski-Szmek 03e93e
+                        /* Get only real errors */
Zbigniew Jędrzejewski-Szmek 03e93e
+                        if (r >= 0 && (k != -ENOENT || !f->ignore))
Zbigniew Jędrzejewski-Szmek 03e93e
+                                r = k;
Zbigniew Jędrzejewski-Szmek 03e93e
+
Zbigniew Jędrzejewski-Szmek 03e93e
+                        log_debug_errno(r, "Failed to chase symlinks for %s: %m", f->path);
Zbigniew Jędrzejewski-Szmek 03e93e
+                        /* Doesn't exist or failed? Then remove it and continue! */
Zbigniew Jędrzejewski-Szmek 03e93e
                         f->path = mfree(f->path);
Zbigniew Jędrzejewski-Szmek 03e93e
                         continue;
Zbigniew Jędrzejewski-Szmek 03e93e
                 }
Zbigniew Jędrzejewski-Szmek 03e93e
-                if (r < 0)
Zbigniew Jędrzejewski-Szmek 03e93e
-                        return log_debug_errno(r, "Failed to chase symlinks for %s: %m", f->path);
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
                 if (!path_equal(f->path, chased)) {
Zbigniew Jędrzejewski-Szmek 03e93e
                         log_debug("Chased %s → %s", f->path, chased);
Zbigniew Jędrzejewski-Szmek 03e93e
-                        r = free_and_replace(f->path, chased);
Zbigniew Jędrzejewski-Szmek 03e93e
-                        if (r < 0)
Zbigniew Jędrzejewski-Szmek 03e93e
-                                return r;
Zbigniew Jędrzejewski-Szmek 03e93e
+                        free_and_replace(f->path, chased);
Zbigniew Jędrzejewski-Szmek 03e93e
                 }
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
                 *t = *f;
Zbigniew Jędrzejewski-Szmek 03e93e
@@ -698,7 +702,7 @@ static int chase_all_symlinks(const char *root_directory, BindMount *m, unsigned
Zbigniew Jędrzejewski-Szmek 03e93e
         }
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
         *n = t - m;
Zbigniew Jędrzejewski-Szmek 03e93e
-        return 0;
Zbigniew Jędrzejewski-Szmek 03e93e
+        return r;
Zbigniew Jędrzejewski-Szmek 03e93e
 }
Zbigniew Jędrzejewski-Szmek 03e93e
 
Zbigniew Jędrzejewski-Szmek 03e93e
 static unsigned namespace_calculate_mounts(
Zbigniew Jędrzejewski-Szmek 03e93e
-- 
Zbigniew Jędrzejewski-Szmek 03e93e
2.9.3
Zbigniew Jędrzejewski-Szmek 03e93e