]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core,systemctl: refuse switching root if we're not in initrd 28971/head
authorMike Yuan <me@yhndnzj.com>
Fri, 25 Aug 2023 16:39:23 +0000 (00:39 +0800)
committerMike Yuan <me@yhndnzj.com>
Sat, 2 Sep 2023 07:56:24 +0000 (15:56 +0800)
NEWS
TODO
src/core/dbus-manager.c
src/systemctl/systemctl-switch-root.c

diff --git a/NEWS b/NEWS
index 3acbafc44af6a7dc50dbecee648c637553915de8..8ba35e5b3151bcaad39972a89a1576000af9ac62 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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
diff --git a/TODO b/TODO
index eda525dc443dc8626386c312cff0292bf361b98e..20d81c4ba7f4e566c554ff59a83bb027881d9377 100644 (file)
--- a/TODO
+++ b/TODO
@@ -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.
 
index 253c315277eafbe4679e41532432f78b5fef02d3..3d1a38b21ed80b1c2f8752ab07bdef499f6874f9 100644 (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);
index cc31cf0e196f5a2308cc7ab706e11a940b212803..ae4a1a72c2b56dd5e29beda3f0053723298e21bb 100644 (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 {