• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 29173644007

11 Jul 2026 09:56PM UTC coverage: 72.704% (-0.2%) from 72.912%
29173644007

push

github

yuwata
claude-review: bump timeout from 60m to 120m

Claude got slower, but in many cases it's on the brink of finishing the
review when the timeout kicks in. Double it.

343647 of 472668 relevant lines covered (72.7%)

1407344.9 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.33
/src/basic/process-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <linux/oom.h>
4
#include <pthread.h>
5
#include <spawn.h>
6
#include <stdio.h>
7
#include <sys/mman.h>
8
#include <sys/mount.h>
9
#include <sys/personality.h>
10
#include <sys/prctl.h>
11
#include <sys/wait.h>
12
#include <syslog.h>
13
#include <threads.h>
14
#include <unistd.h>
15
#if HAVE_VALGRIND_VALGRIND_H
16
#include <valgrind/valgrind.h>
17
#endif
18

19
#include "sd-messages.h"
20

21
#include "alloc-util.h"
22
#include "architecture.h"
23
#include "argv-util.h"
24
#include "capability-util.h"
25
#include "cgroup-util.h"
26
#include "dirent-util.h"
27
#include "dlfcn-util.h"
28
#include "errno-util.h"
29
#include "escape.h"
30
#include "fd-util.h"
31
#include "fileio.h"
32
#include "fs-util.h"
33
#include "io-util.h"
34
#include "iovec-util.h"
35
#include "locale-util.h"
36
#include "log.h"
37
#include "memory-util.h"
38
#include "mountpoint-util.h"
39
#include "namespace-util.h"
40
#include "nulstr-util.h"
41
#include "parse-util.h"
42
#include "path-util.h"
43
#include "pidfd-util.h"
44
#include "pidref.h"
45
#include "process-util.h"
46
#include "raw-clone.h"
47
#include "rlimit-util.h"
48
#include "signal-util.h"
49
#include "socket-util.h"
50
#include "stat-util.h"
51
#include "stdio-util.h"
52
#include "string-table.h"
53
#include "string-util.h"
54
#include "strv.h"
55
#include "time-util.h"
56
#include "user-util.h"
57

58
/* The kernel limits userspace processes to TASK_COMM_LEN (16 bytes), but allows higher values for its own
59
 * workers, e.g. "kworker/u9:3-kcryptd/253:0". Let's pick a fixed smallish limit that will work for the kernel.
60
 */
61
#define COMM_MAX_LEN 128
62

63
static int get_process_state(pid_t pid) {
15,665✔
64
        _cleanup_free_ char *line = NULL;
15,665✔
65
        const char *p;
15,665✔
66
        char state;
15,665✔
67
        int r;
15,665✔
68

69
        assert(pid >= 0);
15,665✔
70

71
        /* Shortcut: if we are enquired about our own state, we are obviously running */
72
        if (pid == 0 || pid == getpid_cached())
15,665✔
73
                return (unsigned char) 'R';
74

75
        p = procfs_file_alloca(pid, "stat");
15,665✔
76

77
        r = read_one_line_file(p, &line);
15,665✔
78
        if (r == -ENOENT)
15,665✔
79
                return -ESRCH;
80
        if (r < 0)
12,271✔
81
                return r;
82

83
        p = strrchr(line, ')');
12,270✔
84
        if (!p)
12,270✔
85
                return -EIO;
86

87
        p++;
12,270✔
88

89
        if (sscanf(p, " %c", &state) != 1)
12,270✔
90
                return -EIO;
91

92
        return (unsigned char) state;
12,270✔
93
}
94

95
int pid_get_comm(pid_t pid, char **ret) {
61,226✔
96
        _cleanup_free_ char *escaped = NULL, *comm = NULL;
61,226✔
97
        int r;
61,226✔
98

99
        assert(pid >= 0);
61,226✔
100
        assert(ret);
61,226✔
101

102
        if (pid == 0 || pid == getpid_cached()) {
61,226✔
103
                comm = new0(char, TASK_COMM_LEN + 1); /* Must fit in 16 byte according to prctl(2) */
28,432✔
104
                if (!comm)
28,432✔
105
                        return -ENOMEM;
106

107
                if (prctl(PR_GET_NAME, comm) < 0)
28,432✔
108
                        return -errno;
×
109
        } else {
110
                const char *p;
32,794✔
111

112
                p = procfs_file_alloca(pid, "comm");
32,794✔
113

114
                /* Note that process names of kernel threads can be much longer than TASK_COMM_LEN */
115
                r = read_one_line_file(p, &comm);
32,794✔
116
                if (r == -ENOENT)
32,794✔
117
                        return -ESRCH;
118
                if (r < 0)
29,255✔
119
                        return r;
120
        }
121

122
        escaped = new(char, COMM_MAX_LEN);
57,687✔
123
        if (!escaped)
57,687✔
124
                return -ENOMEM;
125

126
        /* Escape unprintable characters, just in case, but don't grow the string beyond the underlying size */
127
        cellescape(escaped, COMM_MAX_LEN, comm);
57,687✔
128

129
        *ret = TAKE_PTR(escaped);
57,687✔
130
        return 0;
57,687✔
131
}
132

133
int pidref_get_comm(const PidRef *pid, char **ret) {
343✔
134
        _cleanup_free_ char *comm = NULL;
343✔
135
        int r;
343✔
136

137
        if (!pidref_is_set(pid))
343✔
138
                return -ESRCH;
139

140
        if (pidref_is_remote(pid))
686✔
141
                return -EREMOTE;
142

143
        r = pid_get_comm(pid->pid, &comm);
343✔
144
        if (r < 0)
343✔
145
                return r;
146

147
        r = pidref_verify(pid);
343✔
148
        if (r < 0)
343✔
149
                return r;
150

151
        if (ret)
343✔
152
                *ret = TAKE_PTR(comm);
343✔
153
        return 0;
154
}
155

156
static int pid_get_cmdline_nulstr(
23,326✔
157
                pid_t pid,
158
                size_t max_size,
159
                ProcessCmdlineFlags flags,
160
                char **ret,
161
                size_t *ret_size) {
162

163
        _cleanup_free_ char *t = NULL;
23,326✔
164
        const char *p;
23,326✔
165
        size_t k;
23,326✔
166
        int r;
23,326✔
167

168
        /* Retrieves a process' command line as a "sized nulstr", i.e. possibly without the last NUL, but
169
         * with a specified size.
170
         *
171
         * If PROCESS_CMDLINE_COMM_FALLBACK is specified in flags and the process has no command line set
172
         * (the case for kernel threads), or has a command line that resolves to the empty string, will
173
         * return the "comm" name of the process instead. This will use at most _SC_ARG_MAX bytes of input
174
         * data.
175
         *
176
         * Returns an error, 0 if output was read but is truncated, 1 otherwise.
177
         */
178

179
        p = procfs_file_alloca(pid, "cmdline");
23,542✔
180
        r = read_virtual_file(p, max_size, &t, &k); /* Let's assume that each input byte results in >= 1
23,326✔
181
                                                     * columns of output. We ignore zero-width codepoints. */
182
        if (r == -ENOENT)
23,326✔
183
                return -ESRCH;
184
        if (r < 0)
19,689✔
185
                return r;
186

187
        if (k == 0) {
19,688✔
188
                if (!(flags & PROCESS_CMDLINE_COMM_FALLBACK))
495✔
189
                        return -ENOENT;
476✔
190

191
                /* Kernel threads have no argv[] */
192
                _cleanup_free_ char *comm = NULL;
19✔
193

194
                r = pid_get_comm(pid, &comm);
19✔
195
                if (r < 0)
19✔
196
                        return r;
197

198
                free(t);
19✔
199
                t = strjoin("[", comm, "]");
19✔
200
                if (!t)
19✔
201
                        return -ENOMEM;
202

203
                k = strlen(t);
19✔
204
                r = k <= max_size;
19✔
205
                if (r == 0) /* truncation */
19✔
206
                        t[max_size] = '\0';
12✔
207
        }
208

209
        if (ret)
19,212✔
210
                *ret = TAKE_PTR(t);
19,212✔
211
        if (ret_size)
19,212✔
212
                *ret_size = k;
19,212✔
213

214
        return r;
215
}
216

217
int pid_get_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
17,948✔
218
        _cleanup_free_ char *t = NULL;
17,948✔
219
        size_t k;
17,948✔
220
        char *ans;
17,948✔
221

222
        assert(pid >= 0);
17,948✔
223
        assert(ret);
17,948✔
224

225
        /* Retrieve and format a command line. See above for discussion of retrieval options.
226
         *
227
         * There are two main formatting modes:
228
         *
229
         * - when PROCESS_CMDLINE_QUOTE is specified, output is quoted in C/Python style. If no shell special
230
         *   characters are present, this output can be copy-pasted into the terminal to execute. UTF-8
231
         *   output is assumed.
232
         *
233
         * - otherwise, a compact non-roundtrippable form is returned. Non-UTF8 bytes are replaced by �. The
234
         *   returned string is of the specified console width at most, abbreviated with an ellipsis.
235
         *
236
         * Returns -ESRCH if the process doesn't exist, and -ENOENT if the process has no command line (and
237
         * PROCESS_CMDLINE_COMM_FALLBACK is not specified). Returns 0 and sets *line otherwise. */
238

239
        int full = pid_get_cmdline_nulstr(pid, max_columns, flags, &t, &k);
17,948✔
240
        if (full < 0)
17,948✔
241
                return full;
242

243
        if (flags & (PROCESS_CMDLINE_QUOTE | PROCESS_CMDLINE_QUOTE_POSIX)) {
13,913✔
244
                ShellEscapeFlags shflags = SHELL_ESCAPE_EMPTY |
13,581✔
245
                        FLAGS_SET(flags, PROCESS_CMDLINE_QUOTE_POSIX) * SHELL_ESCAPE_POSIX;
13,581✔
246

247
                assert(!(flags & PROCESS_CMDLINE_USE_LOCALE));
13,581✔
248

249
                _cleanup_strv_free_ char **args = NULL;
13,581✔
250

251
                /* Drop trailing NULs, otherwise strv_parse_nulstr() adds additional empty strings at the end.
252
                 * See also issue #21186. */
253
                args = strv_parse_nulstr_full(t, k, /* drop_trailing_nuls= */ true);
13,581✔
254
                if (!args)
13,581✔
255
                        return -ENOMEM;
256

257
                ans = quote_command_line(args, shflags);
13,581✔
258
                if (!ans)
13,581✔
259
                        return -ENOMEM;
260
        } else {
261
                /* Arguments are separated by NULs. Let's replace those with spaces. */
262
                for (size_t i = 0; i < k - 1; i++)
15,264✔
263
                        if (t[i] == '\0')
14,932✔
264
                                t[i] = ' ';
518✔
265

266
                delete_trailing_chars(t, WHITESPACE);
332✔
267

268
                bool eight_bit = (flags & PROCESS_CMDLINE_USE_LOCALE) && !is_locale_utf8();
332✔
269

270
                ans = escape_non_printable_full(t, max_columns,
996✔
271
                                                eight_bit * XESCAPE_8_BIT | !full * XESCAPE_FORCE_ELLIPSIS);
616✔
272
                if (!ans)
332✔
273
                        return -ENOMEM;
274

275
                ans = str_realloc(ans);
332✔
276
        }
277

278
        *ret = ans;
13,913✔
279
        return 0;
13,913✔
280
}
281

282
int pidref_get_cmdline(const PidRef *pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
109✔
283
        _cleanup_free_ char *s = NULL;
109✔
284
        int r;
109✔
285

286
        if (!pidref_is_set(pid))
109✔
287
                return -ESRCH;
288

289
        if (pidref_is_remote(pid))
218✔
290
                return -EREMOTE;
291

292
        r = pid_get_cmdline(pid->pid, max_columns, flags, &s);
109✔
293
        if (r < 0)
109✔
294
                return r;
295

296
        r = pidref_verify(pid);
109✔
297
        if (r < 0)
109✔
298
                return r;
299

300
        if (ret)
109✔
301
                *ret = TAKE_PTR(s);
109✔
302
        return 0;
303
}
304

