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

systemd / systemd / 13082854884

31 Jan 2025 09:05AM UTC coverage: 71.823% (+0.02%) from 71.804%
13082854884

push

github

poettering
uki: introduce support for a .efifw section

UKIs can be used to bundle uefi firmwares that can be measured and
used on a confidential computing environment. There can be more than one
firmware blob bundle, each one for a specific platform. Also firmware images
can themselves be containers like IGVM files that can in turn bundle the
actual firmware blob. This change is specifically for uefi firmwares, not
IGVM container files.

This change adds support to introduce a .efifw section in UKI that can be
used for firmware blobs/images. There can be multiple such sections and each
section can contain a single firmware image.

The matching .hwids entry for a specific platform can be used to select the
most appropriate firmware blob.

ukify tool has been also changed to support addition of a firmware image
in UKI.

Since firmware gets measured automatically, we do not need to measure it
separately as a part of the UKI.

292987 of 407930 relevant lines covered (71.82%)

711545.13 hits per line

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

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

3
#include <ctype.h>
4
#include <errno.h>
5
#include <limits.h>
6
#include <linux/oom.h>
7
#include <pthread.h>
8
#include <spawn.h>
9
#include <stdbool.h>
10
#include <stdio.h>
11
#include <stdlib.h>
12
#include <sys/mount.h>
13
#include <sys/personality.h>
14
#include <sys/prctl.h>
15
#include <sys/types.h>
16
#include <sys/wait.h>
17
#include <syslog.h>
18
#include <unistd.h>
19
#if HAVE_VALGRIND_VALGRIND_H
20
#include <valgrind/valgrind.h>
21
#endif
22

23
#include "sd-messages.h"
24

25
#include "alloc-util.h"
26
#include "architecture.h"
27
#include "argv-util.h"
28
#include "cgroup-util.h"
29
#include "dirent-util.h"
30
#include "env-file.h"
31
#include "env-util.h"
32
#include "errno-util.h"
33
#include "escape.h"
34
#include "fd-util.h"
35
#include "fileio.h"
36
#include "fs-util.h"
37
#include "hostname-util.h"
38
#include "io-util.h"
39
#include "locale-util.h"
40
#include "log.h"
41
#include "macro.h"
42
#include "memory-util.h"
43
#include "missing_sched.h"
44
#include "missing_syscall.h"
45
#include "missing_threads.h"
46
#include "mountpoint-util.h"
47
#include "namespace-util.h"
48
#include "nulstr-util.h"
49
#include "parse-util.h"
50
#include "path-util.h"
51
#include "pidfd-util.h"
52
#include "process-util.h"
53
#include "raw-clone.h"
54
#include "rlimit-util.h"
55
#include "signal-util.h"
56
#include "stat-util.h"
57
#include "stdio-util.h"
58
#include "string-table.h"
59
#include "string-util.h"
60
#include "terminal-util.h"
61
#include "time-util.h"
62
#include "user-util.h"
63
#include "utf8.h"
64

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

70
static int get_process_state(pid_t pid) {
6,041✔
71
        _cleanup_free_ char *line = NULL;
6,041✔
72
        const char *p;
6,041✔
73
        char state;
6,041✔
74
        int r;
6,041✔
75

76
        assert(pid >= 0);
6,041✔
77

78
        /* Shortcut: if we are enquired about our own state, we are obviously running */
79
        if (pid == 0 || pid == getpid_cached())
6,041✔
80
                return (unsigned char) 'R';
×
81

82
        p = procfs_file_alloca(pid, "stat");
6,041✔
83

84
        r = read_one_line_file(p, &line);
6,041✔
85
        if (r == -ENOENT)
6,041✔
86
                return -ESRCH;
87
        if (r < 0)
5,131✔
88
                return r;
89

90
        p = strrchr(line, ')');
5,131✔
91
        if (!p)
5,131✔
92
                return -EIO;
93

94
        p++;
5,131✔
95

96
        if (sscanf(p, " %c", &state) != 1)
5,131✔
97
                return -EIO;
98

99
        return (unsigned char) state;
5,131✔
100
}
101

102
int pid_get_comm(pid_t pid, char **ret) {
53,224✔
103
        _cleanup_free_ char *escaped = NULL, *comm = NULL;
53,224✔
104
        int r;
53,224✔
105

106
        assert(pid >= 0);
53,224✔
107
        assert(ret);
53,224✔
108

109
        if (pid == 0 || pid == getpid_cached()) {
53,224✔
110
                comm = new0(char, TASK_COMM_LEN + 1); /* Must fit in 16 byte according to prctl(2) */
26,290✔
111
                if (!comm)
26,290✔
112
                        return -ENOMEM;
113

114
                if (prctl(PR_GET_NAME, comm) < 0)
26,290✔
115
                        return -errno;
×
116
        } else {
117
                const char *p;
26,934✔
118

119
                p = procfs_file_alloca(pid, "comm");
26,934✔
120

121
                /* Note that process names of kernel threads can be much longer than TASK_COMM_LEN */
122
                r = read_one_line_file(p, &comm);
26,934✔
123
                if (r == -ENOENT)
26,934✔
124
                        return -ESRCH;
125
                if (r < 0)
22,912✔
126
                        return r;
127
        }
128

129
        escaped = new(char, COMM_MAX_LEN);
49,196✔
130
        if (!escaped)
49,196✔
131
                return -ENOMEM;
132

133
        /* Escape unprintable characters, just in case, but don't grow the string beyond the underlying size */
134
        cellescape(escaped, COMM_MAX_LEN, comm);
49,196✔
135

136
        *ret = TAKE_PTR(escaped);
49,196✔
137
        return 0;
49,196✔
138
}
139

140
int pidref_get_comm(const PidRef *pid, char **ret) {
30✔
141
        _cleanup_free_ char *comm = NULL;
30✔
142
        int r;
30✔
143

144
        if (!pidref_is_set(pid))
30✔
145
                return -ESRCH;
146

147
        if (pidref_is_remote(pid))
60✔
148
                return -EREMOTE;
149

150
        r = pid_get_comm(pid->pid, &comm);
30✔
151
        if (r < 0)
30✔
152
                return r;
153

154
        r = pidref_verify(pid);
30✔
155
        if (r < 0)
30✔
156
                return r;
157

158
        if (ret)
30✔
159
                *ret = TAKE_PTR(comm);
30✔
160
        return 0;
161
}
162

163
static int pid_get_cmdline_nulstr(
17,369✔
164
                pid_t pid,
165
                size_t max_size,
166
                ProcessCmdlineFlags flags,
167
                char **ret,
168
                size_t *ret_size) {
169

170
        _cleanup_free_ char *t = NULL;
17,369✔
171
        const char *p;
17,369✔
172
        size_t k;
17,369✔
173
        int r;
17,369✔
174

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

186
        p = procfs_file_alloca(pid, "cmdline");
17,369✔
187
        r = read_virtual_file(p, max_size, &t, &k); /* Let's assume that each input byte results in >= 1
17,369✔
188
                                                     * columns of output. We ignore zero-width codepoints. */
189
        if (r == -ENOENT)
17,369✔
190
                return -ESRCH;
191
        if (r < 0)
14,402✔
192
                return r;
193

194
        if (k == 0) {
14,402✔
195
                if (!(flags & PROCESS_CMDLINE_COMM_FALLBACK))
495✔
196
                        return -ENOENT;
476✔
197

198
                /* Kernel threads have no argv[] */
199
                _cleanup_free_ char *comm = NULL;
19✔
200

201
                r = pid_get_comm(pid, &comm);
19✔
202
                if (r < 0)
19✔
203
                        return r;
204

205
                free(t);
19✔
206
                t = strjoin("[", comm, "]");
19✔
207
                if (!t)
19✔
208
                        return -ENOMEM;
209

210
                k = strlen(t);
19✔
211
                r = k <= max_size;
19✔
212
                if (r == 0) /* truncation */
19✔
213
                        t[max_size] = '\0';
12✔
214
        }
215

216
        if (ret)
13,926✔
217
                *ret = TAKE_PTR(t);
13,926✔
218
        if (ret_size)
13,926✔
219
                *ret_size = k;
13,926✔
220

221
        return r;
222
}
223

224
int pid_get_cmdline(pid_t pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
12,488✔
225
        _cleanup_free_ char *t = NULL;
12,488✔
226
        size_t k;
12,488✔
227
        char *ans;
12,488✔
228

229
        assert(pid >= 0);
12,488✔
230
        assert(ret);
12,488✔
231

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

246
        int full = pid_get_cmdline_nulstr(pid, max_columns, flags, &t, &k);
12,488✔
247
        if (full < 0)
12,488✔
248
                return full;
249

250
        if (flags & (PROCESS_CMDLINE_QUOTE | PROCESS_CMDLINE_QUOTE_POSIX)) {
9,107✔
251
                ShellEscapeFlags shflags = SHELL_ESCAPE_EMPTY |
8,710✔
252
                        FLAGS_SET(flags, PROCESS_CMDLINE_QUOTE_POSIX) * SHELL_ESCAPE_POSIX;
8,710✔
253

254
                assert(!(flags & PROCESS_CMDLINE_USE_LOCALE));
8,710✔
255

256
                _cleanup_strv_free_ char **args = NULL;
8,710✔
257

258
                /* Drop trailing NULs, otherwise strv_parse_nulstr() adds additional empty strings at the end.
259
                 * See also issue #21186. */
260
                args = strv_parse_nulstr_full(t, k, /* drop_trailing_nuls = */ true);
8,710✔
261
                if (!args)
8,710✔
262
                        return -ENOMEM;
263

264
                ans = quote_command_line(args, shflags);
8,710✔
265
                if (!ans)
8,710✔
266
                        return -ENOMEM;
267
        } else {
268
                /* Arguments are separated by NULs. Let's replace those with spaces. */
269
                for (size_t i = 0; i < k - 1; i++)
19,234✔
270
                        if (t[i] == '\0')
18,837✔
271
                                t[i] = ' ';
705✔
272

273
                delete_trailing_chars(t, WHITESPACE);
397✔
274

275
                bool eight_bit = (flags & PROCESS_CMDLINE_USE_LOCALE) && !is_locale_utf8();
397✔
276

277
                ans = escape_non_printable_full(t, max_columns,
1,191✔
278
                                                eight_bit * XESCAPE_8_BIT | !full * XESCAPE_FORCE_ELLIPSIS);
740✔
279
                if (!ans)
397✔
280
                        return -ENOMEM;
281

282
                ans = str_realloc(ans);
397✔
283
        }
284

285
        *ret = ans;
9,107✔
286
        return 0;
9,107✔
287
}
288

289
int pidref_get_cmdline(const PidRef *pid, size_t max_columns, ProcessCmdlineFlags flags, char **ret) {
104✔
290
        _cleanup_free_ char *s = NULL;
104✔
291
        int r;
104✔
292

293
        if (!pidref_is_set(pid))
104✔
294
                return -ESRCH;
295

296
        if (pidref_is_remote(pid))
208✔
297
                return -EREMOTE;
298

299
        r = pid_get_cmdline(pid->pid, max_columns, flags, &s);
104✔
300
        if (r < 0)
104✔
301
                return r;
302

303
        r = pidref_verify(pid);
104✔
304
        if (r < 0)
104✔
305
                return r;
306

307
        if (ret)
104✔
308
                *ret = TAKE_PTR(s);
104✔
309
        return 0;
310
}
311

