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

systemd / systemd / 29461261567

15 Jul 2026 04:59PM UTC coverage: 72.983% (+0.05%) from 72.936%
29461261567

push

github

yuwata
tpm2-util: keep the measurement log's torn-write marker intact

The userspace measurement log carries a sticky-bit marker while a writer
is between updating a measurement register and appending the matching
record, so that a writer dying in between leaves the log detectably
incomplete.

However, the next successful writer used to clear the marker again after
appending its own record, erasing the evidence that an earlier writer
had died and the log is still missing a record. Keep the marker set in
that case instead; the new record is appended and synced regardless. The
marker likewise stays set if the measurement itself fails, so that any
non-clean completion remains flagged: a spurious flag on a failed but
harmless measurement is preferable to erasing evidence of a real gap,
and PCR replay stays authoritative either way.

Finally, warn when systemd-pcrlock loads a marked log, so the resulting
PCR validation failures come with a hint at their cause.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>

11 of 12 new or added lines in 2 files covered. (91.67%)

2475 existing lines in 54 files now uncovered.

346100 of 474222 relevant lines covered (72.98%)

1321758.71 hits per line

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

82.76
/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,757✔
64
        _cleanup_free_ char *line = NULL;
15,757✔
65
        const char *p;
15,757✔
66
        char state;
15,757✔
67
        int r;
15,757✔
68

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

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

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

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

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

87
        p++;
12,319✔
88

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

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

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

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

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

107
                r = prctl_safe(PR_GET_NAME, (unsigned long) comm, 0, 0, 0);
28,710✔
108
                if (r < 0)
28,710✔
109
                        return r;
110
        } else {
111
                const char *p;
33,017✔
112

113
                p = procfs_file_alloca(pid, "comm");
33,017✔
114

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

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

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

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

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

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

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

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

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

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

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

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

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

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

188
        if (k == 0) {
19,656✔
189
                if (!(flags & PROCESS_CMDLINE_COMM_FALLBACK))
495✔
190
                        return -ENOENT;
472✔
191

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

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

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

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

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

215
        return r;
216
}
217

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

223
        assert(pid >= 0);
18,204✔
224
        assert(ret);
18,204✔
225

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

240
        int full = pid_get_cmdline_nulstr(pid, max_columns, flags, &t, &k);
18,204✔
241
        if (full < 0)
18,204✔
242
                return full;
243

244
        if (flags & (PROCESS_CMDLINE_QUOTE | PROCESS_CMDLINE_QUOTE_POSIX)) {
13,867✔
245
                ShellEscapeFlags shflags = SHELL_ESCAPE_EMPTY |
13,499✔
246
                        FLAGS_SET(flags, PROCESS_CMDLINE_QUOTE_POSIX) * SHELL_ESCAPE_POSIX;
13,499✔
247

248
                assert(!(flags & PROCESS_CMDLINE_USE_LOCALE));
13,499✔
249

250
                _cleanup_strv_free_ char **args = NULL;
13,499✔
251

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

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

267
                delete_trailing_chars(t, WHITESPACE);
368✔
268

269
                bool eight_bit = (flags & PROCESS_CMDLINE_USE_LOCALE) && !is_locale_utf8();
368✔
270

271
                ans = escape_non_printable_full(t, max_columns,
1,104✔
272
                                                eight_bit * XESCAPE_8_BIT | !full * XESCAPE_FORCE_ELLIPSIS);
688✔
273
                if (!ans)
368✔
274
                        return -ENOMEM;
275

276
                ans = str_realloc(ans);
368✔
277
        }
278

279
        *ret = ans;
13,867✔
280
        return 0;
13,867✔
281
}
282

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

287
        if (!pidref_is_set(pid))
136✔
288
                return -ESRCH;
289

290
        if (pidref_is_remote(pid))
272✔
291
                return -EREMOTE;
292

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

297
        r = pidref_verify(pid);
136✔
298
        if (r < 0)
136✔
299
                return r;
300

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

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

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

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

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

324
        *ret = args;
5,317✔
325
        return 0;
5,317✔
326
}
327

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

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

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

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

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

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

349
        return 0;
350
}
351

352
int pid_is_kernel_thread(pid_t pid) {
6,074✔
353
        int r;
6,074✔
354

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

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

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

374
        /* Skip 6 fields to reach the flags field */
375
        for (size_t i = 0; i < 6; i++) {
42,343✔
376
                size_t l = strspn(q, WHITESPACE);
36,294✔
377
                if (l < 1)
36,294✔
378
                        return -EINVAL;
379
                q += l;
36,294✔
380

381
                l = strcspn(q, WHITESPACE);
36,294✔
382
                if (l < 1)
36,294✔
383
                        return -EINVAL;
384
                q += l;
36,294✔
385
        }
386

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

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

399
        unsigned long long flags;
6,049✔
400
        r = safe_atollu(q, &flags);
6,049✔
401
        if (r < 0)
6,049✔
402
                return r;
403

404
        return !!(flags & PF_KTHREAD);
6,049✔
405
}
406

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

410
        if (!pidref_is_set(pid))
2,754✔
411
                return -ESRCH;
412

413
        if (pidref_is_remote(pid))
2,754✔
414
                return -EREMOTE;
415

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

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

424
        return result;
425
}
426

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

431
        assert(proc_file);
17,558✔
432

433
        p = procfs_file_alloca(pid, proc_file);
17,562✔
434

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

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

443
        assert(pid >= 0);
17,532✔
444

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

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

455
        return 0;
456
}
457

458
int pid_get_uid(pid_t pid, uid_t *ret) {
3,241✔
459
        int r;
3,241✔
460

461
        assert(pid >= 0);
3,241✔
462
        assert(ret);
3,241✔
463

464
        if (pid == 0 || pid == getpid_cached()) {
3,241✔
465
                *ret = getuid();
1✔
466
                return 0;
3,241✔
467
        }
468

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

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

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

482
        if (!pidref_is_set(pid))
153✔
483
                return -ESRCH;
153✔
484

485
        if (pidref_is_remote(pid))
153✔
486
                return -EREMOTE;
487

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

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

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

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

508
int get_process_gid(pid_t pid, gid_t *ret) {
3,241✔
509
        int r;
3,241✔
510

511
        assert(pid >= 0);
3,241✔
512
        assert(ret);
3,241✔
513

514
        if (pid == 0 || pid == getpid_cached()) {
3,241✔
515
                *ret = getgid();
1✔
516
                return 0;
3,241✔
517
        }
518

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

526
        return parse_gid(v, ret);
3,240✔
527
}
528

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

587
        return 0;
15✔
588
}
589

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

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

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

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

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

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

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

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

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

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

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

642
        return 0;
643
}
644

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

648
        if (!pidref_is_set(pidref))
6,528✔
649
                return -ESRCH;
6,528✔
650

651
        if (pidref_is_remote(pidref))
6,528✔
652
                return -EREMOTE;
653

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

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

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

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

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

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

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

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

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

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

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

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

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

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

718
        assert(pid >= 0);
2,944✔
719

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

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

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

735
        unsigned long llu;
2,944✔
736

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

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

764
        return 0;
765
}
766

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

771
        if (!pidref_is_set(pid))
2,944✔
772
                return -ESRCH;
2,944✔
773

774
        if (pidref_is_remote(pid))
2,944✔
775
                return -EREMOTE;
776

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

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

785
        if (ret)
2,944✔
786
                *ret = t;
2,944✔
787

788
        return 0;
789
}
790

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

795
        assert(pid >= 0);
29,576✔
796
        assert(ret);
29,576✔
797

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

804
        return parse_mode(m, ret);
29,576✔
805
}
806

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

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

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

840
        int prio = flags & WAIT_LOG_ABNORMAL ? LOG_ERR : LOG_DEBUG;
10,534✔
841

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

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

854
                return status.si_status;
10,534✔
855

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

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

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

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

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

874
        return r;
×
875
}
876

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

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

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

890
        if (!pid_is_valid(pid))
8,354✔
891
                return -EINVAL;
892

893
        path = procfs_file_alloca(pid, "environ");
8,354✔
894

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

901
        for (;;) {
107,718✔
902
                _cleanup_free_ char *line = NULL;
50,712✔
903
                const char *match;
57,024✔
904

905
                if (sum > ENVIRONMENT_BLOCK_MAX) /* Give up searching eventually */
57,024✔
906
                        return -ENOBUFS;
907

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

914
                sum += r;
50,712✔
915

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

921
        *ret = NULL;
6,312✔
922
        return 0;
6,312✔
923
}
924

925
int pidref_is_my_child(PidRef *pid) {
6,506✔
926
        int r;
6,506✔
927

928
        if (!pidref_is_set(pid))
6,506✔
929
                return -ESRCH;
6,506✔
930

931
        if (pidref_is_remote(pid))
6,506✔
932
                return -EREMOTE;
933

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

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

944
        return ppid == getpid_cached();
6,506✔
945
}
946