305
int pid_get_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret) {
5,378✔
306
        _cleanup_free_ char *t = NULL;
5,378✔
307
        char **args;
5,378✔
308
        size_t k;
5,378✔
309
        int r;
5,378✔
310

311
        assert(pid >= 0);
5,378✔
312
        assert((flags & ~PROCESS_CMDLINE_COMM_FALLBACK) == 0);
5,378✔
313
        assert(ret);
5,378✔
314

315
        r = pid_get_cmdline_nulstr(pid, SIZE_MAX, flags, &t, &k);
5,378✔
316
        if (r < 0)
5,378✔
317
                return r;
318

319
        args = strv_parse_nulstr_full(t, k, /* drop_trailing_nuls= */ true);
5,299✔
320
        if (!args)
5,299✔
321
                return -ENOMEM;
322

323
        *ret = args;
5,299✔
324
        return 0;
5,299✔
325
}
326

327
int pidref_get_cmdline_strv(const PidRef *pid, ProcessCmdlineFlags flags, char ***ret) {
×
328
        _cleanup_strv_free_ char **args = NULL;
×
329
        int r;
×
330

331
        if (!pidref_is_set(pid))
×
332
                return -ESRCH;
333

334
        if (pidref_is_remote(pid))
×
335
                return -EREMOTE;
336

337
        r = pid_get_cmdline_strv(pid->pid, flags, &args);
×
338
        if (r < 0)
×
339
                return r;
340

341
        r = pidref_verify(pid);
×
342
        if (r < 0)
×
343
                return r;
344

345
        if (ret)
×
346
                *ret = TAKE_PTR(args);
×
347

348
        return 0;
349
}
350

351
int pid_is_kernel_thread(pid_t pid) {
5,984✔
352
        int r;
5,984✔
353

354
        if (IN_SET(pid, 0, 1) || pid == getpid_cached()) /* pid 1, and we ourselves certainly aren't a kernel thread */
5,984✔
355
                return 0;
5,984✔
356
        if (!pid_is_valid(pid))
5,959✔
357
                return -EINVAL;
358

359
        const char *p = procfs_file_alloca(pid, "stat");
5,959✔
360
        _cleanup_free_ char *line = NULL;
5,959✔
361
        r = read_one_line_file(p, &line);
5,959✔
362
        if (r == -ENOENT)
5,959✔
363
                return -ESRCH;
364
        if (r < 0)
5,959✔
365
                return r;
366

367
        /* Skip past the comm field */
368
        char *q = strrchr(line, ')');
5,959✔
369
        if (!q)
5,959✔
370
                return -EINVAL;
371
        q++;
5,959✔
372

373
        /* Skip 6 fields to reach the flags field */
374
        for (size_t i = 0; i < 6; i++) {
41,713✔
375
                size_t l = strspn(q, WHITESPACE);
35,754✔
376
                if (l < 1)
35,754✔
377
                        return -EINVAL;
378
                q += l;
35,754✔
379

380
                l = strcspn(q, WHITESPACE);
35,754✔
381
                if (l < 1)
35,754✔
382
                        return -EINVAL;
383
                q += l;
35,754✔
384
        }
385

386
        /* Skip preceding whitespace */
387
        size_t l = strspn(q, WHITESPACE);
5,959✔
388
        if (l < 1)
5,959✔
389
                return -EINVAL;
390
        q += l;
5,959✔
391

392
        /* Truncate the rest */
393
        l = strcspn(q, WHITESPACE);
5,959✔
394
        if (l < 1)
5,959✔
395
                return -EINVAL;
396
        q[l] = 0;
5,959✔
397

398
        unsigned long long flags;
5,959✔
399
        r = safe_atollu(q, &flags);
5,959✔
400
        if (r < 0)
5,959✔
401
                return r;
402

403
        return !!(flags & PF_KTHREAD);
5,959✔
404
}
405

406
int pidref_is_kernel_thread(const PidRef *pid) {
2,678✔
407
        int result, r;
2,678✔
408

409
        if (!pidref_is_set(pid))
2,678✔
410
                return -ESRCH;
411

412
        if (pidref_is_remote(pid))
2,678✔
413
                return -EREMOTE;
414

415
        result = pid_is_kernel_thread(pid->pid);
2,678✔
416
        if (result < 0)
2,678✔
417
                return result;
418

419
        r = pidref_verify(pid); /* Verify that the PID wasn't reused since */
2,678✔
420
        if (r < 0)
2,678✔
421
                return r;
×
422

423
        return result;
424
}
425

426
static int get_process_link_contents(pid_t pid, const char *proc_file, char **ret) {
17,386✔
427
        const char *p;
17,386✔
428
        int r;
17,386✔
429

430
        assert(proc_file);
17,386✔
431

432
        p = procfs_file_alloca(pid, proc_file);
17,390✔
433

434
        r = readlink_malloc(p, ret);
17,386✔
435
        return (r == -ENOENT && proc_mounted() > 0) ? -ESRCH : r;
17,386✔
436
}
437

438
int get_process_exe(pid_t pid, char **ret) {
17,360✔
439
        char *d;
17,360✔
440
        int r;
17,360✔
441

442
        assert(pid >= 0);
17,360✔
443

444
        r = get_process_link_contents(pid, "exe", ret);
17,360✔
445
        if (r < 0)
17,360✔
446
                return r;
447

448
        if (ret) {
13,563✔
449
                d = endswith(*ret, " (deleted)");
13,563✔
450
                if (d)
13,563✔
451
                        *d = '\0';
×
452
        }
453

454
        return 0;
455
}
456

457
int pid_get_uid(pid_t pid, uid_t *ret) {
2,922✔
458
        int r;
2,922✔
459

460
        assert(pid >= 0);
2,922✔
461
        assert(ret);
2,922✔
462

463
        if (pid == 0 || pid == getpid_cached()) {
2,922✔
464
                *ret = getuid();
1✔
465
                return 0;
2,922✔
466
        }
467

468
        _cleanup_free_ char *v = NULL;
2,921✔
469
        r = procfs_file_get_field(pid, "status", "Uid", &v);
2,921✔
470
        if (r == -ENOENT)
2,921✔
471
                return -ESRCH;
472
        if (r < 0)
193✔
473
                return r;
474

475
        return parse_uid(v, ret);
193✔
476
}
477

478
int pidref_get_uid(const PidRef *pid, uid_t *ret) {
154✔
479
        int r;
154✔
480

481
        if (!pidref_is_set(pid))
154✔
482
                return -ESRCH;
154✔
483

484
        if (pidref_is_remote(pid))
154✔
485
                return -EREMOTE;
486

487
        if (pid->fd >= 0) {
154✔
488
                r = pidfd_get_uid(pid->fd, ret);
154✔
489
                if (!ERRNO_IS_NEG_NOT_SUPPORTED(r))
154✔
490
                        return r;
491
        }
492

493
        uid_t uid;
×
494
        r = pid_get_uid(pid->pid, &uid);
×
495
        if (r < 0)
×
496
                return r;
497

498
        r = pidref_verify(pid);
×
499
        if (r < 0)
×
500
                return r;
501

502
        if (ret)
×
503
                *ret = uid;
×
504
        return 0;
505
}
506

507
int get_process_gid(pid_t pid, gid_t *ret) {
2,922✔
508
        int r;
2,922✔
509

510
        assert(pid >= 0);
2,922✔
511
        assert(ret);
2,922✔
512

513
        if (pid == 0 || pid == getpid_cached()) {
2,922✔
514
                *ret = getgid();
1✔
515
                return 0;
2,922✔
516
        }
517

518
        _cleanup_free_ char *v = NULL;
2,921✔
519
        r = procfs_file_get_field(pid, "status", "Gid", &v);
2,921✔
520
        if (r == -ENOENT)
2,921✔
521
                return -ESRCH;
522
        if (r < 0)
193✔
523
                return r;
524

525
        return parse_gid(v, ret);
2,921✔
526
}
527

528
int get_process_cwd(pid_t pid, char **ret) {
13✔
529
        assert(pid >= 0);
13✔
530

531
        if (pid == 0 || pid == getpid_cached())
13✔
532
                return safe_getcwd(ret);
×
533

534
        return get_process_link_contents(pid, "cwd", ret);
13✔
535
}
536

537
int get_process_root(pid_t pid, char **ret) {
13✔
538
        assert(pid >= 0);
13✔
539
        return get_process_link_contents(pid, "root", ret);
13✔
540
}
541

542
#define ENVIRONMENT_BLOCK_MAX (5U*1024U*1024U)
543

544
int get_process_environ(pid_t pid, char **ret) {
15✔
545
        _cleanup_fclose_ FILE *f = NULL;
15✔
546
        _cleanup_free_ char *outcome = NULL;
15✔
547
        size_t sz = 0;
15✔
548
        const char *p;
15✔
549
        int r;
15✔
550

551
        assert(pid >= 0);
15✔
552
        assert(ret);
15✔
553

554
        p = procfs_file_alloca(pid, "environ");
15✔
555

556
        r = fopen_unlocked(p, "re", &f);
15✔
557
        if (r == -ENOENT)
15✔
558
                return -ESRCH;
559
        if (r < 0)
15✔
560
                return r;
561

562
        for (;;) {
6,426✔
563
                char c;
6,441✔
564

565
                if (sz >= ENVIRONMENT_BLOCK_MAX)
6,441✔
566
                        return -ENOBUFS;
×
567

568
                if (!GREEDY_REALLOC(outcome, sz + 5))
6,441✔
569
                        return -ENOMEM;
570

571
                r = safe_fgetc(f, &c);
6,441✔
572
                if (r < 0)
6,441✔
573
                        return r;
574
                if (r == 0)
6,441✔
575
                        break;
576

577
                if (c == '\0')
6,426✔
578
                        outcome[sz++] = '\n';
228✔
579
                else
580
                        sz += cescape_char(c, outcome + sz);
6,198✔
581
        }
582

583
        outcome[sz] = '\0';
15✔
584
        *ret = TAKE_PTR(outcome);
15✔
585

586
        return 0;
15✔
587
}
588

589
int pid_get_ppid(pid_t pid, pid_t *ret) {
6✔
590
        _cleanup_free_ char *line = NULL;
6✔
591
        unsigned long ppid;
6✔
592
        const char *p;
6✔
593
        int r;
6✔
594

595
        assert(pid >= 0);
6✔
596

597
        if (pid == 0)
6✔
598
                pid = getpid_cached();
1✔
599
        if (pid == 1) /* PID 1 has no parent, shortcut this case */
6✔
600
                return -EADDRNOTAVAIL;
601

602
        if (pid == getpid_cached()) {
3✔
603
                if (ret)
2✔
604
                        *ret = getppid();
2✔
605
                return 0;
606
        }
607

608
        p = procfs_file_alloca(pid, "stat");
1✔
609
        r = read_one_line_file(p, &line);
1✔
610
        if (r == -ENOENT)
1✔
611
                return -ESRCH;
612
        if (r < 0)
×
613
                return r;
614

615
        /* Let's skip the pid and comm fields. The latter is enclosed in () but does not escape any () in its
616
         * value, so let's skip over it manually */
617

618
        p = strrchr(line, ')');
×
619
        if (!p)
×
620
                return -EIO;
621
        p++;
×
622

623
        if (sscanf(p, " "
×
624
                   "%*c "  /* state */
625
                   "%lu ", /* ppid */
626
                   &ppid) != 1)
627
                return -EIO;
628

629
        /* If ppid is zero the process has no parent. Which might be the case for PID 1 (caught above)
630
         * but also for processes originating in other namespaces that are inserted into a pidns.
631
         * Return a recognizable error in this case. */
632
        if (ppid == 0)
×
633
                return -EADDRNOTAVAIL;
634

635
        if ((pid_t) ppid < 0 || (unsigned long) (pid_t) ppid != ppid)
×
636
                return -ERANGE;
637

638
        if (ret)
×
639
                *ret = (pid_t) ppid;
×
640

641
        return 0;
642
}
643