312
int pid_get_cmdline_strv(pid_t pid, ProcessCmdlineFlags flags, char ***ret) {
4,881✔
313
        _cleanup_free_ char *t = NULL;
4,881✔
314
        char **args;
4,881✔
315
        size_t k;
4,881✔
316
        int r;
4,881✔
317

318
        assert(pid >= 0);
4,881✔
319
        assert((flags & ~PROCESS_CMDLINE_COMM_FALLBACK) == 0);
4,881✔
320
        assert(ret);
4,881✔
321

322
        r = pid_get_cmdline_nulstr(pid, SIZE_MAX, flags, &t, &k);
4,881✔
323
        if (r < 0)
4,881✔
324
                return r;
325

326
        args = strv_parse_nulstr_full(t, k, /* drop_trailing_nuls = */ true);
4,819✔
327
        if (!args)
4,819✔
328
                return -ENOMEM;
329

330
        *ret = args;
4,819✔
331
        return 0;
4,819✔
332
}
333

334
int pidref_get_cmdline_strv(const PidRef *pid, ProcessCmdlineFlags flags, char ***ret) {
×
335
        _cleanup_strv_free_ char **args = NULL;
×
336
        int r;
×
337

338
        if (!pidref_is_set(pid))
×
339
                return -ESRCH;
340

341
        if (pidref_is_remote(pid))
×
342
                return -EREMOTE;
343

344
        r = pid_get_cmdline_strv(pid->pid, flags, &args);
×
345
        if (r < 0)
×
346
                return r;
347

348
        r = pidref_verify(pid);
×
349
        if (r < 0)
×
350
                return r;
351

352
        if (ret)
×
353
                *ret = TAKE_PTR(args);
×
354

355
        return 0;
356
}
357

358
int container_get_leader(const char *machine, pid_t *pid) {
10✔
359
        _cleanup_free_ char *s = NULL, *class = NULL;
10✔
360
        const char *p;
10✔
361
        pid_t leader;
10✔
362
        int r;
10✔
363

364
        assert(machine);
10✔
365
        assert(pid);
10✔
366

367
        if (streq(machine, ".host")) {
10✔
368
                *pid = 1;
1✔
369
                return 0;
1✔
370
        }
371

372
        if (!hostname_is_valid(machine, 0))
9✔
373
                return -EINVAL;
374

375
        p = strjoina("/run/systemd/machines/", machine);
45✔
376
        r = parse_env_file(NULL, p,
9✔
377
                           "LEADER", &s,
378
                           "CLASS", &class);
379
        if (r == -ENOENT)
9✔
380
                return -EHOSTDOWN;
381
        if (r < 0)
9✔
382
                return r;
383
        if (!s)
9✔
384
                return -EIO;
385

386
        if (!streq_ptr(class, "container"))
9✔
387
                return -EIO;
388

389
        r = parse_pid(s, &leader);
9✔
390
        if (r < 0)
9✔
391
                return r;
392
        if (leader <= 1)
9✔
393
                return -EIO;
394

395
        *pid = leader;
9✔
396
        return 0;
9✔
397
}
398

399
int pid_is_kernel_thread(pid_t pid) {
13,633✔
400
        _cleanup_free_ char *line = NULL;
13,633✔
401
        unsigned long long flags;
13,633✔
402
        size_t l, i;
13,633✔
403
        const char *p;
13,633✔
404
        char *q;
13,633✔
405
        int r;
13,633✔
406

407
        if (IN_SET(pid, 0, 1) || pid == getpid_cached()) /* pid 1, and we ourselves certainly aren't a kernel thread */
13,633✔
408
                return 0;
27✔
409
        if (!pid_is_valid(pid))
13,606✔
410
                return -EINVAL;
411

412
        p = procfs_file_alloca(pid, "stat");
13,606✔
413
        r = read_one_line_file(p, &line);
13,606✔
414
        if (r == -ENOENT)
13,606✔
415
                return -ESRCH;
416
        if (r < 0)
13,606✔
417
                return r;
418

419
        /* Skip past the comm field */
420
        q = strrchr(line, ')');
13,606✔
421
        if (!q)
13,606✔
422
                return -EINVAL;
423
        q++;
13,606✔
424

425
        /* Skip 6 fields to reach the flags field */
426
        for (i = 0; i < 6; i++) {
95,242✔
427
                l = strspn(q, WHITESPACE);
81,636✔
428
                if (l < 1)
81,636✔
429
                        return -EINVAL;
430
                q += l;
81,636✔
431

432
                l = strcspn(q, WHITESPACE);
81,636✔
433
                if (l < 1)
81,636✔
434
                        return -EINVAL;
435
                q += l;
81,636✔
436
        }
437

438
        /* Skip preceding whitespace */
439
        l = strspn(q, WHITESPACE);
13,606✔
440
        if (l < 1)
13,606✔
441
                return -EINVAL;
442
        q += l;
13,606✔
443

444
        /* Truncate the rest */
445
        l = strcspn(q, WHITESPACE);
13,606✔
446
        if (l < 1)
13,606✔
447
                return -EINVAL;
448
        q[l] = 0;
13,606✔
449

450
        r = safe_atollu(q, &flags);
13,606✔
451
        if (r < 0)
13,606✔
452
                return r;
453

454
        return !!(flags & PF_KTHREAD);
13,606✔
455
}
456

457
int pidref_is_kernel_thread(const PidRef *pid) {
7,332✔
458
        int result, r;
7,332✔
459

460
        if (!pidref_is_set(pid))
7,332✔
461
                return -ESRCH;
462

463
        if (pidref_is_remote(pid))
7,332✔
464
                return -EREMOTE;
465

466
        result = pid_is_kernel_thread(pid->pid);
7,332✔
467
        if (result < 0)
7,332✔
468
                return result;
469

470
        r = pidref_verify(pid); /* Verify that the PID wasn't reused since */
7,332✔
471
        if (r < 0)
7,332✔
472
                return r;
×
473

474
        return result;
475
}
476

477
static int get_process_link_contents(pid_t pid, const char *proc_file, char **ret) {
11,863✔
478
        const char *p;
11,863✔
479
        int r;
11,863✔
480

481
        assert(proc_file);
11,863✔
482

483
        p = procfs_file_alloca(pid, proc_file);
11,863✔
484

485
        r = readlink_malloc(p, ret);
11,863✔
486
        return (r == -ENOENT && proc_mounted() > 0) ? -ESRCH : r;
11,863✔
487
}
488

489
int get_process_exe(pid_t pid, char **ret) {
11,835✔
490
        char *d;
11,835✔
491
        int r;
11,835✔
492

493
        assert(pid >= 0);
11,835✔
494

495
        r = get_process_link_contents(pid, "exe", ret);
11,835✔
496
        if (r < 0)
11,835✔
497
                return r;
498

499
        if (ret) {
8,707✔
500
                d = endswith(*ret, " (deleted)");
8,707✔
501
                if (d)
8,707✔
502
                        *d = '\0';
×
503
        }
504

505
        return 0;
506
}
507

508
static int get_process_id(pid_t pid, const char *field, uid_t *ret) {
5,647✔
509
        _cleanup_fclose_ FILE *f = NULL;
5,647✔
510
        const char *p;
5,647✔
511
        int r;
5,647✔
512

513
        assert(field);
5,647✔
514
        assert(ret);
5,647✔
515

516
        if (pid < 0)
5,647✔
517
                return -EINVAL;
518

519
        p = procfs_file_alloca(pid, "status");
5,647✔
520
        r = fopen_unlocked(p, "re", &f);
5,647✔
521
        if (r == -ENOENT)
5,647✔
522
                return -ESRCH;
523
        if (r < 0)
543✔
524
                return r;
525

526
        for (;;) {
9,317✔
527
                _cleanup_free_ char *line = NULL;
4,930✔
528
                char *l;
4,930✔
529

530
                r = read_stripped_line(f, LONG_LINE_MAX, &line);
4,930✔
531
                if (r < 0)
4,930✔
532
                        return r;
533
                if (r == 0)
4,930✔
534
                        break;
535

536
                l = startswith(line, field);
4,930✔
537
                if (l) {
4,930✔
538
                        l += strspn(l, WHITESPACE);
543✔
539

540
                        l[strcspn(l, WHITESPACE)] = 0;
543✔
541

542
                        return parse_uid(l, ret);
543✔
543
                }
544
        }
545

546
        return -EIO;
×
547
}
548

549
int pid_get_uid(pid_t pid, uid_t *ret) {
2,922✔
550
        assert(ret);
2,922✔
551

552
        if (pid == 0 || pid == getpid_cached()) {
2,922✔
553
                *ret = getuid();
4✔
554
                return 0;
4✔
555
        }
556

557
        return get_process_id(pid, "Uid:", ret);
2,918✔
558
}
559

560
int pidref_get_uid(const PidRef *pid, uid_t *ret) {
192✔
561
        int r;
192✔
562

563
        if (!pidref_is_set(pid))
192✔
564
                return -ESRCH;
192✔
565

566
        if (pidref_is_remote(pid))
192✔
567
                return -EREMOTE;
568

569
        if (pid->fd >= 0) {
192✔
570
                r = pidfd_get_uid(pid->fd, ret);
192✔
571
                if (!ERRNO_IS_NEG_NOT_SUPPORTED(r))
192✔
572
                        return r;
573
        }
574

575
        uid_t uid;
192✔
576
        r = pid_get_uid(pid->pid, &uid);
192✔
577
        if (r < 0)
192✔
578
                return r;
579

580
        r = pidref_verify(pid);
192✔
581
        if (r < 0)
192✔
582
                return r;
583

584
        if (ret)
192✔
585
                *ret = uid;
192✔
586
        return 0;
587
}
588

589
int get_process_gid(pid_t pid, gid_t *ret) {
2,730✔
590

591
        if (pid == 0 || pid == getpid_cached()) {
2,730✔
592
                *ret = getgid();
1✔
593
                return 0;
1✔
594
        }
595

596
        assert_cc(sizeof(uid_t) == sizeof(gid_t));
2,729✔
597
        return get_process_id(pid, "Gid:", ret);
2,729✔
598
}
599

600
int get_process_cwd(pid_t pid, char **ret) {
14✔
601
        assert(pid >= 0);
14✔
602

603
        if (pid == 0 || pid == getpid_cached())
14✔
604
                return safe_getcwd(ret);
×
605

606
        return get_process_link_contents(pid, "cwd", ret);
14✔
607
}
608

609
int get_process_root(pid_t pid, char **ret) {
14✔
610
        assert(pid >= 0);
14✔
611
        return get_process_link_contents(pid, "root", ret);
14✔
612
}
613

614
#define ENVIRONMENT_BLOCK_MAX (5U*1024U*1024U)
615

