From 064de0b7cd50ec4a83c7af728067facb9b98b414 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Wed, 20 Nov 2024 12:02:46 +0100
Subject: [PATCH 1022/1160] killall: gracefully handle processes inserted into
containers via nsenter -a
"nsenter -a" doesn't migrate the specified process into the target
cgroup (it really should). Thus the cgroup will remain in a cgroup
that is (due to cgroup ns) outside our visibility. The kernel will
report the cgroup path of such cgroups as starting with "/../". Detect
that and print a reasonably error message instead of trying to resolve
that.
(cherry picked from commit f6793bbcf0e3f0a6daa77add96183b88d5ec2117)
(cherry picked from commit 38e0f618ee26d1030a61884db3ba5c317ece3122)
src/basic/cgroup-util.c | 4 ++++
src/shared/killall.c | 8 ++++++--
2 files changed, 10 insertions(+), 2 deletions(-)
@@ -813,6 +813,10 @@ int cg_pid_get_path(const char *controller, pid_t pid, char **ret_path) {
if (!path)
return -ENOMEM;
+ /* Refuse cgroup paths from outside our cgroup namespace */
+ if (startswith(path, "/../"))
+ return -EUNATCH;
+
/* Truncate suffix indicating the process is a zombie */
e = endswith(path, " (deleted)");
if (e)
@@ -46,13 +46,17 @@ static bool argv_has_at(pid_t pid) {
return c == '@';
}
-static bool is_survivor_cgroup(const PidRef *pid) {
+static bool is_in_survivor_cgroup(const PidRef *pid) {
_cleanup_free_ char *cgroup_path = NULL;
int r;
assert(pidref_is_set(pid));
r = cg_pidref_get_path(/* root= */ NULL, pid, &cgroup_path);
+ if (r == -EUNATCH) {
+ log_warning_errno(r, "Process " PID_FMT " appears to originate in foreign namespace, ignoring.", pid->pid);
+ return true;
+ }
if (r < 0) {
log_warning_errno(r, "Failed to get cgroup path of process " PID_FMT ", ignoring: %m", pid->pid);
return false;
@@ -86,7 +90,7 @@ static bool ignore_proc(const PidRef *pid, bool warn_rootfs) {
return true; /* also ignore processes where we can't determine this */
/* Ignore processes that are part of a cgroup marked with the user.survive_final_kill_signal xattr */
- if (is_survivor_cgroup(pid))
+ if (is_in_survivor_cgroup(pid))
return true;
r = pidref_get_uid(pid, &uid);
--
2.33.0