summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-11-24 17:42:19 +0100
committerMartin Pitt <martin.pitt@ubuntu.com>2016-12-14 10:13:52 +0100
commit295ee9845c801300298d01256eb5a9e3ff117ae0 (patch)
treee46946b349906d7ac5148a718c14bd135c684004
parent4014818d530ad3f6f5e4b94b79a9336376feface (diff)
util: Fine tune running_in_chroot() a bit
Let's be a bit more careful when detecting chroot() environments, so that we can discern them from namespaced environments. Previously this would simply check if the root directory of PID 1 matches our own root directory. With this commit, we also check whether the namespaces of PID 1 and ourselves are the same. If not we assume we are running inside of a namespaced environment instead of a chroot() environment. This has the benefit that systemctl (which uses running_in_chroot()) will work as usual when invoked in a namespaced service.
-rw-r--r--src/basic/virt.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/src/basic/virt.c b/src/basic/virt.c
index d8d57381ad..9b7eb71319 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -25,15 +25,16 @@
#include "alloc-util.h"
#include "dirent-util.h"
+#include "env-util.h"
#include "fd-util.h"
#include "fileio.h"
+#include "fs-util.h"
#include "macro.h"
#include "process-util.h"
#include "stat-util.h"
#include "string-table.h"
#include "string-util.h"
#include "virt.h"
-#include "env-util.h"
static int detect_vm_cpuid(void) {
@@ -556,16 +557,30 @@ int running_in_userns(void) {
}
int running_in_chroot(void) {
- int ret;
+ _cleanup_free_ char *self_mnt = NULL, *pid1_mnt = NULL;
+ int r;
+
+ /* Try to detect whether we are running in a chroot() environment. Specifically, check whether we have a
+ * different root directory than PID 1, even though we live in the same mount namespace as it. */
if (getenv_bool("SYSTEMD_IGNORE_CHROOT") > 0)
return 0;
- ret = files_same("/proc/1/root", "/");
- if (ret < 0)
- return ret;
+ r = files_same("/proc/1/root", "/");
+ if (r < 0)
+ return r;
+ if (r > 0)
+ return 0;
+
+ r = readlink_malloc("/proc/self/ns/mnt", &self_mnt);
+ if (r < 0)
+ return r;
+
+ r = readlink_malloc("/proc/1/ns/mnt", &pid1_mnt);
+ if (r < 0)
+ return r;
- return ret == 0;
+ return streq(self_mnt, pid1_mnt); /* Only if we live in the same namespace! */
}
static const char *const virtualization_table[_VIRTUALIZATION_MAX] = {