616
int get_process_environ(pid_t pid, char **ret) {
16✔
617
        _cleanup_fclose_ FILE *f = NULL;
16✔
618
        _cleanup_free_ char *outcome = NULL;
16✔
619
        size_t sz = 0;
16✔
620
        const char *p;
16✔
621
        int r;
16✔
622

623
        assert(pid >= 0);
16✔
624
        assert(ret);
16✔
625

626
        p = procfs_file_alloca(pid, "environ");
16✔
627

628
        r = fopen_unlocked(p, "re", &f);
16✔
629
        if (r == -ENOENT)
16✔
630
                return -ESRCH;
631
        if (r < 0)
16✔
632
                return r;
633

634
        for (;;) {
6,908✔
635
                char c;
6,924✔
636

637
                if (sz >= ENVIRONMENT_BLOCK_MAX)
6,924✔
638
                        return -ENOBUFS;
×
639

640
                if (!GREEDY_REALLOC(outcome, sz + 5))
6,924✔
641
                        return -ENOMEM;
642

643
                r = safe_fgetc(f, &c);
6,924✔
644
                if (r < 0)
6,924✔
645
                        return r;
646
                if (r == 0)
6,924✔
647
                        break;
648

649
                if (c == '\0')
6,908✔
650
                        outcome[sz++] = '\n';
239✔
651
                else
652
                        sz += cescape_char(c, outcome + sz);
6,669✔
653
        }
654

655
        outcome[sz] = '\0';
16✔
656
        *ret = TAKE_PTR(outcome);
16✔
657

658
        return 0;
16✔
659
}
660

661
int pid_get_ppid(pid_t pid, pid_t *ret) {
3,569✔
662
        _cleanup_free_ char *line = NULL;
3,569✔
663
        unsigned long ppid;
3,569✔
664
        const char *p;
3,569✔
665
        int r;
3,569✔
666

667
        assert(pid >= 0);
3,569✔
668

669
        if (pid == 0)
3,569✔
670
                pid = getpid_cached();
1✔
671
        if (pid == 1) /* PID 1 has no parent, shortcut this case */
3,569✔
672
                return -EADDRNOTAVAIL;
673

674
        if (pid == getpid_cached()) {
3,565✔
675
                if (ret)
6✔
676
                        *ret = getppid();
6✔
677
                return 0;
6✔
678
        }
679

680
        p = procfs_file_alloca(pid, "stat");
3,559✔
681
        r = read_one_line_file(p, &line);
3,559✔
682
        if (r == -ENOENT)
3,559✔
683
                return -ESRCH;
684
        if (r < 0)
3,558✔
685
                return r;
686

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

690
        p = strrchr(line, ')');
3,558✔
691
        if (!p)
3,558✔
692
                return -EIO;
693
        p++;
3,558✔
694

695
        if (sscanf(p, " "
3,558✔
696
                   "%*c "  /* state */
697
                   "%lu ", /* ppid */
698
                   &ppid) != 1)
699
                return -EIO;
700

701
        /* If ppid is zero the process has no parent. Which might be the case for PID 1 (caught above)
702
         * but also for processes originating in other namespaces that are inserted into a pidns.
703
         * Return a recognizable error in this case. */
704
        if (ppid == 0)
3,558✔
705
                return -EADDRNOTAVAIL;
706

707
        if ((pid_t) ppid < 0 || (unsigned long) (pid_t) ppid != ppid)
3,558✔
708
                return -ERANGE;
709

710
        if (ret)
3,558✔
711
                *ret = (pid_t) ppid;
3,558✔
712

713
        return 0;
714
}
715

716
int pidref_get_ppid(const PidRef *pidref, pid_t *ret) {
3,563✔
717
        int r;
3,563✔
718

719
        if (!pidref_is_set(pidref))
3,563✔
720
                return -ESRCH;
3,563✔
721

722
        if (pidref_is_remote(pidref))
3,563✔
723
                return -EREMOTE;
724

725
        if (pidref->fd >= 0) {
3,563✔
726
                r = pidfd_get_ppid(pidref->fd, ret);
3,563✔
727
                if (!ERRNO_IS_NEG_NOT_SUPPORTED(r))
3,563✔
728
                        return r;
729
        }
730

731
        pid_t ppid;
3,563✔
732
        r = pid_get_ppid(pidref->pid, ret ? &ppid : NULL);
3,563✔
733
        if (r < 0)
3,563✔
734
                return r;
735

736
        r = pidref_verify(pidref);
3,562✔
737
        if (r < 0)
3,562✔
738
                return r;
739

740
        if (ret)
3,562✔
741
                *ret = ppid;
3,562✔
742
        return 0;
743
}
744

745
int pidref_get_ppid_as_pidref(const PidRef *pidref, PidRef *ret) {
17✔
746
        pid_t ppid;
17✔
747
        int r;
17✔
748

749
        assert(ret);
17✔
750

751
        r = pidref_get_ppid(pidref, &ppid);
17✔
752
        if (r < 0)
17✔
753
                return r;
17✔
754

755
        for (unsigned attempt = 0; attempt < 16; attempt++) {
16✔
756
                _cleanup_(pidref_done) PidRef parent = PIDREF_NULL;
16✔
757

758
                r = pidref_set_pid(&parent, ppid);
16✔
759
                if (r < 0)
16✔
760
                        return r;
761

762
                /* If we have a pidfd of the original PID, let's verify that the process we acquired really
763
                 * is the parent still */
764
                if (pidref->fd >= 0) {
16✔
765
                        r = pidref_get_ppid(pidref, &ppid);
16✔
766
                        if (r < 0)
16✔
767
                                return r;
768

769
                        /* Did the PPID change since we queried it? if so we might have pinned the wrong
770
                         * process, if its PID got reused by now. Let's try again */
771
                        if (parent.pid != ppid)
16✔
772
                                continue;
×
773
                }
774

775
                *ret = TAKE_PIDREF(parent);
16✔
776
                return 0;
16✔
777
        }
778

779
        /* Give up after 16 tries */
780
        return -ENOTRECOVERABLE;
781
}
782

783
int pid_get_start_time(pid_t pid, usec_t *ret) {
628✔
784
        _cleanup_free_ char *line = NULL;
628✔
785
        const char *p;
628✔
786
        int r;
628✔
787

788
        assert(pid >= 0);
628✔
789

790
        p = procfs_file_alloca(pid, "stat");
628✔
791
        r = read_one_line_file(p, &line);
628✔
792
        if (r == -ENOENT)
628✔
793
                return -ESRCH;
794
        if (r < 0)
628✔
795
                return r;
796

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

800
        p = strrchr(line, ')');
628✔
801
        if (!p)
628✔
802
                return -EIO;
803
        p++;
628✔
804

805
        unsigned long llu;
628✔
806

807
        if (sscanf(p, " "
628✔
808
                   "%*c " /* state */
809
                   "%*u " /* ppid */
810
                   "%*u " /* pgrp */
811
                   "%*u " /* session */
812
                   "%*u " /* tty_nr */
813
                   "%*u " /* tpgid */
814
                   "%*u " /* flags */
815
                   "%*u " /* minflt */
816
                   "%*u " /* cminflt */
817
                   "%*u " /* majflt */
818
                   "%*u " /* cmajflt */
819
                   "%*u " /* utime */
820
                   "%*u " /* stime */
821
                   "%*u " /* cutime */
822
                   "%*u " /* cstime */
823
                   "%*i " /* priority */
824
                   "%*i " /* nice */
825
                   "%*u " /* num_threads */
826
                   "%*u " /* itrealvalue */
827
                   "%lu ", /* starttime */
828
                   &llu) != 1)
829
                return -EIO;
830

831
        if (ret)
628✔
832
                *ret = jiffies_to_usec(llu); /* CLOCK_BOOTTIME */
628✔
833

834
        return 0;
835
}
836

837
int pidref_get_start_time(const PidRef *pid, usec_t *ret) {
628✔
838
        usec_t t;
628✔
839
        int r;
628✔
840

841
        if (!pidref_is_set(pid))
628✔
842
                return -ESRCH;
628✔
843

844
        if (pidref_is_remote(pid))
628✔
845
                return -EREMOTE;
846

847
        r = pid_get_start_time(pid->pid, ret ? &t : NULL);
628✔
848
        if (r < 0)
628✔
849
                return r;
850

851
        r = pidref_verify(pid);
628✔
852
        if (r < 0)
628✔
853
                return r;
854

855
        if (ret)
628✔
856
                *ret = t;
628✔
857

858
        return 0;
859
}
860

861
int get_process_umask(pid_t pid, mode_t *ret) {
13,307✔
862
        _cleanup_free_ char *m = NULL;
13,307✔
863
        const char *p;
13,307✔
864
        int r;
13,307✔
865

866
        assert(pid >= 0);
13,307✔
867
        assert(ret);
13,307✔
868

869
        p = procfs_file_alloca(pid, "status");
13,307✔
870

871
        r = get_proc_field(p, "Umask", WHITESPACE, &m);
13,307✔
872
        if (r == -ENOENT)
13,307✔
873
                return -ESRCH;
874
        if (r < 0)
13,307✔
875
                return r;
876

877
        return parse_mode(m, ret);
13,307✔
878
}
879

880
int wait_for_terminate(pid_t pid, siginfo_t *status) {
9,659✔
881
        siginfo_t dummy;
9,659✔
882

883
        assert(pid >= 1);
9,659✔
884

885
        if (!status)
9,659✔
886
                status = &dummy;
92✔
887

888
        for (;;) {
9,659✔
889
                zero(*status);
9,659✔
890

891
                if (waitid(P_PID, pid, status, WEXITED) < 0) {
9,659✔
892

893
                        if (errno == EINTR)
1✔
894
                                continue;
×
895

896
                        return negative_errno();
1✔
897
                }
898

899
                return 0;
900
        }
901
}
902

903
/*
904
 * Return values:
905
 * < 0 : wait_for_terminate() failed to get the state of the
906
 *       process, the process was terminated by a signal, or
907
 *       failed for an unknown reason.
908
 * >=0 : The process terminated normally, and its exit code is
909
 *       returned.
910
 *
911
 * That is, success is indicated by a return value of zero, and an
912
 * error is indicated by a non-zero value.
913
 *
914
 * A warning is emitted if the process terminates abnormally,
915
 * and also if it returns non-zero unless check_exit_code is true.
916
 */
