summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2024-01-09 23:07:27 +0100
committercgzones <cgzones@googlemail.com>2024-04-06 19:42:28 +0200
commit22d25db4678b844842af516c0f2d117382f7c632 (patch)
treeb4c205edd56574f7a829c22962503366e3a230c6
parent76a13dbb4ea82c0a22c8d3a74476b9446aa91a0b (diff)
Linux: detect container process by different PID namespace
Container engines like docker and podman rely on Linux namespaces. If available check if the target process is inside a different PID namespace than htop. This check will mark sandbox'ed applications, e.g. under bubblewrap, but not light-wight containers, like distrobox.
-rw-r--r--Process.h2
-rw-r--r--linux/LinuxProcessTable.c58
2 files changed, 46 insertions, 14 deletions
diff --git a/Process.h b/Process.h
index 066c1402..848894ca 100644
--- a/Process.h
+++ b/Process.h
@@ -94,7 +94,7 @@ typedef struct Process_ {
bool isUserlandThread;
/* This process is running inside a container */
- bool isRunningInContainer;
+ Tristate isRunningInContainer;
/* Controlling terminal identifier of the process */
unsigned long int tty_nr;
diff --git a/linux/LinuxProcessTable.c b/linux/LinuxProcessTable.c
index 64a0fd93..7044314e 100644
--- a/linux/LinuxProcessTable.c
+++ b/linux/LinuxProcessTable.c
@@ -60,6 +60,10 @@ in the source distribution for its full text.
#define PF_KTHREAD 0x00200000
#endif
+/* Inode number of the PID namespace of htop */
+static ino_t rootPidNs = (ino_t)-1;
+
+
static FILE* fopenat(openat_arg_t openatArg, const char* pathname, const char* mode) {
assert(String_eq(mode, "r")); /* only currently supported mode */
@@ -193,6 +197,17 @@ ProcessTable* ProcessTable_new(Machine* host, Hashtable* pidMatchList) {
// Test /proc/PID/smaps_rollup availability (faster to parse, Linux 4.14+)
this->haveSmapsRollup = (access(PROCDIR "/self/smaps_rollup", R_OK) == 0);
+ // Read PID namespace inode number
+ {
+ struct stat sb;
+ int r = stat(PROCDIR "/self/ns/pid", &sb);
+ if (r == 0) {
+ rootPidNs = sb.st_ino;
+ } else {
+ rootPidNs = (ino_t)-1;
+ }
+ }
+
return super;
}
@@ -369,6 +384,7 @@ static bool LinuxProcessTable_readStatusFile(Process* process, openat_arg_t proc
LinuxProcess* lp = (LinuxProcess*) process;
unsigned long ctxt = 0;
+ process->isRunningInContainer = TRI_OFF;
#ifdef HAVE_VSERVER
lp->vxid = 0;
#endif
@@ -397,7 +413,7 @@ static bool LinuxProcessTable_readStatusFile(Process* process, openat_arg_t proc
}
if (pid_ns_count > 1)
- process->isRunningInContainer = true;
+ process->isRunningInContainer = TRI_ON;
} else if (String_startsWith(buffer, "voluntary_ctxt_switches:")) {
unsigned long vctxt;
@@ -1461,7 +1477,7 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
Compat_openatArgClose(procFd);
continue;
}
- if (preExisting && hideRunningInContainer && proc->isRunningInContainer) {
+ if (preExisting && hideRunningInContainer && proc->isRunningInContainer == TRI_ON) {
proc->super.updated = true;
proc->super.show = false;
Compat_openatArgClose(procFd);
@@ -1525,16 +1541,6 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
if (!LinuxProcessTable_updateUser(host, proc, procFd, mainTask))
goto errorReadingProcess;
- if (ss->flags & PROCESS_FLAG_LINUX_CTXT
- || hideRunningInContainer
-#ifdef HAVE_VSERVER
- || ss->flags & PROCESS_FLAG_LINUX_VSERVER
-#endif
- ) {
- if (!LinuxProcessTable_readStatusFile(proc, procFd))
- goto errorReadingProcess;
- }
-
if (!preExisting) {
#ifdef HAVE_OPENVZ
@@ -1568,6 +1574,32 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
}
}
+ /* Check if the process in inside a different PID namespace. */
+ if (proc->isRunningInContainer == TRI_INITIAL && rootPidNs != (ino_t)-1) {
+ struct stat sb;
+#if defined(HAVE_OPENAT) && defined(HAVE_FSTATAT)
+ int res = fstatat(procFd, "ns/pid", &sb, 0);
+#else
+ char path[4096];
+ xSnprintf(path, sizeof(path), "%s/ns/pid", procFd);
+ int res = stat(path, &sb);
+#endif
+ if (res == 0) {
+ proc->isRunningInContainer = (sb.st_ino != rootPidNs) ? TRI_ON : TRI_OFF;
+ }
+ }
+
+ if (ss->flags & PROCESS_FLAG_LINUX_CTXT
+ || (hideRunningInContainer && proc->isRunningInContainer == TRI_INITIAL)
+#ifdef HAVE_VSERVER
+ || ss->flags & PROCESS_FLAG_LINUX_VSERVER
+#endif
+ ) {
+ proc->isRunningInContainer = TRI_OFF;
+ if (!LinuxProcessTable_readStatusFile(proc, procFd))
+ goto errorReadingProcess;
+ }
+
/*
* Section gathering non-critical information that is independent from
* each other.
@@ -1662,7 +1694,7 @@ static bool LinuxProcessTable_recurseProcTree(LinuxProcessTable* this, openat_ar
proc->super.updated = true;
Compat_openatArgClose(procFd);
- if (hideRunningInContainer && proc->isRunningInContainer) {
+ if (hideRunningInContainer && proc->isRunningInContainer == TRI_ON) {
proc->super.show = false;
continue;
}

© 2014-2024 Faster IT GmbH | imprint | privacy policy