summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/dbus-manager.c13
-rw-r--r--src/nspawn/nspawn.c16
-rw-r--r--src/shared/path-util.c12
-rw-r--r--src/shared/path-util.h1
-rw-r--r--src/shared/util.h12
5 files changed, 32 insertions, 22 deletions
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index c23709c2b6..d767dd5236 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -1481,7 +1481,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "SwitchRoot")) {
const char *switch_root, *switch_root_init;
char *u, *v;
- int k;
+ bool good;
SELINUX_ACCESS_CHECK(connection, message, "reboot");
@@ -1506,19 +1506,18 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
/* Safety check */
if (isempty(switch_root_init))
- k = access(switch_root, F_OK);
+ good = path_is_os_tree(switch_root);
else {
- char *p;
+ _cleanup_free_ char *p = NULL;
p = strjoin(switch_root, "/", switch_root_init, NULL);
if (!p)
goto oom;
- k = access(p, X_OK);
- free(p);
+ good = access(p, X_OK) >= 0;
}
- if (k < 0)
- return bus_send_error_reply(connection, message, NULL, -errno);
+ if (!good)
+ return bus_send_error_reply(connection, message, NULL, -EINVAL);
u = strdup(switch_root);
if (!u)
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index c257682451..416d4a69b4 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -918,20 +918,6 @@ static int drop_capabilities(void) {
return capability_bounding_set_drop(~arg_retain, false);
}
-static int is_os_tree(const char *path) {
- int r;
- char *p;
- /* We use /bin/sh as flag file if something is an OS */
-
- if (asprintf(&p, "%s/bin/sh", path) < 0)
- return -ENOMEM;
-
- r = access(p, F_OK);
- free(p);
-
- return r < 0 ? 0 : 1;
-}
-
static int process_pty(int master, pid_t pid, sigset_t *mask) {
char in_buffer[LINE_MAX], out_buffer[LINE_MAX];
@@ -1240,7 +1226,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- if (is_os_tree(arg_directory) <= 0) {
+ if (path_is_os_tree(arg_directory) <= 0) {
log_error("Directory %s doesn't look like an OS root directory. Refusing.", arg_directory);
goto finish;
}
diff --git a/src/shared/path-util.c b/src/shared/path-util.c
index 0b50ea646a..b623fc3dd5 100644
--- a/src/shared/path-util.c
+++ b/src/shared/path-util.c
@@ -413,3 +413,15 @@ int path_is_read_only_fs(const char *path) {
return !!(st.f_flag & ST_RDONLY);
}
+
+int path_is_os_tree(const char *path) {
+ char *p;
+ int r;
+
+ /* We use /etc/os-release as flag file if something is an OS */
+
+ p = strappenda(path, "/etc/os-release");
+ r = access(p, F_OK);
+
+ return r < 0 ? 0 : 1;
+}
diff --git a/src/shared/path-util.h b/src/shared/path-util.h
index 9347bc3a9b..ea0f173082 100644
--- a/src/shared/path-util.h
+++ b/src/shared/path-util.h
@@ -40,3 +40,4 @@ char **path_strv_canonicalize_uniq(char **l);
int path_is_mount_point(const char *path, bool allow_symlink);
int path_is_read_only_fs(const char *path);
+int path_is_os_tree(const char *path);
diff --git a/src/shared/util.h b/src/shared/util.h
index 3aac165e67..cfb54939cd 100644
--- a/src/shared/util.h
+++ b/src/shared/util.h
@@ -684,3 +684,15 @@ int unlink_noerrno(const char *path);
_new_ = alloca(_len_); \
(void *) memset(_new_, 0, _len_); \
})
+
+#define strappenda(a, b) \
+ ({ \
+ const char *_a_ = (a), *_b_ = (b); \
+ char *_c_; \
+ size_t _x_, _y_; \
+ _x_ = strlen(_a_); \
+ _y_ = strlen(_b_); \
+ _c_ = alloca(_x_ + _y_ + 1); \
+ strcpy(stpcpy(_c_, _a_), _b_); \
+ _c_; \
+ })