917
int wait_for_terminate_and_check(const char *name, pid_t pid, WaitFlags flags) {
9,326✔
918
        _cleanup_free_ char *buffer = NULL;
9,326✔
919
        siginfo_t status;
9,326✔
920
        int r, prio;
9,326✔
921

922
        assert(pid > 1);
9,326✔
923

924
        if (!name) {
9,326✔
925
                r = pid_get_comm(pid, &buffer);
×
926
                if (r < 0)
×
927
                        log_debug_errno(r, "Failed to acquire process name of " PID_FMT ", ignoring: %m", pid);
×
928
                else
929
                        name = buffer;
×
930
        }
931

932
        prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG;
9,326✔
933

934
        r = wait_for_terminate(pid, &status);
9,326✔
935
        if (r < 0)
9,326✔
936
                return log_full_errno(prio, r, "Failed to wait for %s: %m", strna(name));
×
937

938
        if (status.si_code == CLD_EXITED) {
9,326✔
939
                if (status.si_status != EXIT_SUCCESS)
9,326✔
940
                        log_full(flags & WAIT_LOG_NON_ZERO_EXIT_STATUS ? LOG_ERR : LOG_DEBUG,
98✔
941
                                 "%s failed with exit status %i.", strna(name), status.si_status);
942
                else
943
                        log_debug("%s succeeded.", name);
9,277✔
944

945
                return status.si_status;
9,326✔
946

947
        } else if (IN_SET(status.si_code, CLD_KILLED, CLD_DUMPED)) {
×
948

949
                log_full(prio, "%s terminated by signal %s.", strna(name), signal_to_string(status.si_status));
×
950
                return -EPROTO;
×
951
        }
952

953
        log_full(prio, "%s failed due to unknown reason.", strna(name));
9,326✔
954
        return -EPROTO;
955
}
956

957
/*
958
 * Return values:
959
 *
960
 * < 0 : wait_for_terminate_with_timeout() failed to get the state of the process, the process timed out, the process
961
 *       was terminated by a signal, or failed for an unknown reason.
962
 *
963
 * >=0 : The process terminated normally with no failures.
964
 *
965
 * Success is indicated by a return value of zero, a timeout is indicated by ETIMEDOUT, and all other child failure
966
 * states are indicated by error is indicated by a non-zero value.
967
 *
968
 * This call assumes SIGCHLD has been blocked already, in particular before the child to wait for has been forked off
969
 * to remain entirely race-free.
970
 */
971
int wait_for_terminate_with_timeout(pid_t pid, usec_t timeout) {
×
972
        sigset_t mask;
×
973
        int r;
×
974
        usec_t until;
×
975

976
        assert_se(sigemptyset(&mask) == 0);
×
977
        assert_se(sigaddset(&mask, SIGCHLD) == 0);
×
978

979
        /* Drop into a sigtimewait-based timeout. Waiting for the
980
         * pid to exit. */
981
        until = usec_add(now(CLOCK_MONOTONIC), timeout);
×
982
        for (;;) {
×
983
                usec_t n;
×
984
                siginfo_t status = {};
×
985

986
                n = now(CLOCK_MONOTONIC);
×
987
                if (n >= until)
×
988
                        break;
989

990
                r = RET_NERRNO(sigtimedwait(&mask, NULL, TIMESPEC_STORE(until - n)));
×
991
                /* Assuming we woke due to the child exiting. */
992
                if (waitid(P_PID, pid, &status, WEXITED|WNOHANG) == 0) {
×
993
                        if (status.si_pid == pid) {
×
994
                                /* This is the correct child. */
995
                                if (status.si_code == CLD_EXITED)
×
996
                                        return status.si_status == 0 ? 0 : -EPROTO;
×
997
                                else
998
                                        return -EPROTO;
999
                        }
1000
                }
1001
                /* Not the child, check for errors and proceed appropriately */
1002
                if (r < 0) {
×
1003
                        switch (r) {
×
1004
                        case -EAGAIN:
1005
                                /* Timed out, child is likely hung. */
1006
                                return -ETIMEDOUT;
1007
                        case -EINTR:
×
1008
                                /* Received a different signal and should retry */
1009
                                continue;
×
1010
                        default:
×
1011
                                /* Return any unexpected errors */
1012
                                return r;
×
1013
                        }
1014
                }
1015
        }
1016

1017
        return -EPROTO;
×
1018
}
1019

1020
void sigkill_wait(pid_t pid) {
31✔
1021
        assert(pid > 1);
31✔
1022

1023
        (void) kill(pid, SIGKILL);
31✔
1024
        (void) wait_for_terminate(pid, NULL);
31✔
1025
}
31✔
1026

1027
void sigkill_waitp(pid_t *pid) {
12,672✔
1028
        PROTECT_ERRNO;
12,672✔
1029

1030
        if (!pid)
12,672✔
1031
                return;
1032
        if (*pid <= 1)
12,672✔
1033
                return;
1034

1035
        sigkill_wait(*pid);
30✔
1036
}
1037

1038
void sigterm_wait(pid_t pid) {
58✔
1039
        assert(pid > 1);
58✔
1040

1041
        (void) kill_and_sigcont(pid, SIGTERM);
58✔
1042
        (void) wait_for_terminate(pid, NULL);
58✔
1043
}
58✔
1044

1045
void sigkill_nowait(pid_t pid) {
×
1046
        assert(pid > 1);
×
1047

1048
        (void) kill(pid, SIGKILL);
×
1049
}
×
1050

1051
void sigkill_nowaitp(pid_t *pid) {
×
1052
        PROTECT_ERRNO;
×
1053

1054
        if (!pid)
×
1055
                return;
1056
        if (*pid <= 1)
×
1057
                return;
1058

1059
        sigkill_nowait(*pid);
×
1060
}
1061

1062
int kill_and_sigcont(pid_t pid, int sig) {
58✔
1063
        int r;
58✔
1064

1065
        r = RET_NERRNO(kill(pid, sig));
58✔
1066

1067
        /* If this worked, also send SIGCONT, unless we already just sent a SIGCONT, or SIGKILL was sent which isn't
1068
         * affected by a process being suspended anyway. */
1069
        if (r >= 0 && !IN_SET(sig, SIGCONT, SIGKILL))
58✔
1070
                (void) kill(pid, SIGCONT);
58✔
1071

1072
        return r;
58✔
1073
}
1074

1075
int getenv_for_pid(pid_t pid, const char *field, char **ret) {
5,479✔
1076
        _cleanup_fclose_ FILE *f = NULL;
5,479✔
1077
        const char *path;
5,479✔
1078
        size_t sum = 0;
5,479✔
1079
        int r;
5,479✔
1080

1081
        assert(pid >= 0);
5,479✔
1082
        assert(field);
5,479✔
1083
        assert(ret);
5,479✔
1084

1085
        if (pid == 0 || pid == getpid_cached())
5,479✔
1086
                return strdup_to_full(ret, getenv(field));
13✔
1087

1088
        if (!pid_is_valid(pid))
5,466✔
1089
                return -EINVAL;
1090

1091
        path = procfs_file_alloca(pid, "environ");
5,466✔
1092

1093
        r = fopen_unlocked(path, "re", &f);
5,466✔
1094
        if (r == -ENOENT)
5,466✔
1095
                return -ESRCH;
1096
        if (r < 0)
4,952✔
1097
                return r;
1098

1099
        for (;;) {
67,152✔
1100
                _cleanup_free_ char *line = NULL;
31,873✔
1101
                const char *match;
35,281✔
1102

1103
                if (sum > ENVIRONMENT_BLOCK_MAX) /* Give up searching eventually */
35,281✔
1104
                        return -ENOBUFS;
1105

1106
                r = read_nul_string(f, LONG_LINE_MAX, &line);
35,281✔
1107
                if (r < 0)
35,281✔
1108
                        return r;
1109
                if (r == 0)  /* EOF */
35,281✔
1110
                        break;
1111

1112
                sum += r;
31,873✔
1113

1114
                match = startswith(line, field);
31,873✔
1115
                if (match && *match == '=')
31,873✔
1116
                        return strdup_to_full(ret, match + 1);
2✔
1117
        }
1118

1119
        *ret = NULL;
3,408✔
1120
        return 0;
3,408✔
1121
}
1122

1123
int pidref_is_my_child(PidRef *pid) {
3,530✔
1124
        int r;
3,530✔
1125

1126
        if (!pidref_is_set(pid))
3,530✔
1127
                return -ESRCH;
3,530✔
1128

1129
        if (pidref_is_remote(pid))
3,530✔
1130
                return -EREMOTE;
1131

1132
        if (pid->pid == 1 || pidref_is_self(pid))
3,530✔
1133
                return false;
×
1134

1135
        pid_t ppid;
3,530✔
1136
        r = pidref_get_ppid(pid, &ppid);
3,530✔
1137
        if (r == -EADDRNOTAVAIL) /* if this process is outside of our pidns, it is definitely not our child */
3,530✔
1138
                return false;
1139
        if (r < 0)
3,530✔
1140
                return r;
1141

1142
        return ppid == getpid_cached();
3,530✔
1143
}
1144

1145
int pid_is_my_child(pid_t pid) {
×
1146

1147
        if (pid == 0)
×
1148
                return false;
×
1149

1150
        return pidref_is_my_child(&PIDREF_MAKE_FROM_PID(pid));
×
1151
}
1152

1153
int pidref_is_unwaited(PidRef *pid) {
8,140✔
1154
        int r;
8,140✔
1155

1156
        /* Checks whether a PID is still valid at all, including a zombie */
1157

1158
        if (!pidref_is_set(pid))
8,140✔
1159
                return -ESRCH;
1160

1161
        if (pidref_is_remote(pid))
8,139✔
1162
                return -EREMOTE;
1163

1164
        if (pid->pid == 1 || pidref_is_self(pid))
8,139✔
1165
                return true;
5✔
1166

1167
        r = pidref_kill(pid, 0);
8,134✔
1168
        if (r == -ESRCH)
8,134✔
1169
                return false;
1170
        if (r < 0)
1,526✔
1171
                return r;
79✔
1172

1173
        return true;
1174
}
1175

1176
int pid_is_unwaited(pid_t pid) {
7,514✔
1177

1178
        if (pid == 0)
7,514✔
1179
                return true;
7,514✔
1180

1181
        return pidref_is_unwaited(&PIDREF_MAKE_FROM_PID(pid));
7,514✔
1182
}
1183

1184
int pid_is_alive(pid_t pid) {
6,043✔
1185
        int r;
6,043✔
1186

1187
        /* Checks whether a PID is still valid and not a zombie */
1188

1189
        if (pid < 0)
6,043✔
1190
                return -ESRCH;
1191

1192
        if (pid <= 1) /* If we or PID 1 would be a zombie, this code would not be running */
6,042✔
1193
                return true;
1194

1195
        if (pid == getpid_cached())
6,042✔
1196
                return true;
1197

1198
        r = get_process_state(pid);
6,041✔
1199
        if (r == -ESRCH)
6,041✔
1200
                return false;
1201
        if (r < 0)
5,131✔
1202
                return r;
1203

1204
        return r != 'Z';
5,131✔
1205
}
1206

1207
int pidref_is_alive(const PidRef *pidref) {
6,044✔
1208
        int r, result;
6,044✔
1209

1210
        if (!pidref_is_set(pidref))
6,044✔
1211
                return -ESRCH;
1212

1213
        if (pidref_is_remote(pidref))
6,038✔
1214
                return -EREMOTE;
1215

1216
        result = pid_is_alive(pidref->pid);
6,038✔
1217
        if (result < 0) {
6,038✔
1218
                assert(result != -ESRCH);
×
1219
                return result;
1220
        }
1221

1222
        r = pidref_verify(pidref);
6,038✔
1223
        if (r == -ESRCH)
6,038✔
1224
                return false;
1225
        if (r < 0)
5,129✔
1226
                return r;
×
1227

1228
        return result;
1229
}
1230

