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.
This commit is contained in:
Lennart Poettering 2016-11-24 17:42:19 +01:00 committed by Martin Pitt
parent 4014818d53
commit 295ee9845c

View file

@ -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;
return ret == 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 streq(self_mnt, pid1_mnt); /* Only if we live in the same namespace! */
}
static const char *const virtualization_table[_VIRTUALIZATION_MAX] = {