From: Mike Yuan Date: Fri, 25 Aug 2023 16:18:25 +0000 (+0800) Subject: core,systemctl: refuse switching root to current root properly X-Git-Tag: v255-rc1~607^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b0c5f0e1f43a23e2cd658175e9c36335a7146c04;p=thirdparty%2Fsystemd.git core,systemctl: refuse switching root to current root properly Fixes #28970 --- diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 245c5f14f1f..253c315277e 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1864,10 +1864,17 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er if (!path_is_valid(root)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory must be a valid path."); + if (!path_is_absolute(root)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root path '%s' is not absolute.", root); - if (path_equal(root, "/")) + + r = path_is_root(root); + if (r < 0) + return sd_bus_error_set_errnof(error, r, + "Failed to check if new root directory '%s' is the same as old root: %m", + root); + if (r > 0) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory cannot be the old root directory."); } diff --git a/src/systemctl/systemctl-switch-root.c b/src/systemctl/systemctl-switch-root.c index b59ea701c91..cc31cf0e196 100644 --- a/src/systemctl/systemctl-switch-root.c +++ b/src/systemctl/systemctl-switch-root.c @@ -4,6 +4,7 @@ #include "bus-error.h" #include "bus-locator.h" #include "chase.h" +#include "fd-util.h" #include "parse-util.h" #include "path-util.h" #include "proc-cmdline.h" @@ -47,11 +48,17 @@ int verb_switch_root(int argc, char *argv[], void *userdata) { if (argc >= 2) { root = argv[1]; + if (!path_is_valid(root)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid root path: %s", root); + if (!path_is_absolute(root)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Root path is not absolute: %s", root); - if (path_equal(root, "/")) + + r = path_is_root(root); + if (r < 0) + return log_error_errno(r, "Failed to check if switch-root directory '%s' is current root: %m", root); + if (r > 0) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Cannot switch to current root directory: %s", root); } else root = "/sysroot";