644
int pidref_get_ppid(const PidRef *pidref, pid_t *ret) {
6,520✔
645
        int r;
6,520✔
646

647
        if (!pidref_is_set(pidref))
6,520✔
648
                return -ESRCH;
6,520✔
649

650
        if (pidref_is_remote(pidref))
6,520✔
651
                return -EREMOTE;
652

653
        if (pidref->fd >= 0) {
6,520✔
654
                r = pidfd_get_ppid(pidref->fd, ret);
6,520✔
655
                if (!ERRNO_IS_NEG_NOT_SUPPORTED(r))
6,520✔
656
                        return r;
657
        }
658

659
        pid_t ppid;
×
660
        r = pid_get_ppid(pidref->pid, ret ? &ppid : NULL);
×
661
        if (r < 0)
×
662
                return r;
663

664
        r = pidref_verify(pidref);
×
665
        if (r < 0)
×
666
                return r;
667

668
        if (ret)
×
669
                *ret = ppid;
×
670
        return 0;
671
}
672

673
int pidref_get_ppid_as_pidref(const PidRef *pidref, PidRef *ret) {
11✔
674
        pid_t ppid;
11✔
675
        int r;
11✔
676

677
        POINTER_MAY_BE_NULL(pidref);
11✔
678
        assert(ret);
11✔
679

680
        r = pidref_get_ppid(pidref, &ppid);
11✔
681
        if (r < 0)
11✔
682
                return r;
11✔
683

684
        for (unsigned attempt = 0; attempt < 16; attempt++) {
10✔
685
                _cleanup_(pidref_done) PidRef parent = PIDREF_NULL;
10✔
686

687
                r = pidref_set_pid(&parent, ppid);
10✔
688
                if (r < 0)
10✔
689
                        return r;
690

691
                /* If we have a pidfd of the original PID, let's verify that the process we acquired really
692
                 * is the parent still */
693
                if (pidref->fd >= 0) {
10✔
694
                        r = pidref_get_ppid(pidref, &ppid);
10✔
695
                        if (r < 0)
10✔
696
                                return r;
697

698
                        /* Did the PPID change since we queried it? if so we might have pinned the wrong
699
                         * process, if its PID got reused by now. Let's try again */
700
                        if (parent.pid != ppid)
10✔
701
                                continue;
×
702
                }
703

704
                *ret = TAKE_PIDREF(parent);
10✔
705
                return 0;
10✔
706
        }
707

708
        /* Give up after 16 tries */
709
        return -ENOTRECOVERABLE;
710
}
711

712
int pid_get_start_time(pid_t pid, usec_t *ret) {
2,943✔
713
        _cleanup_free_ char *line = NULL;
2,943✔
714
        const char *p;
2,943✔
715
        int r;
2,943✔
716

717
        assert(pid >= 0);
2,943✔
718

719
        p = procfs_file_alloca(pid, "stat");
2,943✔
720
        r = read_one_line_file(p, &line);
2,943✔
721
        if (r == -ENOENT)
2,943✔
722
                return -ESRCH;
723
        if (r < 0)
2,943✔
724
                return r;
725

726
        /* Let's skip the pid and comm fields. The latter is enclosed in () but does not escape any () in its
727
         * value, so let's skip over it manually */
728

729
        p = strrchr(line, ')');
2,943✔
730
        if (!p)
2,943✔
731
                return -EIO;
732
        p++;
2,943✔
733

734
        unsigned long llu;
2,943✔
735

736
        if (sscanf(p, " "
2,943✔
737
                   "%*c " /* state */
738
                   "%*u " /* ppid */
739
                   "%*u " /* pgrp */
740
                   "%*u " /* session */
741
                   "%*u " /* tty_nr */
742
                   "%*u " /* tpgid */
743
                   "%*u " /* flags */
744
                   "%*u " /* minflt */
745
                   "%*u " /* cminflt */
746
                   "%*u " /* majflt */
747
                   "%*u " /* cmajflt */
748
                   "%*u " /* utime */
749
                   "%*u " /* stime */
750
                   "%*u " /* cutime */
751
                   "%*u " /* cstime */
752
                   "%*i " /* priority */
753
                   "%*i " /* nice */
754
                   "%*u " /* num_threads */
755
                   "%*u " /* itrealvalue */
756
                   "%lu ", /* starttime */
757
                   &llu) != 1)
758
                return -EIO;
759

760
        if (ret)
2,943✔
761
                *ret = jiffies_to_usec(llu); /* CLOCK_BOOTTIME */
2,943✔
762

763
        return 0;
764
}
765

766
int pidref_get_start_time(const PidRef *pid, usec_t *ret) {
2,943✔
767
        usec_t t;
2,943✔
768
        int r;
2,943✔
769

770
        if (!pidref_is_set(pid))
2,943✔
771
                return -ESRCH;
2,943✔
772

773
        if (pidref_is_remote(pid))
2,943✔
774
                return -EREMOTE;
775

776
        r = pid_get_start_time(pid->pid, ret ? &t : NULL);
2,943✔
777
        if (r < 0)
2,943✔
778
                return r;
779

780
        r = pidref_verify(pid);
2,943✔
781
        if (r < 0)
2,943✔
782
                return r;
783

784
        if (ret)
2,943✔
785
                *ret = t;
2,943✔
786

787
        return 0;
788
}
789

790
int get_process_umask(pid_t pid, mode_t *ret) {
29,587✔
791
        _cleanup_free_ char *m = NULL;
29,587✔
792
        int r;
29,587✔
793

794
        assert(pid >= 0);
29,587✔
795
        assert(ret);
29,587✔
796

797
        r = procfs_file_get_field(pid, "status", "Umask", &m);
29,587✔
798
        if (r == -ENOENT)
29,587✔
799
                return -ESRCH;
800
        if (r < 0)
29,587✔
801
                return r;
802

803
        return parse_mode(m, ret);
29,587✔
804
}
805

806
/*
807
 * Return values:
808
 * < 0 : pidref_wait_for_terminate() failed to get the state of the
809
 *       process, the process was terminated by a signal, or
810
 *       failed for an unknown reason.
811
 * >=0 : The process terminated normally, and its exit code is
812
 *       returned.
813
 *
814
 * That is, success is indicated by a return value of zero, and an
815
 * error is indicated by a non-zero value.
816
 *
817
 * A warning is emitted if the process terminates abnormally,
818
 * and also if it returns non-zero unless check_exit_code is true.
819
 */
820
int pidref_wait_for_terminate_and_check(const char *name, PidRef *pidref, WaitFlags flags) {
10,516✔
821
        int r;
10,516✔
822

823
        if (!pidref_is_set(pidref))
10,516✔
824
                return -ESRCH;
10,516✔
825
        if (pidref_is_remote(pidref))
21,032✔
826
                return -EREMOTE;
827
        if (pidref->pid == 1 || pidref_is_self(pidref))
10,516✔
828
                return -ECHILD;
829

830
        _cleanup_free_ char *buffer = NULL;
10,516✔
831
        if (!name) {
10,516✔
832
                r = pidref_get_comm(pidref, &buffer);
2✔
833
                if (r < 0)
2✔
834
                        log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pidref->pid);
×
835
                else
836
                        name = buffer;
2✔
837
        }
838

839
        int prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG;
10,516✔
840

841
        siginfo_t status;
10,516✔
842
        r = pidref_wait_for_terminate(pidref, &status);
10,516✔
843
        if (r < 0)
10,516✔
844
                return log_full_errno(prio, r, "Failed to wait for '%s': %m", strna(name));
×
845

846
        if (status.si_code == CLD_EXITED) {
10,516✔
847
                if (status.si_status != EXIT_SUCCESS)
10,516✔
848
                        log_full(flags & WAIT_LOG_NON_ZERO_EXIT_STATUS ? LOG_ERR : LOG_DEBUG,
1,136✔
849
                                 "'%s' failed with exit status %i.", strna(name), status.si_status);
850
                else
851
                        log_debug("'%s' succeeded.", name);
9,380✔
852

853
                return status.si_status;
10,516✔
854

855
        } else if (IN_SET(status.si_code, CLD_KILLED, CLD_DUMPED))
×
856
                return log_full_errno(prio, SYNTHETIC_ERRNO(EPROTO),
×
857
                                      "'%s' terminated by signal %s.", strna(name), signal_to_string(status.si_status));
858

859
        return log_full_errno(prio, SYNTHETIC_ERRNO(EPROTO),
×
860
                              "'%s' failed due to unknown reason.", strna(name));
861
}
862

863
int kill_and_sigcont(pid_t pid, int sig) {
×
864
        int r;
×
865

866
        r = RET_NERRNO(kill(pid, sig));
×
867

868
        /* If this worked, also send SIGCONT, unless we already just sent a SIGCONT, or SIGKILL was sent which isn't
869
         * affected by a process being suspended anyway. */
870
        if (r >= 0 && !IN_SET(sig, SIGCONT, SIGKILL))
×
871
                (void) kill(pid, SIGCONT);
×
872

873
        return r;
×
874
}
875

876
int getenv_for_pid(pid_t pid, const char *field, char **ret) {
8,344✔
877
        _cleanup_fclose_ FILE *f = NULL;
8,344✔
878
        const char *path;
8,344✔
879
        size_t sum = 0;
8,344✔
880
        int r;
8,344✔
881

882
        assert(pid >= 0);
8,344✔
883
        assert(field);
8,344✔
884
        assert(ret);
8,344✔
885

886
        if (pid == 0 || pid == getpid_cached())
8,344✔
887
                return strdup_to_full(ret, getenv(field));
14✔
888

889
        if (!pid_is_valid(pid))
8,330✔
890
                return -EINVAL;
891

892
        path = procfs_file_alloca(pid, "environ");
8,330✔
893

894
        r = fopen_unlocked(path, "re", &f);
8,330✔
895
        if (r == -ENOENT)
8,330✔
896
                return -ESRCH;
897
        if (r < 0)
7,904✔
898
                return r;
899

900
        for (;;) {
107,406✔
901
                _cleanup_free_ char *line = NULL;
50,564✔
902
                const char *match;
56,860✔
903

904
                if (sum > ENVIRONMENT_BLOCK_MAX) /* Give up searching eventually */
56,860✔
905
                        return -ENOBUFS;
906

907
                r = read_nul_string(f, LONG_LINE_MAX, &line);
56,860✔
908
                if (r < 0)
56,860✔
909
                        return r;
910
                if (r == 0)  /* EOF */
56,860✔
911
                        break;
912

913
                sum += r;
50,564✔
914

915
                match = startswith(line, field);
50,564✔
916
                if (match && *match == '=')
50,564✔
917
                        return strdup_to_full(ret, match + 1);
18✔
918
        }
919

920
        *ret = NULL;
6,296✔
921
        return 0;
6,296✔
922
}
923

924
int pidref_is_my_child(PidRef *pid) {
6,498✔
925
        int r;
6,498✔
926

927
        if (!pidref_is_set(pid))
6,498✔
928
                return -ESRCH;
6,498✔
929

930
        if (pidref_is_remote(pid))
6,498✔
931
                return -EREMOTE;
932

933
        if (pid->pid == 1 || pidref_is_self(pid))
6,498✔
934
                return false;
935

936
        pid_t ppid;
6,498✔
937
        r = pidref_get_ppid(pid, &ppid);
6,498✔
938
        if (r == -EADDRNOTAVAIL) /* if this process is outside of our pidns, it is definitely not our child */
6,498✔
939
                return false;
940
        if (r < 0)
6,498✔
941
                return r;
942

943
        return ppid == getpid_cached();
6,498✔
944
}
945

