diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-12-08 19:41:27 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-12-20 20:00:09 +0100 |
commit | 710028b473c39446954b72c0d9dadb76cc7f81f8 (patch) | |
tree | bfb8e0d16c2a7f4c3bace6a1772f10c6dfffbd0c | |
parent | ffeb828596ebc9e5b20333c72862569b8b0875ad (diff) |
core: modernize the SwitchRoot() bus method a bit
Let's more verbose error messages when validating the input parameters fails.
Also, call path_is_os_tree() properly, as it doesn't return a boolean, but
possibly also an error. Finally, check for the existance of the new init
process with chase_symlinks() to properly handle possible symlinks on the init
binary (which might actually be pretty likely).
-rw-r--r-- | src/core/dbus-manager.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 9af49dd1bc..9876251438 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -35,6 +35,7 @@ #include "fd-util.h" #include "fileio.h" #include "format-util.h" +#include "fs-util.h" #include "install.h" #include "log.h" #include "path-util.h" @@ -1484,25 +1485,36 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er if (r < 0) return r; - if (path_equal(root, "/") || !path_is_absolute(root)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root); + if (isempty(root)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory may not be the empty string."); + 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, "/")) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory cannot be the old root directory."); /* Safety check */ if (isempty(init)) { - if (!path_is_os_tree(root)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root); + r = path_is_os_tree(root); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Failed to determine whether root path '%s' contains an OS tree: %m", root); + if (r == 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path '%s' does not seem to be an OS tree. os-release file is missing.", root); } else { - _cleanup_free_ char *p = NULL; + _cleanup_free_ char *chased = NULL; if (!path_is_absolute(init)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path to init binary '%s' not absolute.", init); - p = strappend(root, init); - if (!p) - return -ENOMEM; + r = chase_symlinks(init, root, CHASE_PREFIX_ROOT, &chased); + if (r < 0) + return sd_bus_error_set_errnof(error, r, "Could not resolve init executable %s: %m", init); + + if (laccess(chased, X_OK) < 0) { + if (errno == EACCES) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Init binary %s is not executable.", init); - if (access(p, X_OK) < 0) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p); + return sd_bus_error_set_errnof(error, r, "Could not check whether init binary %s is executable: %m", init); + } } rt = strdup(root); |