1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-21 22:04:01 +03:00

core,systemctl: refuse switching root if we're not in initrd

This commit is contained in:
Mike Yuan 2023-08-26 00:39:23 +08:00
parent b0c5f0e1f4
commit 4da159bc53
No known key found for this signature in database
GPG Key ID: 417471C0A40F58B3
4 changed files with 24 additions and 16 deletions

4
NEWS
View File

@ -33,6 +33,10 @@ CHANGES WITH 255 in spe:
by default when combined with --scope, will be changed in a future
release to be enabled by default.
* "systemctl switch-root" is now restricted to initrd transtions only.
Transitions between real systems should be done with "systemctl soft-reboot"
instead.
Device Management:
* udev will now create symlinks to loopback block devices in the

5
TODO
View File

@ -274,11 +274,6 @@ Features:
idea, and specifically works around the fact the autofs ignores busy by mount
namespaces)
* refuse using the switch-root operation without /etc/initrd-release. Now
that we have a concept of userspace reboot, we can clearly say: switch-root
is for transitioning from initrd to host (or initrd to next initrd), while
userspace reboot is for switching host to next version of the host.
* mount most file systems with a restrictive uidmap. e.g. mount /usr/ with a
uidmap that blocks out anything outside 0…1000 (i.e. system users) and similar.

View File

@ -26,6 +26,7 @@
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
#include "initrd-util.h"
#include "install.h"
#include "log.h"
#include "manager-dump.h"
@ -1880,17 +1881,21 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er
}
/* Safety check */
if (isempty(init)) {
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 {
if (!in_initrd())
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Not in initrd, refusing switch-root operation.");
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);
if (!isempty(init)) {
if (!path_is_valid(init))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
"Path to init binary '%s' is not a valid path.", init);

View File

@ -5,6 +5,7 @@
#include "bus-locator.h"
#include "chase.h"
#include "fd-util.h"
#include "initrd-util.h"
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
@ -63,6 +64,9 @@ int verb_switch_root(int argc, char *argv[], void *userdata) {
} else
root = "/sysroot";
if (!in_initrd())
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Not in initrd, refusing switch-root operation.");
if (argc >= 3)
init = argv[2];
else {