1231
int pidref_from_same_root_fs(PidRef *a, PidRef *b) {
13,617✔
1232
        _cleanup_(pidref_done) PidRef self = PIDREF_NULL;
×
1233
        int r;
13,617✔
1234

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

1238
        if (!a || !b) {
13,617✔
1239
                r = pidref_set_self(&self);
13,596✔
1240
                if (r < 0)
13,596✔
1241
                        return r;
1242
                if (!a)
13,596✔
1243
                        a = &self;
×
1244
                if (!b)
13,596✔
1245
                        b = &self;
13,596✔
1246
        }
1247

1248
        if (!pidref_is_set(a) || !pidref_is_set(b))
13,617✔
1249
                return -ESRCH;
×
1250

1251
        /* If one of the two processes have the same root they cannot have the same root fs, but if both of
1252
         * them do we don't know */
1253
        if (pidref_is_remote(a) && pidref_is_remote(b))
13,617✔
1254
                return -EREMOTE;
1255
        if (pidref_is_remote(a) || pidref_is_remote(b))
40,851✔
1256
                return false;
1257

1258
        if (pidref_equal(a, b))
13,617✔
1259
                return true;
1260

1261
        const char *roota = procfs_file_alloca(a->pid, "root");
13,347✔
1262
        const char *rootb = procfs_file_alloca(b->pid, "root");
13,347✔
1263

1264
        int result = inode_same(roota, rootb, 0);
13,347✔
1265
        if (result == -ENOENT)
13,347✔
1266
                return proc_mounted() == 0 ? -ENOSYS : -ESRCH;
×
1267
        if (result < 0)
13,347✔
1268
                return result;
1269

1270
        r = pidref_verify(a);
13,236✔
1271
        if (r < 0)
13,236✔
1272
                return r;
1273
        r = pidref_verify(b);
13,236✔
1274
        if (r < 0)
13,236✔
1275
                return r;
×
1276

1277
        return result;
1278
}
1279

1280
bool is_main_thread(void) {
7,201,544✔
1281
        static thread_local int cached = -1;
7,201,544✔
1282

1283
        if (cached < 0)
7,201,544✔
1284
                cached = getpid_cached() == gettid();
70,123✔
1285

1286
        return cached;
7,201,544✔
1287
}
1288

1289
bool oom_score_adjust_is_valid(int oa) {
6,888✔
1290
        return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
6,888✔
1291
}
1292

1293
unsigned long personality_from_string(const char *p) {
9✔
1294
        Architecture architecture;
9✔
1295

1296
        if (!p)
9✔
1297
                return PERSONALITY_INVALID;
1298

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

1303
        architecture = architecture_from_string(p);
8✔
1304
        if (architecture < 0)
8✔
1305
                return PERSONALITY_INVALID;
1306

1307
        if (architecture == native_architecture())
6✔
1308
                return PER_LINUX;
1309
#ifdef ARCHITECTURE_SECONDARY
1310
        if (architecture == ARCHITECTURE_SECONDARY)
3✔
1311
                return PER_LINUX32;
2✔
1312
#endif
1313

1314
        return PERSONALITY_INVALID;
1315
}
1316

1317
const char* personality_to_string(unsigned long p) {
1,123✔
1318
        Architecture architecture = _ARCHITECTURE_INVALID;
1,123✔
1319

1320
        if (p == PER_LINUX)
1,123✔
1321
                architecture = native_architecture();
1322
#ifdef ARCHITECTURE_SECONDARY
1323
        else if (p == PER_LINUX32)
1,118✔
1324
                architecture = ARCHITECTURE_SECONDARY;
1325
#endif
1326

1327
        if (architecture < 0)
1328
                return NULL;
1329

1330
        return architecture_to_string(architecture);
7✔
1331
}
1332

1333
int safe_personality(unsigned long p) {
2,054✔
1334
        int ret;
2,054✔
1335

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

1343
        errno = 0;
2,054✔
1344
        ret = personality(p);
2,054✔
1345
        if (ret < 0) {
2,054✔
1346
                if (errno != 0)
12✔
1347
                        return -errno;
12✔
1348

1349
                errno = -ret;
×
1350
        }
1351

1352
        return ret;
1353
}
1354

1355
int opinionated_personality(unsigned long *ret) {
2,039✔
1356
        int current;
2,039✔
1357

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

1362
        current = safe_personality(PERSONALITY_INVALID);
2,039✔
1363
        if (current < 0)
2,039✔
1364
                return current;
1365

1366
        if (((unsigned long) current & OPINIONATED_PERSONALITY_MASK) == PER_LINUX32)
2,039✔
1367
                *ret = PER_LINUX32;
×
1368
        else
1369
                *ret = PER_LINUX;
2,039✔
1370

1371
        return 0;
1372
}
1373

1374
void valgrind_summary_hack(void) {
99✔
1375
#if HAVE_VALGRIND_VALGRIND_H
1376
        if (getpid_cached() == 1 && RUNNING_ON_VALGRIND) {
1377
                pid_t pid;
1378
                pid = raw_clone(SIGCHLD);
1379
                if (pid < 0)
1380
                        log_struct_errno(
1381
                                LOG_EMERG, errno,
1382
                                "MESSAGE_ID=" SD_MESSAGE_VALGRIND_HELPER_FORK_STR,
1383
                                LOG_MESSAGE( "Failed to fork off valgrind helper: %m"));
1384
                else if (pid == 0)
1385
                        exit(EXIT_SUCCESS);
1386
                else {
1387
                        log_info("Spawned valgrind helper as PID "PID_FMT".", pid);
1388
                        (void) wait_for_terminate(pid, NULL);
1389
                }
1390
        }
1391
#endif
1392
}
99✔
1393

1394
int pid_compare_func(const pid_t *a, const pid_t *b) {
1,445✔
1395
        /* Suitable for usage in qsort() */
1396
        return CMP(*a, *b);
1,445✔
1397
}
1398

1399
/* The cached PID, possible values:
1400
 *
1401
 *     == UNSET [0]  → cache not initialized yet
1402
 *     == BUSY [-1]  → some thread is initializing it at the moment
1403
 *     any other     → the cached PID
1404
 */
1405

1406
#define CACHED_PID_UNSET ((pid_t) 0)
1407
#define CACHED_PID_BUSY ((pid_t) -1)
1408

1409
static pid_t cached_pid = CACHED_PID_UNSET;
1410

1411
void reset_cached_pid(void) {
3,461✔
1412
        /* Invoked in the child after a fork(), i.e. at the first moment the PID changed */
1413
        cached_pid = CACHED_PID_UNSET;
3,461✔
1414
}
3,461✔
1415

1416
pid_t getpid_cached(void) {
79,151,462✔
1417
        static bool installed = false;
79,151,462✔
1418
        pid_t current_value = CACHED_PID_UNSET;
79,151,462✔
1419

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

1429
        (void) __atomic_compare_exchange_n(
79,151,462✔
1430
                        &cached_pid,
1431
                        &current_value,
1432
                        CACHED_PID_BUSY,
1433
                        false,
1434
                        __ATOMIC_SEQ_CST,
1435
                        __ATOMIC_SEQ_CST);
1436

1437
        switch (current_value) {
79,151,462✔
1438

1439
        case CACHED_PID_UNSET: { /* Not initialized yet, then do so now */
1440
                pid_t new_pid;
120,036✔
1441

1442
                new_pid = raw_getpid();
120,036✔
1443

1444
                if (!installed) {
120,036✔
1445
                        /* __register_atfork() either returns 0 or -ENOMEM, in its glibc implementation. Since it's
1446
                         * only half-documented (glibc doesn't document it but LSB does — though only superficially)
1447
                         * we'll check for errors only in the most generic fashion possible. */
1448

1449
                        if (pthread_atfork(NULL, NULL, reset_cached_pid) != 0) {
92,693✔
1450
                                /* OOM? Let's try again later */
1451
                                cached_pid = CACHED_PID_UNSET;
×
1452
                                return new_pid;
×
1453
                        }
1454

1455
                        installed = true;
92,693✔
1456
                }
1457

1458
                cached_pid = new_pid;
120,036✔
1459
                return new_pid;
120,036✔
1460
        }
1461

1462
        case CACHED_PID_BUSY: /* Somebody else is currently initializing */
1463
                return raw_getpid();
×
1464

1465
        default: /* Properly initialized */
1466
                return current_value;
1467
        }
1468
}
1469

1470
int must_be_root(void) {
108✔
1471

1472
        if (geteuid() == 0)
108✔
1473
                return 0;
1474

1475
        return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Need to be root.");
×
1476
}
1477