947
int pid_is_my_child(pid_t pid) {
×
948

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

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

955
int pidref_is_unwaited(PidRef *pid) {
13,693✔
956
        int r;
13,693✔
957

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

960
        if (!pidref_is_set(pid))
13,693✔
961
                return -ESRCH;
962

963
        if (pidref_is_remote(pid))
13,692✔
964
                return -EREMOTE;
965

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

969
        r = pidref_kill(pid, 0);
13,691✔
970
        if (r == -ESRCH)
13,691✔
971
                return false;
972
        if (r < 0)
5,657✔
973
                return r;
234✔
974

975
        return true;
976
}
977

978
int pid_is_unwaited(pid_t pid) {
10,161✔
979

980
        if (pid == 0)
10,161✔
981
                return true;
10,161✔
982

983
        return pidref_is_unwaited(&PIDREF_MAKE_FROM_PID(pid));
10,161✔
984
}
985

986
int pid_is_alive(pid_t pid) {
15,759✔
987
        int r;
15,759✔
988

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

991
        if (pid < 0)
15,759✔
992
                return -ESRCH;
993

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

997
        if (pid == getpid_cached())
15,758✔
998
                return true;
999

1000
        r = get_process_state(pid);
15,757✔
1001
        if (r == -ESRCH)
15,757✔
1002
                return false;
1003
        if (r < 0)
12,319✔
1004
                return r;
1005

1006
        return r != 'Z';
12,319✔
1007
}
1008

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

1012
        if (!pidref_is_set(pidref))
15,756✔
1013
                return -ESRCH;
1014

1015
        if (pidref_is_remote(pidref))
15,754✔
1016
                return -EREMOTE;
1017

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

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

1030
        return result;
1031
}
1032

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

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

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

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

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

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

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

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

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

1079
        return result;
1080
}
1081

1082
bool is_main_thread(void) {
9,070,363✔
1083
        static thread_local int cached = -1;
9,070,363✔
1084

1085
        if (cached < 0)
9,070,363✔
1086
                cached = getpid_cached() == gettid();
69,785✔
1087

1088
        return cached;
9,070,363✔
1089
}
1090

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

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

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

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

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

1112
        return PERSONALITY_INVALID;
1113
}
1114

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

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

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

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

1131
int safe_personality(unsigned long p) {
1,885✔
1132
        int ret;
1,885✔
1133

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

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

1147
                errno = -ret;
×
1148
        }
1149

1150
        return ret;
1151
}
1152

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

1156
        assert(ret);
1,870✔
1157

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

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

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

1171
        return 0;
1172
}
1173

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

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

1201
        return CMP(*a, *b);
1,831✔
1202
}
1203

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

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

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

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

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

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

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

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

1235
        return 0;
1236
}
1237

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

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

1248
static pid_t cached_pid = CACHED_PID_UNSET;
1249

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

1255
pid_t getpid_cached(void) {
173,625,479✔
1256
        static bool installed = false;
173,625,479✔
1257
        pid_t current_value = CACHED_PID_UNSET;
173,625,479✔
1258

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

1268
        (void) __atomic_compare_exchange_n(
173,625,479✔
1269
                        &cached_pid,
1270
                        &current_value,
1271
                        CACHED_PID_BUSY,
1272
                        false,
1273
                        __ATOMIC_SEQ_CST,
1274
                        __ATOMIC_SEQ_CST);
1275

1276
        switch (current_value) {
173,625,479✔
1277

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

1281
                new_pid = getpid();
123,379✔
1282

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

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

1294
                        installed = true;
87,799✔
1295
                }
1296

1297
                cached_pid = new_pid;
123,379✔
1298
                return new_pid;
123,379✔
1299
        }
1300

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

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

1309
int must_be_root(void) {
114✔
1310

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

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

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

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

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

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

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

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

1353
        return pid;
1354
}
1355

1356
static int fork_flags_to_signal(ForkFlags flags) {
33,726✔
1357
        return (flags & FORK_DEATHSIG_SIGTERM) ? SIGTERM :
33,726✔
1358
                (flags & FORK_DEATHSIG_SIGINT) ? SIGINT :
976✔
1359
                                                 SIGKILL;
1360
}
1361

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

1370
        pid_t original_pid, pid;
32,486✔
1371
        sigset_t saved_ss, ss;
32,486✔
1372
        _unused_ _cleanup_(block_signals_reset) sigset_t *saved_ssp = NULL;
×
1373
        bool block_signals = false, block_all = false, intermediary = false;
