1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 /***
3   Copyright © 2010 ProFUSION embedded systems
4 ***/
5 
6 #include <errno.h>
7 #include <signal.h>
8 #include <sys/wait.h>
9 #include <unistd.h>
10 
11 #include "alloc-util.h"
12 #include "def.h"
13 #include "dirent-util.h"
14 #include "fd-util.h"
15 #include "format-util.h"
16 #include "killall.h"
17 #include "parse-util.h"
18 #include "process-util.h"
19 #include "set.h"
20 #include "stdio-util.h"
21 #include "string-util.h"
22 #include "terminal-util.h"
23 #include "util.h"
24 
ignore_proc(pid_t pid,bool warn_rootfs)25 static bool ignore_proc(pid_t pid, bool warn_rootfs) {
26         _cleanup_fclose_ FILE *f = NULL;
27         const char *p;
28         char c = 0;
29         uid_t uid;
30         int r;
31 
32         /* We are PID 1, let's not commit suicide */
33         if (pid <= 1)
34                 return true;
35 
36         /* Ignore kernel threads */
37         r = is_kernel_thread(pid);
38         if (r != 0)
39                 return true; /* also ignore processes where we can't determine this */
40 
41         r = get_process_uid(pid, &uid);
42         if (r < 0)
43                 return true; /* not really, but better safe than sorry */
44 
45         /* Non-root processes otherwise are always subject to be killed */
46         if (uid != 0)
47                 return false;
48 
49         p = procfs_file_alloca(pid, "cmdline");
50         f = fopen(p, "re");
51         if (!f)
52                 return true; /* not really, but has the desired effect */
53 
54         /* Try to read the first character of the command line. If the cmdline is empty (which might be the case for
55          * kernel threads but potentially also other stuff), this line won't do anything, but we don't care much, as
56          * actual kernel threads are already filtered out above. */
57         (void) fread(&c, 1, 1, f);
58 
59         /* Processes with argv[0][0] = '@' we ignore from the killing spree.
60          *
61          * https://systemd.io/ROOT_STORAGE_DAEMONS */
62         if (c != '@')
63                 return false;
64 
65         if (warn_rootfs &&
66             pid_from_same_root_fs(pid) == 0) {
67 
68                 _cleanup_free_ char *comm = NULL;
69 
70                 (void) get_process_comm(pid, &comm);
71 
72                 log_notice("Process " PID_FMT " (%s) has been marked to be excluded from killing. It is "
73                            "running from the root file system, and thus likely to block re-mounting of the "
74                            "root file system to read-only. Please consider moving it into an initrd file "
75                            "system instead.", pid, strna(comm));
76         }
77 
78         return true;
79 }
80 
log_children_no_yet_killed(Set * pids)81 static void log_children_no_yet_killed(Set *pids) {
82         _cleanup_free_ char *lst_child = NULL;
83         void *p;
84         int r;
85 
86         SET_FOREACH(p, pids) {
87                 _cleanup_free_ char *s = NULL;
88 
89                 if (get_process_comm(PTR_TO_PID(p), &s) >= 0)
90                         r = strextendf(&lst_child, ", " PID_FMT " (%s)", PTR_TO_PID(p), s);
91                 else
92                         r = strextendf(&lst_child, ", " PID_FMT, PTR_TO_PID(p));
93                 if (r < 0)
94                         return (void) log_oom();
95         }
96 
97         if (isempty(lst_child))
98                 return;
99 
100         log_warning("Waiting for process: %s", lst_child + 2);
101 }
102 
wait_for_children(Set * pids,sigset_t * mask,usec_t timeout)103 static int wait_for_children(Set *pids, sigset_t *mask, usec_t timeout) {
104         usec_t until, date_log_child, n;
105 
106         assert(mask);
107 
108         /* Return the number of children remaining in the pids set: That correspond to the number
109          * of processes still "alive" after the timeout */
110 
111         if (set_isempty(pids))
112                 return 0;
113 
114         n = now(CLOCK_MONOTONIC);
115         until = usec_add(n, timeout);
116         date_log_child = usec_add(n, 10u * USEC_PER_SEC);
117         if (date_log_child > until)
118                 date_log_child = usec_add(n, timeout / 2u);
119 
120         for (;;) {
121                 struct timespec ts;
122                 int k;
123                 void *p;
124 
125                 /* First, let the kernel inform us about killed
126                  * children. Most processes will probably be our
127                  * children, but some are not (might be our
128                  * grandchildren instead...). */
129                 for (;;) {
130                         pid_t pid;
131 
132                         pid = waitpid(-1, NULL, WNOHANG);
133                         if (pid == 0)
134                                 break;
135                         if (pid < 0) {
136                                 if (errno == ECHILD)
137                                         break;
138 
139                                 return log_error_errno(errno, "waitpid() failed: %m");
140                         }
141 
142                         (void) set_remove(pids, PID_TO_PTR(pid));
143                 }
144 
145                 /* Now explicitly check who might be remaining, who
146                  * might not be our child. */
147                 SET_FOREACH(p, pids) {
148 
149                         /* kill(pid, 0) sends no signal, but it tells
150                          * us whether the process still exists. */
151                         if (kill(PTR_TO_PID(p), 0) == 0)
152                                 continue;
153 
154                         if (errno != ESRCH)
155                                 continue;
156 
157                         set_remove(pids, p);
158                 }
159 
160                 if (set_isempty(pids))
161                         return 0;
162 
163                 n = now(CLOCK_MONOTONIC);
164                 if (date_log_child > 0 && n >= date_log_child) {
165                         log_children_no_yet_killed(pids);
166                         /* Log the children not yet killed only once */
167                         date_log_child = 0;
168                 }
169 
170                 if (n >= until)
171                         return set_size(pids);
172 
173                 if (date_log_child > 0)
174                         timespec_store(&ts, MIN(until - n, date_log_child - n));
175                 else
176                         timespec_store(&ts, until - n);
177 
178                 k = sigtimedwait(mask, NULL, &ts);
179                 if (k != SIGCHLD) {
180 
181                         if (k < 0 && errno != EAGAIN)
182                                 return log_error_errno(errno, "sigtimedwait() failed: %m");
183 
184                         if (k >= 0)
185                                 log_warning("sigtimedwait() returned unexpected signal.");
186                 }
187         }
188 }
189 
killall(int sig,Set * pids,bool send_sighup)190 static int killall(int sig, Set *pids, bool send_sighup) {
191         _cleanup_closedir_ DIR *dir = NULL;
192         int n_killed = 0;
193 
194         /* Send the specified signal to all remaining processes, if not excluded by ignore_proc().
195          * Returns the number of processes to which the specified signal was sent */
196 
197         dir = opendir("/proc");
198         if (!dir)
199                 return log_warning_errno(errno, "opendir(/proc) failed: %m");
200 
201         FOREACH_DIRENT_ALL(de, dir, break) {
202                 pid_t pid;
203                 int r;
204 
205                 if (!IN_SET(de->d_type, DT_DIR, DT_UNKNOWN))
206                         continue;
207 
208                 if (parse_pid(de->d_name, &pid) < 0)
209                         continue;
210 
211                 if (ignore_proc(pid, sig == SIGKILL && !in_initrd()))
212                         continue;
213 
214                 if (sig == SIGKILL) {
215                         _cleanup_free_ char *s = NULL;
216 
217                         (void) get_process_comm(pid, &s);
218                         log_notice("Sending SIGKILL to PID "PID_FMT" (%s).", pid, strna(s));
219                 }
220 
221                 if (kill(pid, sig) >= 0) {
222                         n_killed++;
223                         if (pids) {
224                                 r = set_put(pids, PID_TO_PTR(pid));
225                                 if (r < 0)
226                                         log_oom();
227                         }
228                 } else if (errno != ENOENT)
229                         log_warning_errno(errno, "Could not kill %d: %m", pid);
230 
231                 if (send_sighup) {
232                         /* Optionally, also send a SIGHUP signal, but
233                         only if the process has a controlling
234                         tty. This is useful to allow handling of
235                         shells which ignore SIGTERM but react to
236                         SIGHUP. We do not send this to processes that
237                         have no controlling TTY since we don't want to
238                         trigger reloads of daemon processes. Also we
239                         make sure to only send this after SIGTERM so
240                         that SIGTERM is always first in the queue. */
241 
242                         if (get_ctty_devnr(pid, NULL) >= 0)
243                                 /* it's OK if the process is gone, just ignore the result */
244                                 (void) kill(pid, SIGHUP);
245                 }
246         }
247 
248         return n_killed;
249 }
250 
broadcast_signal(int sig,bool wait_for_exit,bool send_sighup,usec_t timeout)251 int broadcast_signal(int sig, bool wait_for_exit, bool send_sighup, usec_t timeout) {
252         int n_children_left;
253         sigset_t mask, oldmask;
254         _cleanup_set_free_ Set *pids = NULL;
255 
256         /* Send the specified signal to all remaining processes, if not excluded by ignore_proc().
257          * Return:
258          *  - The number of processes still "alive" after the timeout (that should have been killed)
259          *    if the function needs to wait for the end of the processes (wait_for_exit).
260          *  - Otherwise, the number of processes to which the specified signal was sent */
261 
262         if (wait_for_exit)
263                 pids = set_new(NULL);
264 
265         assert_se(sigemptyset(&mask) == 0);
266         assert_se(sigaddset(&mask, SIGCHLD) == 0);
267         assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) == 0);
268 
269         if (kill(-1, SIGSTOP) < 0 && errno != ESRCH)
270                 log_warning_errno(errno, "kill(-1, SIGSTOP) failed: %m");
271 
272         n_children_left = killall(sig, pids, send_sighup);
273 
274         if (kill(-1, SIGCONT) < 0 && errno != ESRCH)
275                 log_warning_errno(errno, "kill(-1, SIGCONT) failed: %m");
276 
277         if (wait_for_exit && n_children_left > 0)
278                 n_children_left = wait_for_children(pids, &mask, timeout);
279 
280         assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0);
281 
282         return n_children_left;
283 }
284