1478
pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata) {
4,281✔
1479
        size_t ps;
4,281✔
1480
        pid_t pid;
4,281✔
1481
        void *mystack;
4,281✔
1482

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

1491
        assert((flags & (CLONE_VM|CLONE_PARENT_SETTID|CLONE_CHILD_SETTID|
4,281✔
1492
                         CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0);
1493

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

1501
        ps = page_size();
4,281✔
1502
        mystack = alloca(ps*3);
4,281✔
1503
        mystack = (uint8_t*) mystack + ps; /* move pointer one page ahead since stacks usually grow backwards */
4,281✔
1504
        mystack = (void*) ALIGN_TO((uintptr_t) mystack, ps); /* align to page size (moving things further ahead) */
4,281✔
1505

1506
#if HAVE_CLONE
1507
        pid = clone(fn, mystack, flags, userdata);
4,281✔
1508
#else
1509
        pid = __clone2(fn, mystack, ps, flags, userdata);
1510
#endif
1511
        if (pid < 0)
4,281✔
1512
                return -errno;
×
1513

1514
        return pid;
1515
}
1516

1517
static void restore_sigsetp(sigset_t **ssp) {
58,818✔
1518
        if (*ssp)
58,818✔
1519
                (void) sigprocmask(SIG_SETMASK, *ssp, NULL);
25,846✔
1520
}
58,818✔
1521

1522
static int fork_flags_to_signal(ForkFlags flags) {
26,610✔
1523
        return (flags & FORK_DEATHSIG_SIGTERM) ? SIGTERM :
26,610✔
1524
                (flags & FORK_DEATHSIG_SIGINT) ? SIGINT :
922✔
1525
                                                 SIGKILL;
1526
}
1527

1528
int safe_fork_full(
33,032✔
1529
                const char *name,
1530
                const int stdio_fds[3],
1531
                int except_fds[],
1532
                size_t n_except_fds,
1533
                ForkFlags flags,
1534
                pid_t *ret_pid) {
1535

1536
        pid_t original_pid, pid;
33,032✔
1537
        sigset_t saved_ss, ss;
33,032✔
1538
        _unused_ _cleanup_(restore_sigsetp) sigset_t *saved_ssp = NULL;
58,818✔
1539
        bool block_signals = false, block_all = false, intermediary = false;
33,032✔
1540
        int prio, r;
33,032✔
1541

1542
        assert(!FLAGS_SET(flags, FORK_DETACH) ||
33,032✔
1543
               (!ret_pid && (flags & (FORK_WAIT|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL)) == 0));
1544

1545
        /* A wrapper around fork(), that does a couple of important initializations in addition to mere forking. Always
1546
         * returns the child's PID in *ret_pid. Returns == 0 in the child, and > 0 in the parent. */
1547

1548
        prio = flags & FORK_LOG ? LOG_ERR : LOG_DEBUG;
33,032✔
1549

1550
        original_pid = getpid_cached();
33,032✔
1551

1552
        if (flags & FORK_FLUSH_STDIO) {
33,032✔
1553
                fflush(stdout);
5✔
1554
                fflush(stderr); /* This one shouldn't be necessary, stderr should be unbuffered anyway, but let's better be safe than sorry */
5✔
1555
        }
1556

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

1562
                assert_se(sigfillset(&ss) >= 0);
28,347✔
1563
                block_signals = block_all = true;
1564

1565
        } else if (flags & FORK_WAIT) {
4,685✔
1566
                /* Let's block SIGCHLD at least, so that we can safely watch for the child process */
1567

1568
                assert_se(sigemptyset(&ss) >= 0);
106✔
1569
                assert_se(sigaddset(&ss, SIGCHLD) >= 0);
106✔
1570
                block_signals = true;
1571
        }
1572

1573
        if (block_signals) {
1574
                if (sigprocmask(SIG_BLOCK, &ss, &saved_ss) < 0)
28,453✔
1575
                        return log_full_errno(prio, errno, "Failed to block signal mask: %m");
×
1576
                saved_ssp = &saved_ss;
28,453✔
1577
        }
1578

1579
        if (FLAGS_SET(flags, FORK_DETACH)) {
33,032✔
1580
                /* Fork off intermediary child if needed */
1581

1582
                r = is_reaper_process();
192✔
1583
                if (r < 0)
192✔
1584
                        return log_full_errno(prio, r, "Failed to determine if we are a reaper process: %m");
×
1585

1586
                if (!r) {
192✔
1587
                        /* Not a reaper process, hence do a double fork() so we are reparented to one */
1588

1589
                        pid = fork();
2✔
1590
                        if (pid < 0)
4✔
1591
                                return log_full_errno(prio, errno, "Failed to fork off '%s': %m", strna(name));
×
1592
                        if (pid > 0) {
4✔
1593
                                log_debug("Successfully forked off intermediary '%s' as PID " PID_FMT ".", strna(name), pid);
4✔
1594
                                return 1; /* return in the parent */
2✔
1595
                        }
1596

1597
                        intermediary = true;
1598
                }
1599
        }
1600

1601
        if ((flags & (FORK_NEW_MOUNTNS|FORK_NEW_USERNS|FORK_NEW_NETNS|FORK_NEW_PIDNS)) != 0)
33,032✔
1602
                pid = raw_clone(SIGCHLD|
10,999✔
1603
                                (FLAGS_SET(flags, FORK_NEW_MOUNTNS) ? CLONE_NEWNS : 0) |
10,999✔
1604
                                (FLAGS_SET(flags, FORK_NEW_USERNS) ? CLONE_NEWUSER : 0) |
10,999✔
1605
                                (FLAGS_SET(flags, FORK_NEW_NETNS) ? CLONE_NEWNET : 0) |
10,999✔
1606
                                (FLAGS_SET(flags, FORK_NEW_PIDNS) ? CLONE_NEWPID : 0));
10,999✔
1607
        else
1608
                pid = fork();
22,033✔
1609
        if (pid < 0)
58,818✔
1610
                return log_full_errno(prio, errno, "Failed to fork off '%s': %m", strna(name));
2✔
1611
        if (pid > 0) {
58,817✔
1612

1613
                /* If we are in the intermediary process, exit now */
1614
                if (intermediary)
30,418✔
1615
                        _exit(EXIT_SUCCESS);
2✔
1616

1617
                /* We are in the parent process */
1618
                log_debug("Successfully forked off '%s' as PID " PID_FMT ".", strna(name), pid);
58,239✔
1619

1620
                if (flags & FORK_WAIT) {
30,416✔
1621
                        if (block_all) {
3,616✔
1622
                                /* undo everything except SIGCHLD */
1623
                                ss = saved_ss;
3,510✔
1624
                                assert_se(sigaddset(&ss, SIGCHLD) >= 0);
3,510✔
1625
                                (void) sigprocmask(SIG_SETMASK, &ss, NULL);
3,510✔
1626
                        }
1627

1628
                        r = wait_for_terminate_and_check(name, pid, (flags & FORK_LOG ? WAIT_LOG : 0));
6,824✔
1629
                        if (r < 0)
3,616✔
1630
                                return r;
1631
                        if (r != EXIT_SUCCESS) /* exit status > 0 should be treated as failure, too */
3,616✔
1632
                                return -EPROTO;
1633
                }
1634

1635
                if (ret_pid)
30,416✔
1636
                        *ret_pid = pid;
26,334✔
1637

1638
                return 1;
30,416✔
1639
        }
1640

1641
        /* We are in the child process */
1642

1643
        /* Restore signal mask manually */
1644
        saved_ssp = NULL;
28,399✔
1645

1646
        if (flags & FORK_REOPEN_LOG) {
28,399✔
1647
                /* Close the logs if requested, before we log anything. And make sure we reopen it if needed. */
1648
                log_close();
3,299✔
1649
                log_set_open_when_needed(true);
3,299✔
1650
                log_settle_target();
3,299✔
1651
        }
1652

1653
        if (name) {
28,399✔
1654
                r = rename_process(name);
28,399✔
1655
                if (r < 0)
28,399✔
1656
                        log_full_errno(flags & FORK_LOG ? LOG_WARNING : LOG_DEBUG,
×
1657
                                       r, "Failed to rename process, ignoring: %m");
1658
        }
1659

1660
        if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL))
28,399✔
1661
                if (prctl(PR_SET_PDEATHSIG, fork_flags_to_signal(flags)) < 0) {
26,610✔
1662
                        log_full_errno(prio, errno, "Failed to set death signal: %m");
×
1663
                        _exit(EXIT_FAILURE);
×
1664
                }
1665

1666
        if (flags & FORK_RESET_SIGNALS) {
28,399✔
1667
                r = reset_all_signal_handlers();
20,531✔
1668
                if (r < 0) {
20,531✔
1669
                        log_full_errno(prio, r, "Failed to reset signal handlers: %m");
×
1670
                        _exit(EXIT_FAILURE);
×
1671
                }
1672

1673
                /* This implicitly undoes the signal mask stuff we did before the fork()ing above */
1674
                r = reset_signal_mask();
20,531✔
1675
                if (r < 0) {
20,531✔
1676
                        log_full_errno(prio, r, "Failed to reset signal mask: %m");
×
1677
                        _exit(EXIT_FAILURE);
×
1678
                }
1679
        } else if (block_signals) { /* undo what we did above */
7,868✔
1680
                if (sigprocmask(SIG_SETMASK, &saved_ss, NULL) < 0) {
7,572✔
1681
                        log_full_errno(prio, errno, "Failed to restore signal mask: %m");
×
1682
                        _exit(EXIT_FAILURE);
×
1683
                }
1684
        }
1685

1686
        if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGKILL|FORK_DEATHSIG_SIGINT)) {
28,399✔
1687
                pid_t ppid;
26,610✔
1688
                /* Let's see if the parent PID is still the one we started from? If not, then the parent
1689
                 * already died by the time we set PR_SET_PDEATHSIG, hence let's emulate the effect */
1690

1691
                ppid = getppid();
26,610✔
1692
                if (ppid == 0)
26,610✔
1693
                        /* Parent is in a different PID namespace. */;
1694
                else if (ppid != original_pid) {
26,573✔
1695
                        int sig = fork_flags_to_signal(flags);
×
1696
                        log_debug("Parent died early, raising %s.", signal_to_string(sig));
×
1697
                        (void) raise(sig);
×
1698
                        _exit(EXIT_FAILURE);
×
1699
                }
1700
        }
1701

1702
        if (FLAGS_SET(flags, FORK_NEW_MOUNTNS | FORK_MOUNTNS_SLAVE)) {
28,399✔
1703
                /* Optionally, make sure we never propagate mounts to the host. */
1704
                if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
100✔
1705
                        log_full_errno(prio, errno, "Failed to remount root directory as MS_SLAVE: %m");
×
1706
                        _exit(EXIT_FAILURE);
×
1707
                }
1708
        }
1709

1710
        if (FLAGS_SET(flags, FORK_PRIVATE_TMP)) {
28,399✔
1711
                assert(FLAGS_SET(flags, FORK_NEW_MOUNTNS));
×
1712

1713
                /* Optionally, overmount new tmpfs instance on /tmp/. */
1714
                r = mount_nofollow("tmpfs", "/tmp", "tmpfs",
×
1715
                                   MS_NOSUID|MS_NODEV,
1716
                                   "mode=01777" TMPFS_LIMITS_RUN);
1717
                if (r < 0) {
×
1718
                        log_full_errno(prio, r, "Failed to overmount /tmp/: %m");
×
1719
                        _exit(EXIT_FAILURE);
×
1720
                }
1721
        }
1722

1723
        if (flags & FORK_REARRANGE_STDIO) {
28,399✔
1724
                if (stdio_fds) {
13,692✔
1725
                        r = rearrange_stdio(stdio_fds[0], stdio_fds[1], stdio_fds[2]);
13,685✔
1726
                        if (r < 0) {
13,685✔
1727
                                log_full_errno(prio, r, "Failed to rearrange stdio fds: %m");
×
1728
                                _exit(EXIT_FAILURE);
×
1729
                        }
1730

1731
                        /* Turn off O_NONBLOCK on the fdio fds, in case it was left on */
1732
                        stdio_disable_nonblock();
13,685✔
1733
                } else {
1734
                        r = make_null_stdio();
7✔
1735
                        if (r < 0) {
7✔
1736
                                log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
×
1737
                                _exit(EXIT_FAILURE);
×
1738
                        }
1739
                }
1740
        } else if (flags & FORK_STDOUT_TO_STDERR) {
14,707✔
1741
                if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
2✔
1742
                        log_full_errno(prio, errno, "Failed to connect stdout to stderr: %m");
×
1743
                        _exit(EXIT_FAILURE);
×
1744
                }
1745
        }
1746

1747
        if (flags & FORK_CLOSE_ALL_FDS) {
28,399✔
1748
                /* Close the logs here in case it got reopened above, as close_all_fds() would close them for us */
1749
                log_close();
20,009✔
1750

1751
                r = close_all_fds(except_fds, n_except_fds);
20,009✔
1752
                if (r < 0) {
20,009✔
1753
                        log_full_errno(prio, r, "Failed to close all file descriptors: %m");
×
1754
                        _exit(EXIT_FAILURE);
×
1755
                }
1756
        }
1757