32,486✔
1374
        _cleanup_close_pair_ int pidref_transport_fds[2] = EBADF_PAIR;
66,490✔
1375
        int prio, r;
32,486✔
1376

1377
        assert(!FLAGS_SET(flags, FORK_WAIT|FORK_FREEZE));
32,486✔
1378
        assert(!FLAGS_SET(flags, FORK_DETACH) ||
32,486✔
1379
               (flags & (FORK_WAIT|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL)) == 0);
1380

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

1385
        prio = flags & FORK_LOG ? LOG_ERR : LOG_DEBUG;
32,486✔
1386

1387
        original_pid = getpid_cached();
32,486✔
1388

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

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

1399
                assert_se(sigfillset(&ss) >= 0);
27,788✔
1400
                block_signals = block_all = true;
1401

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

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

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

1416
        if (FLAGS_SET(flags, FORK_DETACH)) {
32,486✔
1417
                /* Fork off intermediary child if needed */
1418

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

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

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

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

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

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

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

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

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

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

1471
        if ((flags & (FORK_NEW_MOUNTNS|FORK_NEW_USERNS|FORK_NEW_NETNS|FORK_NEW_PIDNS)) != 0)
32,494✔
1472
                pid = raw_clone(SIGCHLD|
9,284✔
1473
                                (FLAGS_SET(flags, FORK_NEW_MOUNTNS) ? CLONE_NEWNS : 0) |
9,284✔
1474
                                (FLAGS_SET(flags, FORK_NEW_USERNS) ? CLONE_NEWUSER : 0) |
9,284✔
1475
                                (FLAGS_SET(flags, FORK_NEW_NETNS) ? CLONE_NEWNET : 0) |
9,284✔
1476
                                (FLAGS_SET(flags, FORK_NEW_PIDNS) ? CLONE_NEWPID : 0));
9,284✔
1477
        else
1478
                pid = fork();
23,210✔
1479
        if (pid < 0)
66,492✔
1480
                return log_full_errno(prio, errno, "Failed to fork off '%s': %m", strna(name));
×
1481
        if (pid > 0) {
66,492✔
1482

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

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

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

1506
                        _exit(EXIT_SUCCESS);
13✔
1507
                }
1508

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

1512
                if (flags & FORK_WAIT) {
31,297✔
1513
                        if (block_all) {
1,870✔
1514
                                /* undo everything except SIGCHLD */
1515
                                ss = saved_ss;
1,703✔
1516
                                assert_se(sigaddset(&ss, SIGCHLD) >= 0);
1,703✔
1517
                                (void) sigprocmask(SIG_SETMASK, &ss, NULL);
1,703✔
1518
                        }
1519

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

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

1533
                        return 1;
1534
                }
1535

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

1542
                return 1;
1543
        }
1544

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

1547
        pidref_transport_fds[1] = safe_close(pidref_transport_fds[1]);
35,182✔
1548

1549
        /* Restore signal mask manually */
1550
        saved_ssp = NULL;
35,182✔
1551

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

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

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

1576
        if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL)) {
35,182✔
1577
                r = prctl_safe(PR_SET_PDEATHSIG, fork_flags_to_signal(flags), 0, 0, 0);
33,726✔
1578
                if (r < 0) {
33,726✔
1579
                        log_full_errno(prio, r, "Failed to set death signal: %m");
×
1580
                        _exit(EXIT_FAILURE);
×
1581
                }
1582
        }
1583

1584
        if (flags & FORK_RESET_SIGNALS) {
35,182✔
1585
                r = reset_all_signal_handlers();
28,768✔
1586
                if (r < 0) {
28,768✔
1587
                        log_full_errno(prio, r, "Failed to reset signal handlers: %m");
×
1588
                        _exit(EXIT_FAILURE);
×
1589
                }
1590

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

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

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

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

1628
        if (FLAGS_SET(flags, FORK_PRIVATE_TMP)) {
35,182✔
1629
                assert(FLAGS_SET(flags, FORK_NEW_MOUNTNS));
×
1630

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

1641
        if (flags & FORK_REARRANGE_STDIO) {
35,182✔
1642
                if (stdio_fds) {
16,346✔
1643
                        r = rearrange_stdio(stdio_fds[0], stdio_fds[1], stdio_fds[2]);
16,326✔
1644
                        if (r < 0) {
16,326✔
1645
                                log_full_errno(prio, r, "Failed to rearrange stdio fds: %m");
×
1646
                                _exit(EXIT_FAILURE);
×
1647
                        }
1648

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

1665
        if (flags & FORK_CLOSE_ALL_FDS) {
35,182✔
1666
                /* Close the logs here in case it got reopened above, as close_all_fds() would close them for us */
1667
                log_close();
26,806✔
1668

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

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

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

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

1697
        /* When we were asked to reopen the logs, do so again now */
1698
        if (flags & FORK_REOPEN_LOG) {
35,182✔
1699
                log_open();
9,710✔
1700
                log_set_open_when_needed(false);
9,710✔
1701
        }
1702

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

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

1719
        if (FLAGS_SET(flags, FORK_FREEZE))
35,182✔
1720
                freeze();
×
1721

1722
        if (ret) {
35,182✔
1723
                r = pidref_set_self(ret);
32,508✔
1724
                if (r < 0) {
32,508✔
1725
                        log_full_errno(prio, r, "Failed to acquire PID reference on ourselves: %m");
×
1726
                        _exit(EXIT_FAILURE);
×
1727
                }
1728
        }
1729

1730
        return 0;
1731
}
1732

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

1746
        _cleanup_(pidref_done_sigkill_wait) PidRef pidref_outer = PIDREF_NULL;
×
1747
        _cleanup_close_pair_ int errno_pipe_fd[2] = EBADF_PAIR;
239✔
1748
        int r, prio = FLAGS_SET(flags, FORK_LOG) ? LOG_ERR : LOG_DEBUG;
141✔
1749

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

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

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

1768
        r = pidref_safe_fork_full(
379✔
1769
                        outer_name,
1770
                        /* stdio_fds= */ NULL, /* except_fds= */ NULL, /* n_except_fds= */ 0,
1771
                        (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),
141✔
1772
                        &pidref_outer);
1773
        if (r == -EPROTO && FLAGS_SET(flags, FORK_WAIT)) {
238✔
1774
                errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
8✔
1775

1776
                int k = read_errno(errno_pipe_fd[0]);
8✔
1777
                if (k < 0 && k != -EIO)
8✔
1778
                        return k;
1779
        }
1780
        if (r < 0)
238✔
1781
                return r;
1782
        if (r == 0) {
230✔
1783
                _cleanup_(pidref_done) PidRef pidref_inner = PIDREF_NULL;
×
1784

1785
                /* Child */
1786

1787
                errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
97✔
1788

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

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

1807
                        if (!FLAGS_SET(flags, FORK_CLOSE_ALL_FDS)) {
98✔
1808
                                errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
95✔
1809
                                pidref_done(&pidref_outer);
95✔
1810
                        } else {
1811
                                errno_pipe_fd[1] = -EBADF;
3✔
1812
                                pidref_outer = PIDREF_NULL;
3✔
1813
                        }
1814

1815
                        if (ret)
98✔
1816
                                *ret = TAKE_PIDREF(pidref_inner);
98✔
1817
                        return 0;
98✔
1818
                }
1819

1820
                log_forget_fds();
97✔
1821
                log_set_open_when_needed(true);
97✔
1822

1823
                (void) close_all_fds(&pidref_inner.fd, 1);
97✔
1824

1825
                r = pidref_wait_for_terminate_and_check(
194✔
1826
                                inner_name,
1827
                                &pidref_inner,
1828
                                FLAGS_SET(flags, FORK_LOG) ? WAIT_LOG : 0);
1829
                if (r < 0)
97✔
1830
                        _exit(EXIT_FAILURE);
×
1831

1832
                _exit(r);
97✔
1833
        }
1834

1835
        errno_pipe_fd[1] = safe_close(errno_pipe_fd[1]);
133✔
1836

1837
        r = read_errno(errno_pipe_fd[0]);
133✔
1838
        if (r < 0)
133✔
1839
                return r; /* the child logs about failures on its own, no need to duplicate here */
1840

1841
        if (ret)
133✔
1842
                *ret = TAKE_PIDREF(pidref_outer);
107✔
1843
        else
1844
                pidref_done(&pidref_outer); /* disarm sigkill_wait */
26✔
1845

1846
        return 1;
1847
}
1848

1849
bool oom_score_adjust_is_valid(int oa) {
12,757✔
1850
        return oa >= OOM_SCORE_ADJ_MIN && oa <= OOM_SCORE_ADJ_MAX;
12,757✔
1851
}
1852

1853
int set_oom_score_adjust(int value) {
3,688✔
1854
        char t[DECIMAL_STR_MAX(int)];
3,688✔
1855

1856
        if (!oom_score_adjust_is_valid(value))
3,688✔
1857
                return -EINVAL;
3,688✔
1858

1859
        xsprintf(t, "%i", value);
3,688✔
1860

1861
        return write_string_file("/proc/self/oom_score_adj", t,
3,688✔
1862
                                 WRITE_STRING_FILE_VERIFY_ON_FAILURE|WRITE_STRING_FILE_DISABLE_BUFFER);
1863
}
1864

1865
int get_oom_score_adjust(int *ret) {
7,453✔
1866
        _cleanup_free_ char *t = NULL;
7,453✔
1867
        int r, a;
7,453✔
1868

1869
        r = read_virtual_file("/proc/self/oom_score_adj", SIZE_MAX, &t, NULL);
7,453✔
1870
        if (r < 0)
7,453✔
1871
                return r;
1872

1873
        delete_trailing_chars(t, WHITESPACE);
7,453✔
1874

1875
        r = safe_atoi(t, &a);
7,453✔
1876
        if (r < 0)
7,453✔
1877
                return r;
1878

1879
        if (!oom_score_adjust_is_valid(a))
7,453✔
1880
                return -ENODATA;
1881

1882
        if (ret)
7,453✔
1883
                *ret = a;
7,453✔
1884

1885
        return 0;
1886
}
1887

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

1892
        if (limit >= -PRIO_MIN + PRIO_MAX)
2✔
1893
                return PRIO_MIN; /* i.e. -20 */
1894

1895
        return PRIO_MAX - (int) limit;
2✔
1896
}
1897

1898
int setpriority_closest(int priority) {
27✔
1899
        struct rlimit highest;
27✔
1900
        int r, current, limit;
27✔
1901

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

1909
        errno = 0;
2✔
1910
        current = getpriority(PRIO_PROCESS, 0);
2✔
1911
        if (errno != 0)
2✔
1912
                return -errno;
×
1913

1914
        if (priority == current)
2✔
1915
                return 1;
1916

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

1923
        if (getrlimit(RLIMIT_NICE, &highest) < 0)
2✔
1924
                return -errno;
×
1925

1926
        limit = rlimit_to_nice(highest.rlim_cur);
2✔
1927

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

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

1939
_noreturn_ void freeze(void) {
×
1940
        log_close();
×
1941

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

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

1951
                if (waitid(P_ALL, 0, &si, WEXITED) < 0 && errno != EINTR)
×
1952
                        break;
1953
        }
1954

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

1961
int get_process_threads(pid_t pid) {
7✔
1962
        _cleanup_free_ char *t = NULL;
7✔
1963
        int n, r;
7✔
1964

1965
        if (pid < 0)
7✔
1966
                return -EINVAL;
1967

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

1974
        r = safe_atoi(t, &n);
7✔
1975
        if (r < 0)
7✔
1976
                return r;
1977
        if (n < 0)
7✔
1978
                return -EINVAL;
×
1979

1980
        return n;
1981
}
1982

1983
int is_reaper_process(void) {
10,021✔
1984
        int b = 0, r;
10,021✔
1985

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

1989
        if (getpid_cached() == 1)
10,021✔
1990
                return true;
10,021✔
1991

1992
        r = prctl_safe(PR_GET_CHILD_SUBREAPER, (unsigned long) &b, 0, 0, 0);
415✔
1993
        if (r < 0)
415✔
1994
                return r;
1995

1996
        return b != 0;
415✔
1997
}
1998

1999
int make_reaper_process(bool b) {
761✔
2000
        int r;
761✔
2001

2002
        if (getpid_cached() == 1) {
761✔
2003

2004
                if (!b)
82✔
2005
                        return -EINVAL;
2006

2007
                return 0;
82✔
2008
        }
2009

2010
        r = prctl_safe(PR_SET_CHILD_SUBREAPER, b, 0, 0, 0);
679✔
2011
        if (r < 0)
679✔
2012
                return r;
×
2013

2014
        return 0;
2015
}
2016

2017
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(posix_spawnattr_t*, posix_spawnattr_destroy, NULL);
×
2018

2019
int posix_spawn_wrapper(
4,995✔
2020
                const char *path,
2021
                char * const *argv,
2022
                char * const *envp,
2023
                const char *cgroup,
2024
                PidRef *ret_pidref) {
2025

2026
        short flags = POSIX_SPAWN_SETSIGMASK;
4,995✔
2027
        posix_spawnattr_t attr;
4,995✔
2028
        sigset_t mask;
4,995✔
2029
        int r;
4,995✔
2030

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

2042
        assert(path);
4,995✔
2043
        assert(argv);
4,995✔
2044
        assert(ret_pidref);
4,995✔
2045

2046
        assert_se(sigfillset(&mask) >= 0);
4,995✔
2047

2048
        r = posix_spawnattr_init(&attr);
4,995✔
2049
        if (r != 0)
4,995✔
2050
                return -r; /* These functions return a positive errno on failure */
×
2051

2052
        /* Initialization needs to succeed before we can set up a destructor. */
2053
        _unused_ _cleanup_(posix_spawnattr_destroyp) posix_spawnattr_t *attr_destructor = &attr;
4,995✔
2054

2055
        static bool have_clone_into_cgroup = true; /* kernel 5.7+ */
4,995✔
2056
        _cleanup_close_ int cgroup_fd = -EBADF;
4,995✔
2057

2058
        if (cgroup && have_clone_into_cgroup) {
4,995✔
2059
                _cleanup_free_ char *resolved_cgroup = NULL;
4,995✔
2060

2061
                r = cg_get_path(cgroup, /* suffix= */ NULL, &resolved_cgroup);
4,995✔
2062
                if (r < 0)
4,995✔
2063
                        return r;
2064

2065
                cgroup_fd = open(resolved_cgroup, O_PATH|O_DIRECTORY|O_CLOEXEC);
4,995✔
2066
                if (cgroup_fd < 0)
4,995✔
2067
                        return -errno;
×
2068

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

2078
        r = posix_spawnattr_setflags(&attr, flags);
4,995✔
2079
        if (r != 0)
4,995✔
2080
                return -r;
×
2081
        r = posix_spawnattr_setsigmask(&attr, &mask);
4,995✔
2082
        if (r != 0)
4,995✔
2083
                return -r;
×
2084

2085
        _cleanup_close_ int pidfd = -EBADF;
4,995✔
2086

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

2101
                flags &= ~POSIX_SPAWN_SETCGROUP;
×
2102
                r = posix_spawnattr_setflags(&attr, flags);
×
2103
                if (r != 0)
×
2104
                        return -r;
×
2105

2106
                r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
×
2107
        }
2108
        if (r == 0) {
4,995✔
2109
                r = pidref_set_pidfd_consume(ret_pidref, TAKE_FD(pidfd));
4,995✔
2110
                if (r < 0)
4,995✔
2111
                        return r;
2112

2113
                return FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP);
4,995✔
2114
        }
2115
        if (!ERRNO_IS_NOT_SUPPORTED(r))
×
2116
                return -r;
×
2117

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

2120
        pid_t pid;
×
2121

2122
        r = posix_spawn(&pid, path, NULL, &attr, argv, envp);
×
2123
        if (r != 0)
×
2124
                return -r;
×
2125

2126
        r = pidref_set_pid(ret_pidref, pid);
×
2127
        if (r < 0)
×
2128
                return r;
×
2129

2130
        return 0; /* We did not use CLONE_INTO_CGROUP so return 0, the caller will have to move the child */
2131
}
2132

2133
int proc_dir_open(DIR **ret) {
24✔
2134
        DIR *d;
24✔
2135

2136
        assert(ret);
24✔
2137

2138
        d = opendir("/proc");
24✔
2139
        if (!d)
24✔
2140
                return -errno;
×
2141

2142
        *ret = d;
24✔
2143
        return 0;
24✔
2144
}
2145

2146
int proc_dir_read(DIR *d, pid_t *ret) {
2,048✔
2147
        assert(d);
2,048✔
2148

2149
        for (;;) {
3,492✔
2150
                struct dirent *de;
3,492✔
2151

2152
                errno = 0;
3,492✔
2153
                de = readdir_no_dot(d);
3,492✔
2154
                if (!de) {
3,492✔
2155
                        if (errno != 0)
24✔
2156
                                return -errno;
×
2157

2158
                        break;
24✔
2159
                }
2160

2161
                if (!IN_SET(de->d_type, DT_DIR, DT_UNKNOWN))
3,468✔
2162
                        continue;
1,180✔
2163

2164
                if (parse_pid(de->d_name, ret) >= 0)
2,288✔
2165
                        return 1;
2166
        }
2167

2168
        if (ret)
24✔
2169
                *ret = 0;
24✔
2170
        return 0;
2171
}
2172

2173
int proc_dir_read_pidref(DIR *d, PidRef *ret) {
2,001✔
2174
        int r;
2,001✔
2175

2176
        assert(d);
2,001✔
2177

2178
        for (;;) {
2,001✔
2179
                pid_t pid;
2,001✔
2180

2181
                r = proc_dir_read(d, &pid);
2,001✔
2182
                if (r < 0)
2,001✔
2183
                        return r;
1,978✔
2184
                if (r == 0)
2,001✔
2185
                        break;
2186

2187
                r = pidref_set_pid(ret, pid);
1,978✔
2188
                if (r == -ESRCH) /* gone by now? skip it */
1,978✔
UNCOV
2189
                        continue;
×
2190
                if (r < 0)
1,978✔
2191
                        return r;
×
2192

2193
                return 1;
2194
        }
2195

2196
        if (ret)
23✔
2197
                *ret = PIDREF_NULL;
23✔
2198
        return 0;
2199
}
2200

2201
int safe_mlockall(int flags) {
218✔
2202
        int r;
218✔
2203

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

2214
        if (mlockall(flags) < 0)
206✔
2215
                return log_debug_errno(errno, "Failed to call mlockall(): %m");
×
2216

2217
        log_debug("Successfully called mlockall().");
206✔
2218
        return 0;
2219
}
2220

2221
static const char *const sigchld_code_table[] = {
2222
        [CLD_EXITED] = "exited",
2223
        [CLD_KILLED] = "killed",
2224
        [CLD_DUMPED] = "dumped",
2225
        [CLD_TRAPPED] = "trapped",
2226
        [CLD_STOPPED] = "stopped",
2227
        [CLD_CONTINUED] = "continued",
2228
};
2229

2230
DEFINE_STRING_TABLE_LOOKUP(sigchld_code, int);
20,467✔
2231

2232
static const char* const sched_policy_table[] = {
2233
        [SCHED_OTHER] = "other",
2234
        [SCHED_BATCH] = "batch",
2235
        [SCHED_IDLE]  = "idle",
2236
        [SCHED_FIFO]  = "fifo",
2237
        [SCHED_EXT]   = "ext",
2238
        [SCHED_RR]    = "rr",
2239
};
2240

2241
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
1,956✔
2242

2243
_noreturn_ void report_errno_and_exit(int errno_fd, int error) {
204✔
2244
        int r;
204✔
2245

2246
        if (error >= 0)
204✔
2247
                _exit(EXIT_SUCCESS);
203✔
2248

2249
        assert(errno_fd >= 0);
1✔
2250

2251
        r = loop_write(errno_fd, &error, sizeof(error));
1✔
2252
        if (r < 0)
1✔
2253
                log_debug_errno(r, "Failed to write errno to errno_fd=%d: %m", errno_fd);
×
2254

2255
        _exit(EXIT_FAILURE);
1✔
2256
}
2257

2258
int read_errno(int errno_fd) {
152✔
2259
        int r;
152✔
2260

2261
        assert(errno_fd >= 0);
152✔
2262

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

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

2276
        if (r == 0)
8✔
2277
                return 0;
2278
        if (r < 0) /* child process reported an error, return it */
8✔
2279
                return log_debug_errno(r, "Child process failed with errno: %m");
8✔
2280

2281
        return log_debug_errno(SYNTHETIC_ERRNO(EIO), "Received positive errno from child, refusing: %d", r);
×
2282
}
2283

2284
int prctl_safe(int op, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) {
1,606,593✔
2285

2286
        /* prctl(2) is a bit messy: it's a variadic function, defined with "unsigned long" arguments. This
2287
         * means that unless people explicitly cast it's quite likely they end up passing a shorter type even
2288
         * though unsigned long is required. And most of the time it might even kind of work, but not
2289
         * always. Moreover, some calls insist on all unused arguments being zeroed out, others don't
2290
         * care. Let's define this wrapper to enforce the right types, and that all arguments are always
2291
         * passed, to avoid this confusion. */
2292

2293
        return RET_NERRNO(prctl(op, arg2, arg3, arg4, arg5));
1,606,593✔
2294
}
2295

2296
int proc_set_comm(const char *comm) {
161,147✔
2297
        return prctl_safe(PR_SET_NAME, (unsigned long) comm, 0, 0, 0);
161,147✔
2298
}
2299

2300
int proc_set_nnp(void) {
1,857✔
2301
        return prctl_safe(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
1,857✔
2302
}
2303

2304
nsec_t proc_get_timerslack(void) {
23✔
2305
        int r;
23✔
2306

2307
        r = prctl_safe(PR_GET_TIMERSLACK, 0, 0, 0, 0);
23✔
2308
        if (r < 0)
23✔
2309
                return NSEC_INFINITY;
2310

2311
        return r;
23✔
2312
}
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