summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Down <chris@chrisdown.name>2020-04-14 18:15:04 +0100
committerChris Down <chris@chrisdown.name>2020-04-15 18:36:35 +0100
commit80cc3e3eabd2cf4e31ae3f0d6e2ac7b61d0a1832 (patch)
tree4382f7656e7d6d5b2f894406291207ef0d938eb5
parent6ab2e1178e1d98070a2574cea45cb4c0a089f9c0 (diff)
downloadsystemd-80cc3e3eabd2cf4e31ae3f0d6e2ac7b61d0a1832.tar.gz
virt: Detect proot virtualisation by ptrace metadata
proot provides userspace-powered emulation of chroot and mount --bind, lending it to be used on environments without unprivileged user namespaces, or in otherwise restricted environments like Android. In order to achieve this, proot makes use of the kernel's ptrace() facility, which we can use in order to detect its presence. Since it doesn't use any kind of namespacing, including PID namespacing, we don't need to do any tricks when trying to get the tracer's metadata. For our purposes, proot is listed as a "container", since we mostly use this also as the bucket for non-container-but-container-like technologies like WSL. As such, it seems like a good fit for this section as well.
-rw-r--r--man/systemd-detect-virt.xml5
-rw-r--r--man/systemd.unit.xml1
-rw-r--r--src/basic/virt.c19
-rw-r--r--src/basic/virt.h1
4 files changed, 26 insertions, 0 deletions
diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml
index d599ac20f1..77bdd80f32 100644
--- a/man/systemd-detect-virt.xml
+++ b/man/systemd-detect-virt.xml
@@ -167,6 +167,11 @@
<entry><varname>wsl</varname></entry>
<entry><ulink url="https://docs.microsoft.com/en-us/windows/wsl/about">Windows Subsystem for Linux</ulink></entry>
</row>
+
+ <row>
+ <entry><varname>proot</varname></entry>
+ <entry><ulink url="https://proot-me.github.io/">proot</ulink> userspace chroot/bind mount emulation</entry>
+ </row>
</tbody>
</tgroup>
</table>
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index d0de9aa500..c26937e752 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -1170,6 +1170,7 @@
<literal>podman</literal>,
<literal>rkt</literal>,
<literal>wsl</literal>,
+ <literal>proot</literal>,
<literal>acrn</literal> to test
against a specific implementation, or
<literal>private-users</literal> to check whether we are running in a user namespace. See
diff --git a/src/basic/virt.c b/src/basic/virt.c
index f567696265..c22bcf9aea 100644
--- a/src/basic/virt.c
+++ b/src/basic/virt.c
@@ -441,6 +441,7 @@ static const char *const container_table[_VIRTUALIZATION_MAX] = {
[VIRTUALIZATION_PODMAN] = "podman",
[VIRTUALIZATION_RKT] = "rkt",
[VIRTUALIZATION_WSL] = "wsl",
+ [VIRTUALIZATION_PROOT] = "proot",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(container, int);
@@ -449,6 +450,7 @@ int detect_container(void) {
static thread_local int cached_found = _VIRTUALIZATION_INVALID;
_cleanup_free_ char *m = NULL;
_cleanup_free_ char *o = NULL;
+ _cleanup_free_ char *p = NULL;
const char *e = NULL;
int r;
@@ -472,6 +474,22 @@ int detect_container(void) {
goto finish;
}
+ /* proot doesn't use PID namespacing, so we can just check if we have a matching tracer for this
+ * invocation without worrying about it being elsewhere.
+ */
+ r = get_proc_field("/proc/self/status", "TracerPid", WHITESPACE, &p);
+ if (r == 0 && !streq(p, "0")) {
+ pid_t ptrace_pid;
+ r = parse_pid(p, &ptrace_pid);
+ if (r == 0) {
+ const char *pf = procfs_file_alloca(ptrace_pid, "comm");
+ _cleanup_free_ char *ptrace_comm = NULL;
+ r = read_one_line_file(pf, &ptrace_comm);
+ if (r >= 0 && startswith(ptrace_comm, "proot"))
+ return VIRTUALIZATION_PROOT;
+ }
+ }
+
if (getpid_cached() == 1) {
/* If we are PID 1 we can just check our own environment variable, and that's authoritative.
* We distinguish three cases:
@@ -660,6 +678,7 @@ static const char *const virtualization_table[_VIRTUALIZATION_MAX] = {
[VIRTUALIZATION_PODMAN] = "podman",
[VIRTUALIZATION_RKT] = "rkt",
[VIRTUALIZATION_WSL] = "wsl",
+ [VIRTUALIZATION_PROOT] = "proot",
[VIRTUALIZATION_CONTAINER_OTHER] = "container-other",
};
diff --git a/src/basic/virt.h b/src/basic/virt.h
index 26f409afd0..d58c582c91 100644
--- a/src/basic/virt.h
+++ b/src/basic/virt.h
@@ -34,6 +34,7 @@ enum {
VIRTUALIZATION_PODMAN,
VIRTUALIZATION_RKT,
VIRTUALIZATION_WSL,
+ VIRTUALIZATION_PROOT,
VIRTUALIZATION_CONTAINER_OTHER,
VIRTUALIZATION_CONTAINER_LAST = VIRTUALIZATION_CONTAINER_OTHER,