946
int pid_is_my_child(pid_t pid) {
×
947

948
        if (pid == 0)
×
949
                return false;
×
950

951
        return pidref_is_my_child(&PIDREF_MAKE_FROM_PID(pid));
×
952
}
953

954
int pidref_is_unwaited(PidRef *pid) {
13,865✔
955
        int r;
13,865✔
956

957
        /* Checks whether a PID is still valid at all, including a zombie */
958

959
        if (!pidref_is_set(pid))
13,865✔
960
                return -ESRCH;
961

962
        if (pidref_is_remote(pid))
13,864✔
963
                return -EREMOTE;
964

965
        if (pid->pid == 1 || pidref_is_self(pid))
13,864✔
966
                return true;
967

968
        r = pidref_kill(pid, 0);
13,863✔
969
        if (r == -ESRCH)
13,863✔
970
                return false;
971
        if (r < 0)
5,712✔
972
                return r;
233✔
973

974
        return true;
975
}
976

977
int pid_is_unwaited(pid_t pid) {
10,334✔
978

979
        if (pid == 0)
10,334✔
980
                return true;
10,334✔
981

982
        return pidref_is_unwaited(&PIDREF_MAKE_FROM_PID(pid));
10,334✔
983
}
984

985
int pid_is_alive(pid_t pid) {
15,667✔
986
        int r;
15,667✔
987

988
        /* Checks whether a PID is still valid and not a zombie */
989

990
        if (pid < 0)
15,667✔
991
                return -ESRCH;
992

993
        if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */
15,666✔
994
                return true;
995

996
        if (pid == getpid_cached())
15,666✔
997
                return true;
998

999
        r = get_process_state(pid);
15,665✔
1000
        if (r == -ESRCH)
15,665✔
1001
                return false;
1002
        if (r < 0)
12,270✔
1003
                return r;
1004

1005
        return r != 'Z';
12,270✔
1006
}
1007

1008
int pidref_is_alive(const PidRef *pidref) {
15,664✔
1009
        int r, result;
15,664✔
1010

1011
        if (!pidref_is_set(pidref))
15,664✔
1012
                return -ESRCH;
1013

1014
        if (pidref_is_remote(pidref))
15,662✔
1015
                return -EREMOTE;
1016

1017
        result = pid_is_alive(pidref->pid);
15,662✔
1018
        if (result < 0) {
15,662✔
1019
                assert(result != -ESRCH);
×
1020
                return result;
1021
        }
1022

1023
        r = pidref_verify(pidref);
15,662✔
1024
        if (r == -ESRCH)
15,662✔
1025
                return false;
1026
        if (r < 0)
12,267✔
1027
                return r;
×
1028

1029
        return result;
1030
}
1031

1032
int pidref_from_same_root_fs(PidRef *a, PidRef *b) {
20✔
1033
        _cleanup_(pidref_done) PidRef self = PIDREF_NULL;
×
1034
        int r;
20✔
1035

1036
        /* Checks if the two specified processes have the same root fs. Either can be specified as NULL in
1037
         * which case we'll check against ourselves. */
1038

1039
        if (!a || !b) {
20✔
1040
                r = pidref_set_self(&self);
×
1041
                if (r < 0)
×
1042
                        return r;
1043
                if (!a)
×
1044
                        a = &self;
×
1045
                if (!b)
×
1046
                        b = &self;
×
1047
        }
1048

1049
        if (!pidref_is_set(a) || !pidref_is_set(b))
20✔
1050
                return -ESRCH;
1051

1052
        /* If one of the two processes have the same root they cannot have the same root fs, but if both of
1053
         * them do we don't know */
1054
        if (pidref_is_remote(a) && pidref_is_remote(b))
20✔
1055
                return -EREMOTE;
1056
        if (pidref_is_remote(a) || pidref_is_remote(b))
60✔
1057
                return false;
1058

1059
        if (pidref_equal(a, b))
20✔
1060
                return true;
1061

1062
        const char *roota = procfs_file_alloca(a->pid, "root");
18✔
1063
        const char *rootb = procfs_file_alloca(b->pid, "root");
18✔
1064

1065
        int result = inode_same(roota, rootb, 0);
18✔
1066
        if (result == -ENOENT)
18✔
1067
                return proc_mounted() == 0 ? -ENOSYS : -ESRCH;
×
1068
        if (result < 0)
18✔
1069
                return result;
1070

1071
        r = pidref_verify(a);
18✔
1072
        if (r < 0)
18✔
1073
                return r;
1074
        r = pidref_verify(b);
18✔
1075
        if (r < 0)
18✔
1076
                return r;
×
1077

1078
        return result;
1079
}
1080

1081
bool is_main_thread(void) {
9,399,965✔
1082
        static thread_local int cached = -1;
9,399,965✔
1083

1084
        if (cached < 0)
9,399,965✔
1085
                cached = getpid_cached() == gettid();
69,925✔
1086

1087
        return cached;
9,399,965✔
1088
}
1089

1090
unsigned long personality_from_string(const char *s) {
9✔
1091
        Architecture architecture;
9✔
1092

1093
        if (!s)
9✔
1094
                return PERSONALITY_INVALID;
1095

1096
        /* Parse a personality specifier. We use our own identifiers that indicate specific ABIs, rather than just
1097
         * hints regarding the register size, since we want to keep things open for multiple locally supported ABIs for
1098
         * the same register size. */
1099

1100
        architecture = architecture_from_string(s);
8✔
1101
        if (architecture < 0)
8✔
1102
                return PERSONALITY_INVALID;
1103

1104
        if (architecture == native_architecture())
6✔
1105
                return PER_LINUX;
1106
#ifdef ARCHITECTURE_SECONDARY
1107
        if (architecture == ARCHITECTURE_SECONDARY)
3✔
1108
                return PER_LINUX32;
2✔
1109
#endif
1110

1111
        return PERSONALITY_INVALID;
1112
}
1113

1114
const char* personality_to_string(unsigned long p) {
8,034✔
1115
        Architecture architecture = _ARCHITECTURE_INVALID;
8,034✔
1116

1117
        if (p == PER_LINUX)
8,034✔
1118
                architecture = native_architecture();
1119
#ifdef ARCHITECTURE_SECONDARY
1120
        else if (p == PER_LINUX32)
8,029✔
1121
                architecture = ARCHITECTURE_SECONDARY;
1122
#endif
1123

1124
        if (architecture < 0)
1125
                return NULL;
1126

1127
        return architecture_to_string(architecture);
7✔
1128
}
1129

1130
int safe_personality(unsigned long p) {
1,863✔
1131
        int ret;
1,863✔
1132

1133
        /* So here's the deal, personality() is weirdly defined by glibc. In some cases it returns a failure via errno,
1134
         * and in others as negative return value containing an errno-like value. Let's work around this: this is a
1135
         * wrapper that uses errno if it is set, and uses the return value otherwise. And then it sets both errno and
1136
         * the return value indicating the same issue, so that we are definitely on the safe side.
1137
         *
1138
         * See https://github.com/systemd/systemd/issues/6737 */
1139

1140
        errno = 0;
1,863✔
1141
        ret = personality(p);
1,863✔
1142
        if (ret < 0) {
1,863✔
1143
                if (errno != 0)
12✔
1144
                        return -errno;
12✔
1145

1146
                errno = -ret;
×
1147
        }
1148

1149
        return ret;
1150
}
1151

1152
int opinionated_personality(unsigned long *ret) {
1,848✔
1153
        int current;
1,848✔
1154

1155
        assert(ret);
1,848✔
1156

1157
        /* Returns the current personality, or PERSONALITY_INVALID if we can't determine it. This function is a bit
1158
         * opinionated though, and ignores all the finer-grained bits and exotic personalities, only distinguishing the
1159
         * two most relevant personalities: PER_LINUX and PER_LINUX32. */
1160

1161
        current = safe_personality(PERSONALITY_INVALID);
1,848✔
1162
        if (current < 0)
1,848✔
1163
                return current;
1164

1165
        if (((unsigned long) current & OPINIONATED_PERSONALITY_MASK) == PER_LINUX32)
1,848✔
1166
                *ret = PER_LINUX32;
×
1167
        else
1168
                *ret = PER_LINUX;
1,848✔
1169

1170
        return 0;
1171
}
1172

1173
void valgrind_summary_hack(void) {
65✔
1174
#if HAVE_VALGRIND_VALGRIND_H
1175
        if (getpid_cached() == 1 && RUNNING_ON_VALGRIND) {
1176
                pid_t pid;
1177
                pid = raw_clone(SIGCHLD);
1178
                if (pid < 0)
1179
                        log_struct_errno(
1180
                                LOG_EMERG, errno,
1181
                                LOG_MESSAGE_ID(SD_MESSAGE_VALGRIND_HELPER_FORK_STR),
1182
                                LOG_MESSAGE("Failed to fork off valgrind helper: %m"));
1183
                else if (pid == 0)
1184
                        exit(EXIT_SUCCESS);
1185
                else {
1186
                        log_info("Spawned valgrind helper as PID "PID_FMT".", pid);
1187
                        _cleanup_(pidref_done) PidRef pidref = PIDREF_MAKE_FROM_PID(pid);
1188
                        (void) pidref_set_pid(&pidref, pid);
1189
                        (void) pidref_wait_for_terminate(&pidref, NULL);
1190
                }
1191
        }
1192
#endif
1193
}
65✔
1194

1195
int pid_compare_func(const pid_t *a, const pid_t *b) {
1,670✔
1196
        /* Suitable for usage in qsort() */
1197
        assert(a);
1,670✔
1198
        assert(b);
1,670✔
1199

1200
        return CMP(*a, *b);
1,670✔
1201
}
1202

1203
bool nice_is_valid(int n) {
1,248✔
1204
        return n >= PRIO_MIN && n < PRIO_MAX;
1,248✔
1205
}
1206

1207
bool sched_policy_is_valid(int policy) {
×
1208
        return IN_SET(policy, SCHED_OTHER, SCHED_BATCH, SCHED_IDLE, SCHED_FIFO, SCHED_RR, SCHED_EXT);
×
1209
}
1210

1211
bool sched_policy_supported(int policy) {
4✔
1212
        return sched_get_priority_min(policy) >= 0;
4✔
1213
}
1214

1215
/* Wrappers around sched_get_priority_{min,max}() that gracefully handles missing SCHED_EXT support in the kernel */
1216
int sched_get_priority_min_safe(int policy) {
4✔
1217
        int r;
4✔
1218

1219
        r = sched_get_priority_min(policy);
4✔
1220
        if (r >= 0)
4✔
1221
                return r;
4✔
1222

1223
        /* Fallback priority */
1224
        return 0;
1225
}
1226

1227
int sched_get_priority_max_safe(int policy) {
4✔
1228
        int r;
4✔
1229

1230
        r = sched_get_priority_max(policy);
4✔
1231
        if (r >= 0)
4✔
1232
                return r;
4✔
1233

1234
        return 0;
1235
}
1236

1237
/* The cached PID, possible values:
1238
 *
1239
 *     == UNSET [0]  → cache not initialized yet
1240
 *     == BUSY [-1]  → some thread is initializing it at the moment
1241
 *     any other     → the cached PID
1242
 */
1243

1244
#define CACHED_PID_UNSET ((pid_t) 0)
1245
#define CACHED_PID_BUSY ((pid_t) -1)
1246

1247
static pid_t cached_pid = CACHED_PID_UNSET;
1248

1249
void reset_cached_pid(void) {
2,644✔
1250
        /* Invoked in the child after a fork(), i.e. at the first moment the PID changed */
1251
        cached_pid = CACHED_PID_UNSET;
2,644✔
1252
}
2,644✔
1253

