summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-12-08 19:41:27 +0100
committerLennart Poettering <lennart@poettering.net>2016-12-20 20:00:09 +0100
commit710028b473c39446954b72c0d9dadb76cc7f81f8 (patch)
treebfb8e0d16c2a7f4c3bace6a1772f10c6dfffbd0c
parentffeb828596ebc9e5b20333c72862569b8b0875ad (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.c34
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);