]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/killall.c
core/service: remove unnecessary reset of notify_access_override
[thirdparty/systemd.git] / src / shared / killall.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
bd3fa1d2 2/***
96b2fb93 3 Copyright © 2010 ProFUSION embedded systems
bd3fa1d2
LP
4***/
5
bd3fa1d2 6#include <errno.h>
07630cea
LP
7#include <signal.h>
8#include <sys/wait.h>
aaf7eb81 9#include <unistd.h>
bd3fa1d2 10
b5efdb8a 11#include "alloc-util.h"
28db6fbf 12#include "constants.h"
8fb3f009 13#include "dirent-util.h"
559214cb 14#include "errno-util.h"
3ffd4af2 15#include "fd-util.h"
f97b34a6 16#include "format-util.h"
baa6a42d 17#include "initrd-util.h"
3ffd4af2 18#include "killall.h"
6bedfcbb 19#include "parse-util.h"
0b452006 20#include "process-util.h"
07630cea 21#include "set.h"
fbc39784 22#include "stdio-util.h"
07630cea 23#include "string-util.h"
288a74cc 24#include "terminal-util.h"
bd3fa1d2 25
559214cb 26static bool argv_has_at(pid_t pid) {
31885cd5 27 _cleanup_fclose_ FILE *f = NULL;
b68fa010 28 const char *p;
e45154c7 29 char c = 0;
559214cb
LB
30
31 p = procfs_file_alloca(pid, "cmdline");
32 f = fopen(p, "re");
33 if (!f) {
34 log_debug_errno(errno, "Failed to open %s, ignoring: %m", p);
35 return true; /* not really, but has the desired effect */
36 }
37
38 /* Try to read the first character of the command line. If the cmdline is empty (which might be the case for
39 * kernel threads but potentially also other stuff), this line won't do anything, but we don't care much, as
40 * actual kernel threads are already filtered out above. */
41 (void) fread(&c, 1, 1, f);
42
43 /* Processes with argv[0][0] = '@' we ignore from the killing spree.
44 *
45 * https://systemd.io/ROOT_STORAGE_DAEMONS */
46 return c == '@';
47}
48
2d790175 49static bool is_survivor_cgroup(const PidRef *pid) {
559214cb
LB
50 _cleanup_free_ char *cgroup_path = NULL;
51 int r;
52
2d790175
LP
53 assert(pidref_is_set(pid));
54
55 r = cg_pidref_get_path(/* root= */ NULL, pid, &cgroup_path);
559214cb 56 if (r < 0) {
2d790175 57 log_warning_errno(r, "Failed to get cgroup path of process " PID_FMT ", ignoring: %m", pid->pid);
559214cb
LB
58 return false;
59 }
60
bd1791b5 61 r = cg_get_xattr_bool(cgroup_path, "user.survive_final_kill_signal");
559214cb
LB
62 /* user xattr support was added to kernel v5.7, try with the trusted namespace as a fallback */
63 if (ERRNO_IS_NEG_XATTR_ABSENT(r))
bd1791b5 64 r = cg_get_xattr_bool(cgroup_path, "trusted.survive_final_kill_signal");
6fd38dc8 65 if (r < 0 && !ERRNO_IS_NEG_XATTR_ABSENT(r))
559214cb
LB
66 log_debug_errno(r,
67 "Failed to get survive_final_kill_signal xattr of %s, ignoring: %m",
68 cgroup_path);
69
70 return r > 0;
71}
72
2d790175 73static bool ignore_proc(const PidRef *pid, bool warn_rootfs) {
bd3fa1d2
LP
74 uid_t uid;
75 int r;
76
2d790175
LP
77 assert(pidref_is_set(pid));
78
bd3fa1d2 79 /* We are PID 1, let's not commit suicide */
2d790175 80 if (pid->pid == 1)
bd3fa1d2
LP
81 return true;
82
e45154c7 83 /* Ignore kernel threads */
2d790175 84 r = pidref_is_kernel_thread(pid);
e45154c7
LP
85 if (r != 0)
86 return true; /* also ignore processes where we can't determine this */
87
559214cb
LB
88 /* Ignore processes that are part of a cgroup marked with the user.survive_final_kill_signal xattr */
89 if (is_survivor_cgroup(pid))
90 return true;
91
2d790175 92 r = pidref_get_uid(pid, &uid);
bd3fa1d2
LP
93 if (r < 0)
94 return true; /* not really, but better safe than sorry */
95
96 /* Non-root processes otherwise are always subject to be killed */
97 if (uid != 0)
98 return false;
99
2d790175 100 if (!argv_has_at(pid->pid))
9e615117
ZJS
101 return false;
102
103 if (warn_rootfs &&
374c29fc 104 pid_from_same_root_fs(pid->pid) > 0) {
1359fffa 105
9e615117 106 _cleanup_free_ char *comm = NULL;
1359fffa 107
2d790175 108 (void) pidref_get_comm(pid, &comm);
1359fffa 109
9e615117
ZJS
110 log_notice("Process " PID_FMT " (%s) has been marked to be excluded from killing. It is "
111 "running from the root file system, and thus likely to block re-mounting of the "
112 "root file system to read-only. Please consider moving it into an initrd file "
2d790175 113 "system instead.", pid->pid, strna(comm));
9e615117 114 }
bd3fa1d2 115
9e615117 116 return true;
bd3fa1d2
LP
117}
118
bbfb9edc 119static void log_children_not_yet_killed(Set *pids) {
2c32f4f4 120 _cleanup_free_ char *lst_child = NULL;
94ce42bc 121 int r;
2c32f4f4 122
bbfb9edc 123 void *p;
90e74a66 124 SET_FOREACH(p, pids) {
2c32f4f4 125 _cleanup_free_ char *s = NULL;
60cd3676 126
d7d74854 127 if (pid_get_comm(PTR_TO_PID(p), &s) >= 0)
bbfb9edc 128 r = strextendf_with_separator(&lst_child, ", ", PID_FMT " (%s)", PTR_TO_PID(p), s);
94ce42bc 129 else
bbfb9edc 130 r = strextendf_with_separator(&lst_child, ", ", PID_FMT, PTR_TO_PID(p));
94ce42bc 131 if (r < 0)
2d790175 132 return (void) log_oom_warning();
2c32f4f4
BR
133 }
134
60cd3676
LP
135 if (isempty(lst_child))
136 return;
137
bbfb9edc 138 log_warning("Waiting for process: %s", lst_child);
2c32f4f4
BR
139}
140
a012f9f7 141static int wait_for_children(Set *pids, sigset_t *mask, usec_t timeout) {
60cd3676 142 usec_t until, date_log_child, n;
bd3fa1d2
LP
143
144 assert(mask);
145
a012f9f7
BR
146 /* Return the number of children remaining in the pids set: That correspond to the number
147 * of processes still "alive" after the timeout */
148
aaf7eb81 149 if (set_isempty(pids))
a012f9f7 150 return 0;
aaf7eb81 151
2c32f4f4
BR
152 n = now(CLOCK_MONOTONIC);
153 until = usec_add(n, timeout);
154 date_log_child = usec_add(n, 10u * USEC_PER_SEC);
155 if (date_log_child > until)
156 date_log_child = usec_add(n, timeout / 2u);
157
bd3fa1d2
LP
158 for (;;) {
159 struct timespec ts;
160 int k;
aaf7eb81 161 void *p;
bd3fa1d2 162
aaf7eb81
LP
163 /* First, let the kernel inform us about killed
164 * children. Most processes will probably be our
165 * children, but some are not (might be our
166 * grandchildren instead...). */
bd3fa1d2 167 for (;;) {
aaf7eb81 168 pid_t pid;
bd3fa1d2 169
aaf7eb81 170 pid = waitpid(-1, NULL, WNOHANG);
bd3fa1d2
LP
171 if (pid == 0)
172 break;
aaf7eb81
LP
173 if (pid < 0) {
174 if (errno == ECHILD)
175 break;
bd3fa1d2 176
a012f9f7 177 return log_error_errno(errno, "waitpid() failed: %m");
aaf7eb81
LP
178 }
179
fea72cc0 180 (void) set_remove(pids, PID_TO_PTR(pid));
aaf7eb81 181 }
bd3fa1d2 182
aaf7eb81
LP
183 /* Now explicitly check who might be remaining, who
184 * might not be our child. */
90e74a66 185 SET_FOREACH(p, pids) {
aaf7eb81 186
3448a969
AJ
187 /* kill(pid, 0) sends no signal, but it tells
188 * us whether the process still exists. */
189 if (kill(PTR_TO_PID(p), 0) == 0)
aaf7eb81
LP
190 continue;
191
192 if (errno != ESRCH)
193 continue;
194
195 set_remove(pids, p);
bd3fa1d2
LP
196 }
197
aaf7eb81 198 if (set_isempty(pids))
a012f9f7 199 return 0;
aaf7eb81 200
bd3fa1d2 201 n = now(CLOCK_MONOTONIC);
2c32f4f4 202 if (date_log_child > 0 && n >= date_log_child) {
bbfb9edc 203 log_children_not_yet_killed(pids);
2c32f4f4
BR
204 /* Log the children not yet killed only once */
205 date_log_child = 0;
206 }
207
bd3fa1d2 208 if (n >= until)
a012f9f7 209 return set_size(pids);
bd3fa1d2 210
2c32f4f4
BR
211 if (date_log_child > 0)
212 timespec_store(&ts, MIN(until - n, date_log_child - n));
213 else
214 timespec_store(&ts, until - n);
215
aaf7eb81
LP
216 k = sigtimedwait(mask, NULL, &ts);
217 if (k != SIGCHLD) {
bd3fa1d2 218
a012f9f7
BR
219 if (k < 0 && errno != EAGAIN)
220 return log_error_errno(errno, "sigtimedwait() failed: %m");
bd3fa1d2
LP
221
222 if (k >= 0)
223 log_warning("sigtimedwait() returned unexpected signal.");
224 }
225 }
226}
227
0bee65f0 228static int killall(int sig, Set *pids, bool send_sighup) {
aaf7eb81 229 _cleanup_closedir_ DIR *dir = NULL;
2d790175 230 int n_killed = 0, r;
a012f9f7
BR
231
232 /* Send the specified signal to all remaining processes, if not excluded by ignore_proc().
233 * Returns the number of processes to which the specified signal was sent */
bd3fa1d2 234
2d790175
LP
235 r = proc_dir_open(&dir);
236 if (r < 0)
bbfb9edc 237 return log_warning_errno(r, "Failed to open /proc/: %m");
bd3fa1d2 238
2d790175
LP
239 for (;;) {
240 _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
bd3fa1d2 241
2d790175
LP
242 r = proc_dir_read_pidref(dir, &pidref);
243 if (r < 0)
bbfb9edc 244 return log_warning_errno(r, "Failed to enumerate /proc/: %m");
2d790175
LP
245 if (r == 0)
246 break;
bd3fa1d2 247
2d790175 248 if (ignore_proc(&pidref, sig == SIGKILL && !in_initrd()))
bd3fa1d2
LP
249 continue;
250
df758e98 251 if (sig == SIGKILL) {
3e09eb5c 252 _cleanup_free_ char *s = NULL;
df758e98 253
2d790175
LP
254 (void) pidref_get_comm(&pidref, &s);
255 log_notice("Sending SIGKILL to PID "PID_FMT" (%s).", pidref.pid, strna(s));
df758e98
KS
256 }
257
2d790175
LP
258 r = pidref_kill(&pidref, sig);
259 if (r < 0) {
6f7936cf 260 if (r != -ESRCH)
2d790175
LP
261 log_warning_errno(errno, "Could not kill " PID_FMT ", ignoring: %m", pidref.pid);
262 } else {
a012f9f7 263 n_killed++;
60053efb 264 if (pids) {
2d790175 265 r = set_put(pids, PID_TO_PTR(pidref.pid));
60053efb 266 if (r < 0)
2d790175 267 (void) log_oom_warning();
60053efb 268 }
2d790175 269 }
0bee65f0
LP
270
271 if (send_sighup) {
2d790175
LP
272 /* Optionally, also send a SIGHUP signal, but only if the process has a controlling
273 * tty. This is useful to allow handling of shells which ignore SIGTERM but react to
274 * SIGHUP. We do not send this to processes that have no controlling TTY since we
275 * don't want to trigger reloads of daemon processes. Also we make sure to only send
276 * this after SIGTERM so that SIGTERM is always first in the queue. */
277
278 if (get_ctty_devnr(pidref.pid, NULL) >= 0)
5c5d9f26 279 /* it's OK if the process is gone, just ignore the result */
2d790175 280 (void) pidref_kill(&pidref, SIGHUP);
0bee65f0 281 }
bd3fa1d2
LP
282 }
283
a012f9f7 284 return n_killed;
bd3fa1d2
LP
285}
286
a012f9f7
BR
287int broadcast_signal(int sig, bool wait_for_exit, bool send_sighup, usec_t timeout) {
288 int n_children_left;
bd3fa1d2 289 sigset_t mask, oldmask;
e1d75803 290 _cleanup_set_free_ Set *pids = NULL;
aaf7eb81 291
763e7b5d
BR
292 /* Send the specified signal to all remaining processes, if not excluded by ignore_proc().
293 * Return:
294 * - The number of processes still "alive" after the timeout (that should have been killed)
295 * if the function needs to wait for the end of the processes (wait_for_exit).
296 * - Otherwise, the number of processes to which the specified signal was sent */
297
aaf7eb81 298 if (wait_for_exit)
d5099efc 299 pids = set_new(NULL);
bd3fa1d2
LP
300
301 assert_se(sigemptyset(&mask) == 0);
302 assert_se(sigaddset(&mask, SIGCHLD) == 0);
303 assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
304
305 if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
56f64d95 306 log_warning_errno(errno, "kill(-1, SIGSTOP) failed: %m");
bd3fa1d2 307
a012f9f7 308 n_children_left = killall(sig, pids, send_sighup);
bd3fa1d2
LP
309
310 if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
56f64d95 311 log_warning_errno(errno, "kill(-1, SIGCONT) failed: %m");
bd3fa1d2 312
a012f9f7
BR
313 if (wait_for_exit && n_children_left > 0)
314 n_children_left = wait_for_children(pids, &mask, timeout);
aaf7eb81
LP
315
316 assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0);
a012f9f7
BR
317
318 return n_children_left;
bd3fa1d2 319}