1254
pid_t getpid_cached(void) {
186,398,585✔
1255
        static bool installed = false;
186,398,585✔
1256
        pid_t current_value = CACHED_PID_UNSET;
186,398,585✔
1257

1258
        /* getpid_cached() is much like getpid(), but caches the value in local memory, to avoid having to invoke a
1259
         * system call each time. This restores glibc behaviour from before 2.24, when getpid() was unconditionally
1260
         * cached. Starting with 2.24 getpid() started to become prohibitively expensive when used for detecting when
1261
         * objects were used across fork()s. With this caching the old behaviour is somewhat restored.
1262
         *
1263
         * https://bugzilla.redhat.com/show_bug.cgi?id=1443976
1264
         * https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c579f48edba88380635ab98cb612030e3ed8691e
1265
         */
1266

1267
        (void) __atomic_compare_exchange_n(
186,398,585✔
1268
                        &cached_pid,
1269
                        &current_value,
1270
                        CACHED_PID_BUSY,
1271
                        false,
1272
                        __ATOMIC_SEQ_CST,
1273
                        __ATOMIC_SEQ_CST);
1274

1275
        switch (current_value) {
186,398,585✔
1276

1277
        case CACHED_PID_UNSET: { /* Not initialized yet, then do so now */
123,554✔
1278
                pid_t new_pid;
123,554✔
1279

1280
                new_pid = getpid();
123,554✔
1281

1282
                if (!installed) {
123,554✔
1283
                        /* __register_atfork() either returns 0 or -ENOMEM, in its glibc implementation. Since it's
1284
                         * only half-documented (glibc doesn't document it but LSB does — though only superficially)
1285
                         * we'll check for errors only in the most generic fashion possible. */
1286

1287
                        if (pthread_atfork(NULL, NULL, reset_cached_pid) != 0) {
87,877✔
1288
                                /* OOM? Let's try again later */
1289
                                cached_pid = CACHED_PID_UNSET;
×
1290
                                return new_pid;
×
1291
                        }
1292

1293
                        installed = true;
87,877✔
1294
                }
1295

1296
                cached_pid = new_pid;
123,554✔
1297
                return new_pid;
123,554✔
1298
        }
1299

1300
        case CACHED_PID_BUSY: /* Somebody else is currently initializing */
×
1301
                return getpid();
×
1302

1303
        default: /* Properly initialized */
1304
                return current_value;
1305
        }
1306
}
1307

1308
int must_be_root(void) {
114✔
1309

1310
        if (geteuid() == 0)
114✔
1311
                return 0;
1312

1313
        return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root.");
×
1314
}
1315

1316
pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata) {
9,873✔
1317
        size_t ps;
9,873✔
1318
        pid_t pid;
9,873✔
1319
        void *mystack;
9,873✔
1320

1321
        /* A wrapper around glibc's clone() call that automatically sets up a "nested" stack. Only supports
1322
         * invocations without CLONE_VM, so that we can continue to use the parent's stack mapping.
1323
         *
1324
         * Note: glibc's clone() wrapper does not synchronize malloc() locks. This means that if the parent
1325
         * is threaded these locks will be in an undefined state in the child, and hence memory allocations
1326
         * are likely going to run into deadlocks. Hence: if you use this function make sure your parent is
1327
         * strictly single-threaded or your child never calls malloc(). */
1328

1329
        assert((flags & (CLONE_VM|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID|
9,873✔
1330
                         CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0);
1331

1332
        /* We allocate some space on the stack to use as the stack for the child (hence "nested"). Note that
1333
         * the net effect is that the child will have the start of its stack inside the stack of the parent,
1334
         * but since they are a CoW copy of each other that's fine. We allocate one page-aligned page. But
1335
         * since we don't want to deal with differences between systems where the stack grows backwards or
1336
         * forwards we'll allocate one more and place the stack address in the middle. Except that we also
1337
         * want it page aligned, hence we'll allocate one page more. Makes 3. */
1338

1339
        ps = page_size();
9,873✔
1340
        mystack = alloca(ps*3);
9,873✔
1341
        mystack = (uint8_t*) mystack + ps; /* move pointer one page ahead since stacks usually grow backwards */
9,873✔
1342
        mystack = (void*) ALIGN_TO((uintptr_t) mystack, ps); /* align to page size (moving things further ahead) */
9,873✔
1343

1344
#if HAVE_CLONE
1345
        pid = clone(fn, mystack, flags, userdata);
9,873✔
1346
#else
1347
        pid = __clone2(fn, mystack, ps, flags, userdata);
1348
#endif
1349
        if (pid < 0)
9,873✔
1350
                return -errno;
×
1351

1352
        return pid;
1353
}
1354

1355
static int fork_flags_to_signal(ForkFlags flags) {
33,824✔
1356
        return (flags & FORK_DEATHSIG_SIGTERM) ? SIGTERM :
33,824✔
1357
                (flags & FORK_DEATHSIG_SIGINT) ? SIGINT :
1,016✔
1358
                                                 SIGKILL;
1359
}
1360

1361
int pidref_safe_fork_full(
33,434✔
1362
                const char *name,
1363
                const int stdio_fds[3],
1364
                int except_fds[],
1365
                size_t n_except_fds,
1366
                ForkFlags flags,
1367
                PidRef *ret) {
1368

1369
        pid_t original_pid, pid;
33,434✔
1370
        sigset_t saved_ss, ss;
33,434✔
1371
        _unused_ _cleanup_(block_signals_reset) sigset_t *saved_ssp = NULL;
×
1372
        bool block_signals = false, block_all = false, intermediary = false;
33,434✔
1373
        _cleanup_close_pair_ int pidref_transport_fds[2] = EBADF_PAIR;
67,541✔
1374
        int prio, r;
33,434✔
1375

1376
        assert(!FLAGS_SET(flags, FORK_WAIT|FORK_FREEZE));
33,434✔
1377
        assert(!FLAGS_SET(flags, FORK_DETACH) ||
33,434✔
1378
               (flags & (FORK_WAIT|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL)) == 0);
1379

1380
        /* A wrapper around fork(), that does a couple of important initializations in addition to mere
1381
         * forking. If provided, ret is initialized in both the parent and the child process, both times
1382
         * referencing the child process. Returns == 0 in the child and > 0 in the parent. */
1383

1384
        prio = flags & FORK_LOG ? LOG_ERR : LOG_DEBUG;
33,434✔
1385

1386
        original_pid = getpid_cached();
33,434✔
1387

1388
        if (flags & FORK_FLUSH_STDIO) {
33,434✔
1389
                fflush(stdout);
22✔
1390
                fflush(stderr); /* This one shouldn't be necessary, stderr should be unbuffered anyway, but let's better be safe than sorry */
22✔
1391
        }
1392

1393
        if (flags & (FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT)) {
33,434✔
1394
                /* We temporarily block all signals, so that the new child has them blocked initially. This
1395
                 * way, we can be sure that SIGTERMs are not lost we might send to the child. (Note that for
1396
                 * FORK_DEATHSIG_SIGKILL we don't bother, since it cannot be blocked anyway.) */
1397

1398
                assert_se(sigfillset(&ss) >= 0);
28,627✔
1399
                block_signals = block_all = true;
1400

1401
        } else if (flags & FORK_WAIT) {
4,807✔
1402
                /* Let's block SIGCHLD at least, so that we can safely watch for the child process */
1403

1404
                assert_se(sigemptyset(&ss) >= 0);
167✔
1405
                assert_se(sigaddset(&ss, SIGCHLD) >= 0);
167✔
1406
                block_signals = true;
1407
        }
1408

1409
        if (block_signals) {
1410
                if (sigprocmask(SIG_BLOCK, &ss, &saved_ss) < 0)
28,794✔
1411
                        return log_full_errno(prio, errno, "Failed to block signal mask: %m");
×
1412
                saved_ssp = &saved_ss;
28,794✔
1413
        }
1414

1415
        if (FLAGS_SET(flags, FORK_DETACH)) {
33,434✔
1416
                /* Fork off intermediary child if needed */
1417

1418
                r = is_reaper_process();
111✔
1419
                if (r < 0)
111✔
1420
                        return log_full_errno(prio, r, "Failed to determine if we are a reaper process: %m");
×
1421

1422
                if (!r) {
111✔
1423
                        /* Not a reaper process, hence do a double fork() so we are reparented to one */
1424

1425
                        if (ret && socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, pidref_transport_fds) < 0)
11✔
1426
                                return log_full_errno(prio, errno, "Failed to allocate pidref socket: %m");
×
1427

1428
                        pid = fork();
11✔
1429
                        if (pid < 0)
30✔
1430
                                return log_full_errno(prio, errno, "Failed to fork off '%s': %m", strna(name));
×
1431
                        if (pid > 0) {
30✔
1432
                                log_debug("Successfully forked off intermediary '%s' as PID " PID_FMT ".", strna(name), pid);
11✔
1433

1434
                                pidref_transport_fds[1] = safe_close(pidref_transport_fds[1]);
11✔
1435

1436
                                if (pidref_transport_fds[0] >= 0) {
11✔
1437
                                        /* Wait for the intermediary child to exit so the caller can be
1438
                                         * certain the actual child process has been reparented by the time
1439
                                         * this function returns. */
1440
                                        r = pidref_wait_for_terminate_and_check(
10✔
1441
                                                        name,
1442
                                                        &PIDREF_MAKE_FROM_PID(pid),
10✔
1443
                                                        FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
1444
                                        if (r < 0)
10✔
1445
                                                return log_full_errno(prio, r, "Failed to wait for intermediary process: %m");
×
1446
                                        if (r != EXIT_SUCCESS) /* exit status > 0 should be treated as failure, too */
10✔
1447
                                                return -EPROTO;
1448

1449
                                        int pidfd;
10✔
1450
                                        ssize_t n = receive_one_fd_iov(
20✔
1451
                                                        pidref_transport_fds[0],
1452
                                                        &IOVEC_MAKE(&pid, sizeof(pid)),
10✔
1453
                                                        /* iovlen= */ 1,
1454
                                                        /* flags= */ 0,
1455
                                                        &pidfd);
1456
                                        if (n < 0)
10✔
1457
                                                return log_full_errno(prio, n, "Failed to receive child pidref: %m");
×
1458

1459
                                        *ret = (PidRef) { .pid = pid, .fd = pidfd };
10✔
1460
                                }
1461

1462
                                return 1; /* return in the parent */
1463
                        }
1464

1465
                        pidref_transport_fds[0] = safe_close(pidref_transport_fds[0]);
19✔
1466
                        intermediary = true;
19✔
1467
                }
1468
        }
1469

1470
        if ((flags & (FORK_NEW_MOUNTNS|FORK_NEW_USERNS|FORK_NEW_NETNS|FORK_NEW_PIDNS)) != 0)
33,442✔
1471
                pid = raw_clone(SIGCHLD|
9,271✔
1472
                                (FLAGS_SET(flags, FORK_NEW_MOUNTNS) ? CLONE_NEWNS : 0) |
9,271✔
1473
                                (FLAGS_SET(flags, FORK_NEW_USERNS) ? CLONE_NEWUSER : 0) |
9,271✔
1474
                                (FLAGS_SET(flags, FORK_NEW_NETNS) ? CLONE_NEWNET : 0) |
9,271✔
1475
                                (FLAGS_SET(flags, FORK_NEW_PIDNS) ? CLONE_NEWPID : 0));
9,271✔
1476
        else
1477
                pid = fork();
24,171✔
1478
        if (pid < 0)
67,543✔
1479
                return log_full_errno(prio, errno, "Failed to fork off '%s': %m", strna(name));
×
1480
        if (pid > 0) {
67,543✔
1481

1482
                /* If we are in the intermediary process, exit now */
1483
                if (intermediary) {
32,264✔
1484
                        if (pidref_transport_fds[1] >= 0) {
13✔
1485
                                _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
10✔
1486

1487
                                r = pidref_set_pid(&pidref, pid);
10✔
1488
                                if (r < 0) {
10✔
1489
                                        log_full_errno(prio, r, "Failed to open reference to PID "PID_FMT": %m", pid);
×
1490
                                        _exit(EXIT_FAILURE);
×
1491
                                }
1492

1493
                                r = send_one_fd_iov(
10✔
1494
                                                pidref_transport_fds[1],
1495
                                                pidref.fd,
1496
                                                &IOVEC_MAKE(&pidref.pid, sizeof(pidref.pid)),
1497
                                                /* iovlen= */ 1,
1498
                                                /* flags= */ 0);
1499
                                if (r < 0) {
10✔
1500
                                        log_full_errno(prio, r, "Failed to send child pidref: %m");
×
1501
                                        _exit(EXIT_FAILURE);
×
1502
                                }
1503
                        }
1504

1505
                        _exit(EXIT_SUCCESS);
13✔
1506
                }
1507

1508
                /* We are in the parent process */
1509
                log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid);
32,251✔
1510

1511
                if (flags & FORK_WAIT) {
32,251✔
1512
                        if (block_all) {
1,863✔
1513
                                /* undo everything except SIGCHLD */
1514
                                ss = saved_ss;
1,696✔
1515
                                assert_se(sigaddset(&ss, SIGCHLD) >= 0);
1,696✔
1516
                                (void) sigprocmask(SIG_SETMASK, &ss, NULL);
1,696✔
1517
                        }
1518

1519
                        r = pidref_wait_for_terminate_and_check(
1,863✔
1520
                                        name,
1521
                                        &PIDREF_MAKE_FROM_PID(pid),
1,863✔
1522
                                        FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
1523
                        if (r < 0)
1,863✔
1524
                                return r;
1,863✔
1525
                        if (r != EXIT_SUCCESS) /* exit status > 0 should be treated as failure, too */
1,863✔
1526
                                return -EPROTO;
1527

1528
                        /* If we are in the parent and successfully waited, then the process doesn't exist anymore. */
1529
                        if (ret)
1,855✔
1530
                                *ret = PIDREF_NULL;
28✔
1531

1532
                        return 1;
1533
                }
1534

1535
                if (ret) {
30,388✔
1536
                        r = pidref_set_pid(ret, pid);
29,043✔
1537
                        if (r < 0) /* Let's not fail for this, no matter what, the process exists after all, and that's key */
29,043✔
1538
                                *ret = PIDREF_MAKE_FROM_PID(pid);
×
1539
                }
1540

1541
                return 1;
1542
        }
1543

1544
        /* We are in the child process */
1545

1546
        pidref_transport_fds[1] = safe_close(pidref_transport_fds[1]);
35,279✔
1547

1548
        /* Restore signal mask manually */
1549
        saved_ssp = NULL;
35,279✔
1550

1551
        if (flags & FORK_REOPEN_LOG) {
35,279✔
1552
                /* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */
1553
                log_close();
9,918✔
1554
                log_set_open_when_needed(true);
9,918✔
1555
                log_settle_target();
9,918✔
1556
        }
1557

1558
        if (name) {
35,279✔
1559
                r = rename_process(name);
35,279✔
1560
                if (r < 0)
35,279✔
1561
                        log_full_errno(flags & FORK_LOG ? LOG_WARNING : LOG_DEBUG,
×
1562
                                       r, "Failed to rename process, ignoring: %m");
1563
        }
1564

1565
        /* let's disable dlopen() in the child, as a paranoia safety precaution: children should not live for
1566
         * long and only do minimal work before exiting or exec()ing. Doing dlopen() is not either. If people
1567
         * want dlopen() they should do it before forking. This is a safety precaution in particular for
1568
         * cases where the child does namespace shenanigans: we should never end up loading a module from a
1569
         * foreign environment. Note that this has no effect on NSS! (i.e. it only has effect on uses of our
1570
         * dlopen_safe(), which we use comprehensively in our codebase, but glibc NSS doesn't bother, of
1571
         * course.) */
1572
        if (!FLAGS_SET(flags, FORK_ALLOW_DLOPEN))
35,279✔
1573
                block_dlopen();
35,240✔
1574

1575
        if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL))
35,279✔
1576
                if (prctl(PR_SET_PDEATHSIG, fork_flags_to_signal(flags)) < 0) {
33,824✔
1577
                        log_full_errno(prio, errno, "Failed to set death signal: %m");
×
1578
                        _exit(EXIT_FAILURE);
×
1579
                }
1580

1581
        if (flags & FORK_RESET_SIGNALS) {
35,279✔
1582
                r = reset_all_signal_handlers();
28,958✔
1583
                if (r < 0) {
28,958✔
1584
                        log_full_errno(prio, r, "Failed to reset signal handlers: %m");
×
1585
                        _exit(EXIT_FAILURE);
×
1586
                }
1587

1588
                /* This implicitly undoes the signal mask stuff we did before the fork()ing above */
1589
                r = reset_signal_mask();
28,958✔
1590
                if (r < 0) {
28,958✔
1591
                        log_full_errno(prio, r, "Failed to reset signal mask: %m");
×
1592
                        _exit(EXIT_FAILURE);
×
1593
                }
1594
        } else if (block_signals) { /* undo what we did above */
6,321✔
1595
                if (sigprocmask(SIG_SETMASK, &saved_ss, NULL) < 0) {
5,798✔
1596
                        log_full_errno(prio, errno, "Failed to restore signal mask: %m");
×
1597
                        _exit(EXIT_FAILURE);
×
1598
                }
1599
        }
1600

1601
        if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGKILL|FORK_DEATHSIG_SIGINT)) {
35,279✔
1602
                pid_t ppid;
33,824✔
1603
                /* Let's see if the parent PID is still the one we started from? If not, then the parent
1604
                 * already died by the time we set PR_SET_PDEATHSIG, hence let's emulate the effect */
1605

1606
                ppid = getppid();
33,824✔
1607
                if (ppid == 0)
33,824✔
1608
                        /* Parent is in a different PID namespace. */;
1609
                else if (ppid != original_pid) {
33,787✔
1610
                        int sig = fork_flags_to_signal(flags);
×
1611
                        log_debug("Parent died early, raising %s.", signal_to_string(sig));
×
1612
                        (void) raise(sig);
×
1613
                        _exit(EXIT_FAILURE);
×
1614
                }
1615
        }
