summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-10-28 15:59:49 +0200
committerLuca Boccassi <luca.boccassi@gmail.com>2022-11-09 10:10:59 +0100
commit1a25a77f3e87d88e7bdd0e883527fe3b8abeb3cd (patch)
treeaf68c6a92d83dda210dc7cd68b90b791c2c739ca
parentbf1886226724b3db0779d643195d428575cff0be (diff)
downloadsystemd-1a25a77f3e87d88e7bdd0e883527fe3b8abeb3cd.tar.gz
basic/virt: treat missing /proc as sign of being in a chroot
The logic of running_in_chroot() has been the same since the introduction of this function in b4f10a5e8956d26f0bc6b9aef12846b57caee08b: if /proc is not mounted, the function returns -ENOENT and all callers treat this as false. But that might be the most common case of chrooted calls, esp. in all the naïve chroots that were done with the chroot binary without additional setup. (In particular rpm executes all scriptlets in a chroot without bothering to set up /proc or /sys, and we have codepaths in sysusers and tmpfiles to support running in such an environment.) This change effectively shortcircuits various calls to udevadm, downgrades logging in tmpfiles, and disables all verbs marked with VERB_ONLINE_ONLY in systemctl. detect-virt -r is also affected: $ sudo chroot /var/lib/machines/rawhide before> systemd-detect-virt -r && echo OK Failed to check for chroot() environment: No such file or directory after> systemd-detect-virt -r && echo OK OK
-rw-r--r--src/basic/virt.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/basic/virt.c b/src/basic/virt.c
index 710f0372ea..9a0b5a28d1 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -867,10 +867,26 @@ int running_in_userns(void) {
int running_in_chroot(void) {
int r;
+ /* If we're PID1, /proc may not be mounted (and most likely we're not in a chroot). But PID1 will
+ * mount /proc, so all other programs can assume that if /proc is *not* available, we're in some
+ * chroot. */
+
if (getenv_bool("SYSTEMD_IGNORE_CHROOT") > 0)
return 0;
+ if (getpid_cached() == 1)
+ return false; /* We're PID 1, we can't be in a chroot. */
+
r = files_same("/proc/1/root", "/", 0);
+ if (r == -ENOENT) {
+ r = proc_mounted();
+ if (r == 0) {
+ log_debug("/proc is not mounted, assuming we're in a chroot.");
+ return 1;
+ }
+ if (r > 0) /* If we have fake /proc/, we can't do the check properly. */
+ return -ENOSYS;
+ }
if (r < 0)
return r;