1758
        if (flags & FORK_PACK_FDS) {
28,399✔
1759
                /* FORK_CLOSE_ALL_FDS ensures that except_fds are the only FDs >= 3 that are
1760
                 * open, this is including the log. This is required by pack_fds, which will
1761
                 * get stuck in an infinite loop of any FDs other than except_fds are open. */
1762
                assert(FLAGS_SET(flags, FORK_CLOSE_ALL_FDS));
56✔
1763

1764
                r = pack_fds(except_fds, n_except_fds);
56✔
1765
                if (r < 0) {
56✔
1766
                        log_full_errno(prio, r, "Failed to pack file descriptors: %m");
×
1767
                        _exit(EXIT_FAILURE);
×
1768
                }
1769
        }
1770

1771
        if (flags & FORK_CLOEXEC_OFF) {
28,399✔
1772
                r = fd_cloexec_many(except_fds, n_except_fds, false);
62✔
1773
                if (r < 0) {
62✔
1774
                        log_full_errno(prio, r, "Failed to turn off O_CLOEXEC on file descriptors: %m");
×
1775
                        _exit(EXIT_FAILURE);
×
1776
                }
1777
        }
1778

1779
        /* When we were asked to reopen the logs, do so again now */
1780
        if (flags & FORK_REOPEN_LOG) {
28,399✔
1781
                log_open();
3,299✔
1782
                log_set_open_when_needed(false);
3,299✔
1783
        }
1784

1785
        if (flags & FORK_RLIMIT_NOFILE_SAFE) {
28,399✔
1786
                r = rlimit_nofile_safe();
14,945✔
1787
                if (r < 0) {
14,945✔
1788
                        log_full_errno(prio, r, "Failed to lower RLIMIT_NOFILE's soft limit to 1K: %m");
×
1789
                        _exit(EXIT_FAILURE);
×
1790
                }
1791
        }
1792

1793
        if (!FLAGS_SET(flags, FORK_KEEP_NOTIFY_SOCKET)) {
28,399✔
1794
                r = RET_NERRNO(unsetenv("NOTIFY_SOCKET"));
28,399✔
1795
                if (r < 0) {
×
1796
                        log_full_errno(prio, r, "Failed to unset $NOTIFY_SOCKET: %m");
×
1797
                        _exit(EXIT_FAILURE);
×
1798
                }
1799
        }
1800

1801
        if (FLAGS_SET(flags, FORK_FREEZE))
28,399✔
1802
                freeze();
×
1803

1804
        if (ret_pid)
28,399✔
1805
                *ret_pid = getpid_cached();
23,538✔
1806

1807
        return 0;
1808
}
1809

1810
int pidref_safe_fork_full(
4,278✔
1811
                const char *name,
1812
                const int stdio_fds[3],
1813
                int except_fds[],
1814
                size_t n_except_fds,
1815
                ForkFlags flags,
1816
                PidRef *ret_pid) {
1817

1818
        pid_t pid;
4,278✔
1819
        int r, q;
4,278✔
1820

1821
        r = safe_fork_full(name, stdio_fds, except_fds, n_except_fds, flags, &pid);
4,278✔
1822
        if (r < 0 || !ret_pid)
4,417✔
1823
                return r;
4,417✔
1824

1825
        if (r > 0 && FLAGS_SET(flags, FORK_WAIT)) {
4,417✔
1826
                /* If we are in the parent and successfully waited, then the process doesn't exist anymore */
1827
                *ret_pid = PIDREF_NULL;
2✔
1828
                return r;
2✔
1829
        }
1830

1831
        q = pidref_set_pid(ret_pid, pid);
4,415✔
1832
        if (q < 0) /* Let's not fail for this, no matter what, the process exists after all, and that's key */
4,415✔
1833
                *ret_pid = PIDREF_MAKE_FROM_PID(pid);
×
1834

1835
        return r;
1836
}
1837

1838
int namespace_fork(
165✔
1839
                const char *outer_name,
1840
                const char *inner_name,
1841
                int except_fds[],
1842
                size_t n_except_fds,
1843
                ForkFlags flags,
1844
                int pidns_fd,
1845
                int mntns_fd,
1846
                int netns_fd,
1847
                int userns_fd,
1848
                int root_fd,
1849
                pid_t *ret_pid) {
1850

1851
        int r;
165✔
1852

1853
        /* This is much like safe_fork(), but forks twice, and joins the specified namespaces in the middle
1854
         * process. This ensures that we are fully a member of the destination namespace, with pidns an all, so that
1855
         * /proc/self/fd works correctly. */
1856

1857
        r = safe_fork_full(outer_name,
483✔
1858
                           NULL,
1859
                           except_fds, n_except_fds,
1860
                           (flags|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGKILL) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
165✔
1861
        if (r < 0)
318✔
1862
                return r;
1863
        if (r == 0) {
318✔
1864
                pid_t pid;
153✔
1865

1866
                /* Child */
1867

1868
                r = namespace_enter(pidns_fd, mntns_fd, netns_fd, userns_fd, root_fd);
153✔
1869
                if (r < 0) {
153✔
1870
                        log_full_errno(FLAGS_SET(flags, FORK_LOG) ? LOG_ERR : LOG_DEBUG, r, "Failed to join namespace: %m");
×
1871
                        _exit(EXIT_FAILURE);
×
1872
                }
1873

1874
                /* We mask a few flags here that either make no sense for the grandchild, or that we don't have to do again */
1875
                r = safe_fork_full(inner_name,
460✔
1876
                                   NULL,
1877
                                   except_fds, n_except_fds,
1878
                                   flags & ~(FORK_WAIT|FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO), &pid);
153✔
1879
                if (r < 0)
307✔
1880
                        _exit(EXIT_FAILURE);
×
1881
                if (r == 0) {
307✔
1882
                        /* Child */
1883
                        if (ret_pid)
154✔
1884
                                *ret_pid = pid;
154✔
1885
                        return 0;
154✔
1886
                }
1887

1888
                r = wait_for_terminate_and_check(inner_name, pid, FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
306✔
1889
                if (r < 0)
153✔
1890
                        _exit(EXIT_FAILURE);
×
1891

1892
                _exit(r);
153✔
1893
        }
1894

1895
        return 1;
1896
}
1897

1898
int set_oom_score_adjust(int value) {
5,048✔
1899
        char t[DECIMAL_STR_MAX(int)];
5,048✔
1900

1901
        if (!oom_score_adjust_is_valid(value))
5,048✔
1902
                return -EINVAL;
5,048✔
1903

1904
        xsprintf(t, "%i", value);
5,048✔
1905

1906
        return write_string_file("/proc/self/oom_score_adj", t,
5,048✔
1907
                                 WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
1908
}
1909

1910
int get_oom_score_adjust(int *ret) {
910✔
1911
        _cleanup_free_ char *t = NULL;
910✔
1912
        int r, a;
910✔
1913

1914
        r = read_virtual_file("/proc/self/oom_score_adj", SIZE_MAX, &t, NULL);
910✔
1915
        if (r < 0)
910✔
1916
                return r;
1917

1918
        delete_trailing_chars(t, WHITESPACE);
910✔
1919

1920
        r = safe_atoi(t, &a);
910✔
1921
        if (r < 0)
910✔
1922
                return r;
1923

1924
        if (!oom_score_adjust_is_valid(a))
910✔
1925
                return -ENODATA;
1926

1927
        if (ret)
910✔
1928
                *ret = a;
910✔
1929

1930
        return 0;
1931
}
1932

1933
static int rlimit_to_nice(rlim_t limit) {
2✔
1934
        if (limit <= 1)
2✔
1935
                return PRIO_MAX-1; /* i.e. 19 */
1936

1937
        if (limit >= -PRIO_MIN + PRIO_MAX)
2✔
1938
                return PRIO_MIN; /* i.e. -20 */
1939

1940
        return PRIO_MAX - (int) limit;
2✔
1941
}
1942

1943
int setpriority_closest(int priority) {
22✔
1944
        struct rlimit highest;
22✔
1945
        int r, current, limit;
22✔
1946

1947
        /* Try to set requested nice level */
1948
        r = RET_NERRNO(setpriority(PRIO_PROCESS, 0, priority));
22✔
1949
        if (r >= 0)
2✔
1950
                return 1;
20✔
1951
        if (!ERRNO_IS_NEG_PRIVILEGE(r))
2✔
1952
                return r;
1953

1954
        errno = 0;
2✔
1955
        current = getpriority(PRIO_PROCESS, 0);
2✔
1956
        if (errno != 0)
2✔
1957
                return -errno;
×
1958

1959
        if (priority == current)
2✔
1960
                return 1;
1961

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

1968
        if (getrlimit(RLIMIT_NICE, &highest) < 0)
2✔
1969
                return -errno;
×
1970

1971
        limit = rlimit_to_nice(highest.rlim_cur);
2✔
1972

1973
        /* Push to the allowed limit if we're higher than that. Note that we could also be less nice than
1974
         * limit allows us, but still higher than what's requested. In that case our current value is
1975
         * the best choice. */
1976
        if (current > limit)
2✔
1977
                if (setpriority(PRIO_PROCESS, 0, limit) < 0)
2✔
1978
                        return -errno;
×
1979

1980
        log_debug("Cannot set requested nice level (%i), using next best (%i).", priority, MIN(current, limit));
2✔
1981
        return 0;
1982
}
1983

1984
_noreturn_ void freeze(void) {
×
1985
        log_close();
×
1986

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

1992
        /* Let's not freeze right away, but keep reaping zombies. */
1993
        for (;;) {
×
1994
                siginfo_t si = {};
×
1995

1996
                if (waitid(P_ALL, 0, &si, WEXITED) < 0 && errno != EINTR)
×
1997
                        break;
1998
        }
1999

2000
        /* waitid() failed with an ECHLD error (because there are no left-over child processes) or any other
2001
         * (unexpected) error. Freeze for good now! */
2002
        for (;;)
×
2003
                pause();
×
2004
}
2005

2006
int get_process_threads(pid_t pid) {
7✔
2007
        _cleanup_free_ char *t = NULL;
7✔
2008
        const char *p;
7✔
2009
        int n, r;
7✔
2010

2011
        if (pid < 0)
7✔
2012
                return -EINVAL;
2013

2014
        p = procfs_file_alloca(pid, "status");
7✔
2015

2016
        r = get_proc_field(p, "Threads", WHITESPACE, &t);
7✔
2017
        if (r == -ENOENT)
7✔
2018
                return proc_mounted() == 0 ? -ENOSYS : -ESRCH;
×
2019
        if (r < 0)
7✔
2020
                return r;
2021

2022
        r = safe_atoi(t, &n);
7✔
2023
        if (r < 0)
7✔
2024
                return r;
2025
        if (n < 0)
7✔
2026
                return -EINVAL;
×
2027

2028
        return n;
2029
}
2030

2031
int is_reaper_process(void) {
4,476✔
2032
        int b = 0;
4,476✔
2033

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

2037
        if (getpid_cached() == 1)
4,476✔
2038
                return true;
4,476✔
2039

2040
        if (prctl(PR_GET_CHILD_SUBREAPER, (unsigned long) &b, 0UL, 0UL, 0UL) < 0)
263✔
2041
                return -errno;
×
2042

2043
        return b != 0;
263✔
2044
}
2045

2046
int make_reaper_process(bool b) {
698✔
2047

2048
        if (getpid_cached() == 1) {
698✔
2049

2050
                if (!b)
112✔
2051
                        return -EINVAL;
2052

2053
                return 0;
112✔
2054
        }
2055

2056
        /* Some prctl()s insist that all 5 arguments are specified, others do not. Let's always specify all,
2057
         * to avoid any ambiguities */
2058
        if (prctl(PR_SET_CHILD_SUBREAPER, (unsigned long) b, 0UL, 0UL, 0UL) < 0)
586✔
2059
                return -errno;
×
2060

2061
        return 0;
2062
}
2063

2064
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(posix_spawnattr_t*, posix_spawnattr_destroy, NULL);
×
2065

2066
int posix_spawn_wrapper(
3,816✔
2067
                const char *path,
2068
                char * const *argv,
2069
                char * const *envp,
2070
                const char *cgroup,
2071
                PidRef *ret_pidref) {
2072

2073
        short flags = POSIX_SPAWN_SETSIGMASK;
3,816✔
2074
        posix_spawnattr_t attr;
3,816✔
2075
        sigset_t mask;
3,816✔
2076
        int r;
3,816✔
2077

2078
        /* Forks and invokes 'path' with 'argv' and 'envp' using CLONE_VM and CLONE_VFORK, which means the
2079
         * caller will be blocked until the child either exits or exec's. The memory of the child will be
2080
         * fully shared with the memory of the parent, so that there are no copy-on-write or memory.max
2081
         * issues.
2082
         *
2083
         * Also, move the newly-created process into 'cgroup' through POSIX_SPAWN_SETCGROUP (clone3())
2084
         * if available.
2085
         * returns 1: We're already in the right cgroup
2086
         *         0: 'cgroup' not specified or POSIX_SPAWN_SETCGROUP is not supported. The caller
2087
         *            needs to call 'cg_attach' on their own */
2088

2089
        assert(path);
3,816✔
2090
        assert(argv);
3,816✔
2091
        assert(ret_pidref);
3,816✔
2092

2093
        assert_se(sigfillset(&mask) >= 0);
3,816✔
2094

2095
        r = posix_spawnattr_init(&attr);
3,816✔
2096
        if (r != 0)
3,816✔
2097
                return -r; /* These functions return a positive errno on failure */
3,816✔
2098

2099
        /* Initialization needs to succeed before we can set up a destructor. */
2100
        _unused_ _cleanup_(posix_spawnattr_destroyp) posix_spawnattr_t *attr_destructor = &attr;
7,632✔
2101

2102
#if HAVE_PIDFD_SPAWN
2103
        static bool have_clone_into_cgroup = true; /* kernel 5.7+ */
3,816✔
2104
        _cleanup_close_ int cgroup_fd = -EBADF;
3,816✔
2105

2106
        if (cgroup && have_clone_into_cgroup) {
3,816✔
2107
                _cleanup_free_ char *resolved_cgroup = NULL;
3,816✔
2108

2109
                r = cg_get_path_and_check(
3,816✔
2110
                                SYSTEMD_CGROUP_CONTROLLER,
2111
                                cgroup,
2112
                                /* suffix= */ NULL,
2113
                                &resolved_cgroup);
2114
                if (r < 0)
3,816✔
2115
                        return r;
2116

2117
                cgroup_fd = open(resolved_cgroup, O_PATH|O_DIRECTORY|O_CLOEXEC);
3,816✔
2118
                if (cgroup_fd < 0)
3,816✔
2119
                        return -errno;
×
2120

2121
                r = posix_spawnattr_setcgroup_np(&attr, cgroup_fd);
3,816✔
2122
                if (r != 0)
3,816✔
2123
                        return -r;
×
2124

2125
                flags |= POSIX_SPAWN_SETCGROUP;
3,816✔
2126
        }
2127
#endif
2128

2129
        r = posix_spawnattr_setflags(&attr, flags);
3,816✔
2130
        if (r != 0)
3,816✔
2131
                return -r;
×
2132
        r = posix_spawnattr_setsigmask(&attr, &mask);
3,816✔
2133
        if (r != 0)
3,816✔
2134
                return -r;
×
2135

2136
#if HAVE_PIDFD_SPAWN
2137
        _cleanup_close_ int pidfd = -EBADF;
3,816✔
2138

2139
        r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
3,816✔
2140
        if (ERRNO_IS_NOT_SUPPORTED(r) && FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP) && cg_is_threaded(cgroup) > 0)
3,816✔
2141
                return -EUCLEAN; /* clone3() could also return EOPNOTSUPP if the target cgroup is in threaded mode,
2142
                                    turn that into something recognizable */
2143
        if ((ERRNO_IS_NOT_SUPPORTED(r) || ERRNO_IS_PRIVILEGE(r) || r == E2BIG) &&
3,816✔
2144
            FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP)) {
2145
                /* Compiled on a newer host, or seccomp&friends blocking clone3()? Fallback, but
2146
                 * need to disable POSIX_SPAWN_SETCGROUP, which is what redirects to clone3().
2147
                 * Note that we might get E2BIG here since some kernels (e.g. 5.4) support clone3()
2148
                 * but not CLONE_INTO_CGROUP. */
2149

2150
                /* CLONE_INTO_CGROUP definitely won't work, hence remember the fact so that we don't
2151
                 * retry every time. */
2152
                have_clone_into_cgroup = false;
×
2153

2154
                flags &= ~POSIX_SPAWN_SETCGROUP;
×
2155
                r = posix_spawnattr_setflags(&attr, flags);
×
2156
                if (r != 0)
×
2157
                        return -r;
×
2158

2159
                r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
×
2160
        }
2161
        if (r != 0)
3,816✔
2162
                return -r;
×
2163

2164
        r = pidref_set_pidfd_consume(ret_pidref, TAKE_FD(pidfd));
3,816✔
2165
        if (r < 0)
3,816✔
2166
                return r;
2167

2168
        return FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP);
3,816✔
2169
#else
2170
        pid_t pid;
2171

2172
        r = posix_spawn(&pid, path, NULL, &attr, argv, envp);
2173
        if (r != 0)
2174
                return -r;
2175

2176
        r = pidref_set_pid(ret_pidref, pid);
2177
        if (r < 0)
2178
                return r;
2179

2180
        return 0; /* We did not use CLONE_INTO_CGROUP so return 0, the caller will have to move the child */
2181
#endif
2182
}
2183