1616

1617
        if (FLAGS_SET(flags, FORK_NEW_MOUNTNS | FORK_MOUNTNS_SLAVE)) {
35,279✔
1618
                /* Optionally, make sure we never propagate mounts to the host. */
1619
                if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
197✔
1620
                        log_full_errno(prio, errno, "Failed to remount root directory as MS_SLAVE: %m");
×
1621
                        _exit(EXIT_FAILURE);
×
1622
                }
1623
        }
1624

1625
        if (FLAGS_SET(flags, FORK_PRIVATE_TMP)) {
35,279✔
1626
                assert(FLAGS_SET(flags, FORK_NEW_MOUNTNS));
×
1627

1628
                /* Optionally, overmount new tmpfs instance on /tmp/. */
1629
                r = mount_nofollow("tmpfs", "/tmp", "tmpfs",
×
1630
                                   MS_NOSUID|MS_NODEV,
1631
                                   "mode=01777" TMPFS_LIMITS_RUN);
1632
                if (r < 0) {
×
1633
                        log_full_errno(prio, r, "Failed to overmount /tmp/: %m");
×
1634
                        _exit(EXIT_FAILURE);
×
1635
                }
1636
        }
1637

1638
        if (flags & FORK_REARRANGE_STDIO) {
35,279✔
1639
                if (stdio_fds) {
16,282✔
1640
                        r = rearrange_stdio(stdio_fds[0], stdio_fds[1], stdio_fds[2]);
16,262✔
1641
                        if (r < 0) {
16,262✔
1642
                                log_full_errno(prio, r, "Failed to rearrange stdio fds: %m");
×
1643
                                _exit(EXIT_FAILURE);
×
1644
                        }
1645

1646
                        /* Turn off O_NONBLOCK on the fdio fds, in case it was left on */
1647
                        stdio_disable_nonblock();
16,262✔
1648
                } else {
1649
                        r = make_null_stdio();
20✔
1650
                        if (r < 0) {
20✔
1651
                                log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
×
1652
                                _exit(EXIT_FAILURE);
×
1653
                        }
1654
                }
1655
        } else if (flags & FORK_STDOUT_TO_STDERR) {
18,997✔
1656
                if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
6✔
1657
                        log_full_errno(prio, errno, "Failed to connect stdout to stderr: %m");
×
1658
                        _exit(EXIT_FAILURE);
×
1659
                }
1660
        }
1661

1662
        if (flags & FORK_CLOSE_ALL_FDS) {
35,279✔
1663
                /* Close the logs here in case it got reopened above, as close_all_fds() would close them for us */
1664
                log_close();
26,954✔
1665

1666
                r = close_all_fds(except_fds, n_except_fds);
26,954✔
1667
                if (r < 0) {
26,954✔
1668
                        log_full_errno(prio, r, "Failed to close all file descriptors: %m");
×
1669
                        _exit(EXIT_FAILURE);
×
1670
                }
1671
        }
1672

1673
        if (flags & FORK_PACK_FDS) {
35,279✔
1674
                /* FORK_CLOSE_ALL_FDS ensures that except_fds are the only FDs >= 3 that are
1675
                 * open, this is including the log. This is required by pack_fds, which will
1676
                 * get stuck in an infinite loop of any FDs other than except_fds are open. */
1677
                assert(FLAGS_SET(flags, FORK_CLOSE_ALL_FDS));
184✔
1678

1679
                r = pack_fds(except_fds, n_except_fds);
184✔
1680
                if (r < 0) {
184✔
1681
                        log_full_errno(prio, r, "Failed to pack file descriptors: %m");
×
1682
                        _exit(EXIT_FAILURE);
×
1683
                }
1684
        }
1685

1686
        if (flags & FORK_CLOEXEC_OFF) {
35,279✔
1687
                r = fd_cloexec_many(except_fds, n_except_fds, false);
203✔
1688
                if (r < 0) {
203✔
1689
                        log_full_errno(prio, r, "Failed to turn off O_CLOEXEC on file descriptors: %m");
×
1690
                        _exit(EXIT_FAILURE);
×
1691
                }
1692
        }
1693

1694
        /* When we were asked to reopen the logs, do so again now */
1695
        if (flags & FORK_REOPEN_LOG) {
35,279✔
1696
                log_open();
9,918✔
1697
                log_set_open_when_needed(false);
9,918✔
1698
        }
1699

1700
        if (flags & FORK_RLIMIT_NOFILE_SAFE) {
35,279✔
1701
                r = rlimit_nofile_safe();
16,698✔
1702
                if (r < 0) {
16,698✔
1703
                        log_full_errno(prio, r, "Failed to lower RLIMIT_NOFILE's soft limit to 1K: %m");
×
1704
                        _exit(EXIT_FAILURE);
×
1705
                }
1706
        }
1707

1708
        if (!FLAGS_SET(flags, FORK_KEEP_NOTIFY_SOCKET)) {
35,279✔
1709
                r = RET_NERRNO(unsetenv("NOTIFY_SOCKET"));
35,279✔
1710
                if (r < 0) {
×
1711
                        log_full_errno(prio, r, "Failed to unset $NOTIFY_SOCKET: %m");
×
1712
                        _exit(EXIT_FAILURE);
×
1713
                }
1714
        }
1715

1716
        if (FLAGS_SET(flags, FORK_FREEZE))
35,279✔
1717
                freeze();
×
1718

1719
        if (ret) {
35,279✔
1720
                r = pidref_set_self(ret);
32,612✔
1721
                if (r < 0) {
32,612✔
1722
                        log_full_errno(prio, r, "Failed to acquire PID reference on ourselves: %m");
×
1723
                        _exit(EXIT_FAILURE);
×
1724
                }
1725
        }
1726

1727
        return 0;
1728
}
1729

1730
int namespace_fork_full(
139✔
1731
                const char *outer_name,
1732
                const char *inner_name,
1733
                int except_fds[],
1734
                size_t n_except_fds,
1735
                ForkFlags flags,
1736
                int pidns_fd,
1737
                int mntns_fd,
1738
                int netns_fd,
1739
                int userns_fd,
1740
                int root_fd,
1741
                PidRef *ret) {
1742

1743
        _cleanup_(pidref_done_sigkill_wait) PidRef pidref_outer = PIDREF_NULL;
×
1744
        _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
235✔
1745
        int r, prio = FLAGS_SET(flags, FORK_LOG) ? LOG_ERR : LOG_DEBUG;
139✔
1746

1747
        /* This is much like safe_fork(), but forks twice, and joins the specified namespaces in the middle
1748
         * process. This ensures that we are fully a member of the destination namespace, with pidns an all, so that
1749
         * /proc/self/fd works correctly.
1750
         *
1751
         * TODO: once we can rely on PIDFD_INFO_EXIT, do not keep the middle process around and instead
1752
         * return the pidfd of the inner process for direct tracking. */
1753

1754
        /* Insist on PDEATHSIG being enabled, as the pid returned is the one of the middle man, and otherwise
1755
         * killing of it won't be propagated to the inner child. */
1756
        assert((flags & (FORK_DEATHSIG_SIGKILL|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT)) != 0);
139✔
1757
        assert((flags & (FORK_DETACH|FORK_FREEZE)) == 0);
139✔
1758
        assert(!FLAGS_SET(flags, FORK_ALLOW_DLOPEN)); /* never allow loading shared library from another ns */
139✔
1759

1760
        /* We want read() to block as a synchronization point */
1761
        assert_cc(sizeof(int) <= PIPE_BUF);
139✔
1762
        if (pipe2(errno_pipe_fd, O_CLOEXEC) < 0)
139✔
1763
                return log_full_errno(prio, errno, "Failed to create pipe: %m");
×
1764

1765
        r = pidref_safe_fork_full(
373✔
1766
                        outer_name,
1767
                        /* stdio_fds= */ NULL, /* except_fds= */ NULL, /* n_except_fds= */ 0,
1768
                        (flags|FORK_DEATHSIG_SIGKILL) & ~(FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_USERNS|FORK_NEW_NETNS|FORK_NEW_PIDNS|FORK_CLOSE_ALL_FDS|FORK_PACK_FDS|FORK_CLOEXEC_OFF|FORK_RLIMIT_NOFILE_SAFE),
139✔
1769
                        &pidref_outer);
1770
        if (r == -EPROTO && FLAGS_SET(flags, FORK_WAIT)) {
234✔
1771
                errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
8✔
1772

1773
                int k = read_errno(errno_pipe_fd[0]);
8✔
1774
                if (k < 0 && k != -EIO)
8✔
1775
                        return k;
1776
        }
1777
        if (r < 0)
234✔
1778
                return r;
1779
        if (r == 0) {
226✔
1780
                _cleanup_(pidref_done) PidRef pidref_inner = PIDREF_NULL;
×
1781

1782
                /* Child */
1783

1784
                errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
95✔
1785

1786
                r = namespace_enter(pidns_fd, mntns_fd, netns_fd, userns_fd, root_fd);
95✔
1787
                if (r < 0) {
95✔
1788
                        log_full_errno(prio, r, "Failed to join namespace: %m");
×
1789
                        report_errno_and_exit(errno_pipe_fd[1], r);
×
1790
                }
1791

1792
                /* We mask a few flags here that either make no sense for the grandchild, or that we don't have to do again */
1793
                r = pidref_safe_fork_full(
286✔
1794
                                inner_name,
1795
                                NULL,
1796
                                except_fds, n_except_fds,
1797
                                flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_REARRANGE_STDIO|FORK_FLUSH_STDIO|FORK_STDOUT_TO_STDERR),
95✔
1798
                                &pidref_inner);
1799
                if (r < 0)
191✔
1800
                        report_errno_and_exit(errno_pipe_fd[1], r);
×
1801
                if (r == 0) {
191✔
1802
                        /* Child */
1803

1804
                        if (!FLAGS_SET(flags, FORK_CLOSE_ALL_FDS)) {
96✔
1805
                                errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
93✔
1806
                                pidref_done(&pidref_outer);
93✔
1807
                        } else {
1808
                                errno_pipe_fd[1] = -EBADF;
3✔
1809
                                pidref_outer = PIDREF_NULL;
3✔
1810
                        }
1811

1812
                        if (ret)
96✔
1813
                                *ret = TAKE_PIDREF(pidref_inner);
96✔
1814
                        return 0;
96✔
1815
                }
1816

1817
                log_forget_fds();
95✔
1818
                log_set_open_when_needed(true);
95✔
1819

1820
                (void) close_all_fds(&pidref_inner.fd, 1);
95✔
1821

1822
                r = pidref_wait_for_terminate_and_check(
190✔
1823
                                inner_name,
1824
                                &pidref_inner,
1825
                                FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
1826
                if (r < 0)
95✔
1827
                        _exit(EXIT_FAILURE);
×
1828

1829
                _exit(r);
95✔
1830
        }
1831

1832
        errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
131✔
1833

1834
        r = read_errno(errno_pipe_fd[0]);
131✔
1835
        if (r < 0)
131✔
1836
                return r; /* the child logs about failures on its own, no need to duplicate here */
1837

1838
        if (ret)
131✔
1839
                *ret = TAKE_PIDREF(pidref_outer);
105✔
1840
        else
1841
                pidref_done(&pidref_outer); /* disarm sigkill_wait */
26✔
1842

1843
        return 1;
1844
}
1845

1846
bool oom_score_adjust_is_valid(int oa) {
12,609✔
1847
        return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
12,609✔
1848
}
1849

1850
int set_oom_score_adjust(int value) {
3,605✔
1851
        char t[DECIMAL_STR_MAX(int)];
3,605✔
1852

1853
        if (!oom_score_adjust_is_valid(value))
3,605✔
1854
                return -EINVAL;
3,605✔
1855

1856
        xsprintf(t, "%i", value);
3,605✔
1857

1858
        return write_string_file("/proc/self/oom_score_adj", t,
3,605✔
1859
                                 WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
1860
}
1861

1862
int get_oom_score_adjust(int *ret) {
7,390✔
1863
        _cleanup_free_ char *t = NULL;
7,390✔
1864
        int r, a;
7,390✔
1865

1866
        r = read_virtual_file("/proc/self/oom_score_adj", SIZE_MAX, &t, NULL);
7,390✔
1867
        if (r < 0)
7,390✔
1868
                return r;
1869

1870
        delete_trailing_chars(t, WHITESPACE);
7,390✔
1871

1872
        r = safe_atoi(t, &a);
7,390✔
1873
        if (r < 0)
7,390✔
1874
                return r;
1875

1876
        if (!oom_score_adjust_is_valid(a))
7,390✔
1877
                return -ENODATA;
1878

1879
        if (ret)
7,390✔
1880
                *ret = a;
7,390✔
1881

1882
        return 0;
1883
}
1884

1885
static int rlimit_to_nice(rlim_t limit) {
2✔
1886
        if (limit <= 1)
2✔
1887
                return PRIO_MAX-1; /* i.e. 19 */
1888

1889
        if (limit >= -PRIO_MIN + PRIO_MAX)
2✔
1890
                return PRIO_MIN; /* i.e. -20 */
1891

1892
        return PRIO_MAX - (int) limit;
2✔
1893
}
1894

1895
int setpriority_closest(int priority) {
27✔
1896
        struct rlimit highest;
27✔
1897
        int r, current, limit;
27✔
1898

1899
        /* Try to set requested nice level */
1900
        r = RET_NERRNO(setpriority(PRIO_PROCESS, 0, priority));
27✔
1901
        if (r >= 0)
2✔
1902
                return 1;
27✔
1903
        if (!ERRNO_IS_NEG_PRIVILEGE(r))
2✔
1904
                return r;
1905

1906
        errno = 0;
2✔
1907
        current = getpriority(PRIO_PROCESS, 0);
2✔
1908
        if (errno != 0)
2✔
1909
                return -errno;
×
1910

1911
        if (priority == current)
2✔
1912
                return 1;
1913

1914
       /* Hmm, we'd expect that raising the nice level from our status quo would always work. If it doesn't,
1915
        * then the whole setpriority() system call is blocked to us, hence let's propagate the error
1916
        * right-away */
1917
        if (priority > current)
2✔
1918
                return r;
1919

1920
        if (getrlimit(RLIMIT_NICE, &highest) < 0)
2✔
1921
                return -errno;
×
1922

1923
        limit = rlimit_to_nice(highest.rlim_cur);
2✔
1924

1925
        /* Push to the allowed limit if we're higher than that. Note that we could also be less nice than
1926
         * limit allows us, but still higher than what's requested. In that case our current value is
1927
         * the best choice. */
1928
        if (current > limit)
2✔
1929
                if (setpriority(PRIO_PROCESS, 0, limit) < 0)
2✔
1930
                        return -errno;
×
1931

1932
        log_debug("Cannot set requested nice level (%i), using next best (%i).", priority, MIN(current, limit));
2✔
1933
        return 0;
1934
}
1935

1936
_noreturn_ void freeze(void) {
×
1937
        log_close();
×
1938

1939
        /* Make sure nobody waits for us (i.e. on one of our sockets) anymore. Note that we use
1940
         * close_all_fds_without_malloc() instead of plain close_all_fds() here, since we want this function
1941
         * to be compatible with being called from signal handlers. */
1942
        (void) close_all_fds_without_malloc(NULL, 0);
×
1943

1944
        /* Let's not freeze right away, but keep reaping zombies. */
1945
        for (;;) {
×
1946
                siginfo_t si = {};
×
1947

1948
                if (waitid(P_ALL, 0, &si, WEXITED) < 0 && errno != EINTR)
×
1949
                        break;
1950
        }
1951

1952
        /* waitid() failed with an ECHLD error (because there are no left-over child processes) or any other
1953
         * (unexpected) error. Freeze for good now! */
1954
        for (;;)
×
1955
                pause();
×
1956
}
1957

1958
int get_process_threads(pid_t pid) {
7✔
1959
        _cleanup_free_ char *t = NULL;
7✔
1960
        int n, r;
7✔
1961

1962
        if (pid < 0)
7✔
1963
                return -EINVAL;
1964

1965
        r = procfs_file_get_field(pid, "status", "Threads", &t);
7✔
1966
        if (r == -ENOENT)
7✔
1967
                return -ESRCH;
1968
        if (r < 0)
7✔
1969
                return r;
1970

1971
        r = safe_atoi(t, &n);
7✔
1972
        if (r < 0)
7✔
1973
                return r;
1974
        if (n < 0)
7✔
1975
                return -EINVAL;
×
1976

1977
        return n;
1978
}
1979

1980
int is_reaper_process(void) {
9,988✔
1981
        int b = 0;
9,988✔
1982

1983
        /* Checks if we are running in a reaper process, i.e. if we are expected to deal with processes
1984
         * reparented to us. This simply checks if we are PID 1 or if PR_SET_CHILD_SUBREAPER was called. */
1985

1986
        if (getpid_cached() == 1)
9,988✔
1987
                return true;
9,988✔
1988

1989
        if (prctl(PR_GET_CHILD_SUBREAPER, (unsigned long) &b, 0UL, 0UL, 0UL) < 0)
415✔
1990
                return -errno;
×
1991

1992
        return b != 0;
415✔
1993
}
1994

1995
int make_reaper_process(bool b) {
760✔
1996

1997
        if (getpid_cached() == 1) {
760✔
1998

1999
                if (!b)
82✔
2000
                        return -EINVAL;
2001

2002
                return 0;
82✔
2003
        }
2004

2005
        /* Some prctl()s insist that all 5 arguments are specified, others do not. Let's always specify all,
2006
         * to avoid any ambiguities */
2007
        if (prctl(PR_SET_CHILD_SUBREAPER, (unsigned long) b, 0UL, 0UL, 0UL) < 0)
678✔
2008
                return -errno;
×
2009

2010
        return 0;
2011
}
2012

2013
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(posix_spawnattr_t*, posix_spawnattr_destroy, NULL);
×
2014

2015
int posix_spawn_wrapper(
4,986✔
2016
                const char *path,
2017
                char * const *argv,
2018
                char * const *envp,
2019
                const char *cgroup,
2020
                PidRef *ret_pidref) {
2021

2022
        short flags = POSIX_SPAWN_SETSIGMASK;
4,986✔
2023
        posix_spawnattr_t attr;
4,986✔
2024
        sigset_t mask;
4,986✔
2025
        int r;
4,986✔
2026

2027
        /* Forks and invokes 'path' with 'argv' and 'envp' using CLONE_VM and CLONE_VFORK, which means the
2028
         * caller will be blocked until the child either exits or exec's. The memory of the child will be
2029
         * fully shared with the memory of the parent, so that there are no copy-on-write or memory.max
2030
         * issues.
2031
         *
2032
         * Also, move the newly-created process into 'cgroup' through POSIX_SPAWN_SETCGROUP (clone3())
2033
         * if available.
2034
         * returns 1: We're already in the right cgroup
2035
         *         0: 'cgroup' not specified or POSIX_SPAWN_SETCGROUP is not supported. The caller
2036
         *            needs to call 'cg_attach' on their own */
2037

2038
        assert(path);
4,986✔
2039
        assert(argv);
4,986✔
2040
        assert(ret_pidref);
4,986✔
2041

2042
        assert_se(sigfillset(&mask) >= 0);
4,986✔
2043

2044
        r = posix_spawnattr_init(&attr);
4,986✔
2045
        if (r != 0)
4,986✔
2046
                return -r; /* These functions return a positive errno on failure */
×
2047

2048
        /* Initialization needs to succeed before we can set up a destructor. */
2049
        _unused_ _cleanup_(posix_spawnattr_destroyp) posix_spawnattr_t *attr_destructor = &attr;
4,986✔
2050

2051
        static bool have_clone_into_cgroup = true; /* kernel 5.7+ */
4,986✔
2052
        _cleanup_close_ int cgroup_fd = -EBADF;
4,986✔
2053

2054
        if (cgroup && have_clone_into_cgroup) {
4,986✔
2055
                _cleanup_free_ char *resolved_cgroup = NULL;
4,986✔
2056

2057
                r = cg_get_path(cgroup, /* suffix= */ NULL, &resolved_cgroup);
4,986✔
2058
                if (r < 0)
4,986✔
2059
                        return r;
2060

2061
                cgroup_fd = open(resolved_cgroup, O_PATH|O_DIRECTORY|O_CLOEXEC);
4,986✔
2062
                if (cgroup_fd < 0)
4,986✔
2063
                        return -errno;
×
2064

2065
                r = posix_spawnattr_setcgroup_np(&attr, cgroup_fd);
4,986✔
2066
                if (r == 0)
4,986✔
2067
                        flags |= POSIX_SPAWN_SETCGROUP;
2068
                else if (r != ENOSYS)
×
2069
                        return -r;
×
2070
                /* If libc lacks posix_spawnattr_setcgroup_np we silently skip POSIX_SPAWN_SETCGROUP — the
2071
                 * caller will then need to attach the child to the cgroup themselves. */
2072
        }
2073

2074
        r = posix_spawnattr_setflags(&attr, flags);
4,986✔
2075
        if (r != 0)
4,986✔
2076
                return -r;
×
2077
        r = posix_spawnattr_setsigmask(&attr, &mask);
4,986✔
2078
        if (r != 0)
4,986✔
2079
                return -r;
×
2080

2081
        _cleanup_close_ int pidfd = -EBADF;
4,986✔
2082

2083
        r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
4,986✔
2084
        if (ERRNO_IS_NOT_SUPPORTED(r) && FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP) && cg_is_threaded(cgroup) > 0)
4,986✔
2085
                return -EUCLEAN; /* clone3() could also return EOPNOTSUPP if the target cgroup is in threaded mode,
2086
                                    turn that into something recognizable */
2087
        if ((ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r)) &&
4,986✔
2088
            FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP)) {
2089
                /* Compiled on a newer host, or seccomp&friends blocking clone3()? Fallback, but
2090
                 * need to disable POSIX_SPAWN_SETCGROUP, which is what redirects to clone3().
2091
                 * CLONE_INTO_CGROUP definitely won't work, hence remember the fact so that we don't
2092
                 * retry every time.
2093
                 * Note, CLONE_INTO_CGROUP is supported since kernel v5.7, but some architectures still
2094
                 * do not support clone3(). Hence, we need to keep the fallback logic for a while. */
2095
                have_clone_into_cgroup = false;
×
2096

2097
                flags &= ~POSIX_SPAWN_SETCGROUP;
×
2098
                r = posix_spawnattr_setflags(&attr, flags);
×
2099
                if (r != 0)
×
2100
                        return -r;
×
2101

2102
                r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
×
2103
        }
2104
        if (r == 0) {
4,986✔
2105
                r = pidref_set_pidfd_consume(ret_pidref, TAKE_FD(pidfd));
4,986✔
2106
                if (r < 0)
4,986✔
2107
                        return r;
2108

2109
                return FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP);
4,986✔
2110
        }
2111
        if (!ERRNO_IS_NOT_SUPPORTED(r))
×
2112
                return -r;
×
2113

2114
        /* pidfd_spawn unavailable (libc or kernel missing) — fall back to plain posix_spawn. */
2115

2116
        pid_t pid;
×
2117

2118
        r = posix_spawn(&pid, path, NULL, &attr, argv, envp);
×
2119
        if (r != 0)
×
2120
                return -r;
×
2121

2122
        r = pidref_set_pid(ret_pidref, pid);
×
2123
        if (r < 0)
×
2124
                return r;
×
2125

2126
        return 0; /* We did not use CLONE_INTO_CGROUP so return 0, the caller will have to move the child */
2127
}
2128

2129
int proc_dir_open(DIR **ret) {
24✔
2130
        DIR *d;
24✔
2131

2132
        assert(ret);
24✔
2133

2134
        d = opendir("/proc");
24✔
2135
        if (!d)
24✔
2136
                return -errno;
×
2137

2138
        *ret = d;
24✔
2139
        return 0;
24✔
2140
}
2141

2142
int proc_dir_read(DIR *d, pid_t *ret) {
2,035✔
2143
        assert(d);
2,035✔
2144

2145
        for (;;) {
3,479✔
2146
                struct dirent *de;
3,479✔
2147

2148
                errno = 0;
3,479✔
2149
                de = readdir_no_dot(d);
3,479✔
2150
                if (!de) {
3,479✔
2151
                        if (errno != 0)
24✔
2152
                                return -errno;
×
2153

2154
                        break;
24✔
2155
                }
2156

2157
                if (!IN_SET(de->d_type, DT_DIR, DT_UNKNOWN))
3,455✔
2158
                        continue;
1,180✔
2159

2160
                if (parse_pid(de->d_name, ret) >= 0)
2,275✔
2161
                        return 1;
2162
        }
2163

2164
        if (ret)
24✔
2165
                *ret = 0;
24✔
2166
        return 0;
2167
}
2168

2169
int proc_dir_read_pidref(DIR *d, PidRef *ret) {
1,994✔
2170
        int r;
1,994✔
2171

2172
        assert(d);
1,994✔
2173

2174
        for (;;) {
1,994✔
2175
                pid_t pid;
1,994✔
2176

2177
                r = proc_dir_read(d, &pid);
1,994✔
2178
                if (r < 0)
1,994✔
2179
                        return r;
1,971✔
2180
                if (r == 0)
1,994✔
2181
                        break;
2182

2183
                r = pidref_set_pid(ret, pid);
1,971✔
2184
                if (r == -ESRCH) /* gone by now? skip it */
1,971✔
2185
                        continue;
×
2186
                if (r < 0)
1,971✔
2187
                        return r;
×
2188

2189
                return 1;
2190
        }
2191

2192
        if (ret)
23✔
2193
                *ret = PIDREF_NULL;
23✔
2194
        return 0;
2195
}
2196

2197
int safe_mlockall(int flags) {
215✔
2198
        int r;
215✔
2199

2200
        /* When dealing with sensitive data, let's lock ourselves into memory. We do this only when
2201
         * privileged however, as otherwise the amount of lockable memory that RLIMIT_MEMLOCK grants us is
2202
         * frequently too low to make this work. The resource limit has no effect on CAP_IPC_LOCK processes,
2203
         * hence that's the capability we check for. */
2204
        r = have_effective_cap(CAP_IPC_LOCK);
215✔
2205
        if (r < 0)
215✔
2206
                return log_debug_errno(r, "Failed to determine if we have CAP_IPC_LOCK: %m");
×
2207
        if (r == 0)
215✔
2208
                return log_debug_errno(SYNTHETIC_ERRNO(EPERM), "Lacking CAP_IPC_LOCK, skipping mlockall().");
12✔
2209

2210
        if (mlockall(flags) < 0)
203✔
2211
                return log_debug_errno(errno, "Failed to call mlockall(): %m");
×
2212

2213
        log_debug("Successfully called mlockall().");
203✔
2214
        return 0;
2215
}
2216

2217
static const char *const sigchld_code_table[] = {
2218
        [CLD_EXITED] = "exited",
2219
        [CLD_KILLED] = "killed",
2220
        [CLD_DUMPED] = "dumped",
2221
        [CLD_TRAPPED] = "trapped",
2222
        [CLD_STOPPED] = "stopped",
2223
        [CLD_CONTINUED] = "continued",
2224
};
2225

2226
DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
20,413✔
2227

2228
static const char* const sched_policy_table[] = {
2229
        [SCHED_OTHER] = "other",
2230
        [SCHED_BATCH] = "batch",
2231
        [SCHED_IDLE]  = "idle",
2232
        [SCHED_FIFO]  = "fifo",
2233
        [SCHED_EXT]   = "ext",
2234
        [SCHED_RR]    = "rr",
2235
};
2236

2237
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
1,956✔
2238

2239
_noreturn_ void report_errno_and_exit(int errno_fd, int error) {
204✔
2240
        int r;
204✔
2241

2242
        if (error >= 0)
204✔
2243
                _exit(EXIT_SUCCESS);
203✔
2244

2245
        assert(errno_fd >= 0);
1✔
2246

2247
        r = loop_write(errno_fd, &error, sizeof(error));
1✔
2248
        if (r < 0)
1✔
2249
                log_debug_errno(r, "Failed to write errno to errno_fd=%d: %m", errno_fd);
×
2250

2251
        _exit(EXIT_FAILURE);
1✔
2252
}
2253

2254
int read_errno(int errno_fd) {
150✔
2255
        int r;
150✔
2256

2257
        assert(errno_fd >= 0);
150✔
2258

2259
        /* The issue here is that it's impossible to distinguish between an error code returned by child and
2260
         * IO error arose when reading it. So, the function logs errors and return EIO for the later case. */
2261

2262
        ssize_t n = loop_read(errno_fd, &r, sizeof(r), /* do_poll= */ false);
150✔
2263
        if (n < 0) {
150✔
2264
                log_debug_errno(n, "Failed to read errno: %m");
×
2265
                return -EIO;
150✔
2266
        }
2267
        if (n == 0) /* the process exited without reporting an error, assuming success */
150✔
2268
                return 0;
2269
        if (n != sizeof(r))
8✔
2270
                return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received unexpected amount of bytes (%zi) while reading errno.", n);
×
2271

2272
        if (r == 0)
8✔
2273
                return 0;
2274
        if (r < 0) /* child process reported an error, return it */
8✔
2275
                return log_debug_errno(r, "Child process failed with errno: %m");
8✔
2276

2277
        return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received positive errno from child, refusing: %d", r);
×
2278
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc