summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-11-02 22:05:06 -0400
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2016-11-02 22:36:43 -0400
commita6eccc3647c167ba13ac23885a8ea787f44d97e5 (patch)
treef52774258a4239bec232a4a42fd20faa17544825
parent75ead2b753cb9586f3f208326446081baab70da1 (diff)
downloadsystemd-a6eccc3647c167ba13ac23885a8ea787f44d97e5.tar.gz
systemd-a6eccc3647c167ba13ac23885a8ea787f44d97e5.tar.bz2
systemd-a6eccc3647c167ba13ac23885a8ea787f44d97e5.zip
Do not raise in switch root if paths are too long
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.
-rw-r--r--src/shared/switch-root.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/shared/switch-root.c b/src/shared/switch-root.c
index 47d3a5a1fa..4eff4f692e 100644
--- a/src/shared/switch-root.c
+++ b/src/shared/switch-root.c
@@ -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);
}
}