2184
int proc_dir_open(DIR **ret) {
63✔
2185
        DIR *d;
63✔
2186

2187
        assert(ret);
63✔
2188

2189
        d = opendir("/proc");
63✔
2190
        if (!d)
63✔
2191
                return -errno;
×
2192

2193
        *ret = d;
63✔
2194
        return 0;
63✔
2195
}
2196

2197
int proc_dir_read(DIR *d, pid_t *ret) {
6,009✔
2198
        assert(d);
6,009✔
2199

2200
        for (;;) {
9,793✔
2201
                struct dirent *de;
9,793✔
2202

2203
                errno = 0;
9,793✔
2204
                de = readdir_no_dot(d);
9,793✔
2205
                if (!de) {
9,793✔
2206
                        if (errno != 0)
63✔
2207
                                return -errno;
×
2208

2209
                        break;
63✔
2210
                }
2211

2212
                if (!IN_SET(de->d_type, DT_DIR, DT_UNKNOWN))
9,730✔
2213
                        continue;
3,091✔
2214

2215
                if (parse_pid(de->d_name, ret) >= 0)
6,639✔
2216
                        return 1;
2217
        }
2218

2219
        if (ret)
63✔
2220
                *ret = 0;
63✔
2221
        return 0;
2222
}
2223

2224
int proc_dir_read_pidref(DIR *d, PidRef *ret) {
5,966✔
2225
        int r;
5,966✔
2226

2227
        assert(d);
5,966✔
2228

2229
        for (;;) {
5,966✔
2230
                pid_t pid;
5,966✔
2231

2232
                r = proc_dir_read(d, &pid);
5,966✔
2233
                if (r < 0)
5,966✔
2234
                        return r;
5,904✔
2235
                if (r == 0)
5,966✔
2236
                        break;
2237

2238
                r = pidref_set_pid(ret, pid);
5,904✔
2239
                if (r == -ESRCH) /* gone by now? skip it */
5,904✔
2240
                        continue;
×
2241
                if (r < 0)
5,904✔
2242
                        return r;
×
2243

2244
                return 1;
2245
        }
2246

2247
        if (ret)
62✔
2248
                *ret = PIDREF_NULL;
62✔
2249
        return 0;
2250
}
2251

2252
static const char *const sigchld_code_table[] = {
2253
        [CLD_EXITED] = "exited",
2254
        [CLD_KILLED] = "killed",
2255
        [CLD_DUMPED] = "dumped",
2256
        [CLD_TRAPPED] = "trapped",
2257
        [CLD_STOPPED] = "stopped",
2258
        [CLD_CONTINUED] = "continued",
2259
};
2260

2261
DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
13,270✔
2262

2263
static const char* const sched_policy_table[] = {
2264
        [SCHED_OTHER] = "other",
2265
        [SCHED_BATCH] = "batch",
2266
        [SCHED_IDLE] = "idle",
2267
        [SCHED_FIFO] = "fifo",
2268
        [SCHED_RR] = "rr",
2269
};
2270

2271
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
3✔
2272

2273
_noreturn_ void report_errno_and_exit(int errno_fd, int error) {
47✔
2274
        int r;
47✔
2275

2276
        if (error >= 0)
47✔
2277
                _exit(EXIT_SUCCESS);
46✔
2278

2279
        assert(errno_fd >= 0);
1✔
2280

2281
        r = loop_write(errno_fd, &error, sizeof(error));
1✔
2282
        if (r < 0)
1✔
2283
                log_debug_errno(r, "Failed to write errno to errno_fd=%d: %m", errno_fd);
×
2284

2285
        _exit(EXIT_FAILURE);
1✔
2286
}
2287

2288
int read_errno(int errno_fd) {
1✔
2289
        int r;
1✔
2290

2291
        assert(errno_fd >= 0);
1✔
2292

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

2296
        ssize_t n = loop_read(errno_fd, &r, sizeof(r), /* do_poll = */ false);
1✔
2297
        if (n < 0) {
1✔
2298
                log_debug_errno(n, "Failed to read errno: %m");
×
2299
                return -EIO;
×
2300
        }
2301
        if (n == sizeof(r)) {
1✔
2302
                if (r == 0)
×
2303
                        return 0;
2304
                if (r < 0) /* child process reported an error, return it */
×
2305
                        return log_debug_errno(r, "Child process failed with errno: %m");
×
2306
                return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received an errno, but it's a positive value.");
×
2307
        }
2308
        if (n != 0)
1✔
2309
                return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received unexpected amount of bytes while reading errno.");
×
2310

2311
        /* the process exited without reporting an error, assuming success */
2312
        return 0;
2313
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc