]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Do not raise in switch root if paths are too long
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 3 Nov 2016 02:05:06 +0000 (22:05 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 3 Nov 2016 02:36:43 +0000 (22:36 -0400)
If we encounter the (unlikely) situation where the combined path to the
new root and a path to a mount to be moved together exceed maximum path length,
we shouldn't crash, but fail this path instead.

src/shared/switch-root.c

index 47d3a5a1fa21a4f92abc336d4bd74953fe68b619..4eff4f692e00947d899183673a5944599b42ed2c 100644 (file)
@@ -75,17 +75,29 @@ int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot,
         NULSTR_FOREACH(i, move_mounts) {
                 char new_mount[PATH_MAX];
                 struct stat sb;
+                size_t n;
 
-                xsprintf(new_mount, "%s%s", new_root, i);
+                n = snprintf(new_mount, sizeof new_mount, "%s%s", new_root, i);
+                if (n >= sizeof new_mount) {
+                        bool move = mountflags & MS_MOVE;
+
+                        log_warning("New path is too long, %s: %s%s",
+                                    move ? "forcing unmount instead" : "ignoring",
+                                    new_root, i);
+
+                        if (move)
+                                if (umount2(i, MNT_FORCE) < 0)
+                                        log_warning_errno(errno, "Failed to unmount %s: %m", i);
+                        continue;
+                }
 
                 mkdir_p_label(new_mount, 0755);
 
-                if ((stat(new_mount, &sb) < 0) ||
+                if (stat(new_mount, &sb) < 0 ||
                     sb.st_dev != new_root_stat.st_dev) {
 
                         /* Mount point seems to be mounted already or
-                         * stat failed. Unmount the old mount
-                         * point. */
+                         * stat failed. Unmount the old mount point. */
                         if (umount2(i, MNT_DETACH) < 0)
                                 log_warning_errno(errno, "Failed to unmount %s: %m", i);
                         continue;
@@ -97,10 +109,9 @@ int switch_root(const char *new_root, const char *oldroot, bool detach_oldroot,
 
                                 if (umount2(i, MNT_FORCE) < 0)
                                         log_warning_errno(errno, "Failed to unmount %s: %m", i);
-                        }
-                        if (mountflags & MS_BIND)
-                                log_error_errno(errno, "Failed to bind mount %s to %s: %m", i, new_mount);
 
+                        } else if (mountflags & MS_BIND)
+                                log_error_errno(errno, "Failed to bind mount %s to %s: %m", i, new_mount);
                 }
         }