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

systemd / systemd / 13082854884

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

push

github

poettering
uki: introduce support for a .efifw section

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

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

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

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

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

292987 of 407930 relevant lines covered (71.82%)

711545.13 hits per line

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

70.07
/src/core/exec-invoke.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <linux/sched.h>
4
#include <sys/eventfd.h>
5
#include <sys/ioctl.h>
6
#include <sys/mount.h>
7
#include <sys/prctl.h>
8

9
#if HAVE_PAM
10
#include <security/pam_appl.h>
11
#include <security/pam_misc.h>
12
#endif
13

14
#if HAVE_APPARMOR
15
#include <sys/apparmor.h>
16
#endif
17

18
#include "sd-messages.h"
19

20
#if HAVE_APPARMOR
21
#include "apparmor-util.h"
22
#endif
23
#include "argv-util.h"
24
#include "ask-password-api.h"
25
#include "barrier.h"
26
#include "bitfield.h"
27
#include "bpf-dlopen.h"
28
#include "bpf-restrict-fs.h"
29
#include "btrfs-util.h"
30
#include "capability-util.h"
31
#include "cgroup-setup.h"
32
#include "chase.h"
33
#include "chattr-util.h"
34
#include "chown-recursive.h"
35
#include "copy.h"
36
#include "env-util.h"
37
#include "escape.h"
38
#include "exec-credential.h"
39
#include "exec-invoke.h"
40
#include "execute.h"
41
#include "exit-status.h"
42
#include "fd-util.h"
43
#include "hexdecoct.h"
44
#include "hostname-setup.h"
45
#include "io-util.h"
46
#include "iovec-util.h"
47
#include "journal-send.h"
48
#include "memfd-util.h"
49
#include "missing_ioprio.h"
50
#include "missing_prctl.h"
51
#include "missing_sched.h"
52
#include "missing_securebits.h"
53
#include "missing_syscall.h"
54
#include "mkdir-label.h"
55
#include "proc-cmdline.h"
56
#include "process-util.h"
57
#include "psi-util.h"
58
#include "rlimit-util.h"
59
#include "seccomp-util.h"
60
#include "selinux-util.h"
61
#include "signal-util.h"
62
#include "smack-util.h"
63
#include "socket-util.h"
64
#include "string-table.h"
65
#include "strv.h"
66
#include "terminal-util.h"
67
#include "utmp-wtmp.h"
68
#include "vpick.h"
69

70
#define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
71
#define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
72

73
#define SNDBUF_SIZE (8*1024*1024)
74

75
static int flag_fds(
10,998✔
76
                const int fds[],
77
                size_t n_socket_fds,
78
                size_t n_fds,
79
                bool nonblock) {
80

81
        int r;
10,998✔
82

83
        assert(fds || n_fds == 0);
10,998✔
84

85
        /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags.
86
         * O_NONBLOCK only applies to socket activation though. */
87

88
        for (size_t i = 0; i < n_fds; i++) {
13,560✔
89

90
                if (i < n_socket_fds) {
2,562✔
91
                        r = fd_nonblock(fds[i], nonblock);
2,379✔
92
                        if (r < 0)
2,379✔
93
                                return r;
94
                }
95

96
                /* We unconditionally drop FD_CLOEXEC from the fds,
97
                 * since after all we want to pass these fds to our
98
                 * children */
99

100
                r = fd_cloexec(fds[i], false);
2,562✔
101
                if (r < 0)
2,562✔
102
                        return r;
103
        }
104

105
        return 0;
106
}
107

108
static bool is_terminal_input(ExecInput i) {
50,376✔
109
        return IN_SET(i,
50,376✔
110
                      EXEC_INPUT_TTY,
111
                      EXEC_INPUT_TTY_FORCE,
112
                      EXEC_INPUT_TTY_FAIL);
113
}
114

115
static bool is_terminal_output(ExecOutput o) {
47,064✔
116
        return IN_SET(o,
47,064✔
117
                      EXEC_OUTPUT_TTY,
118
                      EXEC_OUTPUT_KMSG_AND_CONSOLE,
119
                      EXEC_OUTPUT_JOURNAL_AND_CONSOLE);
120
}
121

122
static bool is_kmsg_output(ExecOutput o) {
12,220✔
123
        return IN_SET(o,
12,220✔
124
                      EXEC_OUTPUT_KMSG,
125
                      EXEC_OUTPUT_KMSG_AND_CONSOLE);
126
}
127

128
static bool exec_context_needs_term(const ExecContext *c) {
11,025✔
129
        assert(c);
11,025✔
130

131
        /* Return true if the execution context suggests we should set $TERM to something useful. */
132

133
        if (is_terminal_input(c->std_input))
11,025✔
134
                return true;
135

136
        if (is_terminal_output(c->std_output))
10,858✔
137
                return true;
138

139
        if (is_terminal_output(c->std_error))
10,598✔
140
                return true;
141

142
        return !!c->tty_path;
10,597✔
143
}
144

145
static int open_null_as(int flags, int nfd) {
12,997✔
146
        int fd;
12,997✔
147

148
        assert(nfd >= 0);
12,997✔
149

150
        fd = open("/dev/null", flags|O_NOCTTY);
12,997✔
151
        if (fd < 0)
12,997✔
152
                return -errno;
×
153

154
        return move_fd(fd, nfd, false);
12,997✔
155
}
156

157
static int connect_journal_socket(
12,220✔
158
                int fd,
159
                const char *log_namespace,
160
                uid_t uid,
161
                gid_t gid) {
162

163
        uid_t olduid = UID_INVALID;
12,220✔
164
        gid_t oldgid = GID_INVALID;
12,220✔
165
        const char *j;
12,220✔
166
        int r;
12,220✔
167

168
        assert(fd >= 0);
12,220✔
169

170
        j = journal_stream_path(log_namespace);
12,232✔
171
        if (!j)
2✔
172
                return -EINVAL;
×
173

174
        if (gid_is_valid(gid)) {
12,220✔
175
                oldgid = getgid();
2,418✔
176

177
                if (setegid(gid) < 0)
2,418✔
178
                        return -errno;
×
179
        }
180

181
        if (uid_is_valid(uid)) {
12,220✔
182
                olduid = getuid();
2,415✔
183

184
                if (seteuid(uid) < 0) {
2,415✔
185
                        r = -errno;
×
186
                        goto restore_gid;
×
187
                }
188
        }
189

190
        r = connect_unix_path(fd, AT_FDCWD, j);
12,220✔
191

192
        /* If we fail to restore the uid or gid, things will likely fail later on. This should only happen if
193
           an LSM interferes. */
194

195
        if (uid_is_valid(uid))
12,220✔
196
                (void) seteuid(olduid);
2,415✔
197

198
 restore_gid:
9,805✔
199
        if (gid_is_valid(gid))
12,220✔
200
                (void) setegid(oldgid);
2,418✔
201

202
        return r;
203
}
204

205
static int connect_logger_as(
12,220✔
206
                const ExecContext *context,
207
                const ExecParameters *params,
208
                ExecOutput output,
209
                const char *ident,
210
                int nfd,
211
                uid_t uid,
212
                gid_t gid) {
213

214
        _cleanup_close_ int fd = -EBADF;
12,220✔
215
        int r;
12,220✔
216

217
        assert(context);
12,220✔
218
        assert(params);
12,220✔
219
        assert(output < _EXEC_OUTPUT_MAX);
12,220✔
220
        assert(ident);
12,220✔
221
        assert(nfd >= 0);
12,220✔
222

223
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
12,220✔
224
        if (fd < 0)
12,220✔
225
                return -errno;
×
226

227
        r = connect_journal_socket(fd, context->log_namespace, uid, gid);
12,220✔
228
        if (r < 0)
12,220✔
229
                return r;
230

231
        if (shutdown(fd, SHUT_RD) < 0)
12,220✔
232
                return -errno;
×
233

234
        (void) fd_inc_sndbuf(fd, SNDBUF_SIZE);
12,220✔
235

236
        if (dprintf(fd,
23,848✔
237
                "%s\n"
238
                "%s\n"
239
                "%i\n"
240
                "%i\n"
241
                "%i\n"
242
                "%i\n"
243
                "%i\n",
244
                context->syslog_identifier ?: ident,
12,220✔
245
                params->flags & EXEC_PASS_LOG_UNIT ? params->unit_id : "",
12,220✔
246
                context->syslog_priority,
12,220✔
247
                !!context->syslog_level_prefix,
12,220✔
248
                false,
249
                is_kmsg_output(output),
12,220✔
250
                is_terminal_output(output)) < 0)
12,220✔
251
                return -errno;
×
252

253
        return move_fd(TAKE_FD(fd), nfd, false);
12,220✔
254
}
255

256
static int open_terminal_as(const char *path, int flags, int nfd) {
32✔
257
        int fd;
32✔
258

259
        assert(path);
32✔
260
        assert(nfd >= 0);
32✔
261

262
        fd = open_terminal(path, flags | O_NOCTTY);
32✔
263
        if (fd < 0)
32✔
264
                return fd;
265

266
        return move_fd(fd, nfd, false);
32✔
267
}
268

269
static int acquire_path(const char *path, int flags, mode_t mode) {
11✔
270
        _cleanup_close_ int fd = -EBADF;
11✔
271
        int r;
11✔
272

273
        assert(path);
11✔
274

275
        if (IN_SET(flags & O_ACCMODE, O_WRONLY, O_RDWR))
11✔
276
                flags |= O_CREAT;
11✔
277

278
        fd = open(path, flags|O_NOCTTY, mode);
11✔
279
        if (fd >= 0)
11✔
280
                return TAKE_FD(fd);
11✔
281

282
        if (errno != ENXIO) /* ENXIO is returned when we try to open() an AF_UNIX file system socket on Linux */
×
283
                return -errno;
×
284

285
        /* So, it appears the specified path could be an AF_UNIX socket. Let's see if we can connect to it. */
286

287
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
×
288
        if (fd < 0)
×
289
                return -errno;
×
290

291
        r = connect_unix_path(fd, AT_FDCWD, path);
×
292
        if (IN_SET(r, -ENOTSOCK, -EINVAL))
11✔
293
                /* Propagate initial error if we get ENOTSOCK or EINVAL, i.e. we have indication that this
294
                 * wasn't an AF_UNIX socket after all */
295
                return -ENXIO;
296
        if (r < 0)
×
297
                return r;
298

299
        if ((flags & O_ACCMODE) == O_RDONLY)
×
300
                r = shutdown(fd, SHUT_WR);
×
301
        else if ((flags & O_ACCMODE) == O_WRONLY)
×
302
                r = shutdown(fd, SHUT_RD);
×
303
        else
304
                r = 0;
305
        if (r < 0)
×
306
                return -errno;
×
307

308
        return TAKE_FD(fd);
309
}
310

311
static int fixup_input(
38,964✔
312
                const ExecContext *context,
313
                int socket_fd,
314
                bool apply_tty_stdin) {
315

316
        ExecInput std_input;
38,964✔
317

318
        assert(context);
38,964✔
319

320
        std_input = context->std_input;
38,964✔
321

322
        if (is_terminal_input(std_input) && !apply_tty_stdin)
38,964✔
323
                return EXEC_INPUT_NULL;
324

325
        if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
38,964✔
326
                return EXEC_INPUT_NULL;
327

328
        if (std_input == EXEC_INPUT_DATA && context->stdin_data_size == 0)
38,964✔
329
                return EXEC_INPUT_NULL;
×
330

331
        return std_input;
332
}
333

334
static int fixup_output(ExecOutput output, int socket_fd) {
38,964✔
335

336
        if (output == EXEC_OUTPUT_SOCKET && socket_fd < 0)
38,964✔
337
                return EXEC_OUTPUT_INHERIT;
×
338

339
        return output;
340
}
341

342
static int setup_input(
13,388✔
343
                const ExecContext *context,
344
                const ExecParameters *params,
345
                int socket_fd,
346
                const int named_iofds[static 3]) {
347

348
        ExecInput i;
13,388✔
349
        int r;
13,388✔
350

351
        assert(context);
13,388✔
352
        assert(params);
13,388✔
353
        assert(named_iofds);
13,388✔
354

355
        if (params->stdin_fd >= 0) {
13,388✔
356
                if (dup2(params->stdin_fd, STDIN_FILENO) < 0)
400✔
357
                        return -errno;
×
358

359
                /* Try to make this the controlling tty, if it is a tty */
360
                if (isatty_safe(STDIN_FILENO))
400✔
361
                        (void) ioctl(STDIN_FILENO, TIOCSCTTY, context->std_input == EXEC_INPUT_TTY_FORCE);
15✔
362

363
                return STDIN_FILENO;
400✔
364
        }
365

366
        i = fixup_input(context, socket_fd, params->flags & EXEC_APPLY_TTY_STDIN);
12,988✔
367

368
        switch (i) {
12,988✔
369

370
        case EXEC_INPUT_NULL:
12,629✔
371
                return open_null_as(O_RDONLY, STDIN_FILENO);
12,629✔
372

373
        case EXEC_INPUT_TTY:
347✔
374
        case EXEC_INPUT_TTY_FORCE:
375
        case EXEC_INPUT_TTY_FAIL: {
376
                _cleanup_close_ int tty_fd = -EBADF;
13,735✔
377
                const char *tty_path;
347✔
378

379
                tty_path = ASSERT_PTR(exec_context_tty_path(context));
347✔
380

381
                tty_fd = acquire_terminal(tty_path,
694✔
382
                                          i == EXEC_INPUT_TTY_FAIL  ? ACQUIRE_TERMINAL_TRY :
347✔
383
                                          i == EXEC_INPUT_TTY_FORCE ? ACQUIRE_TERMINAL_FORCE :
384
                                                                      ACQUIRE_TERMINAL_WAIT,
385
                                          USEC_INFINITY);
386
                if (tty_fd < 0)
347✔
387
                        return tty_fd;
388

389
                r = move_fd(tty_fd, STDIN_FILENO, /* cloexec= */ false);
347✔
390
                if (r < 0)
347✔
391
                        return r;
×
392

393
                TAKE_FD(tty_fd);
394
                return r;
395
        }
396

397
        case EXEC_INPUT_SOCKET:
11✔
398
                assert(socket_fd >= 0);
11✔
399

400
                return RET_NERRNO(dup2(socket_fd, STDIN_FILENO));
11✔
401

402
        case EXEC_INPUT_NAMED_FD:
×
403
                assert(named_iofds[STDIN_FILENO] >= 0);
×
404

405
                (void) fd_nonblock(named_iofds[STDIN_FILENO], false);
×
406
                return RET_NERRNO(dup2(named_iofds[STDIN_FILENO], STDIN_FILENO));
13,388✔
407

408
        case EXEC_INPUT_DATA: {
1✔
409
                int fd;
1✔
410

411
                fd = memfd_new_and_seal("exec-input", context->stdin_data, context->stdin_data_size);
1✔
412
                if (fd < 0)
1✔
413
                        return fd;
414

415
                return move_fd(fd, STDIN_FILENO, false);
1✔
416
        }
417

418
        case EXEC_INPUT_FILE: {
×
419
                bool rw;
×
420
                int fd;
×
421

422
                assert(context->stdio_file[STDIN_FILENO]);
×
423

424
                rw = (context->std_output == EXEC_OUTPUT_FILE && streq_ptr(context->stdio_file[STDIN_FILENO], context->stdio_file[STDOUT_FILENO])) ||
×
425
                        (context->std_error == EXEC_OUTPUT_FILE && streq_ptr(context->stdio_file[STDIN_FILENO], context->stdio_file[STDERR_FILENO]));
×
426

427
                fd = acquire_path(context->stdio_file[STDIN_FILENO], rw ? O_RDWR : O_RDONLY, 0666 & ~context->umask);
×
428
                if (fd < 0)
×
429
                        return fd;
430

431
                return move_fd(fd, STDIN_FILENO, false);
×
432
        }
433

434
        default:
×
435
                assert_not_reached();
×
436
        }
437
}
438

439
static bool can_inherit_stderr_from_stdout(
12,988✔
440
                const ExecContext *context,
441
                ExecOutput o,
442
                ExecOutput e) {
443

444
        assert(context);
12,988✔
445

446
        /* Returns true, if given the specified STDERR and STDOUT output we can directly dup() the stdout fd to the
447
         * stderr fd */
448

449
        if (e == EXEC_OUTPUT_INHERIT)
12,988✔
450
                return true;
451
        if (e != o)
374✔
452
                return false;
453

454
        if (e == EXEC_OUTPUT_NAMED_FD)
371✔
455
                return streq_ptr(context->stdio_fdname[STDOUT_FILENO], context->stdio_fdname[STDERR_FILENO]);
×
456

457
        if (IN_SET(e, EXEC_OUTPUT_FILE, EXEC_OUTPUT_FILE_APPEND, EXEC_OUTPUT_FILE_TRUNCATE))
371✔
458
                return streq_ptr(context->stdio_file[STDOUT_FILENO], context->stdio_file[STDERR_FILENO]);
4✔
459

460
        return true;
461
}
462

463
static int setup_output(
26,776✔
464
                const ExecContext *context,
465
                const ExecParameters *params,
466
                int fileno,
467
                int socket_fd,
468
                const int named_iofds[static 3],
469
                const char *ident,
470
                uid_t uid,
471
                gid_t gid,
472
                dev_t *journal_stream_dev,
473
                ino_t *journal_stream_ino) {
474

475
        ExecOutput o;
26,776✔
476
        ExecInput i;
26,776✔
477
        int r;
26,776✔
478

479
        assert(context);
26,776✔
480
        assert(params);
26,776✔
481
        assert(ident);
26,776✔
482
        assert(journal_stream_dev);
26,776✔
483
        assert(journal_stream_ino);
26,776✔
484

485
        if (fileno == STDOUT_FILENO && params->stdout_fd >= 0) {
26,776✔
486

487
                if (dup2(params->stdout_fd, STDOUT_FILENO) < 0)
400✔
488
                        return -errno;
×
489

490
                return STDOUT_FILENO;
491
        }
492

493
        if (fileno == STDERR_FILENO && params->stderr_fd >= 0) {
26,376✔
494
                if (dup2(params->stderr_fd, STDERR_FILENO) < 0)
400✔
495
                        return -errno;
×
496

497
                return STDERR_FILENO;
498
        }
499

500
        i = fixup_input(context, socket_fd, params->flags & EXEC_APPLY_TTY_STDIN);
25,976✔
501
        o = fixup_output(context->std_output, socket_fd);
25,976✔
502

503
        // FIXME: we probably should spend some time here to verify that if we inherit an fd from stdin
504
        // (possibly indirect via inheritance from stdout) it is actually opened for write!
505

506
        if (fileno == STDERR_FILENO) {
25,976✔
507
                ExecOutput e;
12,988✔
508
                e = fixup_output(context->std_error, socket_fd);
12,988✔
509

510
                /* This expects the input and output are already set up */
511

512
                /* Don't change the stderr file descriptor if we inherit all
513
                 * the way and are not on a tty */
514
                if (e == EXEC_OUTPUT_INHERIT &&
12,988✔
515
                    o == EXEC_OUTPUT_INHERIT &&
8✔
516
                    i == EXEC_INPUT_NULL &&
×
517
                    !is_terminal_input(context->std_input) &&
×
518
                    getppid() != 1)
×
519
                        return fileno;
520

521
                /* Duplicate from stdout if possible */
522
                if (can_inherit_stderr_from_stdout(context, o, e))
12,988✔
523
                        return RET_NERRNO(dup2(STDOUT_FILENO, fileno));
12,981✔
524

525
                o = e;
526

527
        } else if (o == EXEC_OUTPUT_INHERIT) {
12,988✔
528
                /* If input got downgraded, inherit the original value */
529
                if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
8✔
530
                        return open_terminal_as(exec_context_tty_path(context), O_WRONLY, fileno);
×
531

532
                /* If the input is connected to anything that's not a /dev/null or a data fd, inherit that... */
533
                if (!IN_SET(i, EXEC_INPUT_NULL, EXEC_INPUT_DATA))
8✔
534
                        return RET_NERRNO(dup2(STDIN_FILENO, fileno));
8✔
535

536
                /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
537
                if (getppid() != 1)
×
538
                        return fileno;
539

540
                /* We need to open /dev/null here anew, to get the right access mode. */
541
                return open_null_as(O_WRONLY, fileno);
×
542
        }
543

544
        switch (o) {
12,987✔
545

546
        case EXEC_OUTPUT_NULL:
368✔
547
                return open_null_as(O_WRONLY, fileno);
368✔
548

549
        case EXEC_OUTPUT_TTY:
379✔
550
                if (is_terminal_input(i))
379✔
551
                        return RET_NERRNO(dup2(STDIN_FILENO, fileno));
347✔
552

553
                return open_terminal_as(exec_context_tty_path(context), O_WRONLY, fileno);
32✔
554

555
        case EXEC_OUTPUT_KMSG:
12,220✔
556
        case EXEC_OUTPUT_KMSG_AND_CONSOLE:
557
        case EXEC_OUTPUT_JOURNAL:
558
        case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
559
                r = connect_logger_as(context, params, o, ident, fileno, uid, gid);
12,220✔
560
                if (r < 0) {
12,220✔
561
                        log_exec_warning_errno(context,
×
562
                                               params,
563
                                               r,
564
                                               "Failed to connect %s to the journal socket, ignoring: %m",
565
                                               fileno == STDOUT_FILENO ? "stdout" : "stderr");
566
                        r = open_null_as(O_WRONLY, fileno);
×
567
                } else {
568
                        struct stat st;
12,220✔
569

570
                        /* If we connected this fd to the journal via a stream, patch the device/inode into the passed
571
                         * parameters, but only then. This is useful so that we can set $JOURNAL_STREAM that permits
572
                         * services to detect whether they are connected to the journal or not.
573
                         *
574
                         * If both stdout and stderr are connected to a stream then let's make sure to store the data
575
                         * about STDERR as that's usually the best way to do logging. */
576

577
                        if (fstat(fileno, &st) >= 0 &&
12,220✔
578
                            (*journal_stream_ino == 0 || fileno == STDERR_FILENO)) {
12,220✔
579
                                *journal_stream_dev = st.st_dev;
12,220✔
580
                                *journal_stream_ino = st.st_ino;
12,220✔
581
                        }
582
                }
583
                return r;
584

585
        case EXEC_OUTPUT_SOCKET:
9✔
586
                assert(socket_fd >= 0);
9✔
587

588
                return RET_NERRNO(dup2(socket_fd, fileno));
9✔
589

590
        case EXEC_OUTPUT_NAMED_FD:
×
591
                assert(named_iofds[fileno] >= 0);
×
592

593
                (void) fd_nonblock(named_iofds[fileno], false);
×
594
                return RET_NERRNO(dup2(named_iofds[fileno], fileno));
26,776✔
595

596
        case EXEC_OUTPUT_FILE:
11✔
597
        case EXEC_OUTPUT_FILE_APPEND:
598
        case EXEC_OUTPUT_FILE_TRUNCATE: {
599
                bool rw;
11✔
600
                int fd, flags;
11✔
601

602
                assert(context->stdio_file[fileno]);
11✔
603

604
                rw = context->std_input == EXEC_INPUT_FILE &&
11✔
605
                        streq_ptr(context->stdio_file[fileno], context->stdio_file[STDIN_FILENO]);
×
606

607
                if (rw)
11✔
608
                        return RET_NERRNO(dup2(STDIN_FILENO, fileno));
×
609

610
                flags = O_WRONLY;
11✔
611
                if (o == EXEC_OUTPUT_FILE_APPEND)
11✔
612
                        flags |= O_APPEND;
613
                else if (o == EXEC_OUTPUT_FILE_TRUNCATE)
9✔
614
                        flags |= O_TRUNC;
3✔
615

616
                fd = acquire_path(context->stdio_file[fileno], flags, 0666 & ~context->umask);
11✔
617
                if (fd < 0)
11✔
618
                        return fd;
619

620
                return move_fd(fd, fileno, 0);
11✔
621
        }
622

623
        default:
×
624
                assert_not_reached();
×
625
        }
626
}
627

628
static int chown_terminal(int fd, uid_t uid) {
2,606✔
629
        int r;
2,606✔
630

631
        assert(fd >= 0);
2,606✔
632

633
        /* Before we chown/chmod the TTY, let's ensure this is actually a tty */
634
        if (!isatty_safe(fd))
2,606✔
635
                return 0;
636

637
        /* This might fail. What matters are the results. */
638
        r = fchmod_and_chown(fd, TTY_MODE, uid, GID_INVALID);
6✔
639
        if (r < 0)
6✔
640
                return r;
×
641

642
        return 1;
643
}
644

645
static int setup_confirm_stdio(
×
646
                const ExecContext *context,
647
                const char *vc,
648
                int *ret_saved_stdin,
649
                int *ret_saved_stdout) {
650

651
        _cleanup_close_ int fd = -EBADF, saved_stdin = -EBADF, saved_stdout = -EBADF;
×
652
        int r;
×
653

654
        assert(ret_saved_stdin);
×
655
        assert(ret_saved_stdout);
×
656

657
        saved_stdin = fcntl(STDIN_FILENO, F_DUPFD_CLOEXEC, 3);
×
658
        if (saved_stdin < 0)
×
659
                return -errno;
×
660

661
        saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 3);
×
662
        if (saved_stdout < 0)
×
663
                return -errno;
×
664

665
        fd = acquire_terminal(vc, ACQUIRE_TERMINAL_WAIT, DEFAULT_CONFIRM_USEC);
×
666
        if (fd < 0)
×
667
                return fd;
668

669
        _cleanup_close_ int lock_fd = lock_dev_console();
×
670
        if (lock_fd < 0)
×
671
                log_debug_errno(lock_fd, "Failed to lock /dev/console, ignoring: %m");
×
672

673
        r = chown_terminal(fd, getuid());
×
674
        if (r < 0)
×
675
                return r;
676

677
        r = terminal_reset_defensive(fd, /* switch_to_text= */ true);
×
678
        if (r < 0)
×
679
                return r;
680

681
        r = exec_context_apply_tty_size(context, fd, fd, vc);
×
682
        if (r < 0)
×
683
                return r;
684

685
        r = rearrange_stdio(fd, fd, STDERR_FILENO); /* Invalidates 'fd' also on failure */
×
686
        TAKE_FD(fd);
×
687
        if (r < 0)
×
688
                return r;
689

690
        *ret_saved_stdin = TAKE_FD(saved_stdin);
×
691
        *ret_saved_stdout = TAKE_FD(saved_stdout);
×
692
        return 0;
×
693
}
694

695
static void write_confirm_error_fd(int err, int fd, const char *unit_id) {
×
696
        assert(err != 0);
×
697
        assert(fd >= 0);
×
698
        assert(unit_id);
×
699

700
        errno = abs(err);
×
701

702
        if (errno == ETIMEDOUT)
×
703
                dprintf(fd, "Confirmation question timed out for %s, assuming positive response.\n", unit_id);
×
704
        else
705
                dprintf(fd, "Couldn't ask confirmation for %s, assuming positive response: %m\n", unit_id);
×
706
}
×
707

708
static void write_confirm_error(int err, const char *vc, const char *unit_id) {
×
709
        _cleanup_close_ int fd = -EBADF;
×
710

711
        assert(vc);
×
712

713
        fd = open_terminal(vc, O_WRONLY|O_NOCTTY|O_CLOEXEC);
×
714
        if (fd < 0)
×
715
                return;
×
716

717
        write_confirm_error_fd(err, fd, unit_id);
×
718
}
719

720
static int restore_confirm_stdio(int *saved_stdin, int *saved_stdout) {
×
721
        int r = 0;
×
722

723
        assert(saved_stdin);
×
724
        assert(saved_stdout);
×
725

726
        release_terminal();
×
727

728
        if (*saved_stdin >= 0)
×
729
                if (dup2(*saved_stdin, STDIN_FILENO) < 0)
×
730
                        r = -errno;
×
731

732
        if (*saved_stdout >= 0)
×
733
                if (dup2(*saved_stdout, STDOUT_FILENO) < 0)
×
734
                        r = -errno;
×
735

736
        *saved_stdin = safe_close(*saved_stdin);
×
737
        *saved_stdout = safe_close(*saved_stdout);
×
738

739
        return r;
×
740
}
741

742
enum {
743
        CONFIRM_PRETEND_FAILURE = -1,
744
        CONFIRM_PRETEND_SUCCESS =  0,
745
        CONFIRM_EXECUTE = 1,
746
};
747

748
static bool confirm_spawn_disabled(void) {
×
749
        return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0;
×
750
}
751

752
static int ask_for_confirmation(const ExecContext *context, const ExecParameters *params, const char *cmdline) {
×
753
        int saved_stdout = -EBADF, saved_stdin = -EBADF, r;
×
754
        _cleanup_free_ char *e = NULL;
×
755
        char c;
×
756

757
        assert(context);
×
758
        assert(params);
×
759

760
        /* For any internal errors, assume a positive response. */
761
        r = setup_confirm_stdio(context, params->confirm_spawn, &saved_stdin, &saved_stdout);
×
762
        if (r < 0) {
×
763
                write_confirm_error(r, params->confirm_spawn, params->unit_id);
×
764
                return CONFIRM_EXECUTE;
765
        }
766

767
        /* confirm_spawn might have been disabled while we were sleeping. */
768
        if (!params->confirm_spawn || confirm_spawn_disabled()) {
×
769
                r = 1;
×
770
                goto restore_stdio;
×
771
        }
772

773
        e = ellipsize(cmdline, 60, 100);
×
774
        if (!e) {
×
775
                log_oom();
×
776
                r = CONFIRM_EXECUTE;
×
777
                goto restore_stdio;
×
778
        }
779

780
        for (;;) {
×
781
                r = ask_char(&c, "yfshiDjcn", "Execute %s? [y, f, s – h for help] ", e);
×
782
                if (r < 0) {
×
783
                        write_confirm_error_fd(r, STDOUT_FILENO, params->unit_id);
×
784
                        r = CONFIRM_EXECUTE;
×
785
                        goto restore_stdio;
×
786
                }
787

788
                switch (c) {
×
789
                case 'c':
×
790
                        printf("Resuming normal execution.\n");
×
791
                        manager_disable_confirm_spawn();
×
792
                        r = 1;
793
                        break;
794
                case 'D':
×
795
                        printf("  Unit: %s\n",
×
796
                               params->unit_id);
×
797
                        exec_context_dump(context, stdout, "  ");
×
798
                        exec_params_dump(params, stdout, "  ");
×
799
                        continue; /* ask again */
×
800
                case 'f':
×
801
                        printf("Failing execution.\n");
×
802
                        r = CONFIRM_PRETEND_FAILURE;
803
                        break;
804
                case 'h':
×
805
                        printf("  c - continue, proceed without asking anymore\n"
×
806
                               "  D - dump, show the state of the unit\n"
807
                               "  f - fail, don't execute the command and pretend it failed\n"
808
                               "  h - help\n"
809
                               "  i - info, show a short summary of the unit\n"
810
                               "  j - jobs, show jobs that are in progress\n"
811
                               "  s - skip, don't execute the command and pretend it succeeded\n"
812
                               "  y - yes, execute the command\n");
813
                        continue; /* ask again */
×
814
                case 'i':
×
815
                        printf("  Unit:        %s\n"
×
816
                               "  Command:     %s\n",
817
                               params->unit_id, cmdline);
×
818
                        continue; /* ask again */
×
819
                case 'j':
×
820
                        if (sigqueue(getppid(),
×
821
                                     SIGRTMIN+18,
×
822
                                     (const union sigval) { .sival_int = MANAGER_SIGNAL_COMMAND_DUMP_JOBS }) < 0)
×
823
                                return -errno;
×
824

825
                        continue; /* ask again */
×
826
                case 'n':
×
827
                        /* 'n' was removed in favor of 'f'. */
828
                        printf("Didn't understand 'n', did you mean 'f'?\n");
×
829
                        continue; /* ask again */
×
830
                case 's':
×
831
                        printf("Skipping execution.\n");
×
832
                        r = CONFIRM_PRETEND_SUCCESS;
833
                        break;
834
                case 'y':
835
                        r = CONFIRM_EXECUTE;
836
                        break;
837
                default:
×
838
                        assert_not_reached();
×
839
                }
840
                break;
841
        }
842

843
restore_stdio:
×
844
        restore_confirm_stdio(&saved_stdin, &saved_stdout);
×
845
        return r;
846
}
847

848
static int get_fixed_user(
11,041✔
849
                const char *user_or_uid,
850
                const char **ret_username,
851
                uid_t *ret_uid,
852
                gid_t *ret_gid,
853
                const char **ret_home,
854
                const char **ret_shell) {
855

856
        int r;
11,041✔
857

858
        assert(user_or_uid);
11,041✔
859
        assert(ret_username);
11,041✔
860

861
        r = get_user_creds(&user_or_uid, ret_uid, ret_gid, ret_home, ret_shell, USER_CREDS_CLEAN);
11,041✔
862
        if (r < 0)
11,041✔
863
                return r;
864

865
        /* user_or_uid is normalized by get_user_creds to username */
866
        *ret_username = user_or_uid;
11,039✔
867

868
        return 0;
11,039✔
869
}
870

871
static int get_fixed_group(
9✔
872
                const char *group_or_gid,
873
                const char **ret_groupname,
874
                gid_t *ret_gid) {
875

876
        int r;
9✔
877

878
        assert(group_or_gid);
9✔
879
        assert(ret_groupname);
9✔
880

881
        r = get_group_creds(&group_or_gid, ret_gid, /* flags = */ 0);
9✔
882
        if (r < 0)
9✔
883
                return r;
884

885
        /* group_or_gid is normalized by get_group_creds to groupname */
886
        *ret_groupname = group_or_gid;
9✔
887

888
        return 0;
9✔
889
}
890

891
static int get_supplementary_groups(const ExecContext *c, const char *user,
13,388✔
892
                                    const char *group, gid_t gid,
893
                                    gid_t **supplementary_gids, int *ngids) {
894
        int r, k = 0;
13,388✔
895
        int ngroups_max;
13,388✔
896
        bool keep_groups = false;
13,388✔
897
        gid_t *groups = NULL;
13,388✔
898
        _cleanup_free_ gid_t *l_gids = NULL;
13,388✔
899

900
        assert(c);
13,388✔
901

902
        /*
903
         * If user is given, then lookup GID and supplementary groups list.
904
         * We avoid NSS lookups for gid=0. Also we have to initialize groups
905
         * here and as early as possible so we keep the list of supplementary
906
         * groups of the caller.
907
         */
908
        if (user && gid_is_valid(gid) && gid != 0) {
15,994✔
909
                /* First step, initialize groups from /etc/groups */
910
                if (initgroups(user, gid) < 0)
2,506✔
911
                        return -errno;
×
912

913
                keep_groups = true;
914
        }
915

916
        if (strv_isempty(c->supplementary_groups))
13,392✔
917
                return 0;
918

919
        /*
920
         * If SupplementaryGroups= was passed then NGROUPS_MAX has to
921
         * be positive, otherwise fail.
922
         */
923
        errno = 0;
4✔
924
        ngroups_max = (int) sysconf(_SC_NGROUPS_MAX);
4✔
925
        if (ngroups_max <= 0)
4✔
926
                return errno_or_else(EOPNOTSUPP);
×
927

928
        l_gids = new(gid_t, ngroups_max);
4✔
929
        if (!l_gids)
4✔
930
                return -ENOMEM;
931

932
        if (keep_groups) {
4✔
933
                /*
934
                 * Lookup the list of groups that the user belongs to, we
935
                 * avoid NSS lookups here too for gid=0.
936
                 */
937
                k = ngroups_max;
4✔
938
                if (getgrouplist(user, gid, l_gids, &k) < 0)
4✔
939
                        return -EINVAL;
940
        } else
941
                k = 0;
×
942

943
        STRV_FOREACH(i, c->supplementary_groups) {
8✔
944
                const char *g;
4✔
945

946
                if (k >= ngroups_max)
4✔
947
                        return -E2BIG;
×
948

949
                g = *i;
4✔
950
                r = get_group_creds(&g, l_gids+k, 0);
4✔
951
                if (r < 0)
4✔
952
                        return r;
953

954
                k++;
4✔
955
        }
956

957
        /*
958
         * Sets ngids to zero to drop all supplementary groups, happens
959
         * when we are under root and SupplementaryGroups= is empty.
960
         */
961
        if (k == 0) {
4✔
962
                *ngids = 0;
×
963
                return 0;
×
964
        }
965

966
        /* Otherwise get the final list of supplementary groups */
967
        groups = memdup(l_gids, sizeof(gid_t) * k);
4✔
968
        if (!groups)
4✔
969
                return -ENOMEM;
970

971
        *supplementary_gids = groups;
4✔
972
        *ngids = k;
4✔
973

974
        groups = NULL;
4✔
975

976
        return 0;
4✔
977
}
978

979
static int enforce_groups(gid_t gid, const gid_t *supplementary_gids, int ngids) {
11,000✔
980
        int r;
11,000✔
981

982
        /* Handle SupplementaryGroups= if it is not empty */
983
        if (ngids > 0) {
11,000✔
984
                r = maybe_setgroups(ngids, supplementary_gids);
187✔
985
                if (r < 0)
187✔
986
                        return r;
987
        }
988

989
        if (gid_is_valid(gid)) {
11,000✔
990
                /* Then set our gids */
991
                if (setresgid(gid, gid, gid) < 0)
1,966✔
992
                        return -errno;
1✔
993
        }
994

995
        return 0;
996
}
997

998
static int set_securebits(unsigned bits, unsigned mask) {
840✔
999
        unsigned applied;
840✔
1000
        int current;
840✔
1001

1002
        current = prctl(PR_GET_SECUREBITS);
840✔
1003
        if (current < 0)
840✔
1004
                return -errno;
×
1005

1006
        /* Clear all securebits defined in mask and set bits */
1007
        applied = ((unsigned) current & ~mask) | bits;
840✔
1008
        if ((unsigned) current == applied)
840✔
1009
                return 0;
1010

1011
        if (prctl(PR_SET_SECUREBITS, applied) < 0)
54✔
1012
                return -errno;
×
1013

1014
        return 1;
1015
}
1016

1017
static int enforce_user(
1,961✔
1018
                const ExecContext *context,
1019
                uid_t uid,
1020
                uint64_t capability_ambient_set) {
1021
        assert(context);
1,961✔
1022
        int r;
1,961✔
1023

1024
        if (!uid_is_valid(uid))
1,961✔
1025
                return 0;
1026

1027
        /* Sets (but doesn't look up) the UIS and makes sure we keep the capabilities while doing so. For
1028
         * setting secure bits the capability CAP_SETPCAP is required, so we also need keep-caps in this
1029
         * case. */
1030

1031
        if ((capability_ambient_set != 0 || context->secure_bits != 0) && uid != 0) {
1,961✔
1032

1033
                /* First step: If we need to keep capabilities but drop privileges we need to make sure we
1034
                 * keep our caps, while we drop privileges. Add KEEP_CAPS to the securebits */
1035
                r = set_securebits(1U << SECURE_KEEP_CAPS, 0);
840✔
1036
                if (r < 0)
840✔
1037
                        return r;
1038
        }
1039

1040
        /* Second step: actually set the uids */
1041
        if (setresuid(uid, uid, uid) < 0)
1,961✔
1042
                return -errno;
×
1043

1044
        /* At this point we should have all necessary capabilities but are otherwise a normal user. However,
1045
         * the caps might got corrupted due to the setresuid() so we need clean them up later. This is done
1046
         * outside of this call. */
1047
        return 0;
1048
}
1049

1050
#if HAVE_PAM
1051

1052
static void pam_response_free_array(struct pam_response *responses, size_t n_responses) {
×
1053
        assert(responses || n_responses == 0);
×
1054

1055
        FOREACH_ARRAY(resp, responses, n_responses)
×
1056
                erase_and_free(resp->resp);
×
1057

1058
        free(responses);
×
1059
}
×
1060

1061
typedef struct AskPasswordConvData {
1062
        const ExecContext *context;
1063
        const ExecParameters *params;
1064
} AskPasswordConvData;
1065

1066
static int ask_password_conv(
×
1067
                int num_msg,
1068
                const struct pam_message *msg[],
1069
                struct pam_response **ret,
1070
                void *userdata) {
1071

1072
        AskPasswordConvData *data = ASSERT_PTR(userdata);
×
1073
        bool set_credential_env_var = false;
×
1074
        int r;
×
1075

1076
        assert(num_msg >= 0);
×
1077
        assert(msg);
×
1078
        assert(data->context);
×
1079
        assert(data->params);
×
1080

1081
        size_t n = num_msg;
×
1082
        struct pam_response *responses = new0(struct pam_response, n);
×
1083
        if (!responses)
×
1084
                return PAM_BUF_ERR;
×
1085
        CLEANUP_ARRAY(responses, n, pam_response_free_array);
×
1086

1087
        for (size_t i = 0; i < n; i++) {
×
1088
                const struct pam_message *mi = *msg + i;
×
1089

1090
                switch (mi->msg_style) {
×
1091

1092
                case PAM_PROMPT_ECHO_ON:
×
1093
                case PAM_PROMPT_ECHO_OFF: {
1094

1095
                        /* Locally set the $CREDENTIALS_DIRECTORY to the credentials directory we just populated */
1096
                        if (!set_credential_env_var) {
×
1097
                                _cleanup_free_ char *creds_dir = NULL;
×
1098
                                r = exec_context_get_credential_directory(data->context, data->params, data->params->unit_id, &creds_dir);
×
1099
                                if (r < 0)
×
1100
                                        return log_exec_error_errno(data->context, data->params, r, "Failed to determine credentials directory: %m");
×
1101

1102
                                if (creds_dir) {
×
1103
                                        if (setenv("CREDENTIALS_DIRECTORY", creds_dir, /* overwrite= */ true) < 0)
×
1104
                                                return log_exec_error_errno(data->context, data->params, r, "Failed to set $CREDENTIALS_DIRECTORY: %m");
×
1105
                                } else
1106
                                        (void) unsetenv("CREDENTIALS_DIRECTORY");
×
1107

1108
                                set_credential_env_var = true;
×
1109
                        }
1110

1111
                        _cleanup_free_ char *credential_name = strjoin("pam.authtok.", data->context->pam_name);
×
1112
                        if (!credential_name)
×
1113
                                return log_oom();
×
1114

1115
                        AskPasswordRequest req = {
×
1116
                                .message = mi->msg,
×
1117
                                .credential = credential_name,
1118
                                .tty_fd = -EBADF,
1119
                                .hup_fd = -EBADF,
1120
                                .until = usec_add(now(CLOCK_MONOTONIC), 15 * USEC_PER_SEC),
×
1121
                        };
1122

1123
                        _cleanup_strv_free_erase_ char **acquired = NULL;
×
1124
                        r = ask_password_auto(
×
1125
                                        &req,
1126
                                        ASK_PASSWORD_ACCEPT_CACHED|
1127
                                        ASK_PASSWORD_NO_TTY|
1128
                                        (mi->msg_style == PAM_PROMPT_ECHO_ON ? ASK_PASSWORD_ECHO : 0),
×
1129
                                        &acquired);
1130
                        if (r < 0) {
×
1131
                                log_exec_error_errno(data->context, data->params, r, "Failed to query for password: %m");
×
1132
                                return PAM_CONV_ERR;
×
1133
                        }
1134

1135
                        responses[i].resp = strdup(ASSERT_PTR(acquired[0]));
×
1136
                        if (!responses[i].resp) {
×
1137
                                log_oom();
×
1138
                                return PAM_BUF_ERR;
1139
                        }
1140
                        break;
×
1141
                }
1142

1143
                case PAM_ERROR_MSG:
×
1144
                        log_exec_error(data->context, data->params, "PAM: %s", mi->msg);
×
1145
                        break;
×
1146

1147
                case PAM_TEXT_INFO:
×
1148
                        log_exec_info(data->context, data->params, "PAM: %s", mi->msg);
×
1149
                        break;
×
1150

1151
                default:
1152
                        return PAM_CONV_ERR;
1153
                }
1154
        }
1155

1156
        *ret = TAKE_PTR(responses);
×
1157
        n = 0;
×
1158

1159
        return PAM_SUCCESS;
×
1160
}
1161

1162
static int pam_close_session_and_delete_credentials(pam_handle_t *handle, int flags) {
142✔
1163
        int r, s;
142✔
1164

1165
        assert(handle);
142✔
1166

1167
        r = pam_close_session(handle, flags);
142✔
1168
        if (r != PAM_SUCCESS)
142✔
1169
                log_debug("pam_close_session() failed: %s", pam_strerror(handle, r));
×
1170

1171
        s = pam_setcred(handle, PAM_DELETE_CRED | flags);
142✔
1172
        if (s != PAM_SUCCESS)
142✔
1173
                log_debug("pam_setcred(PAM_DELETE_CRED) failed: %s", pam_strerror(handle, s));
84✔
1174

1175
        return r != PAM_SUCCESS ? r : s;
142✔
1176
}
1177
#endif
1178

1179
static int setup_pam(
280✔
1180
                const ExecContext *context,
1181
                ExecParameters *params,
1182
                const char *user,
1183
                uid_t uid,
1184
                gid_t gid,
1185
                char ***env, /* updated on success */
1186
                const int fds[], size_t n_fds,
1187
                int exec_fd) {
1188

1189
#if HAVE_PAM
1190
        AskPasswordConvData conv_data = {
280✔
1191
                .context = context,
1192
                .params = params,
1193
        };
1194

1195
        const struct pam_conv conv = {
280✔
1196
                .conv = ask_password_conv,
1197
                .appdata_ptr = &conv_data,
1198
        };
1199

1200
        _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
280✔
1201
        _cleanup_strv_free_ char **e = NULL;
280✔
1202
        pam_handle_t *handle = NULL;
280✔
1203
        sigset_t old_ss;
280✔
1204
        int pam_code = PAM_SUCCESS, r;
280✔
1205
        bool close_session = false;
280✔
1206
        pid_t parent_pid;
280✔
1207
        int flags = 0;
280✔
1208

1209
        assert(context);
280✔
1210
        assert(params);
280✔
1211
        assert(user);
280✔
1212
        assert(uid_is_valid(uid));
280✔
1213
        assert(gid_is_valid(gid));
280✔
1214
        assert(fds || n_fds == 0);
280✔
1215
        assert(env);
280✔
1216

1217
        /* We set up PAM in the parent process, then fork. The child
1218
         * will then stay around until killed via PR_GET_PDEATHSIG or
1219
         * systemd via the cgroup logic. It will then remove the PAM
1220
         * session again. The parent process will exec() the actual
1221
         * daemon. We do things this way to ensure that the main PID
1222
         * of the daemon is the one we initially fork()ed. */
1223

1224
        r = barrier_create(&barrier);
280✔
1225
        if (r < 0)
280✔
1226
                goto fail;
×
1227

1228
        if (log_get_max_level() < LOG_DEBUG)
280✔
1229
                flags |= PAM_SILENT;
2✔
1230

1231
        pam_code = pam_start(context->pam_name, user, &conv, &handle);
280✔
1232
        if (pam_code != PAM_SUCCESS) {
280✔
1233
                handle = NULL;
×
1234
                goto fail;
×
1235
        }
1236

1237
        const char *tty = context->tty_path;
280✔
1238
        if (!tty) {
280✔
1239
                _cleanup_free_ char *q = NULL;
×
1240

1241
                /* Hmm, so no TTY was explicitly passed, but an fd passed to us directly might be a TTY. Let's figure
1242
                 * out if that's the case, and read the TTY off it. */
1243

1244
                if (getttyname_malloc(STDIN_FILENO, &q) >= 0)
274✔
1245
                        tty = strjoina("/dev/", q);
×
1246
        }
1247

1248
        if (tty) {
274✔
1249
                pam_code = pam_set_item(handle, PAM_TTY, tty);
6✔
1250
                if (pam_code != PAM_SUCCESS)
6✔
1251
                        goto fail;
×
1252
        }
1253

1254
        STRV_FOREACH(nv, *env) {
3,856✔
1255
                pam_code = pam_putenv(handle, *nv);
3,576✔
1256
                if (pam_code != PAM_SUCCESS)
3,576✔
1257
                        goto fail;
×
1258
        }
1259

1260
        pam_code = pam_acct_mgmt(handle, flags);
280✔
1261
        if (pam_code != PAM_SUCCESS)
280✔
1262
                goto fail;
×
1263

1264
        pam_code = pam_setcred(handle, PAM_ESTABLISH_CRED | flags);
280✔
1265
        if (pam_code != PAM_SUCCESS)
280✔
1266
                log_debug("pam_setcred(PAM_ESTABLISH_CRED) failed, ignoring: %s", pam_strerror(handle, pam_code));
220✔
1267

1268
        pam_code = pam_open_session(handle, flags);
280✔
1269
        if (pam_code != PAM_SUCCESS)
280✔
1270
                goto fail;
×
1271

1272
        close_session = true;
280✔
1273

1274
        e = pam_getenvlist(handle);
280✔
1275
        if (!e) {
280✔
1276
                pam_code = PAM_BUF_ERR;
×
1277
                goto fail;
×
1278
        }
1279

1280
        /* Block SIGTERM, so that we know that it won't get lost in the child */
1281

1282
        assert_se(sigprocmask_many(SIG_BLOCK, &old_ss, SIGTERM) >= 0);
280✔
1283

1284
        parent_pid = getpid_cached();
280✔
1285

1286
        r = safe_fork("(sd-pam)", 0, NULL);
280✔
1287
        if (r < 0)
422✔
1288
                goto fail;
×
1289
        if (r == 0) {
422✔
1290
                int ret = EXIT_PAM;
142✔
1291

1292
                /* The child's job is to reset the PAM session on termination */
1293
                barrier_set_role(&barrier, BARRIER_CHILD);
142✔
1294

1295
                /* Make sure we don't keep open the passed fds in this child. We assume that otherwise only
1296
                 * those fds are open here that have been opened by PAM. */
1297
                (void) close_many(fds, n_fds);
142✔
1298

1299
                /* Also close the 'exec_fd' in the child, since the service manager waits for the EOF induced
1300
                 * by the execve() to wait for completion, and if we'd keep the fd open here in the child
1301
                 * we'd never signal completion. */
1302
                exec_fd = safe_close(exec_fd);
142✔
1303

1304
                /* Drop privileges - we don't need any to pam_close_session and this will make
1305
                 * PR_SET_PDEATHSIG work in most cases.  If this fails, ignore the error - but expect sd-pam
1306
                 * threads to fail to exit normally */
1307

1308
                r = fully_set_uid_gid(uid, gid, /* supplementary_gids= */ NULL, /* n_supplementary_gids= */ 0);
142✔
1309
                if (r < 0)
142✔
1310
                        log_warning_errno(r, "Failed to drop privileges in sd-pam: %m");
×
1311

1312
                (void) ignore_signals(SIGPIPE);
142✔
1313

1314
                /* Wait until our parent died. This will only work if the above setresuid() succeeds,
1315
                 * otherwise the kernel will not allow unprivileged parents kill their privileged children
1316
                 * this way. We rely on the control groups kill logic to do the rest for us. */
1317
                if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
142✔
1318
                        goto child_finish;
×
1319

1320
                /* Tell the parent that our setup is done. This is especially important regarding dropping
1321
                 * privileges. Otherwise, unit setup might race against our setresuid(2) call.
1322
                 *
1323
                 * If the parent aborted, we'll detect this below, hence ignore return failure here. */
1324
                (void) barrier_place(&barrier);
142✔
1325

1326
                /* Check if our parent process might already have died? */
1327
                if (getppid() == parent_pid) {
142✔
1328
                        sigset_t ss;
142✔
1329
                        int sig;
142✔
1330

1331
                        assert_se(sigemptyset(&ss) >= 0);
142✔
1332
                        assert_se(sigaddset(&ss, SIGTERM) >= 0);
142✔
1333

1334
                        assert_se(sigwait(&ss, &sig) == 0);
142✔
1335
                        assert(sig == SIGTERM);
142✔
1336
                }
1337

1338
                /* If our parent died we'll end the session */
1339
                if (getppid() != parent_pid) {
142✔
1340
                        pam_code = pam_close_session_and_delete_credentials(handle, flags);
142✔
1341
                        if (pam_code != PAM_SUCCESS)
142✔
1342
                                goto child_finish;
84✔
1343
                }
1344

1345
                ret = 0;
1346

1347
        child_finish:
142✔
1348
                /* NB: pam_end() when called in child processes should set PAM_DATA_SILENT to let the module
1349
                 * know about this. See pam_end(3) */
1350
                (void) pam_end(handle, pam_code | flags | PAM_DATA_SILENT);
142✔
1351
                _exit(ret);
142✔
1352
        }
1353

1354
        barrier_set_role(&barrier, BARRIER_PARENT);
280✔
1355

1356
        /* If the child was forked off successfully it will do all the cleanups, so forget about the handle
1357
         * here. */
1358
        handle = NULL;
280✔
1359

1360
        /* Unblock SIGTERM again in the parent */
1361
        assert_se(sigprocmask(SIG_SETMASK, &old_ss, NULL) >= 0);
280✔
1362

1363
        /* We close the log explicitly here, since the PAM modules might have opened it, but we don't want
1364
         * this fd around. */
1365
        closelog();
280✔
1366

1367
        /* Synchronously wait for the child to initialize. We don't care for errors as we cannot
1368
         * recover. However, warn loudly if it happens. */
1369
        if (!barrier_place_and_sync(&barrier))
560✔
1370
                log_error("PAM initialization failed");
×
1371

1372
        return strv_free_and_replace(*env, e);
280✔
1373

1374
fail:
×
1375
        if (pam_code != PAM_SUCCESS) {
×
1376
                log_error("PAM failed: %s", pam_strerror(handle, pam_code));
×
1377
                r = -EPERM;  /* PAM errors do not map to errno */
1378
        } else
1379
                log_error_errno(r, "PAM failed: %m");
×
1380

1381
        if (handle) {
×
1382
                if (close_session)
×
1383
                        pam_code = pam_close_session_and_delete_credentials(handle, flags);
×
1384

1385
                (void) pam_end(handle, pam_code | flags);
×
1386
        }
1387

1388
        closelog();
×
1389
        return r;
1390
#else
1391
        return 0;
1392
#endif
1393
}
1394

1395
static void rename_process_from_path(const char *path) {
13,391✔
1396
        _cleanup_free_ char *buf = NULL;
13,391✔
1397
        const char *p;
13,391✔
1398

1399
        assert(path);
13,391✔
1400

1401
        /* This resulting string must fit in 10 chars (i.e. the length of "/sbin/init") to look pretty in
1402
         * /bin/ps */
1403

1404
        if (path_extract_filename(path, &buf) < 0) {
13,391✔
1405
                rename_process("(...)");
×
1406
                return;
×
1407
        }
1408

1409
        size_t l = strlen(buf);
13,391✔
1410
        if (l > 8) {
13,391✔
1411
                /* The end of the process name is usually more interesting, since the first bit might just be
1412
                 * "systemd-" */
1413
                p = buf + l - 8;
9,469✔
1414
                l = 8;
9,469✔
1415
        } else
1416
                p = buf;
1417

1418
        char process_name[11];
13,391✔
1419
        process_name[0] = '(';
13,391✔
1420
        memcpy(process_name+1, p, l);
13,391✔
1421
        process_name[1+l] = ')';
13,391✔
1422
        process_name[1+l+1] = 0;
13,391✔
1423

1424
        (void) rename_process(process_name);
13,391✔
1425
}
1426

1427
static bool context_has_address_families(const ExecContext *c) {
13,657✔
1428
        assert(c);
13,657✔
1429

1430
        return c->address_families_allow_list ||
13,657✔
1431
                !set_isempty(c->address_families);
11,619✔
1432
}
1433

1434
static bool context_has_syscall_filters(const ExecContext *c) {
13,621✔
1435
        assert(c);
13,621✔
1436

1437
        return c->syscall_allow_list ||
13,621✔
1438
                !hashmap_isempty(c->syscall_filter);
11,588✔
1439
}
1440

1441
static bool context_has_syscall_logs(const ExecContext *c) {
13,621✔
1442
        assert(c);
13,621✔
1443

1444
        return c->syscall_log_allow_list ||
13,621✔
1445
                !hashmap_isempty(c->syscall_log);
13,621✔
1446
}
1447

1448
static bool context_has_seccomp(const ExecContext *c) {
3,460✔
1449
        /* We need NNP if we have any form of seccomp and are unprivileged */
1450
        return c->lock_personality ||
3,460✔
1451
                c->memory_deny_write_execute ||
2,660✔
1452
                c->private_devices ||
2,660✔
1453
                c->protect_clock ||
2,660✔
1454
                c->protect_hostname == PROTECT_HOSTNAME_YES ||
2,660✔
1455
                c->protect_kernel_tunables ||
1456
                c->protect_kernel_modules ||
2,660✔
1457
                c->protect_kernel_logs ||
2,660✔
1458
                context_has_address_families(c) ||
5,320✔
1459
                exec_context_restrict_namespaces_set(c) ||
2,660✔
1460
                c->restrict_realtime ||
2,660✔
1461
                c->restrict_suid_sgid ||
2,624✔
1462
                !set_isempty(c->syscall_archs) ||
5,248✔
1463
                context_has_syscall_filters(c) ||
8,708✔
1464
                context_has_syscall_logs(c);
2,624✔
1465
}
1466

1467
static bool context_has_no_new_privileges(const ExecContext *c) {
10,997✔
1468
        assert(c);
10,997✔
1469

1470
        if (c->no_new_privileges)
10,997✔
1471
                return true;
1472

1473
        if (have_effective_cap(CAP_SYS_ADMIN) > 0) /* if we are privileged, we don't need NNP */
9,085✔
1474
                return false;
1475

1476
        return context_has_seccomp(c);
1,499✔
1477
}
1478

1479
#if HAVE_SECCOMP
1480

1481
static bool seccomp_allows_drop_privileges(const ExecContext *c) {
836✔
1482
        void *id, *val;
836✔
1483
        bool has_capget = false, has_capset = false, has_prctl = false;
836✔
1484

1485
        assert(c);
836✔
1486

1487
        /* No syscall filter, we are allowed to drop privileges */
1488
        if (hashmap_isempty(c->syscall_filter))
836✔
1489
                return true;
836✔
1490

1491
        HASHMAP_FOREACH_KEY(val, id, c->syscall_filter) {
302,292✔
1492
                _cleanup_free_ char *name = NULL;
301,498✔
1493

1494
                name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
301,498✔
1495

1496
                if (streq(name, "capget"))
301,498✔
1497
                        has_capget = true;
1498
                else if (streq(name, "capset"))
300,704✔
1499
                        has_capset = true;
1500
                else if (streq(name, "prctl"))
299,910✔
1501
                        has_prctl = true;
794✔
1502
        }
1503

1504
        if (c->syscall_allow_list)
794✔
1505
                return has_capget && has_capset && has_prctl;
794✔
1506
        else
1507
                return !(has_capget || has_capset || has_prctl);
×
1508
}
1509

1510
static bool skip_seccomp_unavailable(const ExecContext *c, const ExecParameters *p, const char* msg) {
20,884✔
1511

1512
        if (is_seccomp_available())
20,884✔
1513
                return false;
1514

1515
        log_exec_debug(c, p, "SECCOMP features not detected in the kernel, skipping %s", msg);
×
1516
        return true;
×
1517
}
1518

1519
static int apply_syscall_filter(const ExecContext *c, const ExecParameters *p) {
10,997✔
1520
        uint32_t negative_action, default_action, action;
10,997✔
1521
        int r;
10,997✔
1522

1523
        assert(c);
10,997✔
1524
        assert(p);
10,997✔
1525

1526
        if (!context_has_syscall_filters(c))
10,997✔
1527
                return 0;
1528

1529
        if (skip_seccomp_unavailable(c, p, "SystemCallFilter="))
2,034✔
1530
                return 0;
1531

1532
        negative_action = c->syscall_errno == SECCOMP_ERROR_NUMBER_KILL ? scmp_act_kill_process() : SCMP_ACT_ERRNO(c->syscall_errno);
2,034✔
1533

1534
        if (c->syscall_allow_list) {
2,034✔
1535
                default_action = negative_action;
1536
                action = SCMP_ACT_ALLOW;
1537
        } else {
1538
                default_action = SCMP_ACT_ALLOW;
1✔
1539
                action = negative_action;
1✔
1540
        }
1541

1542
        /* Sending over exec_fd or handoff_timestamp_fd requires write() syscall. */
1543
        if (p->exec_fd >= 0 || p->handoff_timestamp_fd >= 0) {
2,034✔
1544
                r = seccomp_filter_set_add_by_name(c->syscall_filter, c->syscall_allow_list, "write");
2,034✔
1545
                if (r < 0)
2,034✔
1546
                        return r;
1547
        }
1548

1549
        return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action, false);
2,034✔
1550
}
1551

1552
static int apply_syscall_log(const ExecContext *c, const ExecParameters *p) {
10,997✔
1553
#ifdef SCMP_ACT_LOG
1554
        uint32_t default_action, action;
10,997✔
1555
#endif
1556

1557
        assert(c);
10,997✔
1558
        assert(p);
10,997✔
1559

1560
        if (!context_has_syscall_logs(c))
10,997✔
1561
                return 0;
1562

1563
#ifdef SCMP_ACT_LOG
1564
        if (skip_seccomp_unavailable(c, p, "SystemCallLog="))
×
1565
                return 0;
1566

1567
        if (c->syscall_log_allow_list) {
×
1568
                /* Log nothing but the ones listed */
1569
                default_action = SCMP_ACT_ALLOW;
1570
                action = SCMP_ACT_LOG;
1571
        } else {
1572
                /* Log everything but the ones listed */
1573
                default_action = SCMP_ACT_LOG;
×
1574
                action = SCMP_ACT_ALLOW;
×
1575
        }
1576

1577
        return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_log, action, false);
×
1578
#else
1579
        /* old libseccomp */
1580
        log_exec_debug(c, p, "SECCOMP feature SCMP_ACT_LOG not available, skipping SystemCallLog=");
1581
        return 0;
1582
#endif
1583
}
1584

1585
static int apply_syscall_archs(const ExecContext *c, const ExecParameters *p) {
10,997✔
1586
        assert(c);
10,997✔
1587
        assert(p);
10,997✔
1588

1589
        if (set_isempty(c->syscall_archs))
10,997✔
1590
                return 0;
1591

1592
        if (skip_seccomp_unavailable(c, p, "SystemCallArchitectures="))
2,041✔
1593
                return 0;
1594

1595
        return seccomp_restrict_archs(c->syscall_archs);
2,041✔
1596
}
1597

1598
static int apply_address_families(const ExecContext *c, const ExecParameters *p) {
10,997✔
1599
        assert(c);
10,997✔
1600
        assert(p);
10,997✔
1601

1602
        if (!context_has_address_families(c))
10,997✔
1603
                return 0;
1604

1605
        if (skip_seccomp_unavailable(c, p, "RestrictAddressFamilies="))
2,038✔
1606
                return 0;
1607

1608
        return seccomp_restrict_address_families(c->address_families, c->address_families_allow_list);
2,038✔
1609
}
1610

1611
static int apply_memory_deny_write_execute(const ExecContext *c, const ExecParameters *p) {
10,997✔
1612
        int r;
10,997✔
1613

1614
        assert(c);
10,997✔
1615
        assert(p);
10,997✔
1616

1617
        if (!c->memory_deny_write_execute)
10,997✔
1618
                return 0;
1619

1620
        /* use prctl() if kernel supports it (6.3) */
1621
        r = prctl(PR_SET_MDWE, PR_MDWE_REFUSE_EXEC_GAIN, 0, 0, 0);
2,038✔
1622
        if (r == 0) {
2,038✔
1623
                log_exec_debug(c, p, "Enabled MemoryDenyWriteExecute= with PR_SET_MDWE");
6,114✔
1624
                return 0;
2,038✔
1625
        }
1626
        if (r < 0 && errno != EINVAL)
×
1627
                return log_exec_debug_errno(c,
×
1628
                                            p,
1629
                                            errno,
1630
                                            "Failed to enable MemoryDenyWriteExecute= with PR_SET_MDWE: %m");
1631
        /* else use seccomp */
1632
        log_exec_debug(c, p, "Kernel doesn't support PR_SET_MDWE: falling back to seccomp");
×
1633

1634
        if (skip_seccomp_unavailable(c, p, "MemoryDenyWriteExecute="))
×
1635
                return 0;
1636

1637
        return seccomp_memory_deny_write_execute();
×
1638
}
1639

1640
static int apply_restrict_realtime(const ExecContext *c, const ExecParameters *p) {
10,997✔
1641
        assert(c);
10,997✔
1642
        assert(p);
10,997✔
1643

1644
        if (!c->restrict_realtime)
10,997✔
1645
                return 0;
1646

1647
        if (skip_seccomp_unavailable(c, p, "RestrictRealtime="))
2,038✔
1648
                return 0;
1649

1650
        return seccomp_restrict_realtime();
2,038✔
1651
}
1652

1653
static int apply_restrict_suid_sgid(const ExecContext *c, const ExecParameters *p) {
10,997✔
1654
        assert(c);
10,997✔
1655
        assert(p);
10,997✔
1656

1657
        if (!c->restrict_suid_sgid)
10,997✔
1658
                return 0;
1659

1660
        if (skip_seccomp_unavailable(c, p, "RestrictSUIDSGID="))
1,957✔
1661
                return 0;
1662

1663
        return seccomp_restrict_suid_sgid();
1,957✔
1664
}
1665

1666
static int apply_protect_sysctl(const ExecContext *c, const ExecParameters *p) {
10,997✔
1667
        assert(c);
10,997✔
1668
        assert(p);
10,997✔
1669

1670
        /* Turn off the legacy sysctl() system call. Many distributions turn this off while building the kernel, but
1671
         * let's protect even those systems where this is left on in the kernel. */
1672

1673
        if (!c->protect_kernel_tunables)
10,997✔
1674
                return 0;
1675

1676
        if (skip_seccomp_unavailable(c, p, "ProtectKernelTunables="))
702✔
1677
                return 0;
1678

1679
        return seccomp_protect_sysctl();
702✔
1680
}
1681

1682
static int apply_protect_kernel_modules(const ExecContext *c, const ExecParameters *p) {
10,997✔
1683
        assert(c);
10,997✔
1684
        assert(p);
10,997✔
1685

1686
        /* Turn off module syscalls on ProtectKernelModules=yes */
1687

1688
        if (!c->protect_kernel_modules)
10,997✔
1689
                return 0;
1690

1691
        if (skip_seccomp_unavailable(c, p, "ProtectKernelModules="))
1,570✔
1692
                return 0;
1693

1694
        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM), false);
1,570✔
1695
}
1696

1697
static int apply_protect_kernel_logs(const ExecContext *c, const ExecParameters *p) {
10,997✔
1698
        assert(c);
10,997✔
1699
        assert(p);
10,997✔
1700

1701
        if (!c->protect_kernel_logs)
10,997✔
1702
                return 0;
1703

1704
        if (skip_seccomp_unavailable(c, p, "ProtectKernelLogs="))
1,570✔
1705
                return 0;
1706

1707
        return seccomp_protect_syslog();
1,570✔
1708
}
1709

1710
static int apply_protect_clock(const ExecContext *c, const ExecParameters *p) {
10,997✔
1711
        assert(c);
10,997✔
1712
        assert(p);
10,997✔
1713

1714
        if (!c->protect_clock)
10,997✔
1715
                return 0;
1716

1717
        if (skip_seccomp_unavailable(c, p, "ProtectClock="))
930✔
1718
                return 0;
1719

1720
        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_CLOCK, SCMP_ACT_ERRNO(EPERM), false);
930✔
1721
}
1722

1723
static int apply_private_devices(const ExecContext *c, const ExecParameters *p) {
10,997✔
1724
        assert(c);
10,997✔
1725
        assert(p);
10,997✔
1726

1727
        /* If PrivateDevices= is set, also turn off iopl and all @raw-io syscalls. */
1728

1729
        if (!c->private_devices)
10,997✔
1730
                return 0;
1731

1732
        if (skip_seccomp_unavailable(c, p, "PrivateDevices="))
1,177✔
1733
                return 0;
1734

1735
        return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO, SCMP_ACT_ERRNO(EPERM), false);
1,177✔
1736
}
1737

1738
static int apply_restrict_namespaces(const ExecContext *c, const ExecParameters *p) {
10,997✔
1739
        assert(c);
10,997✔
1740
        assert(p);
10,997✔
1741

1742
        if (!exec_context_restrict_namespaces_set(c))
10,997✔
1743
                return 0;
1744

1745
        if (skip_seccomp_unavailable(c, p, "RestrictNamespaces="))
1,679✔
1746
                return 0;
1747

1748
        return seccomp_restrict_namespaces(c->restrict_namespaces);
1,679✔
1749
}
1750

1751
static int apply_lock_personality(const ExecContext *c, const ExecParameters *p) {
10,997✔
1752
        unsigned long personality;
10,997✔
1753
        int r;
10,997✔
1754

1755
        assert(c);
10,997✔
1756
        assert(p);
10,997✔
1757

1758
        if (!c->lock_personality)
10,997✔
1759
                return 0;
10,997✔
1760

1761
        if (skip_seccomp_unavailable(c, p, "LockPersonality="))
2,038✔
1762
                return 0;
1763

1764
        personality = c->personality;
2,038✔
1765

1766
        /* If personality is not specified, use either PER_LINUX or PER_LINUX32 depending on what is currently set. */
1767
        if (personality == PERSONALITY_INVALID) {
2,038✔
1768

1769
                r = opinionated_personality(&personality);
2,038✔
1770
                if (r < 0)
2,038✔
1771
                        return r;
1772
        }
1773

1774
        return seccomp_lock_personality(personality);
2,038✔
1775
}
1776

1777
#endif
1778

1779
#if HAVE_LIBBPF
1780
static int apply_restrict_filesystems(const ExecContext *c, const ExecParameters *p) {
10,997✔
1781
        int r;
10,997✔
1782

1783
        assert(c);
10,997✔
1784
        assert(p);
10,997✔
1785

1786
        if (!exec_context_restrict_filesystems_set(c))
10,997✔
1787
                return 0;
1788

1789
        if (p->bpf_restrict_fs_map_fd < 0) {
×
1790
                /* LSM BPF is unsupported or lsm_bpf_setup failed */
1791
                log_exec_debug(c, p, "LSM BPF not supported, skipping RestrictFileSystems=");
×
1792
                return 0;
×
1793
        }
1794

1795
        /* We are in a new binary, so dl-open again */
1796
        r = dlopen_bpf();
×
1797
        if (r < 0)
×
1798
                return r;
1799

1800
        return bpf_restrict_fs_update(c->restrict_filesystems, p->cgroup_id, p->bpf_restrict_fs_map_fd, c->restrict_filesystems_allow_list);
×
1801
}
1802
#endif
1803

1804
static int apply_protect_hostname(const ExecContext *c, const ExecParameters *p, int *ret_exit_status) {
11,000✔
1805
        int r;
11,000✔
1806

1807
        assert(c);
11,000✔
1808
        assert(p);
11,000✔
1809

1810
        if (c->protect_hostname == PROTECT_HOSTNAME_NO)
11,000✔
1811
                return 0;
1812

1813
        if (ns_type_supported(NAMESPACE_UTS)) {
1,114✔
1814
                if (unshare(CLONE_NEWUTS) < 0) {
1,114✔
1815
                        if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) {
×
1816
                                *ret_exit_status = EXIT_NAMESPACE;
×
1817
                                return log_exec_error_errno(c, p, errno, "Failed to set up UTS namespacing: %m");
×
1818
                        }
1819

1820
                        log_exec_warning(c, p,
×
1821
                                         "ProtectHostname=%s is configured, but UTS namespace setup is prohibited (container manager?), ignoring namespace setup.",
1822
                                         protect_hostname_to_string(c->protect_hostname));
1823

1824
                } else if (c->private_hostname) {
1,114✔
1825
                        r = sethostname_idempotent(c->private_hostname);
4✔
1826
                        if (r < 0) {
4✔
1827
                                *ret_exit_status = EXIT_NAMESPACE;
×
1828
                                return log_exec_error_errno(c, p, r, "Failed to set private hostname '%s': %m", c->private_hostname);
×
1829
                        }
1830
                }
1831
        } else
1832
                log_exec_warning(c, p,
×
1833
                                 "ProtectHostname=%s is configured, but the kernel does not support UTS namespaces, ignoring namespace setup.",
1834
                                 protect_hostname_to_string(c->protect_hostname));
1835

1836
#if HAVE_SECCOMP
1837
        if (c->protect_hostname == PROTECT_HOSTNAME_YES) {
1,114✔
1838
                if (skip_seccomp_unavailable(c, p, "ProtectHostname="))
1,110✔
1839
                        return 0;
1840

1841
                r = seccomp_protect_hostname();
1,110✔
1842
                if (r < 0) {
1,110✔
1843
                        *ret_exit_status = EXIT_SECCOMP;
×
1844
                        return log_exec_error_errno(c, p, r, "Failed to apply hostname restrictions: %m");
×
1845
                }
1846
        }
1847
#endif
1848

1849
        return 0;
1850
}
1851

1852
static void do_idle_pipe_dance(int idle_pipe[static 4]) {
147✔
1853
        assert(idle_pipe);
147✔
1854

1855
        idle_pipe[1] = safe_close(idle_pipe[1]);
147✔
1856
        idle_pipe[2] = safe_close(idle_pipe[2]);
147✔
1857

1858
        if (idle_pipe[0] >= 0) {
147✔
1859
                int r;
147✔
1860

1861
                r = fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
147✔
1862

1863
                if (idle_pipe[3] >= 0 && r == 0 /* timeout */) {
147✔
1864
                        ssize_t n;
108✔
1865

1866
                        /* Signal systemd that we are bored and want to continue. */
1867
                        n = write(idle_pipe[3], "x", 1);
108✔
1868
                        if (n > 0)
108✔
1869
                                /* Wait for systemd to react to the signal above. */
1870
                                (void) fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC);
108✔
1871
                }
1872

1873
                idle_pipe[0] = safe_close(idle_pipe[0]);
147✔
1874

1875
        }
1876

1877
        idle_pipe[3] = safe_close(idle_pipe[3]);
147✔
1878
}
147✔
1879

1880
static const char *exec_directory_env_name_to_string(ExecDirectoryType t);
1881

1882
/* And this table also maps ExecDirectoryType, to the environment variable we pass the selected directory to
1883
 * the service payload in. */
1884
static const char* const exec_directory_env_name_table[_EXEC_DIRECTORY_TYPE_MAX] = {
1885
        [EXEC_DIRECTORY_RUNTIME]       = "RUNTIME_DIRECTORY",
1886
        [EXEC_DIRECTORY_STATE]         = "STATE_DIRECTORY",
1887
        [EXEC_DIRECTORY_CACHE]         = "CACHE_DIRECTORY",
1888
        [EXEC_DIRECTORY_LOGS]          = "LOGS_DIRECTORY",
1889
        [EXEC_DIRECTORY_CONFIGURATION] = "CONFIGURATION_DIRECTORY",
1890
};
1891

1892
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(exec_directory_env_name, ExecDirectoryType);
2,677✔
1893

1894
static int build_environment(
11,025✔
1895
                const ExecContext *c,
1896
                const ExecParameters *p,
1897
                const CGroupContext *cgroup_context,
1898
                size_t n_fds,
1899
                const char *home,
1900
                const char *username,
1901
                const char *shell,
1902
                dev_t journal_stream_dev,
1903
                ino_t journal_stream_ino,
1904
                const char *memory_pressure_path,
1905
                bool needs_sandboxing,
1906
                char ***ret) {
1907

1908
        _cleanup_strv_free_ char **our_env = NULL;
11,025✔
1909
        size_t n_env = 0;
11,025✔
1910
        char *x;
11,025✔
1911
        int r;
11,025✔
1912

1913
        assert(c);
11,025✔
1914
        assert(p);
11,025✔
1915
        assert(ret);
11,025✔
1916

1917
#define N_ENV_VARS 20
1918
        our_env = new0(char*, N_ENV_VARS + _EXEC_DIRECTORY_TYPE_MAX);
11,025✔
1919
        if (!our_env)
11,025✔
1920
                return -ENOMEM;
1921

1922
        if (n_fds > 0) {
11,025✔
1923
                _cleanup_free_ char *joined = NULL;
1,565✔
1924

1925
                if (asprintf(&x, "LISTEN_PID="PID_FMT, getpid_cached()) < 0)
1,565✔
1926
                        return -ENOMEM;
1927
                our_env[n_env++] = x;
1,565✔
1928

1929
                if (asprintf(&x, "LISTEN_FDS=%zu", n_fds) < 0)
1,565✔
1930
                        return -ENOMEM;
1931
                our_env[n_env++] = x;
1,565✔
1932

1933
                joined = strv_join(p->fd_names, ":");
1,565✔
1934
                if (!joined)
1,565✔
1935
                        return -ENOMEM;
1936

1937
                x = strjoin("LISTEN_FDNAMES=", joined);
1,565✔
1938
                if (!x)
1,565✔
1939
                        return -ENOMEM;
1940
                our_env[n_env++] = x;
1,565✔
1941
        }
1942

1943
        if ((p->flags & EXEC_SET_WATCHDOG) && p->watchdog_usec > 0) {
11,025✔
1944
                if (asprintf(&x, "WATCHDOG_PID="PID_FMT, getpid_cached()) < 0)
2,033✔
1945
                        return -ENOMEM;
1946
                our_env[n_env++] = x;
2,033✔
1947

1948
                if (asprintf(&x, "WATCHDOG_USEC="USEC_FMT, p->watchdog_usec) < 0)
2,033✔
1949
                        return -ENOMEM;
1950
                our_env[n_env++] = x;
2,033✔
1951
        }
1952

1953
        /* If this is D-Bus, tell the nss-systemd module, since it relies on being able to use blocking
1954
         * Varlink calls back to us for look up dynamic users in PID 1. Break the deadlock between D-Bus and
1955
         * PID 1 by disabling use of PID1' NSS interface for looking up dynamic users. */
1956
        if (p->flags & EXEC_NSS_DYNAMIC_BYPASS) {
11,025✔
1957
                x = strdup("SYSTEMD_NSS_DYNAMIC_BYPASS=1");
175✔
1958
                if (!x)
175✔
1959
                        return -ENOMEM;
1960
                our_env[n_env++] = x;
175✔
1961
        }
1962

1963
        /* We query "root" if this is a system unit and User= is not specified. $USER is always set. $HOME
1964
         * could cause problem for e.g. getty, since login doesn't override $HOME, and $LOGNAME and $SHELL don't
1965
         * really make much sense since we're not logged in. Hence we conditionalize the three based on
1966
         * SetLoginEnvironment= switch. */
1967
        if (!c->user && !c->dynamic_user && p->runtime_scope == RUNTIME_SCOPE_SYSTEM) {
11,025✔
1968
                r = get_fixed_user("root", &username, NULL, NULL, &home, &shell);
8,490✔
1969
                if (r < 0)
8,490✔
1970
                        return log_exec_debug_errno(c,
×
1971
                                                    p,
1972
                                                    r,
1973
                                                    "Failed to determine user credentials for root: %m");
1974
        }
1975

1976
        bool set_user_login_env = exec_context_get_set_login_environment(c);
11,025✔
1977

1978
        if (username) {
11,025✔
1979
                x = strjoin("USER=", username);
10,393✔
1980
                if (!x)
10,393✔
1981
                        return -ENOMEM;
1982
                our_env[n_env++] = x;
10,393✔
1983

1984
                if (set_user_login_env) {
10,393✔
1985
                        x = strjoin("LOGNAME=", username);
1,962✔
1986
                        if (!x)
1,962✔
1987
                                return -ENOMEM;
1988
                        our_env[n_env++] = x;
1,962✔
1989
                }
1990
        }
1991

1992
        /* Note that we don't set $HOME or $SHELL if they are not particularly enlightening anyway
1993
         * (i.e. are "/" or "/bin/nologin"). */
1994

1995
        if (home && set_user_login_env && !empty_or_root(home)) {
11,025✔
1996
                x = strjoin("HOME=", home);
293✔
1997
                if (!x)
293✔
1998
                        return -ENOMEM;
1999

2000
                path_simplify(x + 5);
293✔
2001
                our_env[n_env++] = x;
293✔
2002
        }
2003

2004
        if (shell && set_user_login_env && !shell_is_placeholder(shell)) {
11,025✔
2005
                x = strjoin("SHELL=", shell);
293✔
2006
                if (!x)
293✔
2007
                        return -ENOMEM;
2008

2009
                path_simplify(x + 6);
293✔
2010
                our_env[n_env++] = x;
293✔
2011
        }
2012

2013
        if (!sd_id128_is_null(p->invocation_id)) {
11,025✔
2014
                assert(p->invocation_id_string);
11,025✔
2015

2016
                x = strjoin("INVOCATION_ID=", p->invocation_id_string);
11,025✔
2017
                if (!x)
11,025✔
2018
                        return -ENOMEM;
2019

2020
                our_env[n_env++] = x;
11,025✔
2021
        }
2022

2023
        if (exec_context_needs_term(c)) {
11,025✔
2024
                _cleanup_free_ char *cmdline = NULL;
443✔
2025
                const char *tty_path, *term = NULL;
443✔
2026

2027
                tty_path = exec_context_tty_path(c);
443✔
2028

2029
                /* If we are forked off PID 1 and we are supposed to operate on /dev/console, then let's try
2030
                 * to inherit the $TERM set for PID 1. This is useful for containers so that the $TERM the
2031
                 * container manager passes to PID 1 ends up all the way in the console login shown. */
2032

2033
                if (path_equal(tty_path, "/dev/console") && getppid() == 1)
443✔
2034
                        term = getenv("TERM");
391✔
2035
                else if (tty_path && in_charset(skip_dev_prefix(tty_path), ALPHANUMERICAL)) {
52✔
2036
                        _cleanup_free_ char *key = NULL;
37✔
2037

2038
                        key = strjoin("systemd.tty.term.", skip_dev_prefix(tty_path));
37✔
2039
                        if (!key)
37✔
2040
                                return -ENOMEM;
×
2041

2042
                        r = proc_cmdline_get_key(key, 0, &cmdline);
37✔
2043
                        if (r < 0)
37✔
2044
                                log_exec_debug_errno(c,
×
2045
                                                     p,
2046
                                                     r,
2047
                                                     "Failed to read %s from kernel cmdline, ignoring: %m",
2048
                                                     key);
2049
                        else if (r > 0)
37✔
2050
                                term = cmdline;
×
2051
                }
2052

2053
                if (!term)
428✔
2054
                        term = default_term_for_tty(tty_path);
52✔
2055

2056
                x = strjoin("TERM=", term);
443✔
2057
                if (!x)
443✔
2058
                        return -ENOMEM;
2059
                our_env[n_env++] = x;
443✔
2060
        }
2061

2062
        if (journal_stream_dev != 0 && journal_stream_ino != 0) {
11,025✔
2063
                if (asprintf(&x, "JOURNAL_STREAM=" DEV_FMT ":" INO_FMT, journal_stream_dev, journal_stream_ino) < 0)
10,285✔
2064
                        return -ENOMEM;
2065

2066
                our_env[n_env++] = x;
10,285✔
2067
        }
2068

2069
        if (c->log_namespace) {
11,025✔
2070
                x = strjoin("LOG_NAMESPACE=", c->log_namespace);
2✔
2071
                if (!x)
2✔
2072
                        return -ENOMEM;
2073

2074
                our_env[n_env++] = x;
2✔
2075
        }
2076

2077
        for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
66,150✔
2078
                _cleanup_free_ char *joined = NULL;
55,125✔
2079
                const char *n;
55,125✔
2080

2081
                if (!p->prefix[t])
55,125✔
2082
                        continue;
×
2083

2084
                if (c->directories[t].n_items == 0)
55,125✔
2085
                        continue;
52,448✔
2086

2087
                n = exec_directory_env_name_to_string(t);
2,677✔
2088
                if (!n)
2,677✔
2089
                        continue;
×
2090

2091
                for (size_t i = 0; i < c->directories[t].n_items; i++) {
5,850✔
2092
                        _cleanup_free_ char *prefixed = NULL;
3,173✔
2093

2094
                        prefixed = path_join(p->prefix[t], c->directories[t].items[i].path);
3,173✔
2095
                        if (!prefixed)
3,173✔
2096
                                return -ENOMEM;
2097

2098
                        if (!strextend_with_separator(&joined, ":", prefixed))
3,173✔
2099
                                return -ENOMEM;
2100
                }
2101

2102
                x = strjoin(n, "=", joined);
2,677✔
2103
                if (!x)
2,677✔
2104
                        return -ENOMEM;
2105

2106
                our_env[n_env++] = x;
2,677✔
2107
        }
2108

2109
        _cleanup_free_ char *creds_dir = NULL;
11,025✔
2110
        r = exec_context_get_credential_directory(c, p, p->unit_id, &creds_dir);
11,025✔
2111
        if (r < 0)
11,025✔
2112
                return r;
2113
        if (r > 0) {
11,025✔
2114
                x = strjoin("CREDENTIALS_DIRECTORY=", creds_dir);
2,348✔
2115
                if (!x)
2,348✔
2116
                        return -ENOMEM;
2117

2118
                our_env[n_env++] = x;
2,348✔
2119
        }
2120

2121
        if (asprintf(&x, "SYSTEMD_EXEC_PID=" PID_FMT, getpid_cached()) < 0)
11,025✔
2122
                return -ENOMEM;
2123

2124
        our_env[n_env++] = x;
11,025✔
2125

2126
        if (memory_pressure_path) {
11,025✔
2127
                x = strjoin("MEMORY_PRESSURE_WATCH=", memory_pressure_path);
10,671✔
2128
                if (!x)
10,671✔
2129
                        return -ENOMEM;
2130

2131
                our_env[n_env++] = x;
10,671✔
2132

2133
                if (cgroup_context && !path_equal(memory_pressure_path, "/dev/null")) {
21,342✔
2134
                        _cleanup_free_ char *b = NULL, *e = NULL;
10,671✔
2135

2136
                        if (asprintf(&b, "%s " USEC_FMT " " USEC_FMT,
10,671✔
2137
                                     MEMORY_PRESSURE_DEFAULT_TYPE,
2138
                                     cgroup_context->memory_pressure_threshold_usec == USEC_INFINITY ? MEMORY_PRESSURE_DEFAULT_THRESHOLD_USEC :
10,671✔
2139
                                     CLAMP(cgroup_context->memory_pressure_threshold_usec, 1U, MEMORY_PRESSURE_DEFAULT_WINDOW_USEC),
10,671✔
2140
                                     MEMORY_PRESSURE_DEFAULT_WINDOW_USEC) < 0)
2141
                                return -ENOMEM;
2142

2143
                        if (base64mem(b, strlen(b) + 1, &e) < 0)
10,671✔
2144
                                return -ENOMEM;
2145

2146
                        x = strjoin("MEMORY_PRESSURE_WRITE=", e);
10,671✔
2147
                        if (!x)
10,671✔
2148
                                return -ENOMEM;
2149

2150
                        our_env[n_env++] = x;
10,671✔
2151
                }
2152
        }
2153

2154
        if (p->notify_socket) {
11,025✔
2155
                x = strjoin("NOTIFY_SOCKET=", exec_get_private_notify_socket_path(c, p, needs_sandboxing) ?: p->notify_socket);
2,441✔
2156
                if (!x)
2,441✔
2157
                        return -ENOMEM;
2158

2159
                our_env[n_env++] = x;
2,441✔
2160
        }
2161

2162
        assert(n_env < N_ENV_VARS + _EXEC_DIRECTORY_TYPE_MAX);
11,025✔
2163
#undef N_ENV_VARS
2164

2165
        *ret = TAKE_PTR(our_env);
11,025✔
2166

2167
        return 0;
11,025✔
2168
}
2169

2170
static int build_pass_environment(const ExecContext *c, char ***ret) {
11,025✔
2171
        _cleanup_strv_free_ char **pass_env = NULL;
11,025✔
2172
        size_t n_env = 0;
11,025✔
2173

2174
        STRV_FOREACH(i, c->pass_environment) {
11,343✔
2175
                _cleanup_free_ char *x = NULL;
×
2176
                char *v;
318✔
2177

2178
                v = getenv(*i);
318✔
2179
                if (!v)
318✔
2180
                        continue;
×
2181
                x = strjoin(*i, "=", v);
318✔
2182
                if (!x)
318✔
2183
                        return -ENOMEM;
2184

2185
                if (!GREEDY_REALLOC(pass_env, n_env + 2))
318✔
2186
                        return -ENOMEM;
2187

2188
                pass_env[n_env++] = TAKE_PTR(x);
318✔
2189
                pass_env[n_env] = NULL;
318✔
2190
        }
2191

2192
        *ret = TAKE_PTR(pass_env);
11,025✔
2193

2194
        return 0;
11,025✔
2195
}
2196

2197
static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogid, uid_t uid, gid_t gid, bool allow_setgroups) {
11,005✔
2198
        _cleanup_free_ char *uid_map = NULL, *gid_map = NULL;
11,005✔
2199
        _cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR;
11,005✔
2200
        _cleanup_close_ int unshare_ready_fd = -EBADF;
11,005✔
2201
        _cleanup_(sigkill_waitp) pid_t pid = 0;
11,005✔
2202
        uint64_t c = 1;
11,005✔
2203
        ssize_t n;
11,005✔
2204
        int r;
11,005✔
2205

2206
        /* Set up a user namespace and map the original UID/GID (IDs from before any user or group changes, i.e.
2207
         * the IDs from the user or system manager(s)) to itself, the selected UID/GID to itself, and everything else to
2208
         * nobody. In order to be able to write this mapping we need CAP_SETUID in the original user namespace, which
2209
         * we however lack after opening the user namespace. To work around this we fork() a temporary child process,
2210
         * which waits for the parent to create the new user namespace while staying in the original namespace. The
2211
         * child then writes the UID mapping, under full privileges. The parent waits for the child to finish and
2212
         * continues execution normally.
2213
         * For unprivileged users (i.e. without capabilities), the root to root mapping is excluded. As such, it
2214
         * does not need CAP_SETUID to write the single line mapping to itself. */
2215

2216
        if (private_users == PRIVATE_USERS_NO)
11,005✔
2217
                return 0;
2218

2219
        if (private_users == PRIVATE_USERS_IDENTITY) {
37✔
2220
                uid_map = strdup("0 0 65536\n");
2✔
2221
                if (!uid_map)
2✔
2222
                        return -ENOMEM;
2223
        } else if (private_users == PRIVATE_USERS_FULL) {
35✔
2224
                /* Map all UID/GID from original to new user namespace. We can't use `0 0 UINT32_MAX` because
2225
                 * this is the same UID/GID map as the init user namespace and systemd's running_in_userns()
2226
                 * checks whether its in a user namespace by comparing uid_map/gid_map to `0 0 UINT32_MAX`.
2227
                 * Thus, we still map all UIDs/GIDs but do it using two extents to differentiate the new user
2228
                 * namespace from the init namespace:
2229
                 *   0 0 1
2230
                 *   1 1 UINT32_MAX - 1
2231
                 *
2232
                 * systemd will remove the heuristic in running_in_userns() and use namespace inodes in version 258
2233
                 * (PR #35382). But some users may be running a container image with older systemd < 258 so we keep
2234
                 * this uid_map/gid_map hack until version 259 for version N-1 compatibility.
2235
                 *
2236
                 * TODO: Switch to `0 0 UINT32_MAX` in systemd v259.
2237
                 *
2238
                 * Note the kernel defines the UID range between 0 and UINT32_MAX so we map all UIDs even though
2239
                 * the UID range beyond INT32_MAX (e.g. i.e. the range above the signed 32-bit range) is
2240
                 * icky. For example, setfsuid() returns the old UID as signed integer. But units can decide to
2241
                 * use these UIDs/GIDs so we need to map them. */
2242
                r = asprintf(&uid_map, "0 0 1\n"
3✔
2243
                                       "1 1 " UID_FMT "\n", (uid_t) (UINT32_MAX - 1));
2244
                if (r < 0)
3✔
2245
                        return -ENOMEM;
2246
        /* Can only set up multiple mappings with CAP_SETUID. */
2247
        } else if (have_effective_cap(CAP_SETUID) > 0 && uid != ouid && uid_is_valid(uid)) {
32✔
2248
                r = asprintf(&uid_map,
×
2249
                             UID_FMT " " UID_FMT " 1\n"     /* Map $OUID → $OUID */
2250
                             UID_FMT " " UID_FMT " 1\n",    /* Map $UID → $UID */
2251
                             ouid, ouid, uid, uid);
2252
                if (r < 0)
×
2253
                        return -ENOMEM;
2254
        } else {
2255
                r = asprintf(&uid_map,
32✔
2256
                             UID_FMT " " UID_FMT " 1\n",    /* Map $OUID → $OUID */
2257
                             ouid, ouid);
2258
                if (r < 0)
32✔
2259
                        return -ENOMEM;
2260
        }
2261

2262
        if (private_users == PRIVATE_USERS_IDENTITY) {
37✔
2263
                gid_map = strdup("0 0 65536\n");
2✔
2264
                if (!gid_map)
2✔
2265
                        return -ENOMEM;
2266
        } else if (private_users == PRIVATE_USERS_FULL) {
35✔
2267
                r = asprintf(&gid_map, "0 0 1\n"
3✔
2268
                                       "1 1 " GID_FMT "\n", (gid_t) (UINT32_MAX - 1));
2269
                if (r < 0)
3✔
2270
                        return -ENOMEM;
2271
        /* Can only set up multiple mappings with CAP_SETGID. */
2272
        } else if (have_effective_cap(CAP_SETGID) > 0 && gid != ogid && gid_is_valid(gid)) {
38✔
2273
                r = asprintf(&gid_map,
×
2274
                             GID_FMT " " GID_FMT " 1\n"     /* Map $OGID → $OGID */
2275
                             GID_FMT " " GID_FMT " 1\n",    /* Map $GID → $GID */
2276
                             ogid, ogid, gid, gid);
2277
                if (r < 0)
×
2278
                        return -ENOMEM;
2279
        } else {
2280
                r = asprintf(&gid_map,
32✔
2281
                             GID_FMT " " GID_FMT " 1\n",    /* Map $OGID -> $OGID */
2282
                             ogid, ogid);
2283
                if (r < 0)
32✔
2284
                        return -ENOMEM;
2285
        }
2286

2287
        /* Create a communication channel so that the parent can tell the child when it finished creating the user
2288
         * namespace. */
2289
        unshare_ready_fd = eventfd(0, EFD_CLOEXEC);
37✔
2290
        if (unshare_ready_fd < 0)
37✔
2291
                return -errno;
×
2292

2293
        /* Create a communication channel so that the child can tell the parent a proper error code in case it
2294
         * failed. */
2295
        if (pipe2(errno_pipe, O_CLOEXEC) < 0)
37✔
2296
                return -errno;
×
2297

2298
        r = safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pid);
37✔
2299
        if (r < 0)
74✔
2300
                return r;
2301
        if (r == 0) {
74✔
2302
                _cleanup_close_ int fd = -EBADF;
×
2303
                const char *a;
37✔
2304
                pid_t ppid;
37✔
2305

2306
                /* Child process, running in the original user namespace. Let's update the parent's UID/GID map from
2307
                 * here, after the parent opened its own user namespace. */
2308

2309
                ppid = getppid();
37✔
2310
                errno_pipe[0] = safe_close(errno_pipe[0]);
37✔
2311

2312
                /* Wait until the parent unshared the user namespace */
2313
                if (read(unshare_ready_fd, &c, sizeof(c)) < 0)
37✔
2314
                        report_errno_and_exit(errno_pipe[1], -errno);
×
2315

2316
                /* Disable the setgroups() system call in the child user namespace, for good, unless PrivateUsers=full
2317
                 * and using the system service manager. */
2318
                a = procfs_file_alloca(ppid, "setgroups");
37✔
2319
                fd = open(a, O_WRONLY|O_CLOEXEC);
37✔
2320
                if (fd < 0) {
37✔
2321
                        if (errno != ENOENT) {
×
2322
                                r = log_debug_errno(errno, "Failed to open %s: %m", a);
×
2323
                                report_errno_and_exit(errno_pipe[1], r);
×
2324
                        }
2325

2326
                        /* If the file is missing the kernel is too old, let's continue anyway. */
2327
                } else {
2328
                        const char *setgroups = allow_setgroups ? "allow\n" : "deny\n";
37✔
2329
                        if (write(fd, setgroups, strlen(setgroups)) < 0) {
37✔
2330
                                r = log_debug_errno(errno, "Failed to write '%s' to %s: %m", setgroups, a);
×
2331
                                report_errno_and_exit(errno_pipe[1], r);
×
2332
                        }
2333

2334
                        fd = safe_close(fd);
37✔
2335
                }
2336

2337
                /* First write the GID map */
2338
                a = procfs_file_alloca(ppid, "gid_map");
37✔
2339
                fd = open(a, O_WRONLY|O_CLOEXEC);
37✔
2340
                if (fd < 0) {
37✔
2341
                        r = log_debug_errno(errno, "Failed to open %s: %m", a);
×
2342
                        report_errno_and_exit(errno_pipe[1], r);
×
2343
                }
2344

2345
                if (write(fd, gid_map, strlen(gid_map)) < 0) {
37✔
2346
                        r = log_debug_errno(errno, "Failed to write GID map to %s: %m", a);
×
2347
                        report_errno_and_exit(errno_pipe[1], r);
×
2348
                }
2349

2350
                fd = safe_close(fd);
37✔
2351

2352
                /* The write the UID map */
2353
                a = procfs_file_alloca(ppid, "uid_map");
37✔
2354
                fd = open(a, O_WRONLY|O_CLOEXEC);
37✔
2355
                if (fd < 0) {
37✔
2356
                        r = log_debug_errno(errno, "Failed to open %s: %m", a);
×
2357
                        report_errno_and_exit(errno_pipe[1], r);
×
2358
                }
2359

2360
                if (write(fd, uid_map, strlen(uid_map)) < 0) {
37✔
2361
                        r = log_debug_errno(errno, "Failed to write UID map to %s: %m", a);
×
2362
                        report_errno_and_exit(errno_pipe[1], r);
×
2363
                }
2364

2365
                _exit(EXIT_SUCCESS);
37✔
2366
        }
2367

2368
        errno_pipe[1] = safe_close(errno_pipe[1]);
37✔
2369

2370
        if (unshare(CLONE_NEWUSER) < 0)
37✔
2371
                return log_debug_errno(errno, "Failed to unshare user namespace: %m");
×
2372

2373
        /* Let the child know that the namespace is ready now */
2374
        if (write(unshare_ready_fd, &c, sizeof(c)) < 0)
37✔
2375
                return -errno;
×
2376

2377
        /* Try to read an error code from the child */
2378
        n = read(errno_pipe[0], &r, sizeof(r));
37✔
2379
        if (n < 0)
37✔
2380
                return -errno;
×
2381
        if (n == sizeof(r)) { /* an error code was sent to us */
37✔
2382
                if (r < 0)
×
2383
                        return r;
2384
                return -EIO;
×
2385
        }
2386
        if (n != 0) /* on success we should have read 0 bytes */
37✔
2387
                return -EIO;
2388

2389
        r = wait_for_terminate_and_check("(sd-userns)", TAKE_PID(pid), 0);
37✔
2390
        if (r < 0)
37✔
2391
                return r;
2392
        if (r != EXIT_SUCCESS) /* If something strange happened with the child, let's consider this fatal, too */
37✔
2393
                return -EIO;
×
2394

2395
        return 1;
2396
}
2397

2398
static int can_mount_proc(const ExecContext *c, ExecParameters *p) {
7✔
2399
        _cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR;
5✔
2400
        _cleanup_(sigkill_waitp) pid_t pid = 0;
×
2401
        ssize_t n;
7✔
2402
        int r;
7✔
2403

2404
        assert(c);
7✔
2405
        assert(p);
7✔
2406

2407
        /* If running via unprivileged user manager and /proc/ is masked (e.g. /proc/kmsg is over-mounted with tmpfs
2408
         * like systemd-nspawn does), then mounting /proc/ will fail with EPERM. This is due to a kernel restriction
2409
         * where unprivileged user namespaces cannot mount a less restrictive instance of /proc. */
2410

2411
        /* Create a communication channel so that the child can tell the parent a proper error code in case it
2412
         * failed. */
2413
        if (pipe2(errno_pipe, O_CLOEXEC) < 0)
7✔
2414
                return log_exec_debug_errno(c, p, errno, "Failed to create pipe for communicating with child process (sd-proc-check): %m");
×
2415

2416
        /* Fork a child process into its own mount and PID namespace. Note safe_fork() already remounts / as SLAVE
2417
         * with FORK_MOUNTNS_SLAVE. */
2418
        r = safe_fork("(sd-proc-check)",
7✔
2419
                      FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_NEW_PIDNS, &pid);
2420
        if (r < 0)
7✔
2421
                return log_exec_debug_errno(c, p, r, "Failed to fork child process (sd-proc-check): %m");
×
2422
        if (r == 0) {
7✔
2423
                errno_pipe[0] = safe_close(errno_pipe[0]);
2✔
2424

2425
                /* Try mounting /proc on /dev/shm/. No need to clean up the mount since the mount
2426
                 * namespace will be cleaned up once the process exits. */
2427
                r = mount_follow_verbose(LOG_DEBUG, "proc", "/dev/shm/", "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
2✔
2428
                if (r < 0) {
2✔
2429
                        (void) write(errno_pipe[1], &r, sizeof(r));
×
2430
                        _exit(EXIT_FAILURE);
×
2431
                }
2432

2433
                _exit(EXIT_SUCCESS);
2✔
2434
        }
2435

2436
        errno_pipe[1] = safe_close(errno_pipe[1]);
5✔
2437

2438
        /* Try to read an error code from the child */
2439
        n = read(errno_pipe[0], &r, sizeof(r));
5✔
2440
        if (n < 0)
5✔
2441
                return log_exec_debug_errno(c, p, errno, "Failed to read errno from pipe with child process (sd-proc-check): %m");
×
2442
        if (n == sizeof(r)) { /* an error code was sent to us */
5✔
2443
                /* This is the expected case where proc cannot be mounted due to permissions. */
2444
                if (ERRNO_IS_NEG_PRIVILEGE(r))
5✔
2445
                        return 0;
2446
                if (r < 0)
×
2447
                        return r;
2448

2449
                return -EIO;
×
2450
        }
2451
        if (n != 0) /* on success we should have read 0 bytes */
4✔
2452
                return -EIO;
2453

2454
        r = wait_for_terminate_and_check("(sd-proc-check)", TAKE_PID(pid), 0 /* flags= */);
4✔
2455
        if (r < 0)
4✔
2456
                return log_exec_debug_errno(c, p, r, "Failed to wait for (sd-proc-check) child process to terminate: %m");
×
2457
        if (r != EXIT_SUCCESS) /* If something strange happened with the child, let's consider this fatal, too */
4✔
2458
                return log_exec_debug_errno(c, p, SYNTHETIC_ERRNO(EIO), "Child process (sd-proc-check) exited with unexpected exit status '%d'.", r);
×
2459

2460
        return 1;
2461
}
2462

2463
static int setup_private_pids(const ExecContext *c, ExecParameters *p) {
13✔
2464
        _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
×
2465
        _cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR;
6✔
2466
        ssize_t n;
13✔
2467
        int r, q;
13✔
2468

2469
        assert(c);
13✔
2470
        assert(p);
13✔
2471
        assert(p->pidref_transport_fd >= 0);
13✔
2472

2473
        /* The first process created after unsharing a pid namespace becomes PID 1 in the pid namespace, so
2474
         * we have to fork after unsharing the pid namespace to become PID 1. The parent sends the child
2475
         * pidref to the manager and exits while the child process continues with the rest of exec_invoke()
2476
         * and finally executes the actual payload. */
2477

2478
        /* Create a communication channel so that the parent can tell the child a proper error code in case it
2479
         * failed to send child pidref to the manager. */
2480
        if (pipe2(errno_pipe, O_CLOEXEC) < 0)
13✔
2481
                return log_exec_debug_errno(c, p, errno, "Failed to create pipe for communicating with parent process: %m");
×
2482

2483
        r = pidref_safe_fork("(sd-pidns-child)", FORK_NEW_PIDNS, &pidref);
13✔
2484
        if (r < 0)
13✔
2485
                return log_exec_debug_errno(c, p, r, "Failed to fork child into new pid namespace: %m");
×
2486
        if (r > 0) {
13✔
2487
                errno_pipe[0] = safe_close(errno_pipe[0]);
7✔
2488

2489
                /* In the parent process, we send the child pidref to the manager and exit.
2490
                 * If PIDFD is not supported, only the child PID is sent. The server then
2491
                 * uses the child PID to set the new exec main process. */
2492
                q = send_one_fd_iov(
7✔
2493
                                p->pidref_transport_fd,
2494
                                pidref.fd,
2495
                                &IOVEC_MAKE(&pidref.pid, sizeof(pidref.pid)),
2496
                                /*iovlen=*/ 1,
2497
                                /*flags=*/ 0);
2498
                /* Send error code to child process. */
2499
                (void) write(errno_pipe[1], &q, sizeof(q));
7✔
2500
                /* Exit here so we only go through the destructors in exec_invoke only once - in the child - as
2501
                 * some destructors have external effects. The main codepaths continue in the child process. */
2502
                _exit(q < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
7✔
2503
        }
2504

2505
        errno_pipe[1] = safe_close(errno_pipe[1]);
6✔
2506
        p->pidref_transport_fd = safe_close(p->pidref_transport_fd);
6✔
2507

2508
        /* Try to read an error code from the parent. Note a child process cannot wait for the parent so we always
2509
         * receive an errno even on success. */
2510
        n = read(errno_pipe[0], &r, sizeof(r));
6✔
2511
        if (n < 0)
6✔
2512
                return log_exec_debug_errno(c, p, errno, "Failed to read errno from pipe with parent process: %m");
×
2513
        if (n != sizeof(r))
6✔
2514
                return log_exec_debug_errno(c, p, SYNTHETIC_ERRNO(EIO), "Failed to read enough bytes from pipe with parent process");
×
2515
        if (r < 0)
6✔
2516
                return log_exec_debug_errno(c, p, r, "Failed to send child pidref to manager: %m");
×
2517

2518
        /* NOTE! This function returns in the child process only. */
2519
        return r;
2520
}
2521

2522
static int create_many_symlinks(const char *root, const char *source, char **symlinks) {
1,626✔
2523
        _cleanup_free_ char *src_abs = NULL;
1,626✔
2524
        int r;
1,626✔
2525

2526
        assert(source);
1,626✔
2527

2528
        src_abs = path_join(root, source);
1,626✔
2529
        if (!src_abs)
1,626✔
2530
                return -ENOMEM;
2531

2532
        STRV_FOREACH(dst, symlinks) {
1,639✔
2533
                _cleanup_free_ char *dst_abs = NULL;
13✔
2534

2535
                dst_abs = path_join(root, *dst);
13✔
2536
                if (!dst_abs)
13✔
2537
                        return -ENOMEM;
2538

2539
                r = mkdir_parents_label(dst_abs, 0755);
13✔
2540
                if (r < 0)
13✔
2541
                        return r;
2542

2543
                r = symlink_idempotent(src_abs, dst_abs, true);
13✔
2544
                if (r < 0)
13✔
2545
                        return r;
2546
        }
2547

2548
        return 0;
2549
}
2550

2551
static int setup_exec_directory(
66,926✔
2552
                const ExecContext *context,
2553
                const ExecParameters *params,
2554
                uid_t uid,
2555
                gid_t gid,
2556
                ExecDirectoryType type,
2557
                bool needs_mount_namespace,
2558
                int *exit_status) {
2559

2560
        static const int exit_status_table[_EXEC_DIRECTORY_TYPE_MAX] = {
66,926✔
2561
                [EXEC_DIRECTORY_RUNTIME]       = EXIT_RUNTIME_DIRECTORY,
2562
                [EXEC_DIRECTORY_STATE]         = EXIT_STATE_DIRECTORY,
2563
                [EXEC_DIRECTORY_CACHE]         = EXIT_CACHE_DIRECTORY,
2564
                [EXEC_DIRECTORY_LOGS]          = EXIT_LOGS_DIRECTORY,
2565
                [EXEC_DIRECTORY_CONFIGURATION] = EXIT_CONFIGURATION_DIRECTORY,
2566
        };
2567
        int r;
66,926✔
2568

2569
        assert(context);
66,926✔
2570
        assert(params);
66,926✔
2571
        assert(type >= 0 && type < _EXEC_DIRECTORY_TYPE_MAX);
66,926✔
2572
        assert(exit_status);
66,926✔
2573

2574
        if (!params->prefix[type])
66,926✔
2575
                return 0;
2576

2577
        if (params->flags & EXEC_CHOWN_DIRECTORIES) {
66,926✔
2578
                if (!uid_is_valid(uid))
63,761✔
2579
                        uid = 0;
50,731✔
2580
                if (!gid_is_valid(gid))
63,761✔
2581
                        gid = 0;
50,711✔
2582
        }
2583

2584
        FOREACH_ARRAY(i, context->directories[type].items, context->directories[type].n_items) {
70,910✔
2585
                _cleanup_free_ char *p = NULL, *pp = NULL;
3,985✔
2586

2587
                p = path_join(params->prefix[type], i->path);
3,985✔
2588
                if (!p) {
3,985✔
2589
                        r = -ENOMEM;
×
2590
                        goto fail;
×
2591
                }
2592

2593
                r = mkdir_parents_label(p, 0755);
3,985✔
2594
                if (r < 0)
3,985✔
2595
                        goto fail;
×
2596

2597
                if (IN_SET(type, EXEC_DIRECTORY_STATE, EXEC_DIRECTORY_LOGS) && params->runtime_scope == RUNTIME_SCOPE_USER) {
3,985✔
2598

2599
                        /* If we are in user mode, and a configuration directory exists but a state directory
2600
                         * doesn't exist, then we likely are upgrading from an older systemd version that
2601
                         * didn't know the more recent addition to the xdg-basedir spec: the $XDG_STATE_HOME
2602
                         * directory. In older systemd versions EXEC_DIRECTORY_STATE was aliased to
2603
                         * EXEC_DIRECTORY_CONFIGURATION, with the advent of $XDG_STATE_HOME it is now
2604
                         * separated. If a service has both dirs configured but only the configuration dir
2605
                         * exists and the state dir does not, we assume we are looking at an update
2606
                         * situation. Hence, create a compatibility symlink, so that all expectations are
2607
                         * met.
2608
                         *
2609
                         * (We also do something similar with the log directory, which still doesn't exist in
2610
                         * the xdg basedir spec. We'll make it a subdir of the state dir.) */
2611

2612
                        /* this assumes the state dir is always created before the configuration dir */
2613
                        assert_cc(EXEC_DIRECTORY_STATE < EXEC_DIRECTORY_LOGS);
7✔
2614
                        assert_cc(EXEC_DIRECTORY_LOGS < EXEC_DIRECTORY_CONFIGURATION);
7✔
2615

2616
                        r = access_nofollow(p, F_OK);
7✔
2617
                        if (r == -ENOENT) {
3✔
2618
                                _cleanup_free_ char *q = NULL;
3✔
2619

2620
                                /* OK, we know that the state dir does not exist. Let's see if the dir exists
2621
                                 * under the configuration hierarchy. */
2622

2623
                                if (type == EXEC_DIRECTORY_STATE)
3✔
2624
                                        q = path_join(params->prefix[EXEC_DIRECTORY_CONFIGURATION], i->path);
3✔
2625
                                else if (type == EXEC_DIRECTORY_LOGS)
×
2626
                                        q = path_join(params->prefix[EXEC_DIRECTORY_CONFIGURATION], "log", i->path);
×
2627
                                else
2628
                                        assert_not_reached();
×
2629
                                if (!q) {
3✔
2630
                                        r = -ENOMEM;
×
2631
                                        goto fail;
×
2632
                                }
2633

2634
                                r = access_nofollow(q, F_OK);
3✔
2635
                                if (r >= 0) {
2✔
2636
                                        /* It does exist! This hence looks like an update. Symlink the
2637
                                         * configuration directory into the state directory. */
2638

2639
                                        r = symlink_idempotent(q, p, /* make_relative= */ true);
1✔
2640
                                        if (r < 0)
1✔
2641
                                                goto fail;
×
2642

2643
                                        log_exec_notice(context, params, "Unit state directory %s missing but matching configuration directory %s exists, assuming update from systemd 253 or older, creating compatibility symlink.", p, q);
1✔
2644
                                        continue;
1✔
2645
                                } else if (r != -ENOENT)
2✔
2646
                                        log_exec_warning_errno(context, params, r, "Unable to detect whether unit configuration directory '%s' exists, assuming not: %m", q);
×
2647

2648
                        } else if (r < 0)
4✔
2649
                                log_exec_warning_errno(context, params, r, "Unable to detect whether unit state directory '%s' is missing, assuming it is: %m", p);
×
2650
                }
2651

2652
                if (exec_directory_is_private(context, type)) {
3,984✔
2653
                        /* So, here's one extra complication when dealing with DynamicUser=1 units. In that
2654
                         * case we want to avoid leaving a directory around fully accessible that is owned by
2655
                         * a dynamic user whose UID is later on reused. To lock this down we use the same
2656
                         * trick used by container managers to prohibit host users to get access to files of
2657
                         * the same UID in containers: we place everything inside a directory that has an
2658
                         * access mode of 0700 and is owned root:root, so that it acts as security boundary
2659
                         * for unprivileged host code. We then use fs namespacing to make this directory
2660
                         * permeable for the service itself.
2661
                         *
2662
                         * Specifically: for a service which wants a special directory "foo/" we first create
2663
                         * a directory "private/" with access mode 0700 owned by root:root. Then we place
2664
                         * "foo" inside of that directory (i.e. "private/foo/"), and make "foo" a symlink to
2665
                         * "private/foo". This way, privileged host users can access "foo/" as usual, but
2666
                         * unprivileged host users can't look into it. Inside of the namespace of the unit
2667
                         * "private/" is replaced by a more liberally accessible tmpfs, into which the host's
2668
                         * "private/foo/" is mounted under the same name, thus disabling the access boundary
2669
                         * for the service and making sure it only gets access to the dirs it needs but no
2670
                         * others. Tricky? Yes, absolutely, but it works!
2671
                         *
2672
                         * Note that we don't do this for EXEC_DIRECTORY_CONFIGURATION as that's assumed not
2673
                         * to be owned by the service itself.
2674
                         *
2675
                         * Also, note that we don't do this for EXEC_DIRECTORY_RUNTIME as that's often used
2676
                         * for sharing files or sockets with other services. */
2677

2678
                        pp = path_join(params->prefix[type], "private");
8✔
2679
                        if (!pp) {
8✔
2680
                                r = -ENOMEM;
×
2681
                                goto fail;
×
2682
                        }
2683

2684
                        /* First set up private root if it doesn't exist yet, with access mode 0700 and owned by root:root */
2685
                        r = mkdir_safe_label(pp, 0700, 0, 0, MKDIR_WARN_MODE);
8✔
2686
                        if (r < 0)
8✔
2687
                                goto fail;
×
2688

2689
                        if (!path_extend(&pp, i->path)) {
8✔
2690
                                r = -ENOMEM;
×
2691
                                goto fail;
×
2692
                        }
2693

2694
                        /* Create all directories between the configured directory and this private root, and mark them 0755 */
2695
                        r = mkdir_parents_label(pp, 0755);
8✔
2696
                        if (r < 0)
8✔
2697
                                goto fail;
×
2698

2699
                        if (is_dir(p, false) > 0 &&
8✔
2700
                            (access_nofollow(pp, F_OK) == -ENOENT)) {
×
2701

2702
                                /* Hmm, the private directory doesn't exist yet, but the normal one exists? If so, move
2703
                                 * it over. Most likely the service has been upgraded from one that didn't use
2704
                                 * DynamicUser=1, to one that does. */
2705

2706
                                log_exec_info(context,
×
2707
                                              params,
2708
                                              "Found pre-existing public %s= directory %s, migrating to %s.\n"
2709
                                              "Apparently, service previously had DynamicUser= turned off, and has now turned it on.",
2710
                                              exec_directory_type_to_string(type), p, pp);
2711

2712
                                r = RET_NERRNO(rename(p, pp));
×
2713
                                if (r < 0)
×
2714
                                        goto fail;
×
2715
                        } else {
2716
                                /* Otherwise, create the actual directory for the service */
2717

2718
                                r = mkdir_label(pp, context->directories[type].mode);
8✔
2719
                                if (r < 0 && r != -EEXIST)
8✔
2720
                                        goto fail;
×
2721
                        }
2722

2723
                        if (!FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE)) {
8✔
2724
                                /* And link it up from the original place.
2725
                                 * Notes
2726
                                 * 1) If a mount namespace is going to be used, then this symlink remains on
2727
                                 *    the host, and a new one for the child namespace will be created later.
2728
                                 * 2) It is not necessary to create this symlink when one of its parent
2729
                                 *    directories is specified and already created. E.g.
2730
                                 *        StateDirectory=foo foo/bar
2731
                                 *    In that case, the inode points to pp and p for "foo/bar" are the same:
2732
                                 *        pp = "/var/lib/private/foo/bar"
2733
                                 *        p = "/var/lib/foo/bar"
2734
                                 *    and, /var/lib/foo is a symlink to /var/lib/private/foo. So, not only
2735
                                 *    we do not need to create the symlink, but we cannot create the symlink.
2736
                                 *    See issue #24783. */
2737
                                r = symlink_idempotent(pp, p, true);
8✔
2738
                                if (r < 0)
8✔
2739
                                        goto fail;
×
2740
                        }
2741

2742
                } else {
2743
                        _cleanup_free_ char *target = NULL;
3,976✔
2744

2745
                        if (EXEC_DIRECTORY_TYPE_SHALL_CHOWN(type) &&
7,912✔
2746
                            readlink_and_make_absolute(p, &target) >= 0) {
3,936✔
2747
                                _cleanup_free_ char *q = NULL, *q_resolved = NULL, *target_resolved = NULL;
11✔
2748

2749
                                /* This already exists and is a symlink? Interesting. Maybe it's one created
2750
                                 * by DynamicUser=1 (see above)?
2751
                                 *
2752
                                 * We do this for all directory types except for ConfigurationDirectory=,
2753
                                 * since they all support the private/ symlink logic at least in some
2754
                                 * configurations, see above. */
2755

2756
                                r = chase(target, NULL, 0, &target_resolved, NULL);
11✔
2757
                                if (r < 0)
11✔
2758
                                        goto fail;
×
2759

2760
                                q = path_join(params->prefix[type], "private", i->path);
11✔
2761
                                if (!q) {
11✔
2762
                                        r = -ENOMEM;
×
2763
                                        goto fail;
×
2764
                                }
2765

2766
                                /* /var/lib or friends may be symlinks. So, let's chase them also. */
2767
                                r = chase(q, NULL, CHASE_NONEXISTENT, &q_resolved, NULL);
11✔
2768
                                if (r < 0)
11✔
2769
                                        goto fail;
×
2770

2771
                                if (path_equal(q_resolved, target_resolved)) {
11✔
2772

2773
                                        /* Hmm, apparently DynamicUser= was once turned on for this service,
2774
                                         * but is no longer. Let's move the directory back up. */
2775

2776
                                        log_exec_info(context,
24✔
2777
                                                      params,
2778
                                                      "Found pre-existing private %s= directory %s, migrating to %s.\n"
2779
                                                      "Apparently, service previously had DynamicUser= turned on, and has now turned it off.",
2780
                                                      exec_directory_type_to_string(type), q, p);
2781

2782
                                        r = RET_NERRNO(unlink(p));
8✔
2783
                                        if (r < 0)
×
2784
                                                goto fail;
×
2785

2786
                                        r = RET_NERRNO(rename(q, p));
11✔
2787
                                        if (r < 0)
×
2788
                                                goto fail;
×
2789
                                }
2790
                        }
2791

2792
                        r = mkdir_label(p, context->directories[type].mode);
3,976✔
2793
                        if (r < 0) {
3,976✔
2794
                                if (r != -EEXIST)
2,648✔
2795
                                        goto fail;
×
2796

2797
                                if (!EXEC_DIRECTORY_TYPE_SHALL_CHOWN(type)) {
2,648✔
2798
                                        struct stat st;
27✔
2799

2800
                                        /* Don't change the owner/access mode of the configuration directory,
2801
                                         * as in the common case it is not written to by a service, and shall
2802
                                         * not be writable. */
2803

2804
                                        r = RET_NERRNO(stat(p, &st));
27✔
2805
                                        if (r < 0)
×
2806
                                                goto fail;
×
2807

2808
                                        /* Still complain if the access mode doesn't match */
2809
                                        if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0)
27✔
2810
                                                log_exec_warning(context,
×
2811
                                                                 params,
2812
                                                                 "%s \'%s\' already exists but the mode is different. "
2813
                                                                 "(File system: %o %sMode: %o)",
2814
                                                                 exec_directory_type_to_string(type), i->path,
2815
                                                                 st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777);
2816

2817
                                        continue;
27✔
2818
                                }
2819
                        }
2820
                }
2821

2822
                /* Lock down the access mode (we use chmod_and_chown() to make this idempotent. We don't
2823
                 * specify UID/GID here, so that path_chown_recursive() can optimize things depending on the
2824
                 * current UID/GID ownership.) */
2825
                const char *target_dir = pp ?: p;
3,957✔
2826
                r = chmod_and_chown(target_dir, context->directories[type].mode, UID_INVALID, GID_INVALID);
3,957✔
2827
                if (r < 0)
3,957✔
2828
                        goto fail;
×
2829

2830
                /* Skip the rest (which deals with ownership) in user mode, since ownership changes are not
2831
                 * available to user code anyway */
2832
                if (params->runtime_scope != RUNTIME_SCOPE_SYSTEM)
3,957✔
2833
                        continue;
9✔
2834

2835
                int idmapping_supported = is_idmapping_supported(target_dir);
3,948✔
2836
                if (idmapping_supported < 0) {
3,948✔
2837
                        r = log_debug_errno(idmapping_supported, "Unable to determine if ID mapping is supported on mount '%s': %m", target_dir);
×
2838
                        goto fail;
×
2839
                }
2840

2841
                log_debug("ID-mapping is%ssupported for exec directory %s", idmapping_supported ? " " : " not ", target_dir);
4,007✔
2842

2843
                /* Change the ownership of the whole tree, if necessary. When dynamic users are used we
2844
                 * drop the suid/sgid bits, since we really don't want SUID/SGID files for dynamic UID/GID
2845
                 * assignments to exist. */
2846
                uid_t chown_uid = uid;
3,948✔
2847
                gid_t chown_gid = gid;
3,948✔
2848
                bool do_chown = false;
3,948✔
2849

2850
                if (uid == 0 || gid == 0 || !idmapping_supported) {
3,948✔
2851
                        do_chown = true;
1,592✔
2852
                        i->idmapped = false;
1,592✔
2853
                } else {
2854
                        /* Use 'nobody' uid/gid for exec directories if ID-mapping is supported. For backward compatibility,
2855
                         * continue doing chmod/chown if the directory was chmod/chowned before (if uid/gid is not 'nobody') */
2856
                        struct stat st;
2,356✔
2857
                        r = RET_NERRNO(stat(target_dir, &st));
2,356✔
2858
                        if (r < 0)
×
2859
                                goto fail;
×
2860

2861
                        if (st.st_uid == UID_NOBODY && st.st_gid == GID_NOBODY) {
2,356✔
2862
                                do_chown = false;
2✔
2863
                                i->idmapped = true;
2✔
2864
                       } else if (exec_directory_is_private(context, type) && st.st_uid == 0 && st.st_gid == 0) {
2,354✔
2865
                                chown_uid = UID_NOBODY;
6✔
2866
                                chown_gid = GID_NOBODY;
6✔
2867
                                do_chown = true;
6✔
2868
                                i->idmapped = true;
6✔
2869
                        } else {
2870
                                do_chown = true;
2,348✔
2871
                                i->idmapped = false;
2,348✔
2872
                        }
2873
                }
2874

2875
                if (do_chown) {
3,948✔
2876
                        r = path_chown_recursive(target_dir, chown_uid, chown_gid, context->dynamic_user ? 01777 : 07777, AT_SYMLINK_FOLLOW);
7,883✔
2877
                        if (r < 0)
3,946✔
2878
                                goto fail;
1✔
2879
                }
2880
        }
2881

2882
        /* If we are not going to run in a namespace, set up the symlinks - otherwise
2883
         * they are set up later, to allow configuring empty var/run/etc. */
2884
        if (!needs_mount_namespace)
66,925✔
2885
                FOREACH_ARRAY(i, context->directories[type].items, context->directories[type].n_items) {
52,541✔
2886
                        r = create_many_symlinks(params->prefix[type], i->path, i->symlinks);
1,626✔
2887
                        if (r < 0)
1,626✔
2888
                                goto fail;
×
2889
                }
2890

2891
        return 0;
2892

2893
fail:
1✔
2894
        *exit_status = exit_status_table[type];
1✔
2895
        return r;
1✔
2896
}
2897

2898
#if ENABLE_SMACK
2899
static int setup_smack(
×
2900
                const ExecParameters *params,
2901
                const ExecContext *context,
2902
                int executable_fd) {
2903
        int r;
×
2904

2905
        assert(params);
×
2906
        assert(executable_fd >= 0);
×
2907

2908
        if (context->smack_process_label) {
×
2909
                r = mac_smack_apply_pid(0, context->smack_process_label);
×
2910
                if (r < 0)
×
2911
                        return r;
×
2912
        } else if (params->fallback_smack_process_label) {
×
2913
                _cleanup_free_ char *exec_label = NULL;
×
2914

2915
                r = mac_smack_read_fd(executable_fd, SMACK_ATTR_EXEC, &exec_label);
×
2916
                if (r < 0 && !ERRNO_IS_XATTR_ABSENT(r))
×
2917
                        return r;
2918

2919
                r = mac_smack_apply_pid(0, exec_label ?: params->fallback_smack_process_label);
×
2920
                if (r < 0)
×
2921
                        return r;
2922
        }
2923

2924
        return 0;
2925
}
2926
#endif
2927

2928
static int compile_bind_mounts(
2,538✔
2929
                const ExecContext *context,
2930
                const ExecParameters *params,
2931
                uid_t exec_directory_uid, /* only used for id-mapped mounts Exec directories */
2932
                gid_t exec_directory_gid, /* only used for id-mapped mounts Exec directories */
2933
                BindMount **ret_bind_mounts,
2934
                size_t *ret_n_bind_mounts,
2935
                char ***ret_empty_directories) {
2936

2937
        _cleanup_strv_free_ char **empty_directories = NULL;
2,538✔
2938
        BindMount *bind_mounts = NULL;
2,538✔
2939
        size_t n, h = 0;
2,538✔
2940
        int r;
2,538✔
2941

2942
        assert(context);
2,538✔
2943
        assert(params);
2,538✔
2944
        assert(ret_bind_mounts);
2,538✔
2945
        assert(ret_n_bind_mounts);
2,538✔
2946
        assert(ret_empty_directories);
2,538✔
2947

2948
        CLEANUP_ARRAY(bind_mounts, h, bind_mount_free_many);
2,538✔
2949

2950
        n = context->n_bind_mounts;
2,538✔
2951
        for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
15,228✔
2952
                if (!params->prefix[t])
12,690✔
2953
                        continue;
×
2954

2955
                FOREACH_ARRAY(i, context->directories[t].items, context->directories[t].n_items)
14,419✔
2956
                        n += !FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE) || FLAGS_SET(i->flags, EXEC_DIRECTORY_READ_ONLY);
1,729✔
2957
        }
2958

2959
        if (n <= 0) {
2,538✔
2960
                *ret_bind_mounts = NULL;
1,529✔
2961
                *ret_n_bind_mounts = 0;
1,529✔
2962
                *ret_empty_directories = NULL;
1,529✔
2963
                return 0;
1,529✔
2964
        }
2965

2966
        bind_mounts = new(BindMount, n);
1,009✔
2967
        if (!bind_mounts)
1,009✔
2968
                return -ENOMEM;
2969

2970
        FOREACH_ARRAY(item, context->bind_mounts, context->n_bind_mounts) {
1,029✔
2971
                r = bind_mount_add(&bind_mounts, &h, item);
20✔
2972
                if (r < 0)
20✔
2973
                        return r;
2974
        }
2975

2976
        for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
6,054✔
2977
                if (!params->prefix[t])
5,045✔
2978
                        continue;
×
2979

2980
                if (context->directories[t].n_items == 0)
5,045✔
2981
                        continue;
3,772✔
2982

2983
                if (exec_directory_is_private(context, t) &&
1,281✔
2984
                    !exec_context_with_rootfs(context)) {
8✔
2985
                        char *private_root;
8✔
2986

2987
                        /* So this is for a dynamic user, and we need to make sure the process can access its own
2988
                         * directory. For that we overmount the usually inaccessible "private" subdirectory with a
2989
                         * tmpfs that makes it accessible and is empty except for the submounts we do this for. */
2990

2991
                        private_root = path_join(params->prefix[t], "private");
8✔
2992
                        if (!private_root)
8✔
2993
                                return -ENOMEM;
2994

2995
                        r = strv_consume(&empty_directories, private_root);
8✔
2996
                        if (r < 0)
8✔
2997
                                return r;
2998
                }
2999

3000
                FOREACH_ARRAY(i, context->directories[t].items, context->directories[t].n_items) {
3,002✔
3001
                        _cleanup_free_ char *s = NULL, *d = NULL;
1,729✔
3002

3003
                        /* When one of the parent directories is in the list, we cannot create the symlink
3004
                         * for the child directory. See also the comments in setup_exec_directory().
3005
                         * But if it needs to be read only, then we have to create a bind mount anyway to
3006
                         * make it so. */
3007
                        if (FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE) && !FLAGS_SET(i->flags, EXEC_DIRECTORY_READ_ONLY))
1,729✔
3008
                                continue;
×
3009

3010
                        if (exec_directory_is_private(context, t))
1,729✔
3011
                                s = path_join(params->prefix[t], "private", i->path);
8✔
3012
                        else
3013
                                s = path_join(params->prefix[t], i->path);
1,721✔
3014
                        if (!s)
1,729✔
3015
                                return -ENOMEM;
3016

3017
                        if (exec_directory_is_private(context, t) &&
1,737✔
3018
                            exec_context_with_rootfs(context))
8✔
3019
                                /* When RootDirectory= or RootImage= are set, then the symbolic link to the private
3020
                                 * directory is not created on the root directory. So, let's bind-mount the directory
3021
                                 * on the 'non-private' place. */
3022
                                d = path_join(params->prefix[t], i->path);
×
3023
                        else
3024
                                d = strdup(s);
1,729✔
3025
                        if (!d)
1,729✔
3026
                                return -ENOMEM;
3027

3028
                        bind_mounts[h++] = (BindMount) {
1,729✔
3029
                                .source = TAKE_PTR(s),
1,729✔
3030
                                .destination = TAKE_PTR(d),
1,729✔
3031
                                .nosuid = context->dynamic_user, /* don't allow suid/sgid when DynamicUser= is on */
1,729✔
3032
                                .recursive = true,
3033
                                .read_only = FLAGS_SET(i->flags, EXEC_DIRECTORY_READ_ONLY),
1,729✔
3034
                                .idmapped = i->idmapped,
1,729✔
3035
                                .uid = exec_directory_uid,
3036
                                .gid = exec_directory_gid,
3037
                        };
3038
                }
3039
        }
3040

3041
        assert(h == n);
1,009✔
3042

3043
        *ret_bind_mounts = TAKE_PTR(bind_mounts);
1,009✔
3044
        *ret_n_bind_mounts = n;
1,009✔
3045
        *ret_empty_directories = TAKE_PTR(empty_directories);
1,009✔
3046

3047
        return (int) n;
1,009✔
3048
}
3049

3050
/* ret_symlinks will contain a list of pairs src:dest that describes
3051
 * the symlinks to create later on. For example, the symlinks needed
3052
 * to safely give private directories to DynamicUser=1 users. */
3053
static int compile_symlinks(
2,538✔
3054
                const ExecContext *context,
3055
                const ExecParameters *params,
3056
                bool setup_os_release_symlink,
3057
                char ***ret_symlinks) {
3058

3059
        _cleanup_strv_free_ char **symlinks = NULL;
2,538✔
3060
        int r;
2,538✔
3061

3062
        assert(context);
2,538✔
3063
        assert(params);
2,538✔
3064
        assert(ret_symlinks);
2,538✔
3065

3066
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++)
15,228✔
3067
                FOREACH_ARRAY(i, context->directories[dt].items, context->directories[dt].n_items) {
14,419✔
3068
                        _cleanup_free_ char *private_path = NULL, *path = NULL;
1,721✔
3069

3070
                        STRV_FOREACH(symlink, i->symlinks) {
1,855✔
3071
                                _cleanup_free_ char *src_abs = NULL, *dst_abs = NULL;
126✔
3072

3073
                                src_abs = path_join(params->prefix[dt], i->path);
126✔
3074
                                dst_abs = path_join(params->prefix[dt], *symlink);
126✔
3075
                                if (!src_abs || !dst_abs)
126✔
3076
                                        return -ENOMEM;
3077

3078
                                r = strv_consume_pair(&symlinks, TAKE_PTR(src_abs), TAKE_PTR(dst_abs));
126✔
3079
                                if (r < 0)
126✔
3080
                                        return r;
3081
                        }
3082

3083
                        if (!exec_directory_is_private(context, dt) ||
1,737✔
3084
                            exec_context_with_rootfs(context) ||
8✔
3085
                            FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE))
8✔
3086
                                continue;
1,721✔
3087

3088
                        private_path = path_join(params->prefix[dt], "private", i->path);
8✔
3089
                        if (!private_path)
8✔
3090
                                return -ENOMEM;
3091

3092
                        path = path_join(params->prefix[dt], i->path);
8✔
3093
                        if (!path)
8✔
3094
                                return -ENOMEM;
3095

3096
                        r = strv_consume_pair(&symlinks, TAKE_PTR(private_path), TAKE_PTR(path));
8✔
3097
                        if (r < 0)
8✔
3098
                                return r;
3099
                }
3100

3101
        /* We make the host's os-release available via a symlink, so that we can copy it atomically
3102
         * and readers will never get a half-written version. Note that, while the paths specified here are
3103
         * absolute, when they are processed in namespace.c they will be made relative automatically, i.e.:
3104
         * 'os-release -> .os-release-stage/os-release' is what will be created. */
3105
        if (setup_os_release_symlink) {
2,538✔
3106
                r = strv_extend_many(
7✔
3107
                                &symlinks,
3108
                                "/run/host/.os-release-stage/os-release",
3109
                                "/run/host/os-release");
3110
                if (r < 0)
7✔
3111
                        return r;
3112
        }
3113

3114
        *ret_symlinks = TAKE_PTR(symlinks);
2,538✔
3115

3116
        return 0;
2,538✔
3117
}
3118

3119
static bool insist_on_sandboxing(
×
3120
                const ExecContext *context,
3121
                const char *root_dir,
3122
                const char *root_image,
3123
                const BindMount *bind_mounts,
3124
                size_t n_bind_mounts) {
3125

3126
        assert(context);
×
3127
        assert(n_bind_mounts == 0 || bind_mounts);
×
3128

3129
        /* Checks whether we need to insist on fs namespacing. i.e. whether we have settings configured that
3130
         * would alter the view on the file system beyond making things read-only or invisible, i.e. would
3131
         * rearrange stuff in a way we cannot ignore gracefully. */
3132

3133
        if (context->n_temporary_filesystems > 0)
×
3134
                return true;
3135

3136
        if (root_dir || root_image)
×
3137
                return true;
3138

3139
        if (context->n_mount_images > 0)
×
3140
                return true;
3141

3142
        if (context->dynamic_user)
×
3143
                return true;
3144

3145
        if (context->n_extension_images > 0 || !strv_isempty(context->extension_directories))
×
3146
                return true;
3147

3148
        /* If there are any bind mounts set that don't map back onto themselves, fs namespacing becomes
3149
         * essential. */
3150
        FOREACH_ARRAY(i, bind_mounts, n_bind_mounts)
×
3151
                if (!path_equal(i->source, i->destination))
×
3152
                        return true;
3153

3154
        if (context->log_namespace)
×
3155
                return true;
×
3156

3157
        return false;
3158
}
3159

3160
static int setup_ephemeral(
2,538✔
3161
                const ExecContext *context,
3162
                ExecRuntime *runtime,
3163
                char **root_image,            /* both input and output! modified if ephemeral logic enabled */
3164
                char **root_directory,        /* ditto */
3165
                char **reterr_path) {
3166

3167
        _cleanup_close_ int fd = -EBADF;
2,538✔
3168
        _cleanup_free_ char *new_root = NULL;
2,538✔
3169
        int r;
2,538✔
3170

3171
        assert(context);
2,538✔
3172
        assert(root_image);
2,538✔
3173
        assert(root_directory);
2,538✔
3174

3175
        if (!*root_image && !*root_directory)
2,538✔
3176
                return 0;
3177

3178
        if (!runtime || !runtime->ephemeral_copy)
8✔
3179
                return 0;
3180

3181
        assert(runtime->ephemeral_storage_socket[0] >= 0);
×
3182
        assert(runtime->ephemeral_storage_socket[1] >= 0);
×
3183

3184
        new_root = strdup(runtime->ephemeral_copy);
×
3185
        if (!new_root)
×
3186
                return log_oom_debug();
×
3187

3188
        r = posix_lock(runtime->ephemeral_storage_socket[0], LOCK_EX);
×
3189
        if (r < 0)
×
3190
                return log_debug_errno(r, "Failed to lock ephemeral storage socket: %m");
×
3191

3192
        CLEANUP_POSIX_UNLOCK(runtime->ephemeral_storage_socket[0]);
×
3193

3194
        fd = receive_one_fd(runtime->ephemeral_storage_socket[0], MSG_PEEK|MSG_DONTWAIT);
×
3195
        if (fd >= 0)
×
3196
                /* We got an fd! That means ephemeral has already been set up, so nothing to do here. */
3197
                return 0;
3198
        if (fd != -EAGAIN)
×
3199
                return log_debug_errno(fd, "Failed to receive file descriptor queued on ephemeral storage socket: %m");
×
3200

3201
        if (*root_image) {
×
3202
                log_debug("Making ephemeral copy of %s to %s", *root_image, new_root);
×
3203

3204
                fd = copy_file(*root_image, new_root, O_EXCL, 0600,
×
3205
                               COPY_LOCK_BSD|COPY_REFLINK|COPY_CRTIME|COPY_NOCOW_AFTER);
3206
                if (fd < 0) {
×
3207
                        *reterr_path = strdup(*root_image);
×
3208
                        return log_debug_errno(fd, "Failed to copy image %s to %s: %m",
×
3209
                                               *root_image, new_root);
3210
                }
3211
        } else {
3212
                assert(*root_directory);
×
3213

3214
                log_debug("Making ephemeral snapshot of %s to %s", *root_directory, new_root);
×
3215

3216
                fd = btrfs_subvol_snapshot_at(
×
3217
                                AT_FDCWD, *root_directory,
3218
                                AT_FDCWD, new_root,
3219
                                BTRFS_SNAPSHOT_FALLBACK_COPY |
3220
                                BTRFS_SNAPSHOT_FALLBACK_DIRECTORY |
3221
                                BTRFS_SNAPSHOT_RECURSIVE |
3222
                                BTRFS_SNAPSHOT_LOCK_BSD);
3223
                if (fd < 0) {
×
3224
                        *reterr_path = strdup(*root_directory);
×
3225
                        return log_debug_errno(fd, "Failed to snapshot directory %s to %s: %m",
×
3226
                                               *root_directory, new_root);
3227
                }
3228
        }
3229

3230
        r = send_one_fd(runtime->ephemeral_storage_socket[1], fd, MSG_DONTWAIT);
×
3231
        if (r < 0)
×
3232
                return log_debug_errno(r, "Failed to queue file descriptor on ephemeral storage socket: %m");
×
3233

3234
        if (*root_image)
×
3235
                free_and_replace(*root_image, new_root);
×
3236
        else {
3237
                assert(*root_directory);
×
3238
                free_and_replace(*root_directory, new_root);
×
3239
        }
3240

3241
        return 1;
3242
}
3243

3244
static int verity_settings_prepare(
7✔
3245
                VeritySettings *verity,
3246
                const char *root_image,
3247
                const void *root_hash,
3248
                size_t root_hash_size,
3249
                const char *root_hash_path,
3250
                const void *root_hash_sig,
3251
                size_t root_hash_sig_size,
3252
                const char *root_hash_sig_path,
3253
                const char *verity_data_path) {
3254

3255
        int r;
7✔
3256

3257
        assert(verity);
7✔
3258

3259
        if (root_hash) {
7✔
3260
                void *d;
4✔
3261

3262
                d = memdup(root_hash, root_hash_size);
4✔
3263
                if (!d)
4✔
3264
                        return -ENOMEM;
7✔
3265

3266
                free_and_replace(verity->root_hash, d);
4✔
3267
                verity->root_hash_size = root_hash_size;
4✔
3268
                verity->designator = PARTITION_ROOT;
4✔
3269
        }
3270

3271
        if (root_hash_sig) {
7✔
3272
                void *d;
×
3273

3274
                d = memdup(root_hash_sig, root_hash_sig_size);
×
3275
                if (!d)
×
3276
                        return -ENOMEM;
7✔
3277

3278
                free_and_replace(verity->root_hash_sig, d);
×
3279
                verity->root_hash_sig_size = root_hash_sig_size;
×
3280
                verity->designator = PARTITION_ROOT;
×
3281
        }
3282

3283
        if (verity_data_path) {
7✔
3284
                r = free_and_strdup(&verity->data_path, verity_data_path);
×
3285
                if (r < 0)
×
3286
                        return r;
3287
        }
3288

3289
        r = verity_settings_load(
7✔
3290
                        verity,
3291
                        root_image,
3292
                        root_hash_path,
3293
                        root_hash_sig_path);
3294
        if (r < 0)
7✔
3295
                return log_debug_errno(r, "Failed to load root hash: %m");
×
3296

3297
        return 0;
3298
}
3299

3300
static int pick_versions(
2,540✔
3301
                const ExecContext *context,
3302
                const ExecParameters *params,
3303
                char **ret_root_image,
3304
                char **ret_root_directory,
3305
                char **reterr_path) {
3306

3307
        int r;
2,540✔
3308

3309
        assert(context);
2,540✔
3310
        assert(params);
2,540✔
3311
        assert(ret_root_image);
2,540✔
3312
        assert(ret_root_directory);
2,540✔
3313

3314
        if (context->root_image) {
2,540✔
3315
                _cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
8✔
3316

3317
                r = path_pick(/* toplevel_path= */ NULL,
16✔
3318
                              /* toplevel_fd= */ AT_FDCWD,
3319
                              context->root_image,
8✔
3320
                              &pick_filter_image_raw,
3321
                              PICK_ARCHITECTURE|PICK_TRIES|PICK_RESOLVE,
3322
                              &result);
3323
                if (r < 0) {
8✔
3324
                        *reterr_path = strdup(context->root_image);
1✔
3325
                        return r;
1✔
3326
                }
3327

3328
                if (!result.path) {
7✔
3329
                        *reterr_path = strdup(context->root_image);
×
3330
                        return log_exec_debug_errno(context, params, SYNTHETIC_ERRNO(ENOENT), "No matching entry in .v/ directory %s found.", context->root_image);
×
3331
                }
3332

3333
                *ret_root_image = TAKE_PTR(result.path);
7✔
3334
                *ret_root_directory = NULL;
7✔
3335
                return r;
7✔
3336
        }
3337

3338
        if (context->root_directory) {
2,532✔
3339
                _cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
2✔
3340

3341
                r = path_pick(/* toplevel_path= */ NULL,
4✔
3342
                              /* toplevel_fd= */ AT_FDCWD,
3343
                              context->root_directory,
2✔
3344
                              &pick_filter_image_dir,
3345
                              PICK_ARCHITECTURE|PICK_TRIES|PICK_RESOLVE,
3346
                              &result);
3347
                if (r < 0) {
2✔
3348
                        *reterr_path = strdup(context->root_directory);
×
3349
                        return r;
×
3350
                }
3351

3352
                if (!result.path) {
2✔
3353
                        *reterr_path = strdup(context->root_directory);
1✔
3354
                        return log_exec_debug_errno(context, params, SYNTHETIC_ERRNO(ENOENT), "No matching entry in .v/ directory %s found.", context->root_directory);
3✔
3355
                }
3356

3357
                *ret_root_image = NULL;
1✔
3358
                *ret_root_directory = TAKE_PTR(result.path);
1✔
3359
                return r;
1✔
3360
        }
3361

3362
        *ret_root_image = *ret_root_directory = NULL;
2,530✔
3363
        return 0;
2,530✔
3364
}
3365

3366
static int apply_mount_namespace(
2,540✔
3367
                ExecCommandFlags command_flags,
3368
                const ExecContext *context,
3369
                const ExecParameters *params,
3370
                ExecRuntime *runtime,
3371
                const char *memory_pressure_path,
3372
                bool needs_sandboxing,
3373
                char **reterr_path,
3374
                uid_t exec_directory_uid,
3375
                gid_t exec_directory_gid) {
3376

3377
        _cleanup_(verity_settings_done) VeritySettings verity = VERITY_SETTINGS_DEFAULT;
2,540✔
3378
        _cleanup_strv_free_ char **empty_directories = NULL, **symlinks = NULL,
2,540✔
3379
                        **read_write_paths_cleanup = NULL;
×
3380
        _cleanup_free_ char *creds_path = NULL, *incoming_dir = NULL, *propagate_dir = NULL,
×
3381
                *private_namespace_dir = NULL, *host_os_release_stage = NULL, *root_image = NULL, *root_dir = NULL;
2,540✔
3382
        const char *tmp_dir = NULL, *var_tmp_dir = NULL;
2,540✔
3383
        char **read_write_paths;
2,540✔
3384
        bool setup_os_release_symlink;
2,540✔
3385
        BindMount *bind_mounts = NULL;
2,540✔
3386
        size_t n_bind_mounts = 0;
2,540✔
3387
        int r;
2,540✔
3388

3389
        assert(context);
2,540✔
3390

3391
        CLEANUP_ARRAY(bind_mounts, n_bind_mounts, bind_mount_free_many);
2,540✔
3392

3393
        if (params->flags & EXEC_APPLY_CHROOT) {
2,540✔
3394
                r = pick_versions(
2,540✔
3395
                                context,
3396
                                params,
3397
                                &root_image,
3398
                                &root_dir,
3399
                                reterr_path);
3400
                if (r < 0)
2,540✔
3401
                        return r;
3402

3403
                r = setup_ephemeral(
2,538✔
3404
                                context,
3405
                                runtime,
3406
                                &root_image,
3407
                                &root_dir,
3408
                                reterr_path);
3409
                if (r < 0)
2,538✔
3410
                        return r;
3411
        }
3412

3413
        r = compile_bind_mounts(context, params, exec_directory_uid, exec_directory_gid, &bind_mounts, &n_bind_mounts, &empty_directories);
2,538✔
3414
        if (r < 0)
2,538✔
3415
                return r;
3416

3417
        /* We need to make the pressure path writable even if /sys/fs/cgroups is made read-only, as the
3418
         * service will need to write to it in order to start the notifications. */
3419
        if (exec_is_cgroup_mount_read_only(context, params) && memory_pressure_path && !streq(memory_pressure_path, "/dev/null")) {
2,538✔
3420
                read_write_paths_cleanup = strv_copy(context->read_write_paths);
1,577✔
3421
                if (!read_write_paths_cleanup)
1,577✔
3422
                        return -ENOMEM;
3423

3424
                r = strv_extend(&read_write_paths_cleanup, memory_pressure_path);
1,577✔
3425
                if (r < 0)
1,577✔
3426
                        return r;
3427

3428
                read_write_paths = read_write_paths_cleanup;
1,577✔
3429
        } else
3430
                read_write_paths = context->read_write_paths;
961✔
3431

3432
        if (needs_sandboxing) {
2,538✔
3433
                /* The runtime struct only contains the parent of the private /tmp, which is non-accessible
3434
                 * to world users. Inside of it there's a /tmp that is sticky, and that's the one we want to
3435
                 * use here.  This does not apply when we are using /run/systemd/empty as fallback. */
3436

3437
                if (context->private_tmp == PRIVATE_TMP_CONNECTED && runtime && runtime->shared) {
2,538✔
3438
                        if (streq_ptr(runtime->shared->tmp_dir, RUN_SYSTEMD_EMPTY))
617✔
3439
                                tmp_dir = runtime->shared->tmp_dir;
3440
                        else if (runtime->shared->tmp_dir)
617✔
3441
                                tmp_dir = strjoina(runtime->shared->tmp_dir, "/tmp");
3,085✔
3442

3443
                        if (streq_ptr(runtime->shared->var_tmp_dir, RUN_SYSTEMD_EMPTY))
617✔
3444
                                var_tmp_dir = runtime->shared->var_tmp_dir;
3445
                        else if (runtime->shared->var_tmp_dir)
617✔
3446
                                var_tmp_dir = strjoina(runtime->shared->var_tmp_dir, "/tmp");
3,085✔
3447
                }
3448
        }
3449

3450
        /* Symlinks (exec dirs, os-release) are set up after other mounts, before they are made read-only. */
3451
        setup_os_release_symlink = needs_sandboxing && exec_context_get_effective_mount_apivfs(context) && (root_dir || root_image);
2,538✔
3452
        r = compile_symlinks(context, params, setup_os_release_symlink, &symlinks);
2,538✔
3453
        if (r < 0)
2,538✔
3454
                return r;
3455

3456
        if (context->mount_propagation_flag == MS_SHARED)
2,538✔
3457
                log_exec_debug(context,
×
3458
                               params,
3459
                               "shared mount propagation hidden by other fs namespacing unit settings: ignoring");
3460

3461
        r = exec_context_get_credential_directory(context, params, params->unit_id, &creds_path);
2,538✔
3462
        if (r < 0)
2,538✔
3463
                return r;
3464

3465
        if (params->runtime_scope == RUNTIME_SCOPE_SYSTEM) {
2,538✔
3466
                propagate_dir = path_join("/run/systemd/propagate/", params->unit_id);
2,515✔
3467
                if (!propagate_dir)
2,515✔
3468
                        return -ENOMEM;
3469

3470
                incoming_dir = strdup("/run/systemd/incoming");
2,515✔
3471
                if (!incoming_dir)
2,515✔
3472
                        return -ENOMEM;
3473

3474
                private_namespace_dir = strdup("/run/systemd");
2,515✔
3475
                if (!private_namespace_dir)
2,515✔
3476
                        return -ENOMEM;
3477

3478
                /* If running under a different root filesystem, propagate the host's os-release. We make a
3479
                 * copy rather than just bind mounting it, so that it can be updated on soft-reboot. */
3480
                if (setup_os_release_symlink) {
2,515✔
3481
                        host_os_release_stage = strdup("/run/systemd/propagate/.os-release-stage");
7✔
3482
                        if (!host_os_release_stage)
7✔
3483
                                return -ENOMEM;
3484
                }
3485
        } else {
3486
                assert(params->runtime_scope == RUNTIME_SCOPE_USER);
23✔
3487

3488
                if (asprintf(&private_namespace_dir, "/run/user/" UID_FMT "/systemd", geteuid()) < 0)
23✔
3489
                        return -ENOMEM;
3490

3491
                if (setup_os_release_symlink) {
23✔
3492
                        if (asprintf(&host_os_release_stage,
×
3493
                                     "/run/user/" UID_FMT "/systemd/propagate/.os-release-stage",
3494
                                     geteuid()) < 0)
3495
                                return -ENOMEM;
3496
                }
3497
        }
3498

3499
        if (root_image) {
2,538✔
3500
                r = verity_settings_prepare(
14✔
3501
                        &verity,
3502
                        root_image,
3503
                        context->root_hash, context->root_hash_size, context->root_hash_path,
7✔
3504
                        context->root_hash_sig, context->root_hash_sig_size, context->root_hash_sig_path,
7✔
3505
                        context->root_verity);
7✔
3506
                if (r < 0)
7✔
3507
                        return r;
3508
        }
3509

3510
        NamespaceParameters parameters = {
×
3511
                .runtime_scope = params->runtime_scope,
2,538✔
3512

3513
                .root_directory = root_dir,
3514
                .root_image = root_image,
3515
                .root_image_options = context->root_image_options,
2,538✔
3516
                .root_image_policy = context->root_image_policy ?: &image_policy_service,
2,538✔
3517

3518
                .read_write_paths = read_write_paths,
3519
                .read_only_paths = needs_sandboxing ? context->read_only_paths : NULL,
2,538✔
3520
                .inaccessible_paths = needs_sandboxing ? context->inaccessible_paths : NULL,
2,538✔
3521

3522
                .exec_paths = needs_sandboxing ? context->exec_paths : NULL,
2,538✔
3523
                .no_exec_paths = needs_sandboxing ? context->no_exec_paths : NULL,
2,538✔
3524

3525
                .empty_directories = empty_directories,
3526
                .symlinks = symlinks,
3527

3528
                .bind_mounts = bind_mounts,
3529
                .n_bind_mounts = n_bind_mounts,
3530

3531
                .temporary_filesystems = context->temporary_filesystems,
2,538✔
3532
                .n_temporary_filesystems = context->n_temporary_filesystems,
2,538✔
3533

3534
                .mount_images = context->mount_images,
2,538✔
3535
                .n_mount_images = context->n_mount_images,
2,538✔
3536
                .mount_image_policy = context->mount_image_policy ?: &image_policy_service,
2,538✔
3537

3538
                .tmp_dir = tmp_dir,
3539
                .var_tmp_dir = var_tmp_dir,
3540

3541
                .creds_path = creds_path,
3542
                .log_namespace = context->log_namespace,
2,538✔
3543
                .mount_propagation_flag = context->mount_propagation_flag,
2,538✔
3544

3545
                .verity = &verity,
3546

3547
                .extension_images = context->extension_images,
2,538✔
3548
                .n_extension_images = context->n_extension_images,
2,538✔
3549
                .extension_image_policy = context->extension_image_policy ?: &image_policy_sysext,
2,538✔
3550
                .extension_directories = context->extension_directories,
2,538✔
3551

3552
                .propagate_dir = propagate_dir,
3553
                .incoming_dir = incoming_dir,
3554
                .private_namespace_dir = private_namespace_dir,
3555
                .host_notify_socket = params->notify_socket,
2,538✔
3556
                .notify_socket_path = exec_get_private_notify_socket_path(context, params, needs_sandboxing),
2,538✔
3557
                .host_os_release_stage = host_os_release_stage,
3558

3559
                /* If DynamicUser=no and RootDirectory= is set then lets pass a relaxed sandbox info,
3560
                 * otherwise enforce it, don't ignore protected paths and fail if we are enable to apply the
3561
                 * sandbox inside the mount namespace. */
3562
                .ignore_protect_paths = !needs_sandboxing && !context->dynamic_user && root_dir,
2,538✔
3563

3564
                .protect_control_groups = needs_sandboxing ? exec_get_protect_control_groups(context, params) : PROTECT_CONTROL_GROUPS_NO,
2,538✔
3565
                .protect_kernel_tunables = needs_sandboxing && context->protect_kernel_tunables,
2,538✔
3566
                .protect_kernel_modules = needs_sandboxing && context->protect_kernel_modules,
2,538✔
3567
                .protect_kernel_logs = needs_sandboxing && context->protect_kernel_logs,
2,538✔
3568

3569
                .private_dev = needs_sandboxing && context->private_devices,
2,538✔
3570
                .private_network = needs_sandboxing && exec_needs_network_namespace(context),
2,538✔
3571
                .private_ipc = needs_sandboxing && exec_needs_ipc_namespace(context),
2,538✔
3572
                .private_pids = needs_sandboxing && exec_needs_pid_namespace(context) ? context->private_pids : PRIVATE_PIDS_NO,
2,538✔
3573
                .private_tmp = needs_sandboxing ? context->private_tmp : PRIVATE_TMP_NO,
2,538✔
3574

3575
                .mount_apivfs = needs_sandboxing && exec_context_get_effective_mount_apivfs(context),
2,538✔
3576
                .bind_log_sockets = needs_sandboxing && exec_context_get_effective_bind_log_sockets(context),
2,538✔
3577

3578
                /* If NNP is on, we can turn on MS_NOSUID, since it won't have any effect anymore. */
3579
                .mount_nosuid = needs_sandboxing && context->no_new_privileges && !mac_selinux_use(),
2,538✔
3580

3581
                .protect_home = needs_sandboxing ? context->protect_home : PROTECT_HOME_NO,
2,538✔
3582
                .protect_hostname = needs_sandboxing ? context->protect_hostname : PROTECT_HOSTNAME_NO,
2,538✔
3583
                .protect_system = needs_sandboxing ? context->protect_system : PROTECT_SYSTEM_NO,
2,538✔
3584
                .protect_proc = needs_sandboxing ? context->protect_proc : PROTECT_PROC_DEFAULT,
2,538✔
3585
                .proc_subset = needs_sandboxing ? context->proc_subset : PROC_SUBSET_ALL,
2,538✔
3586
        };
3587

3588
        r = setup_namespace(&parameters, reterr_path);
2,538✔
3589
        /* If we couldn't set up the namespace this is probably due to a missing capability. setup_namespace() reports
3590
         * that with a special, recognizable error ENOANO. In this case, silently proceed, but only if exclusively
3591
         * sandboxing options were used, i.e. nothing such as RootDirectory= or BindMount= that would result in a
3592
         * completely different execution environment. */
3593
        if (r == -ENOANO) {
2,538✔
3594
                if (insist_on_sandboxing(
×
3595
                                    context,
3596
                                    root_dir, root_image,
3597
                                    bind_mounts,
3598
                                    n_bind_mounts))
3599
                        return log_exec_debug_errno(context,
×
3600
                                                    params,
3601
                                                    SYNTHETIC_ERRNO(EOPNOTSUPP),
3602
                                                    "Failed to set up namespace, and refusing to continue since "
3603
                                                    "the selected namespacing options alter mount environment non-trivially.\n"
3604
                                                    "Bind mounts: %zu, temporary filesystems: %zu, root directory: %s, root image: %s, dynamic user: %s",
3605
                                                    n_bind_mounts,
3606
                                                    context->n_temporary_filesystems,
3607
                                                    yes_no(root_dir),
3608
                                                    yes_no(root_image),
3609
                                                    yes_no(context->dynamic_user));
3610

3611
                log_exec_debug(context, params, "Failed to set up namespace, assuming containerized execution and ignoring.");
×
3612
                return 0;
×
3613
        }
3614

3615
        return r;
3616
}
3617

3618
static int apply_working_directory(
10,998✔
3619
                const ExecContext *context,
3620
                const ExecParameters *params,
3621
                ExecRuntime *runtime,
3622
                const char *home) {
3623

3624
        const char *wd;
10,998✔
3625
        int r;
10,998✔
3626

3627
        assert(context);
10,998✔
3628

3629
        if (context->working_directory_home) {
10,998✔
3630
                if (!home)
32✔
3631
                        return -ENXIO;
3632

3633
                wd = home;
3634
        } else
3635
                wd = empty_to_root(context->working_directory);
10,966✔
3636

3637
        if (params->flags & EXEC_APPLY_CHROOT)
10,998✔
3638
                r = RET_NERRNO(chdir(wd));
10,998✔
3639
        else {
3640
                _cleanup_close_ int dfd = -EBADF;
×
3641

3642
                r = chase(wd,
×
3643
                          (runtime ? runtime->ephemeral_copy : NULL) ?: context->root_directory,
×
3644
                          CHASE_PREFIX_ROOT|CHASE_AT_RESOLVE_IN_ROOT,
3645
                          /* ret_path= */ NULL,
3646
                          &dfd);
3647
                if (r >= 0)
×
3648
                        r = RET_NERRNO(fchdir(dfd));
×
3649
        }
3650
        return context->working_directory_missing_ok ? 0 : r;
10,998✔
3651
}
3652

3653
static int apply_root_directory(
10,998✔
3654
                const ExecContext *context,
3655
                const ExecParameters *params,
3656
                ExecRuntime *runtime,
3657
                const bool needs_mount_ns,
3658
                int *exit_status) {
3659

3660
        assert(context);
10,998✔
3661
        assert(exit_status);
10,998✔
3662

3663
        if (params->flags & EXEC_APPLY_CHROOT)
10,998✔
3664
                if (!needs_mount_ns && context->root_directory)
10,998✔
3665
                        if (chroot((runtime ? runtime->ephemeral_copy : NULL) ?: context->root_directory) < 0) {
×
3666
                                *exit_status = EXIT_CHROOT;
×
3667
                                return -errno;
×
3668
                        }
3669

3670
        return 0;
3671
}
3672

3673
static int setup_keyring(
11,025✔
3674
                const ExecContext *context,
3675
                const ExecParameters *p,
3676
                uid_t uid, gid_t gid) {
3677

3678
        key_serial_t keyring;
11,025✔
3679
        int r = 0;
11,025✔
3680
        uid_t saved_uid;
11,025✔
3681
        gid_t saved_gid;
11,025✔
3682

3683
        assert(context);
11,025✔
3684
        assert(p);
11,025✔
3685

3686
        /* Let's set up a new per-service "session" kernel keyring for each system service. This has the benefit that
3687
         * each service runs with its own keyring shared among all processes of the service, but with no hook-up beyond
3688
         * that scope, and in particular no link to the per-UID keyring. If we don't do this the keyring will be
3689
         * automatically created on-demand and then linked to the per-UID keyring, by the kernel. The kernel's built-in
3690
         * on-demand behaviour is very appropriate for login users, but probably not so much for system services, where
3691
         * UIDs are not necessarily specific to a service but reused (at least in the case of UID 0). */
3692

3693
        if (context->keyring_mode == EXEC_KEYRING_INHERIT)
11,025✔
3694
                return 0;
3695

3696
        /* Acquiring a reference to the user keyring is nasty. We briefly change identity in order to get things set up
3697
         * properly by the kernel. If we don't do that then we can't create it atomically, and that sucks for parallel
3698
         * execution. This mimics what pam_keyinit does, too. Setting up session keyring, to be owned by the right user
3699
         * & group is just as nasty as acquiring a reference to the user keyring. */
3700

3701
        saved_uid = getuid();
10,258✔
3702
        saved_gid = getgid();
10,258✔
3703

3704
        if (gid_is_valid(gid) && gid != saved_gid) {
10,258✔
3705
                if (setregid(gid, -1) < 0)
1,758✔
3706
                        return log_exec_error_errno(context,
×
3707
                                                    p,
3708
                                                    errno,
3709
                                                    "Failed to change GID for user keyring: %m");
3710
        }
3711

3712
        if (uid_is_valid(uid) && uid != saved_uid) {
10,258✔
3713
                if (setreuid(uid, -1) < 0) {
1,755✔
3714
                        r = log_exec_error_errno(context,
×
3715
                                                 p,
3716
                                                 errno,
3717
                                                 "Failed to change UID for user keyring: %m");
3718
                        goto out;
×
3719
                }
3720
        }
3721

3722
        keyring = keyctl(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0);
10,258✔
3723
        if (keyring == -1) {
10,258✔
3724
                if (errno == ENOSYS)
3,753✔
3725
                        log_exec_debug_errno(context,
×
3726
                                             p,
3727
                                             errno,
3728
                                             "Kernel keyring not supported, ignoring.");
3729
                else if (ERRNO_IS_PRIVILEGE(errno))
3,753✔
3730
                        log_exec_debug_errno(context,
11,254✔
3731
                                             p,
3732
                                             errno,
3733
                                             "Kernel keyring access prohibited, ignoring.");
3734
                else if (errno == EDQUOT)
×
3735
                        log_exec_debug_errno(context,
×
3736
                                             p,
3737
                                             errno,
3738
                                             "Out of kernel keyrings to allocate, ignoring.");
3739
                else
3740
                        r = log_exec_error_errno(context,
×
3741
                                                 p,
3742
                                                 errno,
3743
                                                 "Setting up kernel keyring failed: %m");
3744

3745
                goto out;
3,753✔
3746
        }
3747

3748
        /* When requested link the user keyring into the session keyring. */
3749
        if (context->keyring_mode == EXEC_KEYRING_SHARED) {
6,505✔
3750

3751
                if (keyctl(KEYCTL_LINK,
826✔
3752
                           KEY_SPEC_USER_KEYRING,
3753
                           KEY_SPEC_SESSION_KEYRING, 0, 0) < 0) {
3754
                        r = log_exec_error_errno(context,
×
3755
                                                 p,
3756
                                                 errno,
3757
                                                 "Failed to link user keyring into session keyring: %m");
3758
                        goto out;
×
3759
                }
3760
        }
3761

3762
        /* Restore uid/gid back */
3763
        if (uid_is_valid(uid) && uid != saved_uid) {
6,505✔
3764
                if (setreuid(saved_uid, -1) < 0) {
1,434✔
3765
                        r = log_exec_error_errno(context,
×
3766
                                                 p,
3767
                                                 errno,
3768
                                                 "Failed to change UID back for user keyring: %m");
3769
                        goto out;
×
3770
                }
3771
        }
3772

3773
        if (gid_is_valid(gid) && gid != saved_gid) {
6,505✔
3774
                if (setregid(saved_gid, -1) < 0)
1,434✔
3775
                        return log_exec_error_errno(context,
×
3776
                                                    p,
3777
                                                    errno,
3778
                                                    "Failed to change GID back for user keyring: %m");
3779
        }
3780

3781
        /* Populate they keyring with the invocation ID by default, as original saved_uid. */
3782
        if (!sd_id128_is_null(p->invocation_id)) {
6,505✔
3783
                key_serial_t key;
6,505✔
3784

3785
                key = add_key("user",
13,010✔
3786
                              "invocation_id",
3787
                              &p->invocation_id,
6,505✔
3788
                              sizeof(p->invocation_id),
3789
                              KEY_SPEC_SESSION_KEYRING);
3790
                if (key == -1)
6,505✔
3791
                        log_exec_debug_errno(context,
×
3792
                                             p,
3793
                                             errno,
3794
                                             "Failed to add invocation ID to keyring, ignoring: %m");
3795
                else {
3796
                        if (keyctl(KEYCTL_SETPERM, key,
6,505✔
3797
                                   KEY_POS_VIEW|KEY_POS_READ|KEY_POS_SEARCH|
3798
                                   KEY_USR_VIEW|KEY_USR_READ|KEY_USR_SEARCH, 0, 0) < 0)
3799
                                r = log_exec_error_errno(context,
×
3800
                                                         p,
3801
                                                         errno,
3802
                                                         "Failed to restrict invocation ID permission: %m");
3803
                }
3804
        }
3805

3806
out:
6,505✔
3807
        /* Revert back uid & gid for the last time, and exit */
3808
        /* no extra logging, as only the first already reported error matters */
3809
        if (getuid() != saved_uid)
10,258✔
3810
                (void) setreuid(saved_uid, -1);
321✔
3811

3812
        if (getgid() != saved_gid)
10,258✔
3813
                (void) setregid(saved_gid, -1);
324✔
3814

3815
        return r;
3816
}
3817

3818
static void append_socket_pair(int *array, size_t *n, const int pair[static 2]) {
40,284✔
3819
        assert(array);
40,284✔
3820
        assert(n);
40,284✔
3821
        assert(pair);
40,284✔
3822

3823
        if (pair[0] >= 0)
40,284✔
3824
                array[(*n)++] = pair[0];
408✔
3825
        if (pair[1] >= 0)
40,284✔
3826
                array[(*n)++] = pair[1];
408✔
3827
}
40,284✔
3828

3829
static int close_remaining_fds(
13,390✔
3830
                const ExecParameters *params,
3831
                const ExecRuntime *runtime,
3832
                int socket_fd,
3833
                const int *fds, size_t n_fds) {
13,390✔
3834

3835
        size_t n_dont_close = 0;
13,390✔
3836
        int dont_close[n_fds + 17];
13,390✔
3837

3838
        assert(params);
13,390✔
3839

3840
        if (params->stdin_fd >= 0)
13,390✔
3841
                dont_close[n_dont_close++] = params->stdin_fd;
400✔
3842
        if (params->stdout_fd >= 0)
13,390✔
3843
                dont_close[n_dont_close++] = params->stdout_fd;
400✔
3844
        if (params->stderr_fd >= 0)
13,390✔
3845
                dont_close[n_dont_close++] = params->stderr_fd;
400✔
3846

3847
        if (socket_fd >= 0)
13,390✔
3848
                dont_close[n_dont_close++] = socket_fd;
17✔
3849
        if (n_fds > 0) {
13,390✔
3850
                memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds);
13,390✔
3851
                n_dont_close += n_fds;
13,390✔
3852
        }
3853

3854
        if (runtime)
13,390✔
3855
                append_socket_pair(dont_close, &n_dont_close, runtime->ephemeral_storage_socket);
13,390✔
3856

3857
        if (runtime && runtime->shared) {
13,390✔
3858
                append_socket_pair(dont_close, &n_dont_close, runtime->shared->netns_storage_socket);
13,390✔
3859
                append_socket_pair(dont_close, &n_dont_close, runtime->shared->ipcns_storage_socket);
13,390✔
3860
        }
3861

3862
        if (runtime && runtime->dynamic_creds) {
13,390✔
3863
                if (runtime->dynamic_creds->user)
13,390✔
3864
                        append_socket_pair(dont_close, &n_dont_close, runtime->dynamic_creds->user->storage_socket);
57✔
3865
                if (runtime->dynamic_creds->group)
13,390✔
3866
                        append_socket_pair(dont_close, &n_dont_close, runtime->dynamic_creds->group->storage_socket);
57✔
3867
        }
3868

3869
        if (params->user_lookup_fd >= 0)
13,390✔
3870
                dont_close[n_dont_close++] = params->user_lookup_fd;
13,390✔
3871

3872
        if (params->handoff_timestamp_fd >= 0)
13,390✔
3873
                dont_close[n_dont_close++] = params->handoff_timestamp_fd;
13,390✔
3874

3875
        if (params->pidref_transport_fd >= 0)
13,390✔
3876
                dont_close[n_dont_close++] = params->pidref_transport_fd;
12,268✔
3877

3878
        assert(n_dont_close <= ELEMENTSOF(dont_close));
13,390✔
3879

3880
        return close_all_fds(dont_close, n_dont_close);
13,390✔
3881
}
3882

3883
static int send_user_lookup(
13,388✔
3884
                const char *unit_id,
3885
                int user_lookup_fd,
3886
                uid_t uid,
3887
                gid_t gid) {
3888

3889
        assert(unit_id);
13,388✔
3890

3891
        /* Send the resolved UID/GID to PID 1 after we learnt it. We send a single datagram, containing the UID/GID
3892
         * data as well as the unit name. Note that we suppress sending this if no user/group to resolve was
3893
         * specified. */
3894

3895
        if (user_lookup_fd < 0)
13,388✔
3896
                return 0;
3897

3898
        if (!uid_is_valid(uid) && !gid_is_valid(gid))
13,388✔
3899
                return 0;
3900

3901
        if (writev(user_lookup_fd,
2,611✔
3902
               (struct iovec[]) {
5,222✔
3903
                           IOVEC_MAKE(&uid, sizeof(uid)),
3904
                           IOVEC_MAKE(&gid, sizeof(gid)),
3905
                           IOVEC_MAKE_STRING(unit_id) }, 3) < 0)
5,222✔
3906
                return -errno;
×
3907

3908
        return 0;
2,611✔
3909
}
3910

3911
static int acquire_home(const ExecContext *c, const char **home, char **ret_buf) {
13,388✔
3912
        int r;
13,388✔
3913

3914
        assert(c);
13,388✔
3915
        assert(home);
13,388✔
3916
        assert(ret_buf);
13,388✔
3917

3918
        /* If WorkingDirectory=~ is set, try to acquire a usable home directory. */
3919

3920
        if (*home) /* Already acquired from get_fixed_user()? */
13,388✔
3921
                return 0;
3922

3923
        if (!c->working_directory_home)
10,839✔
3924
                return 0;
3925

3926
        if (c->dynamic_user || (c->user && is_this_me(c->user) <= 0))
×
3927
                return -EADDRNOTAVAIL;
×
3928

3929
        r = get_home_dir(ret_buf);
×
3930
        if (r < 0)
×
3931
                return r;
3932

3933
        *home = *ret_buf;
×
3934
        return 1;
×
3935
}
3936

3937
static int compile_suggested_paths(const ExecContext *c, const ExecParameters *p, char ***ret) {
57✔
3938
        _cleanup_strv_free_ char ** list = NULL;
57✔
3939
        int r;
57✔
3940

3941
        assert(c);
57✔
3942
        assert(p);
57✔
3943
        assert(ret);
57✔
3944

3945
        assert(c->dynamic_user);
57✔
3946

3947
        /* Compile a list of paths that it might make sense to read the owning UID from to use as initial candidate for
3948
         * dynamic UID allocation, in order to save us from doing costly recursive chown()s of the special
3949
         * directories. */
3950

3951
        for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
342✔
3952

3953
                if (!EXEC_DIRECTORY_TYPE_SHALL_CHOWN(t))
285✔
3954
                        continue;
57✔
3955

3956
                if (!p->prefix[t])
228✔
3957
                        continue;
×
3958

3959
                for (size_t i = 0; i < c->directories[t].n_items; i++) {
238✔
3960
                        char *e;
10✔
3961

3962
                        if (exec_directory_is_private(c, t))
10✔
3963
                                e = path_join(p->prefix[t], "private", c->directories[t].items[i].path);
8✔
3964
                        else
3965
                                e = path_join(p->prefix[t], c->directories[t].items[i].path);
2✔
3966
                        if (!e)
10✔
3967
                                return -ENOMEM;
3968

3969
                        r = strv_consume(&list, e);
10✔
3970
                        if (r < 0)
10✔
3971
                                return r;
3972
                }
3973
        }
3974

3975
        *ret = TAKE_PTR(list);
57✔
3976

3977
        return 0;
57✔
3978
}
3979

3980
static int exec_context_cpu_affinity_from_numa(const ExecContext *c, CPUSet *ret) {
2✔
3981
        _cleanup_(cpu_set_reset) CPUSet s = {};
2✔
3982
        int r;
2✔
3983

3984
        assert(c);
2✔
3985
        assert(ret);
2✔
3986

3987
        if (!c->numa_policy.nodes.set) {
2✔
3988
                log_debug("Can't derive CPU affinity mask from NUMA mask because NUMA mask is not set, ignoring");
×
3989
                return 0;
×
3990
        }
3991

3992
        r = numa_to_cpu_set(&c->numa_policy, &s);
2✔
3993
        if (r < 0)
2✔
3994
                return r;
3995

3996
        cpu_set_reset(ret);
2✔
3997

3998
        return cpu_set_add_all(ret, &s);
2✔
3999
}
4000

4001
static int add_shifted_fd(int *fds, size_t fds_size, size_t *n_fds, int *fd) {
51,168✔
4002
        int r;
51,168✔
4003

4004
        assert(fds);
51,168✔
4005
        assert(n_fds);
51,168✔
4006
        assert(*n_fds < fds_size);
51,168✔
4007
        assert(fd);
51,168✔
4008

4009
        if (*fd < 0)
51,168✔
4010
               return 0;
51,168✔
4011

4012
        if (*fd < 3 + (int) *n_fds) {
24,657✔
4013
                /* Let's move the fd up, so that it's outside of the fd range we will use to store
4014
                 * the fds we pass to the process (or which are closed only during execve). */
4015

4016
                r = fcntl(*fd, F_DUPFD_CLOEXEC, 3 + (int) *n_fds);
10,998✔
4017
                if (r < 0)
10,998✔
4018
                        return -errno;
×
4019

4020
                close_and_replace(*fd, r);
10,998✔
4021
        }
4022

4023
        fds[(*n_fds)++] = *fd;
24,657✔
4024
        return 1;
24,657✔
4025
}
4026

4027
static int connect_unix_harder(const ExecContext *c, const ExecParameters *p, const OpenFile *of, int ofd) {
1✔
4028
        static const int socket_types[] = { SOCK_DGRAM, SOCK_STREAM, SOCK_SEQPACKET };
1✔
4029

4030
        union sockaddr_union addr = {
1✔
4031
                .un.sun_family = AF_UNIX,
4032
        };
4033
        socklen_t sa_len;
1✔
4034
        int r;
1✔
4035

4036
        assert(c);
1✔
4037
        assert(p);
1✔
4038
        assert(of);
1✔
4039
        assert(ofd >= 0);
1✔
4040

4041
        r = sockaddr_un_set_path(&addr.un, FORMAT_PROC_FD_PATH(ofd));
1✔
4042
        if (r < 0)
1✔
4043
                return log_exec_debug_errno(c, p, r, "Failed to set sockaddr for '%s': %m", of->path);
×
4044
        sa_len = r;
1✔
4045

4046
        FOREACH_ELEMENT(i, socket_types) {
2✔
4047
                _cleanup_close_ int fd = -EBADF;
2✔
4048

4049
                fd = socket(AF_UNIX, *i|SOCK_CLOEXEC, 0);
2✔
4050
                if (fd < 0)
2✔
4051
                        return log_exec_debug_errno(c, p,
×
4052
                                                    errno, "Failed to create socket for '%s': %m",
4053
                                                    of->path);
4054

4055
                r = RET_NERRNO(connect(fd, &addr.sa, sa_len));
2✔
4056
                if (r >= 0)
1✔
4057
                        return TAKE_FD(fd);
1✔
4058
                if (r != -EPROTOTYPE)
1✔
4059
                        return log_exec_debug_errno(c, p,
×
4060
                                                    r, "Failed to connect to socket for '%s': %m",
4061
                                                    of->path);
4062
        }
4063

4064
        return log_exec_debug_errno(c, p,
×
4065
                                    SYNTHETIC_ERRNO(EPROTOTYPE), "No suitable socket type to connect to socket '%s'.",
4066
                                    of->path);
4067
}
4068

4069
static int get_open_file_fd(const ExecContext *c, const ExecParameters *p, const OpenFile *of) {
5✔
4070
        _cleanup_close_ int fd = -EBADF, ofd = -EBADF;
5✔
4071
        struct stat st;
5✔
4072

4073
        assert(c);
5✔
4074
        assert(p);
5✔
4075
        assert(of);
5✔
4076

4077
        ofd = open(of->path, O_PATH | O_CLOEXEC);
5✔
4078
        if (ofd < 0)
5✔
4079
                return log_exec_debug_errno(c, p, errno, "Failed to open '%s' as O_PATH: %m", of->path);
6✔
4080

4081
        if (fstat(ofd, &st) < 0)
3✔
4082
                return log_exec_debug_errno(c, p, errno, "Failed to stat '%s': %m", of->path);
×
4083

4084
        if (S_ISSOCK(st.st_mode)) {
3✔
4085
                fd = connect_unix_harder(c, p, of, ofd);
1✔
4086
                if (fd < 0)
1✔
4087
                        return fd;
4088

4089
                if (FLAGS_SET(of->flags, OPENFILE_READ_ONLY) && shutdown(fd, SHUT_WR) < 0)
1✔
4090
                        return log_exec_debug_errno(c, p,
×
4091
                                                    errno, "Failed to shutdown send for socket '%s': %m",
4092
                                                    of->path);
4093

4094
                log_exec_debug(c, p, "Opened socket '%s' as fd %d.", of->path, fd);
3✔
4095
        } else {
4096
                int flags = FLAGS_SET(of->flags, OPENFILE_READ_ONLY) ? O_RDONLY : O_RDWR;
2✔
4097
                if (FLAGS_SET(of->flags, OPENFILE_APPEND))
2✔
4098
                        flags |= O_APPEND;
×
4099
                else if (FLAGS_SET(of->flags, OPENFILE_TRUNCATE))
2✔
4100
                        flags |= O_TRUNC;
×
4101

4102
                fd = fd_reopen(ofd, flags|O_NOCTTY|O_CLOEXEC);
2✔
4103
                if (fd < 0)
2✔
4104
                        return log_exec_debug_errno(c, p, fd, "Failed to reopen file '%s': %m", of->path);
×
4105

4106
                log_exec_debug(c, p, "Opened file '%s' as fd %d.", of->path, fd);
6✔
4107
        }
4108

4109
        return TAKE_FD(fd);
4110
}
4111

4112
static int collect_open_file_fds(const ExecContext *c, ExecParameters *p, size_t *n_fds) {
13,391✔
4113
        assert(c);
13,391✔
4114
        assert(p);
13,391✔
4115
        assert(n_fds);
13,391✔
4116

4117
        LIST_FOREACH(open_files, of, p->open_files) {
13,391✔
4118
                _cleanup_close_ int fd = -EBADF;
13,396✔
4119

4120
                fd = get_open_file_fd(c, p, of);
5✔
4121
                if (fd < 0) {
5✔
4122
                        if (FLAGS_SET(of->flags, OPENFILE_GRACEFUL)) {
2✔
4123
                                log_exec_full_errno(c, p,
3✔
4124
                                                    fd == -ENOENT || ERRNO_IS_NEG_PRIVILEGE(fd) ? LOG_DEBUG : LOG_WARNING,
4125
                                                    fd,
4126
                                                    "Failed to get OpenFile= file descriptor for '%s', ignoring: %m",
4127
                                                    of->path);
4128
                                continue;
1✔
4129
                        }
4130

4131
                        return log_exec_error_errno(c, p, fd,
3✔
4132
                                                    "Failed to get OpenFile= file descriptor for '%s': %m",
4133
                                                    of->path);
4134
                }
4135

4136
                if (!GREEDY_REALLOC(p->fds, *n_fds + 1))
3✔
4137
                        return log_oom();
×
4138

4139
                if (strv_extend(&p->fd_names, of->fdname) < 0)
3✔
4140
                        return log_oom();
×
4141

4142
                p->fds[(*n_fds)++] = TAKE_FD(fd);
3✔
4143
        }
4144

4145
        return 0;
4146
}
4147

4148
static void log_command_line(
10,997✔
4149
                const ExecContext *context,
4150
                const ExecParameters *params,
4151
                const char *msg,
4152
                const char *executable,
4153
                char **argv) {
4154

4155
        assert(context);
10,997✔
4156
        assert(params);
10,997✔
4157
        assert(msg);
10,997✔
4158
        assert(executable);
10,997✔
4159

4160
        if (!DEBUG_LOGGING)
10,997✔
4161
                return;
10,997✔
4162

4163
        _cleanup_free_ char *cmdline = quote_command_line(argv, SHELL_ESCAPE_EMPTY);
21,396✔
4164

4165
        log_exec_struct(context, params, LOG_DEBUG,
40,914✔
4166
                        "EXECUTABLE=%s", executable,
4167
                        LOG_EXEC_MESSAGE(params, "%s: %s", msg, strnull(cmdline)),
4168
                        LOG_EXEC_INVOCATION_ID(params));
4169
}
4170

4171
static bool exec_context_need_unprivileged_private_users(
11,025✔
4172
                const ExecContext *context,
4173
                const ExecParameters *params) {
4174

4175
        assert(context);
11,025✔
4176
        assert(params);
11,025✔
4177

4178
        /* These options require PrivateUsers= when used in user units, as we need to be in a user namespace
4179
         * to have permission to enable them when not running as root. If we have effective CAP_SYS_ADMIN
4180
         * (system manager) then we have privileges and don't need this. */
4181
        if (params->runtime_scope != RUNTIME_SCOPE_USER)
11,025✔
4182
                return false;
4183

4184
        return context->private_users != PRIVATE_USERS_NO ||
632✔
4185
               context->private_tmp != PRIVATE_TMP_NO ||
4186
               context->private_devices ||
629✔
4187
               context->private_network ||
624✔
4188
               context->network_namespace_path ||
624✔
4189
               context->private_ipc ||
624✔
4190
               context->ipc_namespace_path ||
624✔
4191
               context->private_mounts > 0 ||
624✔
4192
               context->mount_apivfs > 0 ||
624✔
4193
               context->bind_log_sockets > 0 ||
624✔
4194
               context->n_bind_mounts > 0 ||
624✔
4195
               context->n_temporary_filesystems > 0 ||
623✔
4196
               context->root_directory ||
623✔
4197
               !strv_isempty(context->extension_directories) ||
623✔
4198
               context->protect_system != PROTECT_SYSTEM_NO ||
623✔
4199
               context->protect_home != PROTECT_HOME_NO ||
620✔
4200
               exec_needs_pid_namespace(context) ||
620✔
4201
               context->protect_kernel_tunables ||
4202
               context->protect_kernel_modules ||
613✔
4203
               context->protect_kernel_logs ||
611✔
4204
               exec_needs_cgroup_mount(context, params) ||
611✔
4205
               context->protect_clock ||
611✔
4206
               context->protect_hostname != PROTECT_HOSTNAME_NO ||
610✔
4207
               !strv_isempty(context->read_write_paths) ||
609✔
4208
               !strv_isempty(context->read_only_paths) ||
606✔
4209
               !strv_isempty(context->inaccessible_paths) ||
606✔
4210
               !strv_isempty(context->exec_paths) ||
1,238✔
4211
               !strv_isempty(context->no_exec_paths);
632✔
4212
}
4213

4214
static bool exec_context_shall_confirm_spawn(const ExecContext *context) {
×
4215
        assert(context);
×
4216

4217
        if (confirm_spawn_disabled())
×
4218
                return false;
4219

4220
        /* For some reasons units remaining in the same process group
4221
         * as PID 1 fail to acquire the console even if it's not used
4222
         * by any process. So skip the confirmation question for them. */
4223
        return !context->same_pgrp;
×
4224
}
4225

4226
static int exec_context_named_iofds(
13,391✔
4227
                const ExecContext *c,
4228
                const ExecParameters *p,
4229
                int named_iofds[static 3]) {
4230

4231
        size_t targets;
13,391✔
4232
        const char* stdio_fdname[3];
13,391✔
4233
        size_t n_fds;
13,391✔
4234

4235
        assert(c);
13,391✔
4236
        assert(p);
13,391✔
4237
        assert(named_iofds);
13,391✔
4238

4239
        targets = (c->std_input == EXEC_INPUT_NAMED_FD) +
13,391✔
4240
                  (c->std_output == EXEC_OUTPUT_NAMED_FD) +
13,391✔
4241
                  (c->std_error == EXEC_OUTPUT_NAMED_FD);
13,391✔
4242

4243
        for (size_t i = 0; i < 3; i++)
53,564✔
4244
                stdio_fdname[i] = exec_context_fdname(c, i);
40,173✔
4245

4246
        n_fds = p->n_storage_fds + p->n_socket_fds + p->n_extra_fds;
13,391✔
4247

4248
        for (size_t i = 0; i < n_fds  && targets > 0; i++)
13,391✔
4249
                if (named_iofds[STDIN_FILENO] < 0 &&
×
4250
                    c->std_input == EXEC_INPUT_NAMED_FD &&
×
4251
                    stdio_fdname[STDIN_FILENO] &&
×
4252
                    streq(p->fd_names[i], stdio_fdname[STDIN_FILENO])) {
×
4253

4254
                        named_iofds[STDIN_FILENO] = p->fds[i];
×
4255
                        targets--;
×
4256

4257
                } else if (named_iofds[STDOUT_FILENO] < 0 &&
×
4258
                           c->std_output == EXEC_OUTPUT_NAMED_FD &&
×
4259
                           stdio_fdname[STDOUT_FILENO] &&
×
4260
                           streq(p->fd_names[i], stdio_fdname[STDOUT_FILENO])) {
×
4261

4262
                        named_iofds[STDOUT_FILENO] = p->fds[i];
×
4263
                        targets--;
×
4264

4265
                } else if (named_iofds[STDERR_FILENO] < 0 &&
×
4266
                           c->std_error == EXEC_OUTPUT_NAMED_FD &&
×
4267
                           stdio_fdname[STDERR_FILENO] &&
×
4268
                           streq(p->fd_names[i], stdio_fdname[STDERR_FILENO])) {
×
4269

4270
                        named_iofds[STDERR_FILENO] = p->fds[i];
×
4271
                        targets--;
×
4272
                }
4273

4274
        return targets == 0 ? 0 : -ENOENT;
13,391✔
4275
}
4276

4277
static void exec_shared_runtime_close(ExecSharedRuntime *shared) {
10,998✔
4278
        if (!shared)
10,998✔
4279
                return;
4280

4281
        safe_close_pair(shared->netns_storage_socket);
10,998✔
4282
        safe_close_pair(shared->ipcns_storage_socket);
10,998✔
4283
}
4284

4285
static void exec_runtime_close(ExecRuntime *rt) {
10,998✔
4286
        if (!rt)
10,998✔
4287
                return;
4288

4289
        safe_close_pair(rt->ephemeral_storage_socket);
10,998✔
4290

4291
        exec_shared_runtime_close(rt->shared);
10,998✔
4292
        dynamic_creds_close(rt->dynamic_creds);
10,998✔
4293
}
4294

4295
static void exec_params_close(ExecParameters *p) {
10,998✔
4296
        if (!p)
10,998✔
4297
                return;
4298

4299
        p->stdin_fd = safe_close(p->stdin_fd);
10,998✔
4300
        p->stdout_fd = safe_close(p->stdout_fd);
10,998✔
4301
        p->stderr_fd = safe_close(p->stderr_fd);
10,998✔
4302
}
4303

4304
static int exec_fd_mark_hot(
11,000✔
4305
                const ExecContext *c,
4306
                ExecParameters *p,
4307
                bool hot,
4308
                int *reterr_exit_status) {
4309

4310
        assert(c);
11,000✔
4311
        assert(p);
11,000✔
4312

4313
        if (p->exec_fd < 0)
11,000✔
4314
                return 0;
11,000✔
4315

4316
        uint8_t x = hot;
212✔
4317

4318
        if (write(p->exec_fd, &x, sizeof(x)) < 0) {
212✔
4319
                if (reterr_exit_status)
×
4320
                        *reterr_exit_status = EXIT_EXEC;
×
4321
                return log_exec_error_errno(c, p, errno, "Failed to mark exec_fd as %s: %m", hot ? "hot" : "cold");
×
4322
        }
4323

4324
        return 1;
4325
}
4326

4327
static int send_handoff_timestamp(
10,997✔
4328
                const ExecContext *c,
4329
                ExecParameters *p,
4330
                int *reterr_exit_status) {
4331

4332
        assert(c);
10,997✔
4333
        assert(p);
10,997✔
4334

4335
        if (p->handoff_timestamp_fd < 0)
10,997✔
4336
                return 0;
10,997✔
4337

4338
        dual_timestamp dt;
10,997✔
4339
        dual_timestamp_now(&dt);
10,997✔
4340

4341
        if (write(p->handoff_timestamp_fd, (const usec_t[2]) { dt.realtime, dt.monotonic }, sizeof(usec_t) * 2) < 0) {
10,997✔
4342
                if (reterr_exit_status)
×
4343
                        *reterr_exit_status = EXIT_EXEC;
×
4344
                return log_exec_error_errno(c, p, errno, "Failed to send handoff timestamp: %m");
×
4345
        }
4346

4347
        return 1;
10,997✔
4348
}
4349

4350
static void prepare_terminal(
13,388✔
4351
                const ExecContext *context,
4352
                ExecParameters *p) {
4353

4354
        _cleanup_close_ int lock_fd = -EBADF;
13,388✔
4355

4356
        /* This is the "constructive" reset, i.e. is about preparing things for our invocation rather than
4357
         * cleaning up things from older invocations. */
4358

4359
        assert(context);
13,388✔
4360
        assert(p);
13,388✔
4361

4362
        /* We only try to reset things if we there's the chance our stdout points to a TTY */
4363
        if (!(is_terminal_output(context->std_output) ||
13,388✔
4364
              (context->std_output == EXEC_OUTPUT_INHERIT && is_terminal_input(context->std_input)) ||
12,781✔
4365
              context->std_output == EXEC_OUTPUT_NAMED_FD ||
4366
              p->stdout_fd >= 0))
12,781✔
4367
                return;
12,381✔
4368

4369
        if (context->tty_reset) {
1,007✔
4370
                /* When we are resetting the TTY, then let's create a lock first, to synchronize access. This
4371
                 * in particular matters as concurrent resets and the TTY size ANSI DSR logic done by the
4372
                 * exec_context_apply_tty_size() below might interfere */
4373
                lock_fd = lock_dev_console();
149✔
4374
                if (lock_fd < 0)
149✔
4375
                        log_exec_debug_errno(context, p, lock_fd, "Failed to lock /dev/console, ignoring: %m");
×
4376

4377
                (void) terminal_reset_defensive(STDOUT_FILENO, /* switch_to_text= */ false);
149✔
4378
        }
4379

4380
        (void) exec_context_apply_tty_size(context, STDIN_FILENO, STDOUT_FILENO, /* tty_path= */ NULL);
1,007✔
4381
}
4382

4383
int exec_invoke(
13,391✔
4384
                const ExecCommand *command,
4385
                const ExecContext *context,
4386
                ExecParameters *params,
4387
                ExecRuntime *runtime,
4388
                const CGroupContext *cgroup_context,
4389
                int *exit_status) {
13,391✔
4390

4391
        _cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **joined_exec_search_path = NULL, **accum_env = NULL, **replaced_argv = NULL;
28✔
4392
        int r, ngids = 0;
13,391✔
4393
        _cleanup_free_ gid_t *supplementary_gids = NULL;
×
4394
        const char *username = NULL, *groupname = NULL;
13,391✔
4395
        _cleanup_free_ char *home_buffer = NULL, *memory_pressure_path = NULL, *own_user = NULL;
×
4396
        const char *home = NULL, *shell = NULL;
13,391✔
4397
        char **final_argv = NULL;
13,391✔
4398
        dev_t journal_stream_dev = 0;
13,391✔
4399
        ino_t journal_stream_ino = 0;
13,391✔
4400
        bool userns_set_up = false;
13,391✔
4401
        bool needs_sandboxing,          /* Do we need to set up full sandboxing? (i.e. all namespacing, all MAC stuff, caps, yadda yadda */
13,391✔
4402
                needs_setuid,           /* Do we need to do the actual setresuid()/setresgid() calls? */
4403
                needs_mount_namespace;  /* Do we need to set up a mount namespace for this kernel? */
4404
        bool keep_seccomp_privileges = false;
13,391✔
4405
        bool has_cap_sys_admin = false;
13,391✔
4406
#if HAVE_SELINUX
4407
        _cleanup_free_ char *mac_selinux_context_net = NULL;
4408
        bool use_selinux = false;
4409
#endif
4410
#if ENABLE_SMACK
4411
        bool use_smack = false;
13,391✔
4412
#endif
4413
#if HAVE_APPARMOR
4414
        bool use_apparmor = false;
4415
#endif
4416
#if HAVE_SECCOMP
4417
        uint64_t saved_bset = 0;
13,391✔
4418
#endif
4419
        uid_t saved_uid = getuid();
13,391✔
4420
        gid_t saved_gid = getgid();
13,391✔
4421
        uid_t uid = UID_INVALID;
13,391✔
4422
        gid_t gid = GID_INVALID;
13,391✔
4423
        size_t n_fds, /* fds to pass to the child */
13,391✔
4424
               n_keep_fds; /* total number of fds not to close */
4425
        int secure_bits;
13,391✔
4426
        _cleanup_free_ gid_t *gids_after_pam = NULL;
28✔
4427
        int ngids_after_pam = 0;
13,391✔
4428

4429
        int socket_fd = -EBADF, named_iofds[3] = EBADF_TRIPLET;
13,391✔
4430
        size_t n_storage_fds, n_socket_fds, n_extra_fds;
13,391✔
4431

4432
        assert(command);
13,391✔
4433
        assert(context);
13,391✔
4434
        assert(params);
13,391✔
4435
        assert(exit_status);
13,391✔
4436

4437
        /* This should be mostly redundant, as the log level is also passed as an argument of the executor,
4438
         * and is already applied earlier. Just for safety. */
4439
        if (params->debug_invocation)
13,391✔
4440
                log_set_max_level(LOG_PRI(LOG_DEBUG));
2✔
4441
        else if (context->log_level_max >= 0)
13,389✔
4442
                log_set_max_level(context->log_level_max);
5✔
4443

4444
        /* Explicitly test for CVE-2021-4034 inspired invocations */
4445
        if (!command->path || strv_isempty(command->argv)) {
13,391✔
4446
                *exit_status = EXIT_EXEC;
×
4447
                return log_exec_error_errno(
×
4448
                                context,
4449
                                params,
4450
                                SYNTHETIC_ERRNO(EINVAL),
4451
                                "Invalid command line arguments.");
4452
        }
4453

4454
        LOG_CONTEXT_PUSH_EXEC(context, params);
38,935✔
4455

4456
        if (context->std_input == EXEC_INPUT_SOCKET ||
13,391✔
4457
            context->std_output == EXEC_OUTPUT_SOCKET ||
13,380✔
4458
            context->std_error == EXEC_OUTPUT_SOCKET) {
13,374✔
4459

4460
                if (params->n_socket_fds > 1)
17✔
4461
                        return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EINVAL), "Got more than one socket.");
×
4462

4463
                if (params->n_socket_fds == 0)
17✔
4464
                        return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EINVAL), "Got no socket.");
×
4465

4466
                socket_fd = params->fds[0];
17✔
4467
                n_storage_fds = n_socket_fds = n_extra_fds = 0;
17✔
4468
        } else {
4469
                n_socket_fds = params->n_socket_fds;
13,374✔
4470
                n_storage_fds = params->n_storage_fds;
13,374✔
4471
                n_extra_fds = params->n_extra_fds;
13,374✔
4472
        }
4473
        n_fds = n_socket_fds + n_storage_fds + n_extra_fds;
13,391✔
4474

4475
        r = exec_context_named_iofds(context, params, named_iofds);
13,391✔
4476
        if (r < 0)
13,391✔
4477
                return log_exec_error_errno(context, params, r, "Failed to load a named file descriptor: %m");
×
4478

4479
        rename_process_from_path(command->path);
13,391✔
4480

4481
        /* We reset exactly these signals, since they are the only ones we set to SIG_IGN in the main
4482
         * daemon. All others we leave untouched because we set them to SIG_DFL or a valid handler initially,
4483
         * both of which will be demoted to SIG_DFL. */
4484
        (void) default_signals(SIGNALS_CRASH_HANDLER,
13,391✔
4485
                               SIGNALS_IGNORE);
4486

4487
        if (context->ignore_sigpipe)
13,391✔
4488
                (void) ignore_signals(SIGPIPE);
13,242✔
4489

4490
        r = reset_signal_mask();
13,391✔
4491
        if (r < 0) {
13,391✔
4492
                *exit_status = EXIT_SIGNAL_MASK;
×
4493
                return log_exec_error_errno(context, params, r, "Failed to set process signal mask: %m");
×
4494
        }
4495

4496
        if (params->idle_pipe)
13,391✔
4497
                do_idle_pipe_dance(params->idle_pipe);
147✔
4498

4499
        /* Close fds we don't need very early to make sure we don't block init reexecution because it cannot bind its
4500
         * sockets. Among the fds we close are the logging fds, and we want to keep them closed, so that we don't have
4501
         * any fds open we don't really want open during the transition. In order to make logging work, we switch the
4502
         * log subsystem into open_when_needed mode, so that it reopens the logs on every single log call. */
4503

4504
        log_forget_fds();
13,391✔
4505
        log_set_open_when_needed(true);
13,391✔
4506
        log_settle_target();
13,391✔
4507

4508
        /* In case anything used libc syslog(), close this here, too */
4509
        closelog();
13,391✔
4510

4511
        r = collect_open_file_fds(context, params, &n_fds);
13,391✔
4512
        if (r < 0) {
13,391✔
4513
                *exit_status = EXIT_FDS;
1✔
4514
                return log_exec_error_errno(context, params, r, "Failed to get OpenFile= file descriptors: %m");
3✔
4515
        }
4516

4517
        int keep_fds[n_fds + 4];
13,390✔
4518
        memcpy_safe(keep_fds, params->fds, n_fds * sizeof(int));
13,390✔
4519
        n_keep_fds = n_fds;
13,390✔
4520

4521
        r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, &params->exec_fd);
13,390✔
4522
        if (r < 0) {
13,390✔
4523
                *exit_status = EXIT_FDS;
×
4524
                return log_exec_error_errno(context, params, r, "Failed to collect shifted fd: %m");
×
4525
        }
4526

4527
        r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, &params->handoff_timestamp_fd);
13,390✔
4528
        if (r < 0) {
13,390✔
4529
                *exit_status = EXIT_FDS;
×
4530
                return log_exec_error_errno(context, params, r, "Failed to collect shifted fd: %m");
×
4531
        }
4532

4533
#if HAVE_LIBBPF
4534
        r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, &params->bpf_restrict_fs_map_fd);
13,390✔
4535
        if (r < 0) {
13,390✔
4536
                *exit_status = EXIT_FDS;
×
4537
                return log_exec_error_errno(context, params, r, "Failed to collect shifted fd: %m");
×
4538
        }
4539
#endif
4540

4541
        r = close_remaining_fds(params, runtime, socket_fd, keep_fds, n_keep_fds);
13,390✔
4542
        if (r < 0) {
13,390✔
4543
                *exit_status = EXIT_FDS;
×
4544
                return log_exec_error_errno(context, params, r, "Failed to close unwanted file descriptors: %m");
×
4545
        }
4546

4547
        if (!context->same_pgrp &&
25,803✔
4548
            setsid() < 0) {
12,413✔
4549
                *exit_status = EXIT_SETSID;
×
4550
                return log_exec_error_errno(context, params, errno, "Failed to create new process session: %m");
×
4551
        }
4552

4553
        /* Now, reset the TTY associated to this service "destructively" (i.e. possibly even hang up or
4554
         * disallocate the VT), to get rid of any prior uses of the device. Note that we do not keep any fd
4555
         * open here, hence some of the settings made here might vanish again, depending on the TTY driver
4556
         * used. A 2nd ("constructive") initialization after we opened the input/output fds we actually want
4557
         * will fix this. */
4558
        exec_context_tty_reset(context, params);
13,390✔
4559

4560
        if (params->shall_confirm_spawn && exec_context_shall_confirm_spawn(context)) {
13,390✔
4561
                _cleanup_free_ char *cmdline = NULL;
×
4562

4563
                cmdline = quote_command_line(command->argv, SHELL_ESCAPE_EMPTY);
×
4564
                if (!cmdline) {
×
4565
                        *exit_status = EXIT_MEMORY;
×
4566
                        return log_oom();
×
4567
                }
4568

4569
                r = ask_for_confirmation(context, params, cmdline);
×
4570
                if (r != CONFIRM_EXECUTE) {
×
4571
                        if (r == CONFIRM_PRETEND_SUCCESS) {
×
4572
                                *exit_status = EXIT_SUCCESS;
×
4573
                                return 0;
×
4574
                        }
4575

4576
                        *exit_status = EXIT_CONFIRM;
×
4577
                        return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(ECANCELED),
×
4578
                                                    "Execution cancelled by the user.");
4579
                }
4580
        }
4581

4582
        /* We are about to invoke NSS and PAM modules. Let's tell them what we are doing here, maybe they care. This is
4583
         * used by nss-resolve to disable itself when we are about to start systemd-resolved, to avoid deadlocks. Note
4584
         * that these env vars do not survive the execve(), which means they really only apply to the PAM and NSS
4585
         * invocations themselves. Also note that while we'll only invoke NSS modules involved in user management they
4586
         * might internally call into other NSS modules that are involved in hostname resolution, we never know. */
4587
        if (setenv("SYSTEMD_ACTIVATION_UNIT", params->unit_id, true) != 0 ||
26,780✔
4588
            setenv("SYSTEMD_ACTIVATION_SCOPE", runtime_scope_to_string(params->runtime_scope), true) != 0) {
13,390✔
4589
                *exit_status = EXIT_MEMORY;
×
4590
                return log_exec_error_errno(context, params, errno, "Failed to update environment: %m");
×
4591
        }
4592

4593
        if (context->dynamic_user && runtime && runtime->dynamic_creds) {
13,447✔
4594
                _cleanup_strv_free_ char **suggested_paths = NULL;
57✔
4595

4596
                /* On top of that, make sure we bypass our own NSS module nss-systemd comprehensively for any NSS
4597
                 * checks, if DynamicUser=1 is used, as we shouldn't create a feedback loop with ourselves here. */
4598
                if (putenv((char*) "SYSTEMD_NSS_DYNAMIC_BYPASS=1") != 0) {
57✔
4599
                        *exit_status = EXIT_USER;
×
4600
                        return log_exec_error_errno(context, params, errno, "Failed to update environment: %m");
×
4601
                }
4602

4603
                r = compile_suggested_paths(context, params, &suggested_paths);
57✔
4604
                if (r < 0) {
57✔
4605
                        *exit_status = EXIT_MEMORY;
×
4606
                        return log_oom();
×
4607
                }
4608

4609
                r = dynamic_creds_realize(runtime->dynamic_creds, suggested_paths, &uid, &gid);
57✔
4610
                if (r < 0) {
57✔
4611
                        *exit_status = EXIT_USER;
×
4612
                        if (r == -EILSEQ)
×
4613
                                return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EOPNOTSUPP),
×
4614
                                                            "Failed to update dynamic user credentials: User or group with specified name already exists.");
4615
                        return log_exec_error_errno(context, params, r, "Failed to update dynamic user credentials: %m");
×
4616
                }
4617

4618
                if (!uid_is_valid(uid)) {
57✔
4619
                        *exit_status = EXIT_USER;
×
4620
                        return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(ESRCH), "UID validation failed for \""UID_FMT"\".", uid);
×
4621
                }
4622

4623
                if (!gid_is_valid(gid)) {
57✔
4624
                        *exit_status = EXIT_USER;
×
4625
                        return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(ESRCH), "GID validation failed for \""GID_FMT"\".", gid);
×
4626
                }
4627

4628
                if (runtime->dynamic_creds->user)
57✔
4629
                        username = runtime->dynamic_creds->user->name;
57✔
4630

4631
        } else {
4632
                const char *u;
13,333✔
4633

4634
                if (context->user)
13,333✔
4635
                        u = context->user;
4636
                else if (context->pam_name) {
10,841✔
4637
                        /* If PAM is enabled but no user name is explicitly selected, then use our own one. */
4638
                        own_user = getusername_malloc();
59✔
4639
                        if (!own_user) {
59✔
4640
                                *exit_status = EXIT_USER;
×
4641
                                return log_exec_error_errno(context, params, r, "Failed to determine my own user ID: %m");
×
4642
                        }
4643
                        u = own_user;
4644
                } else
4645
                        u = NULL;
4646

4647
                if (u) {
4648
                        r = get_fixed_user(u, &username, &uid, &gid, &home, &shell);
2,551✔
4649
                        if (r < 0) {
2,551✔
4650
                                *exit_status = EXIT_USER;
2✔
4651
                                return log_exec_error_errno(context, params, r, "Failed to determine user credentials: %m");
6✔
4652
                        }
4653
                }
4654

4655
                if (context->group) {
13,331✔
4656
                        r = get_fixed_group(context->group, &groupname, &gid);
9✔
4657
                        if (r < 0) {
9✔
4658
                                *exit_status = EXIT_GROUP;
×
4659
                                return log_exec_error_errno(context, params, r, "Failed to determine group credentials: %m");
×
4660
                        }
4661
                }
4662
        }
4663

4664
        /* Initialize user supplementary groups and get SupplementaryGroups= ones */
4665
        r = get_supplementary_groups(context, username, groupname, gid,
13,388✔
4666
                                     &supplementary_gids, &ngids);
4667
        if (r < 0) {
13,388✔
4668
                *exit_status = EXIT_GROUP;
×
4669
                return log_exec_error_errno(context, params, r, "Failed to determine supplementary groups: %m");
×
4670
        }
4671

4672
        r = send_user_lookup(params->unit_id, params->user_lookup_fd, uid, gid);
13,388✔
4673
        if (r < 0) {
13,388✔
4674
                *exit_status = EXIT_USER;
×
4675
                return log_exec_error_errno(context, params, r, "Failed to send user credentials to PID1: %m");
×
4676
        }
4677

4678
        params->user_lookup_fd = safe_close(params->user_lookup_fd);
13,388✔
4679

4680
        r = acquire_home(context, &home, &home_buffer);
13,388✔
4681
        if (r < 0) {
13,388✔
4682
                *exit_status = EXIT_CHDIR;
×
4683
                return log_exec_error_errno(context, params, r, "Failed to determine $HOME for the invoking user: %m");
×
4684
        }
4685

4686
        /* If a socket is connected to STDIN/STDOUT/STDERR, we must drop O_NONBLOCK */
4687
        if (socket_fd >= 0)
13,388✔
4688
                (void) fd_nonblock(socket_fd, false);
17✔
4689

4690
        /* Journald will try to look-up our cgroup in order to populate _SYSTEMD_CGROUP and _SYSTEMD_UNIT fields.
4691
         * Hence we need to migrate to the target cgroup from init.scope before connecting to journald */
4692
        if (params->cgroup_path) {
13,388✔
4693
                _cleanup_free_ char *p = NULL;
13,388✔
4694

4695
                r = exec_params_get_cgroup_path(params, cgroup_context, &p);
13,388✔
4696
                if (r < 0) {
13,388✔
4697
                        *exit_status = EXIT_CGROUP;
×
4698
                        return log_exec_error_errno(context, params, r, "Failed to acquire cgroup path: %m");
×
4699
                }
4700

4701
                r = cg_attach_everywhere(params->cgroup_supported, p, 0);
13,388✔
4702
                if (r == -EUCLEAN) {
13,388✔
4703
                        *exit_status = EXIT_CGROUP;
×
4704
                        return log_exec_error_errno(context, params, r,
×
4705
                                                    "Failed to attach process to cgroup '%s', "
4706
                                                    "because the cgroup or one of its parents or "
4707
                                                    "siblings is in the threaded mode.", p);
4708
                }
4709
                if (r < 0) {
13,388✔
4710
                        *exit_status = EXIT_CGROUP;
×
4711
                        return log_exec_error_errno(context, params, r, "Failed to attach to cgroup %s: %m", p);
×
4712
                }
4713
        }
4714

4715
        if (context->network_namespace_path && runtime && runtime->shared && runtime->shared->netns_storage_socket[0] >= 0) {
13,388✔
4716
                r = open_shareable_ns_path(runtime->shared->netns_storage_socket, context->network_namespace_path, CLONE_NEWNET);
×
4717
                if (r < 0) {
×
4718
                        *exit_status = EXIT_NETWORK;
×
4719
                        return log_exec_error_errno(context, params, r, "Failed to open network namespace path %s: %m", context->network_namespace_path);
×
4720
                }
4721
        }
4722

4723
        if (context->ipc_namespace_path && runtime && runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) {
13,388✔
4724
                r = open_shareable_ns_path(runtime->shared->ipcns_storage_socket, context->ipc_namespace_path, CLONE_NEWIPC);
×
4725
                if (r < 0) {
×
4726
                        *exit_status = EXIT_NAMESPACE;
×
4727
                        return log_exec_error_errno(context, params, r, "Failed to open IPC namespace path %s: %m", context->ipc_namespace_path);
×
4728
                }
4729
        }
4730

4731
        r = setup_input(context, params, socket_fd, named_iofds);
13,388✔
4732
        if (r < 0) {
13,388✔
4733
                *exit_status = EXIT_STDIN;
×
4734
                return log_exec_error_errno(context, params, r, "Failed to set up standard input: %m");
×
4735
        }
4736

4737
        _cleanup_free_ char *fname = NULL;
25✔
4738
        r = path_extract_filename(command->path, &fname);
13,388✔
4739
        if (r < 0) {
13,388✔
4740
                *exit_status = EXIT_STDOUT;
×
4741
                return log_exec_error_errno(context, params, r, "Failed to extract filename from path %s: %m", command->path);
×
4742
        }
4743

4744
        r = setup_output(context, params, STDOUT_FILENO, socket_fd, named_iofds, fname, uid, gid, &journal_stream_dev, &journal_stream_ino);
13,388✔
4745
        if (r < 0) {
13,388✔
4746
                *exit_status = EXIT_STDOUT;
×
4747
                return log_exec_error_errno(context, params, r, "Failed to set up standard output: %m");
×
4748
        }
4749

4750
        r = setup_output(context, params, STDERR_FILENO, socket_fd, named_iofds, fname, uid, gid, &journal_stream_dev, &journal_stream_ino);
13,388✔
4751
        if (r < 0) {
13,388✔
4752
                *exit_status = EXIT_STDERR;
×
4753
                return log_exec_error_errno(context, params, r, "Failed to set up standard error output: %m");
×
4754
        }
4755

4756
        /* Now that stdin/stdout are definiely opened, properly initialize it with our desired
4757
         * settings. Note: this is a "constructive" reset, it prepares things for us to use. This is
4758
         * different from the "destructive" TTY reset further up. Also note: we apply this on stdin/stdout in
4759
         * case this is a tty, regardless if we opened it ourselves or got it passed in pre-opened. */
4760
        prepare_terminal(context, params);
13,388✔
4761

4762
        if (context->oom_score_adjust_set) {
13,388✔
4763
                /* When we can't make this change due to EPERM, then let's silently skip over it. User
4764
                 * namespaces prohibit write access to this file, and we shouldn't trip up over that. */
4765
                r = set_oom_score_adjust(context->oom_score_adjust);
1,447✔
4766
                if (ERRNO_IS_NEG_PRIVILEGE(r))
1,447✔
4767
                        log_exec_debug_errno(context, params, r,
×
4768
                                             "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
4769
                else if (r < 0) {
1,447✔
4770
                        *exit_status = EXIT_OOM_ADJUST;
×
4771
                        return log_exec_error_errno(context, params, r, "Failed to adjust OOM setting: %m");
×
4772
                }
4773
        }
4774

4775
        if (context->coredump_filter_set) {
13,388✔
4776
                r = set_coredump_filter(context->coredump_filter);
2✔
4777
                if (ERRNO_IS_NEG_PRIVILEGE(r))
2✔
4778
                        log_exec_debug_errno(context, params, r, "Failed to adjust coredump_filter, ignoring: %m");
×
4779
                else if (r < 0) {
2✔
4780
                        *exit_status = EXIT_LIMITS;
×
4781
                        return log_exec_error_errno(context, params, r, "Failed to adjust coredump_filter: %m");
×
4782
                }
4783
        }
4784

4785
        if (context->cpu_sched_set) {
13,388✔
4786
                struct sched_attr attr = {
×
4787
                        .size = sizeof(attr),
4788
                        .sched_policy = context->cpu_sched_policy,
×
4789
                        .sched_priority = context->cpu_sched_priority,
×
4790
                        .sched_flags = context->cpu_sched_reset_on_fork ? SCHED_FLAG_RESET_ON_FORK : 0,
×
4791
                };
4792

4793
                r = sched_setattr(/* pid= */ 0, &attr, /* flags= */ 0);
×
4794
                if (r < 0) {
×
4795
                        *exit_status = EXIT_SETSCHEDULER;
×
4796
                        return log_exec_error_errno(context, params, errno, "Failed to set up CPU scheduling: %m");
×
4797
                }
4798
        }
4799

4800
        /*
4801
         * Set nice value _after_ the call to sched_setattr() because struct sched_attr includes sched_nice
4802
         * which we do not set, thus it will clobber any previously set nice value. Scheduling policy might
4803
         * be reasonably set together with nice value e.g. in case of SCHED_BATCH (see sched(7)).
4804
         * It would be ideal to set both with the same call, but we cannot easily do so because of all the
4805
         * extra logic in setpriority_closest().
4806
         */
4807
        if (context->nice_set) {
13,388✔
4808
                r = setpriority_closest(context->nice);
14✔
4809
                if (r < 0) {
14✔
4810
                        *exit_status = EXIT_NICE;
×
4811
                        return log_exec_error_errno(context, params, r, "Failed to set up process scheduling priority (nice level): %m");
×
4812
                }
4813
        }
4814

4815
        if (context->cpu_affinity_from_numa || context->cpu_set.set) {
13,388✔
4816
                _cleanup_(cpu_set_reset) CPUSet converted_cpu_set = {};
2✔
4817
                const CPUSet *cpu_set;
2✔
4818

4819
                if (context->cpu_affinity_from_numa) {
2✔
4820
                        r = exec_context_cpu_affinity_from_numa(context, &converted_cpu_set);
2✔
4821
                        if (r < 0) {
2✔
4822
                                *exit_status = EXIT_CPUAFFINITY;
×
4823
                                return log_exec_error_errno(context, params, r, "Failed to derive CPU affinity mask from NUMA mask: %m");
×
4824
                        }
4825

4826
                        cpu_set = &converted_cpu_set;
4827
                } else
4828
                        cpu_set = &context->cpu_set;
×
4829

4830
                if (sched_setaffinity(0, cpu_set->allocated, cpu_set->set) < 0) {
2✔
4831
                        *exit_status = EXIT_CPUAFFINITY;
×
4832
                        return log_exec_error_errno(context, params, errno, "Failed to set up CPU affinity: %m");
×
4833
                }
4834
        }
4835

4836
        if (mpol_is_valid(numa_policy_get_type(&context->numa_policy))) {
13,388✔
4837
                r = apply_numa_policy(&context->numa_policy);
19✔
4838
                if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
19✔
4839
                        log_exec_debug_errno(context, params, r, "NUMA support not available, ignoring.");
×
4840
                else if (r < 0) {
19✔
4841
                        *exit_status = EXIT_NUMA_POLICY;
2✔
4842
                        return log_exec_error_errno(context, params, r, "Failed to set NUMA memory policy: %m");
6✔
4843
                }
4844
        }
4845

4846
        if (context->ioprio_set)
13,386✔
4847
                if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
6✔
4848
                        *exit_status = EXIT_IOPRIO;
×
4849
                        return log_exec_error_errno(context, params, errno, "Failed to set up IO scheduling priority: %m");
×
4850
                }
4851

4852
        if (context->timer_slack_nsec != NSEC_INFINITY)
13,386✔
4853
                if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
×
4854
                        *exit_status = EXIT_TIMERSLACK;
×
4855
                        return log_exec_error_errno(context, params, errno, "Failed to set up timer slack: %m");
×
4856
                }
4857

4858
        if (context->personality != PERSONALITY_INVALID) {
13,386✔
4859
                r = safe_personality(context->personality);
×
4860
                if (r < 0) {
×
4861
                        *exit_status = EXIT_PERSONALITY;
×
4862
                        return log_exec_error_errno(context, params, r, "Failed to set up execution domain (personality): %m");
×
4863
                }
4864
        }
4865

4866
#if ENABLE_UTMP
4867
        if (context->utmp_id) {
13,386✔
4868
                _cleanup_free_ char *username_alloc = NULL;
151✔
4869

4870
                if (!username && context->utmp_mode == EXEC_UTMP_USER) {
151✔
4871
                        username_alloc = uid_to_name(uid_is_valid(uid) ? uid : saved_uid);
1✔
4872
                        if (!username_alloc) {
1✔
4873
                                *exit_status = EXIT_USER;
×
4874
                                return log_oom();
×
4875
                        }
4876
                }
4877

4878
                const char *line = context->tty_path ?
302✔
4879
                        (path_startswith(context->tty_path, "/dev/") ?: context->tty_path) :
151✔
4880
                        NULL;
4881
                utmp_put_init_process(context->utmp_id, getpid_cached(), getsid(0),
151✔
4882
                                      line,
4883
                                      context->utmp_mode == EXEC_UTMP_INIT  ? INIT_PROCESS :
151✔
4884
                                      context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS :
6✔
4885
                                      USER_PROCESS,
4886
                                      username ?: username_alloc);
151✔
4887
        }
4888
#endif
4889

4890
        if (uid_is_valid(uid)) {
13,386✔
4891
                r = chown_terminal(STDIN_FILENO, uid);
2,606✔
4892
                if (r < 0) {
2,606✔
4893
                        *exit_status = EXIT_STDIN;
×
4894
                        return log_exec_error_errno(context, params, r, "Failed to change ownership of terminal: %m");
×
4895
                }
4896
        }
4897

4898
        /* We need sandboxing if the caller asked us to apply it and the command isn't explicitly excepted
4899
         * from it. */
4900
        needs_sandboxing = (params->flags & EXEC_APPLY_SANDBOXING) && !(command->flags & EXEC_COMMAND_FULLY_PRIVILEGED);
13,386✔
4901

4902
        if (params->cgroup_path) {
13,386✔
4903
                /* If delegation is enabled we'll pass ownership of the cgroup to the user of the new process. On cgroup v1
4904
                 * this is only about systemd's own hierarchy, i.e. not the controller hierarchies, simply because that's not
4905
                 * safe. On cgroup v2 there's only one hierarchy anyway, and delegation is safe there, hence in that case only
4906
                 * touch a single hierarchy too. */
4907

4908
                if (params->flags & EXEC_CGROUP_DELEGATE) {
13,386✔
4909
                        _cleanup_free_ char *p = NULL;
652✔
4910

4911
                        r = cg_set_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, uid, gid);
652✔
4912
                        if (r < 0) {
652✔
4913
                                *exit_status = EXIT_CGROUP;
×
4914
                                return log_exec_error_errno(context, params, r, "Failed to adjust control group access: %m");
×
4915
                        }
4916

4917
                        r = exec_params_get_cgroup_path(params, cgroup_context, &p);
652✔
4918
                        if (r < 0) {
652✔
4919
                                *exit_status = EXIT_CGROUP;
×
4920
                                return log_exec_error_errno(context, params, r, "Failed to acquire cgroup path: %m");
×
4921
                        }
4922
                        if (r > 0) {
652✔
4923
                                r = cg_set_access_recursive(SYSTEMD_CGROUP_CONTROLLER, p, uid, gid);
318✔
4924
                                if (r < 0) {
318✔
4925
                                        *exit_status = EXIT_CGROUP;
×
4926
                                        return log_exec_error_errno(context, params, r, "Failed to adjust control subgroup access: %m");
×
4927
                                }
4928
                        }
4929
                }
4930

4931
                if (cgroup_context && cg_unified() > 0 && is_pressure_supported() > 0) {
26,772✔
4932
                        if (cgroup_context_want_memory_pressure(cgroup_context)) {
13,386✔
4933
                                r = cg_get_path("memory", params->cgroup_path, "memory.pressure", &memory_pressure_path);
13,033✔
4934
                                if (r < 0) {
13,033✔
4935
                                        *exit_status = EXIT_MEMORY;
×
4936
                                        return log_oom();
×
4937
                                }
4938

4939
                                r = chmod_and_chown(memory_pressure_path, 0644, uid, gid);
13,033✔
4940
                                if (r < 0) {
13,033✔
4941
                                        log_exec_full_errno(context, params, r == -ENOENT || ERRNO_IS_PRIVILEGE(r) ? LOG_DEBUG : LOG_WARNING, r,
2✔
4942
                                                            "Failed to adjust ownership of '%s', ignoring: %m", memory_pressure_path);
4943
                                        memory_pressure_path = mfree(memory_pressure_path);
1✔
4944
                                }
4945
                                /* First we use the current cgroup path to chmod and chown the memory pressure path, then pass the path relative
4946
                                 * to the cgroup namespace to environment variables and mounts. If chown/chmod fails, we should not pass memory
4947
                                 * pressure path environment variable or read-write mount to the unit. This is why we check if
4948
                                 * memory_pressure_path != NULL in the conditional below. */
4949
                                if (memory_pressure_path && needs_sandboxing && exec_needs_cgroup_namespace(context, params)) {
13,033✔
4950
                                        memory_pressure_path = mfree(memory_pressure_path);
9✔
4951
                                        r = cg_get_path("memory", "", "memory.pressure", &memory_pressure_path);
9✔
4952
                                        if (r < 0) {
9✔
4953
                                                *exit_status = EXIT_MEMORY;
×
4954
                                                return log_oom();
×
4955
                                        }
4956
                                }
4957
                        } else if (cgroup_context->memory_pressure_watch == CGROUP_PRESSURE_WATCH_NO) {
353✔
4958
                                memory_pressure_path = strdup("/dev/null"); /* /dev/null is explicit indicator for turning of memory pressure watch */
×
4959
                                if (!memory_pressure_path) {
×
4960
                                        *exit_status = EXIT_MEMORY;
×
4961
                                        return log_oom();
×
4962
                                }
4963
                        }
4964
                }
4965
        }
4966

4967
        needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime);
13,386✔
4968

4969
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
80,311✔
4970
                r = setup_exec_directory(context, params, uid, gid, dt, needs_mount_namespace, exit_status);
66,926✔
4971
                if (r < 0)
66,926✔
4972
                        return log_exec_error_errno(context, params, r, "Failed to set up special execution directory in %s: %m", params->prefix[dt]);
3✔
4973
        }
4974

4975
        r = exec_setup_credentials(context, params, params->unit_id, uid, gid);
13,385✔
4976
        if (r < 0) {
11,025✔
4977
                *exit_status = EXIT_CREDENTIALS;
×
4978
                return log_exec_error_errno(context, params, r, "Failed to set up credentials: %m");
×
4979
        }
4980

4981
        r = build_environment(
11,025✔
4982
                        context,
4983
                        params,
4984
                        cgroup_context,
4985
                        n_fds,
4986
                        home,
4987
                        username,
4988
                        shell,
4989
                        journal_stream_dev,
4990
                        journal_stream_ino,
4991
                        memory_pressure_path,
4992
                        needs_sandboxing,
4993
                        &our_env);
4994
        if (r < 0) {
11,025✔
4995
                *exit_status = EXIT_MEMORY;
×
4996
                return log_oom();
×
4997
        }
4998

4999
        r = build_pass_environment(context, &pass_env);
11,025✔
5000
        if (r < 0) {
11,025✔
5001
                *exit_status = EXIT_MEMORY;
×
5002
                return log_oom();
×
5003
        }
5004

5005
        /* The $PATH variable is set to the default path in params->environment. However, this is overridden
5006
         * if user-specified fields have $PATH set. The intention is to also override $PATH if the unit does
5007
         * not specify PATH but the unit has ExecSearchPath. */
5008
        if (!strv_isempty(context->exec_search_path)) {
11,025✔
5009
                _cleanup_free_ char *joined = NULL;
×
5010

5011
                joined = strv_join(context->exec_search_path, ":");
×
5012
                if (!joined) {
×
5013
                        *exit_status = EXIT_MEMORY;
×
5014
                        return log_oom();
×
5015
                }
5016

5017
                r = strv_env_assign(&joined_exec_search_path, "PATH", joined);
×
5018
                if (r < 0) {
×
5019
                        *exit_status = EXIT_MEMORY;
×
5020
                        return log_oom();
×
5021
                }
5022
        }
5023

5024
        accum_env = strv_env_merge(params->environment,
11,025✔
5025
                                   our_env,
5026
                                   joined_exec_search_path,
5027
                                   pass_env,
5028
                                   context->environment,
5029
                                   params->files_env);
5030
        if (!accum_env) {
11,025✔
5031
                *exit_status = EXIT_MEMORY;
×
5032
                return log_oom();
×
5033
        }
5034
        accum_env = strv_env_clean(accum_env);
11,025✔
5035

5036
        (void) umask(context->umask);
11,025✔
5037

5038
        r = setup_keyring(context, params, uid, gid);
11,025✔
5039
        if (r < 0) {
11,025✔
5040
                *exit_status = EXIT_KEYRING;
×
5041
                return log_exec_error_errno(context, params, r, "Failed to set up kernel keyring: %m");
×
5042
        }
5043

5044
        /* We need setresuid() if the caller asked us to apply sandboxing and the command isn't explicitly
5045
         * excepted from either whole sandboxing or just setresuid() itself. */
5046
        needs_setuid = (params->flags & EXEC_APPLY_SANDBOXING) && !(command->flags & (EXEC_COMMAND_FULLY_PRIVILEGED|EXEC_COMMAND_NO_SETUID));
11,025✔
5047

5048
        uint64_t capability_ambient_set = context->capability_ambient_set;
11,025✔
5049

5050
        /* Check CAP_SYS_ADMIN before we enter user namespace to see if we can mount /proc even though its masked. */
5051
        has_cap_sys_admin = have_effective_cap(CAP_SYS_ADMIN) > 0;
11,025✔
5052

5053
        if (needs_sandboxing) {
11,025✔
5054
                /* MAC enablement checks need to be done before a new mount ns is created, as they rely on
5055
                 * /sys being present. The actual MAC context application will happen later, as late as
5056
                 * possible, to avoid impacting our own code paths. */
5057

5058
#if HAVE_SELINUX
5059
                use_selinux = mac_selinux_use();
5060
#endif
5061
#if ENABLE_SMACK
5062
                use_smack = mac_smack_use();
11,025✔
5063
#endif
5064
#if HAVE_APPARMOR
5065
                use_apparmor = mac_apparmor_use();
5066
#endif
5067
        }
5068

5069
        if (needs_sandboxing) {
11,025✔
5070
                int which_failed;
11,025✔
5071

5072
                /* Let's set the resource limits before we call into PAM, so that pam_limits wins over what
5073
                 * is set here. (See below.) */
5074

5075
                r = setrlimit_closest_all((const struct rlimit* const *) context->rlimit, &which_failed);
11,025✔
5076
                if (r < 0) {
11,025✔
5077
                        *exit_status = EXIT_LIMITS;
×
5078
                        return log_exec_error_errno(context, params, r, "Failed to adjust resource limit RLIMIT_%s: %m", rlimit_to_string(which_failed));
×
5079
                }
5080
        }
5081

5082
        if (needs_setuid && context->pam_name && username) {
11,025✔
5083
                /* Let's call into PAM after we set up our own idea of resource limits so that pam_limits
5084
                 * wins here. (See above.) */
5085

5086
                /* All fds passed in the fds array will be closed in the pam child process. */
5087
                r = setup_pam(context, params, username, uid, gid, &accum_env, params->fds, n_fds, params->exec_fd);
280✔
5088
                if (r < 0) {
280✔
5089
                        *exit_status = EXIT_PAM;
×
5090
                        return log_exec_error_errno(context, params, r, "Failed to set up PAM session: %m");
×
5091
                }
5092

5093
                /* PAM modules might have set some ambient caps. Query them here and merge them into
5094
                 * the caps we want to set in the end, so that we don't end up unsetting them. */
5095
                uint64_t ambient_after_pam;
280✔
5096
                r = capability_get_ambient(&ambient_after_pam);
280✔
5097
                if (r < 0) {
280✔
5098
                        *exit_status = EXIT_CAPABILITIES;
×
5099
                        return log_exec_error_errno(context, params, r, "Failed to query ambient caps: %m");
×
5100
                }
5101

5102
                capability_ambient_set |= ambient_after_pam;
280✔
5103

5104
                ngids_after_pam = getgroups_alloc(&gids_after_pam);
280✔
5105
                if (ngids_after_pam < 0) {
280✔
5106
                        *exit_status = EXIT_GROUP;
×
5107
                        return log_exec_error_errno(context, params, ngids_after_pam, "Failed to obtain groups after setting up PAM: %m");
×
5108
                }
5109
        }
5110

5111
        if (needs_sandboxing && exec_context_need_unprivileged_private_users(context, params)) {
11,025✔
5112
                /* If we're unprivileged, set up the user namespace first to enable use of the other namespaces.
5113
                 * Users with CAP_SYS_ADMIN can set up user namespaces last because they will be able to
5114
                 * set up all of the other namespaces (i.e. network, mount, UTS) without a user namespace. */
5115
                PrivateUsers pu = context->private_users;
26✔
5116
                if (pu == PRIVATE_USERS_NO)
26✔
5117
                        pu = PRIVATE_USERS_SELF;
23✔
5118

5119
                /* The kernel requires /proc/pid/setgroups be set to "deny" prior to writing /proc/pid/gid_map in
5120
                 * unprivileged user namespaces. */
5121
                r = setup_private_users(pu, saved_uid, saved_gid, uid, gid, /* allow_setgroups= */ false);
26✔
5122
                /* If it was requested explicitly and we can't set it up, fail early. Otherwise, continue and let
5123
                 * the actual requested operations fail (or silently continue). */
5124
                if (r < 0 && context->private_users != PRIVATE_USERS_NO) {
26✔
5125
                        *exit_status = EXIT_USER;
×
5126
                        return log_exec_error_errno(context, params, r, "Failed to set up user namespacing for unprivileged user: %m");
×
5127
                }
5128
                if (r < 0)
×
5129
                        log_exec_info_errno(context, params, r, "Failed to set up user namespacing for unprivileged user, ignoring: %m");
×
5130
                else {
5131
                        assert(r > 0);
26✔
5132
                        userns_set_up = true;
5133
                }
5134
        }
5135

5136
        if (exec_needs_network_namespace(context) && runtime && runtime->shared && runtime->shared->netns_storage_socket[0] >= 0) {
11,025✔
5137

5138
                /* Try to enable network namespacing if network namespacing is available and we have
5139
                 * CAP_NET_ADMIN. We need CAP_NET_ADMIN to be able to configure the loopback device in the
5140
                 * new network namespace. And if we don't have that, then we could only create a network
5141
                 * namespace without the ability to set up "lo". Hence gracefully skip things then. */
5142
                if (ns_type_supported(NAMESPACE_NET) && have_effective_cap(CAP_NET_ADMIN) > 0) {
292✔
5143
                        r = setup_shareable_ns(runtime->shared->netns_storage_socket, CLONE_NEWNET);
292✔
5144
                        if (ERRNO_IS_NEG_PRIVILEGE(r))
292✔
5145
                                log_exec_notice_errno(context, params, r,
×
5146
                                                      "PrivateNetwork=yes is configured, but network namespace setup not permitted, proceeding without: %m");
5147
                        else if (r < 0) {
292✔
5148
                                *exit_status = EXIT_NETWORK;
×
5149
                                return log_exec_error_errno(context, params, r, "Failed to set up network namespacing: %m");
×
5150
                        }
5151
                } else if (context->network_namespace_path) {
×
5152
                        *exit_status = EXIT_NETWORK;
×
5153
                        return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EOPNOTSUPP),
×
5154
                                                    "NetworkNamespacePath= is not supported, refusing.");
5155
                } else
5156
                        log_exec_notice(context, params, "PrivateNetwork=yes is configured, but the kernel does not support or we lack privileges for network namespace, proceeding without.");
×
5157
        }
5158

5159
        if (exec_needs_ipc_namespace(context) && runtime && runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) {
11,025✔
5160

5161
                if (ns_type_supported(NAMESPACE_IPC)) {
2✔
5162
                        r = setup_shareable_ns(runtime->shared->ipcns_storage_socket, CLONE_NEWIPC);
2✔
5163
                        if (ERRNO_IS_NEG_PRIVILEGE(r))
2✔
5164
                                log_exec_warning_errno(context, params, r,
×
5165
                                                       "PrivateIPC=yes is configured, but IPC namespace setup failed, ignoring: %m");
5166
                        else if (r < 0) {
2✔
5167
                                *exit_status = EXIT_NAMESPACE;
×
5168
                                return log_exec_error_errno(context, params, r, "Failed to set up IPC namespacing: %m");
×
5169
                        }
5170
                } else if (context->ipc_namespace_path) {
×
5171
                        *exit_status = EXIT_NAMESPACE;
×
5172
                        return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EOPNOTSUPP),
×
5173
                                                    "IPCNamespacePath= is not supported, refusing.");
5174
                } else
5175
                        log_exec_warning(context, params, "PrivateIPC=yes is configured, but the kernel does not support IPC namespaces, ignoring.");
×
5176
        }
5177

5178
        if (needs_sandboxing && exec_needs_cgroup_namespace(context, params)) {
11,025✔
5179
                r = unshare(CLONE_NEWCGROUP);
9✔
5180
                if (r < 0) {
9✔
5181
                        *exit_status = EXIT_NAMESPACE;
×
5182
                        return log_exec_error_errno(context, params, r, "Failed to set up cgroup namespacing: %m");
×
5183
                }
5184
        }
5185

5186
        /* Unshare a new PID namespace before setting up mounts to ensure /proc/ is mounted with only processes in PID namespace visible.
5187
         * Note PrivatePIDs=yes implies MountAPIVFS=yes so we'll always ensure procfs is remounted. */
5188
        if (needs_sandboxing && exec_needs_pid_namespace(context)) {
11,025✔
5189
                if (params->pidref_transport_fd < 0) {
16✔
5190
                        *exit_status = EXIT_NAMESPACE;
×
5191
                        return log_exec_error_errno(context, params, r, "PidRef socket is not set up: %m");
×
5192
                }
5193

5194
                /* If we had CAP_SYS_ADMIN prior to joining the user namespace, then we are privileged and don't need
5195
                 * to check if we can mount /proc/.
5196
                 *
5197
                 * We need to check prior to entering the user namespace because if we're running unprivileged or in a
5198
                 * system without CAP_SYS_ADMIN, then we can have CAP_SYS_ADMIN in the current user namespace but not
5199
                 * once we unshare a mount namespace. */
5200
                r = has_cap_sys_admin ? 1 : can_mount_proc(context, params);
16✔
5201
                if (r < 0) {
5✔
5202
                        *exit_status = EXIT_NAMESPACE;
×
5203
                        return log_exec_error_errno(context, params, r, "Failed to detect if /proc/ can be remounted: %m");
×
5204
                }
5205
                if (r == 0) {
14✔
5206
                        *exit_status = EXIT_NAMESPACE;
1✔
5207
                        return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EPERM),
1✔
5208
                                                    "PrivatePIDs=yes is configured, but /proc/ cannot be re-mounted due to lack of privileges, refusing.");
5209
                }
5210

5211
                r = setup_private_pids(context, params);
13✔
5212
                if (r < 0) {
6✔
5213
                        *exit_status = EXIT_NAMESPACE;
×
5214
                        return log_exec_error_errno(context, params, r, "Failed to set up pid namespace: %m");
×
5215
                }
5216
        }
5217

5218
        /* If PrivatePIDs= yes is configured, we're now running as pid 1 in a pid namespace! */
5219

5220
        if (needs_mount_namespace) {
11,015✔
5221
                _cleanup_free_ char *error_path = NULL;
2,540✔
5222

5223
                r = apply_mount_namespace(command->flags,
2,540✔
5224
                                          context,
5225
                                          params,
5226
                                          runtime,
5227
                                          memory_pressure_path,
5228
                                          needs_sandboxing,
5229
                                          &error_path,
5230
                                          uid,
5231
                                          gid);
5232
                if (r < 0) {
2,540✔
5233
                        *exit_status = EXIT_NAMESPACE;
15✔
5234
                        return log_exec_error_errno(context, params, r, "Failed to set up mount namespacing%s%s: %m",
59✔
5235
                                                    error_path ? ": " : "", strempty(error_path));
5236
                }
5237
        }
5238

5239
        if (needs_sandboxing) {
11,000✔
5240
                r = apply_protect_hostname(context, params, exit_status);
11,000✔
5241
                if (r < 0)
11,000✔
5242
                        return r;
5243
        }
5244

5245
        if (context->memory_ksm >= 0)
11,000✔
5246
                if (prctl(PR_SET_MEMORY_MERGE, context->memory_ksm, 0, 0, 0) < 0) {
×
5247
                        if (ERRNO_IS_NOT_SUPPORTED(errno))
×
5248
                                log_exec_debug_errno(context,
×
5249
                                                     params,
5250
                                                     errno,
5251
                                                     "KSM support not available, ignoring.");
5252
                        else {
5253
                                *exit_status = EXIT_KSM;
×
5254
                                return log_exec_error_errno(context, params, errno, "Failed to set KSM: %m");
×
5255
                        }
5256
                }
5257

5258
        /* Drop groups as early as possible.
5259
         * This needs to be done after PrivateDevices=yes setup as device nodes should be owned by the host's root.
5260
         * For non-root in a userns, devices will be owned by the user/group before the group change, and nobody. */
5261
        if (needs_setuid) {
11,000✔
5262
                _cleanup_free_ gid_t *gids_to_enforce = NULL;
11,000✔
5263
                int ngids_to_enforce = 0;
11,000✔
5264

5265
                ngids_to_enforce = merge_gid_lists(supplementary_gids,
11,000✔
5266
                                                   ngids,
5267
                                                   gids_after_pam,
5268
                                                   ngids_after_pam,
5269
                                                   &gids_to_enforce);
5270
                if (ngids_to_enforce < 0) {
11,000✔
5271
                        *exit_status = EXIT_GROUP;
×
5272
                        return log_exec_error_errno(context, params,
×
5273
                                                    ngids_to_enforce,
5274
                                                    "Failed to merge group lists. Group membership might be incorrect: %m");
5275
                }
5276

5277
                r = enforce_groups(gid, gids_to_enforce, ngids_to_enforce);
11,000✔
5278
                if (r < 0) {
11,000✔
5279
                        *exit_status = EXIT_GROUP;
1✔
5280
                        return log_exec_error_errno(context, params, r, "Changing group credentials failed: %m");
1✔
5281
                }
5282
        }
5283

5284
        /* If the user namespace was not set up above, try to do it now.
5285
         * It's preferred to set up the user namespace later (after all other namespaces) so as not to be
5286
         * restricted by rules pertaining to combining user namespaces with other namespaces (e.g. in the
5287
         * case of mount namespaces being less privileged when the mount point list is copied from a
5288
         * different user namespace). */
5289

5290
        if (needs_sandboxing && !userns_set_up) {
10,999✔
5291
                r = setup_private_users(context->private_users, saved_uid, saved_gid, uid, gid,
21,958✔
5292
                                        /* allow_setgroups= */ context->private_users == PRIVATE_USERS_FULL);
10,979✔
5293
                if (r < 0) {
10,979✔
5294
                        *exit_status = EXIT_USER;
×
5295
                        return log_exec_error_errno(context, params, r, "Failed to set up user namespacing: %m");
×
5296
                }
5297
        }
5298

5299
        /* Now that the mount namespace has been set up and privileges adjusted, let's look for the thing we
5300
         * shall execute. */
5301

5302
        _cleanup_free_ char *executable = NULL;
5✔
5303
        _cleanup_close_ int executable_fd = -EBADF;
5✔
5304
        r = find_executable_full(command->path, /* root= */ NULL, context->exec_search_path, false, &executable, &executable_fd);
10,999✔
5305
        if (r < 0) {
10,999✔
5306
                *exit_status = EXIT_EXEC;
1✔
5307
                log_exec_struct_errno(context, params, LOG_NOTICE, r,
3✔
5308
                                      "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR,
5309
                                      LOG_EXEC_MESSAGE(params,
5310
                                                       "Unable to locate executable '%s': %m",
5311
                                                       command->path),
5312
                                      "EXECUTABLE=%s", command->path);
5313
                /* If the error will be ignored by manager, tune down the log level here. Missing executable
5314
                 * is very much expected in this case. */
5315
                return r != -ENOMEM && FLAGS_SET(command->flags, EXEC_COMMAND_IGNORE_FAILURE) ? 1 : r;
1✔
5316
        }
5317

5318
        r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, &executable_fd);
10,998✔
5319
        if (r < 0) {
10,998✔
5320
                *exit_status = EXIT_FDS;
×
5321
                return log_exec_error_errno(context, params, r, "Failed to collect shifted fd: %m");
×
5322
        }
5323

5324
#if HAVE_SELINUX
5325
        if (needs_sandboxing && use_selinux && params->selinux_context_net) {
5326
                int fd = -EBADF;
5327

5328
                if (socket_fd >= 0)
5329
                        fd = socket_fd;
5330
                else if (params->n_socket_fds == 1)
5331
                        /* If stdin is not connected to a socket but we are triggered by exactly one socket unit then we
5332
                         * use context from that fd to compute the label. */
5333
                        fd = params->fds[0];
5334

5335
                if (fd >= 0) {
5336
                        r = mac_selinux_get_child_mls_label(fd, executable, context->selinux_context, &mac_selinux_context_net);
5337
                        if (r < 0) {
5338
                                if (!context->selinux_context_ignore) {
5339
                                        *exit_status = EXIT_SELINUX_CONTEXT;
5340
                                        return log_exec_error_errno(context,
5341
                                                                    params,
5342
                                                                    r,
5343
                                                                    "Failed to determine SELinux context: %m");
5344
                                }
5345
                                log_exec_debug_errno(context,
5346
                                                     params,
5347
                                                     r,
5348
                                                     "Failed to determine SELinux context, ignoring: %m");
5349
                        }
5350
                }
5351
        }
5352
#endif
5353

5354
        /* We repeat the fd closing here, to make sure that nothing is leaked from the PAM modules. Note that
5355
         * we are more aggressive this time, since we don't need socket_fd and the netns and ipcns fds any
5356
         * more. We do keep exec_fd and handoff_timestamp_fd however, if we have it, since we need to keep
5357
         * them open until the final execve(). But first, close the remaining sockets in the context
5358
         * objects. */
5359

5360
        exec_runtime_close(runtime);
10,998✔
5361
        exec_params_close(params);
10,998✔
5362

5363
        r = close_all_fds(keep_fds, n_keep_fds);
10,998✔
5364
        if (r >= 0)
10,998✔
5365
                r = pack_fds(params->fds, n_fds);
10,998✔
5366
        if (r >= 0)
10,998✔
5367
                r = flag_fds(params->fds, n_socket_fds, n_fds, context->non_blocking);
10,998✔
5368
        if (r < 0) {
10,998✔
5369
                *exit_status = EXIT_FDS;
×
5370
                return log_exec_error_errno(context, params, r, "Failed to adjust passed file descriptors: %m");
×
5371
        }
5372

5373
        /* At this point, the fds we want to pass to the program are all ready and set up, with O_CLOEXEC turned off
5374
         * and at the right fd numbers. The are no other fds open, with one exception: the exec_fd if it is defined,
5375
         * and it has O_CLOEXEC set, after all we want it to be closed by the execve(), so that our parent knows we
5376
         * came this far. */
5377

5378
        secure_bits = context->secure_bits;
10,998✔
5379

5380
        if (needs_sandboxing) {
10,998✔
5381
                uint64_t bset;
10,998✔
5382

5383
                /* Set the RTPRIO resource limit to 0, but only if nothing else was explicitly requested.
5384
                 * (Note this is placed after the general resource limit initialization, see above, in order
5385
                 * to take precedence.) */
5386
                if (context->restrict_realtime && !context->rlimit[RLIMIT_RTPRIO]) {
10,998✔
5387
                        if (setrlimit(RLIMIT_RTPRIO, &RLIMIT_MAKE_CONST(0)) < 0) {
2,038✔
5388
                                *exit_status = EXIT_LIMITS;
×
5389
                                return log_exec_error_errno(context, params, errno, "Failed to adjust RLIMIT_RTPRIO resource limit: %m");
×
5390
                        }
5391
                }
5392

5393
#if ENABLE_SMACK
5394
                /* LSM Smack needs the capability CAP_MAC_ADMIN to change the current execution security context of the
5395
                 * process. This is the latest place before dropping capabilities. Other MAC context are set later. */
5396
                if (use_smack) {
10,998✔
5397
                        r = setup_smack(params, context, executable_fd);
×
5398
                        if (r < 0 && !context->smack_process_label_ignore) {
×
5399
                                *exit_status = EXIT_SMACK_PROCESS_LABEL;
×
5400
                                return log_exec_error_errno(context, params, r, "Failed to set SMACK process label: %m");
×
5401
                        }
5402
                }
5403
#endif
5404

5405
                bset = context->capability_bounding_set;
10,998✔
5406

5407
#if HAVE_SECCOMP
5408
                /* If the service has any form of a seccomp filter and it allows dropping privileges, we'll
5409
                 * keep the needed privileges to apply it even if we're not root. */
5410
                if (needs_setuid &&
21,996✔
5411
                    uid_is_valid(uid) &&
12,959✔
5412
                    context_has_seccomp(context) &&
2,797✔
5413
                    seccomp_allows_drop_privileges(context)) {
836✔
5414
                        keep_seccomp_privileges = true;
836✔
5415

5416
                        if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
836✔
5417
                                *exit_status = EXIT_USER;
×
5418
                                return log_exec_error_errno(context, params, errno, "Failed to enable keep capabilities flag: %m");
×
5419
                        }
5420

5421
                        /* Save the current bounding set so we can restore it after applying the seccomp
5422
                         * filter */
5423
                        saved_bset = bset;
836✔
5424
                        bset |= (UINT64_C(1) << CAP_SYS_ADMIN) |
836✔
5425
                                (UINT64_C(1) << CAP_SETPCAP);
5426
                }
5427
#endif
5428

5429
                if (!cap_test_all(bset)) {
10,998✔
5430
                        r = capability_bounding_set_drop(bset, /* right_now= */ false);
2,218✔
5431
                        if (r < 0) {
2,218✔
5432
                                *exit_status = EXIT_CAPABILITIES;
×
5433
                                return log_exec_error_errno(context, params, r, "Failed to drop capabilities: %m");
×
5434
                        }
5435
                }
5436

5437
                /* Ambient capabilities are cleared during setresuid() (in enforce_user()) even with
5438
                 * keep-caps set.
5439
                 *
5440
                 * To be able to raise the ambient capabilities after setresuid() they have to be added to
5441
                 * the inherited set and keep caps has to be set (done in enforce_user()).  After setresuid()
5442
                 * the ambient capabilities can be raised as they are present in the permitted and
5443
                 * inhertiable set. However it is possible that someone wants to set ambient capabilities
5444
                 * without changing the user, so we also set the ambient capabilities here.
5445
                 *
5446
                 * The requested ambient capabilities are raised in the inheritable set if the second
5447
                 * argument is true. */
5448
                if (capability_ambient_set != 0) {
10,998✔
5449
                        r = capability_ambient_set_apply(capability_ambient_set, /* also_inherit= */ true);
841✔
5450
                        if (r < 0) {
841✔
5451
                                *exit_status = EXIT_CAPABILITIES;
×
5452
                                return log_exec_error_errno(context, params, r, "Failed to apply ambient capabilities (before UID change): %m");
×
5453
                        }
5454
                }
5455
        }
5456

5457
        /* chroot to root directory first, before we lose the ability to chroot */
5458
        r = apply_root_directory(context, params, runtime, needs_mount_namespace, exit_status);
10,998✔
5459
        if (r < 0)
10,998✔
5460
                return log_exec_error_errno(context, params, r, "Chrooting to the requested root directory failed: %m");
×
5461

5462
        if (needs_setuid) {
10,998✔
5463
                if (uid_is_valid(uid)) {
10,998✔
5464
                        r = enforce_user(context, uid, capability_ambient_set);
1,961✔
5465
                        if (r < 0) {
1,961✔
5466
                                *exit_status = EXIT_USER;
×
5467
                                return log_exec_error_errno(context, params, r, "Failed to change UID to " UID_FMT ": %m", uid);
×
5468
                        }
5469

5470
                        if (keep_seccomp_privileges) {
1,961✔
5471
                                if (!BIT_SET(capability_ambient_set, CAP_SETUID)) {
836✔
5472
                                        r = drop_capability(CAP_SETUID);
836✔
5473
                                        if (r < 0) {
836✔
5474
                                                *exit_status = EXIT_USER;
×
5475
                                                return log_exec_error_errno(context, params, r, "Failed to drop CAP_SETUID: %m");
×
5476
                                        }
5477
                                }
5478

5479
                                r = keep_capability(CAP_SYS_ADMIN);
836✔
5480
                                if (r < 0) {
836✔
5481
                                        *exit_status = EXIT_USER;
×
5482
                                        return log_exec_error_errno(context, params, r, "Failed to keep CAP_SYS_ADMIN: %m");
×
5483
                                }
5484

5485
                                r = keep_capability(CAP_SETPCAP);
836✔
5486
                                if (r < 0) {
836✔
5487
                                        *exit_status = EXIT_USER;
×
5488
                                        return log_exec_error_errno(context, params, r, "Failed to keep CAP_SETPCAP: %m");
×
5489
                                }
5490
                        }
5491

5492
                        if (capability_ambient_set != 0) {
1,961✔
5493

5494
                                /* Raise the ambient capabilities after user change. */
5495
                                r = capability_ambient_set_apply(capability_ambient_set, /* also_inherit= */ false);
840✔
5496
                                if (r < 0) {
840✔
5497
                                        *exit_status = EXIT_CAPABILITIES;
×
5498
                                        return log_exec_error_errno(context, params, r, "Failed to apply ambient capabilities (after UID change): %m");
×
5499
                                }
5500
                        }
5501
                }
5502
        }
5503

5504
        /* Apply working directory here, because the working directory might be on NFS and only the user
5505
         * running this service might have the correct privilege to change to the working directory. Also, it
5506
         * is absolutely 💣 crucial 💣 we applied all mount namespacing rearrangements before this, so that
5507
         * the cwd cannot be used to pin directories outside of the sandbox. */
5508
        r = apply_working_directory(context, params, runtime, home);
10,998✔
5509
        if (r < 0) {
10,998✔
5510
                *exit_status = EXIT_CHDIR;
1✔
5511
                return log_exec_error_errno(context, params, r, "Changing to the requested working directory failed: %m");
3✔
5512
        }
5513

5514
        if (needs_sandboxing) {
10,997✔
5515
                /* Apply other MAC contexts late, but before seccomp syscall filtering, as those should really be last to
5516
                 * influence our own codepaths as little as possible. Moreover, applying MAC contexts usually requires
5517
                 * syscalls that are subject to seccomp filtering, hence should probably be applied before the syscalls
5518
                 * are restricted. */
5519

5520
#if HAVE_SELINUX
5521
                if (use_selinux) {
5522
                        char *exec_context = mac_selinux_context_net ?: context->selinux_context;
5523

5524
                        if (exec_context) {
5525
                                r = setexeccon(exec_context);
5526
                                if (r < 0) {
5527
                                        if (!context->selinux_context_ignore) {
5528
                                                *exit_status = EXIT_SELINUX_CONTEXT;
5529
                                                return log_exec_error_errno(context, params, r, "Failed to change SELinux context to %s: %m", exec_context);
5530
                                        }
5531
                                        log_exec_debug_errno(context,
5532
                                                             params,
5533
                                                             r,
5534
                                                             "Failed to change SELinux context to %s, ignoring: %m",
5535
                                                             exec_context);
5536
                                }
5537
                        }
5538
                }
5539
#endif
5540

5541
#if HAVE_APPARMOR
5542
                if (use_apparmor && context->apparmor_profile) {
5543
                        r = aa_change_onexec(context->apparmor_profile);
5544
                        if (r < 0 && !context->apparmor_profile_ignore) {
5545
                                *exit_status = EXIT_APPARMOR_PROFILE;
5546
                                return log_exec_error_errno(context,
5547
                                                            params,
5548
                                                            errno,
5549
                                                            "Failed to prepare AppArmor profile change to %s: %m",
5550
                                                            context->apparmor_profile);
5551
                        }
5552
                }
5553
#endif
5554

5555
                /* PR_GET_SECUREBITS is not privileged, while PR_SET_SECUREBITS is. So to suppress potential
5556
                 * EPERMs we'll try not to call PR_SET_SECUREBITS unless necessary. Setting securebits
5557
                 * requires CAP_SETPCAP. */
5558
                if (prctl(PR_GET_SECUREBITS) != secure_bits) {
10,997✔
5559
                        /* CAP_SETPCAP is required to set securebits. This capability is raised into the
5560
                         * effective set here.
5561
                         *
5562
                         * The effective set is overwritten during execve() with the following values:
5563
                         *
5564
                         * - ambient set (for non-root processes)
5565
                         *
5566
                         * - (inheritable | bounding) set for root processes)
5567
                         *
5568
                         * Hence there is no security impact to raise it in the effective set before execve
5569
                         */
5570
                        r = capability_gain_cap_setpcap(/* ret_before_caps = */ NULL);
889✔
5571
                        if (r < 0) {
889✔
5572
                                *exit_status = EXIT_CAPABILITIES;
×
5573
                                return log_exec_error_errno(context, params, r, "Failed to gain CAP_SETPCAP for setting secure bits");
×
5574
                        }
5575
                        if (prctl(PR_SET_SECUREBITS, secure_bits) < 0) {
889✔
5576
                                *exit_status = EXIT_SECUREBITS;
×
5577
                                return log_exec_error_errno(context, params, errno, "Failed to set process secure bits: %m");
×
5578
                        }
5579
                }
5580

5581
                if (context_has_no_new_privileges(context))
10,997✔
5582
                        if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
1,912✔
5583
                                *exit_status = EXIT_NO_NEW_PRIVILEGES;
×
5584
                                return log_exec_error_errno(context, params, errno, "Failed to disable new privileges: %m");
×
5585
                        }
5586

5587
#if HAVE_SECCOMP
5588
                r = apply_address_families(context, params);
10,997✔
5589
                if (r < 0) {
10,997✔
5590
                        *exit_status = EXIT_ADDRESS_FAMILIES;
×
5591
                        return log_exec_error_errno(context, params, r, "Failed to restrict address families: %m");
×
5592
                }
5593

5594
                r = apply_memory_deny_write_execute(context, params);
10,997✔
5595
                if (r < 0) {
10,997✔
5596
                        *exit_status = EXIT_SECCOMP;
×
5597
                        return log_exec_error_errno(context, params, r, "Failed to disable writing to executable memory: %m");
×
5598
                }
5599

5600
                r = apply_restrict_realtime(context, params);
10,997✔
5601
                if (r < 0) {
10,997✔
5602
                        *exit_status = EXIT_SECCOMP;
×
5603
                        return log_exec_error_errno(context, params, r, "Failed to apply realtime restrictions: %m");
×
5604
                }
5605

5606
                r = apply_restrict_suid_sgid(context, params);
10,997✔
5607
                if (r < 0) {
10,997✔
5608
                        *exit_status = EXIT_SECCOMP;
×
5609
                        return log_exec_error_errno(context, params, r, "Failed to apply SUID/SGID restrictions: %m");
×
5610
                }
5611

5612
                r = apply_restrict_namespaces(context, params);
10,997✔
5613
                if (r < 0) {
10,997✔
5614
                        *exit_status = EXIT_SECCOMP;
×
5615
                        return log_exec_error_errno(context, params, r, "Failed to apply namespace restrictions: %m");
×
5616
                }
5617

5618
                r = apply_protect_sysctl(context, params);
10,997✔
5619
                if (r < 0) {
10,997✔
5620
                        *exit_status = EXIT_SECCOMP;
×
5621
                        return log_exec_error_errno(context, params, r, "Failed to apply sysctl restrictions: %m");
×
5622
                }
5623

5624
                r = apply_protect_kernel_modules(context, params);
10,997✔
5625
                if (r < 0) {
10,997✔
5626
                        *exit_status = EXIT_SECCOMP;
×
5627
                        return log_exec_error_errno(context, params, r, "Failed to apply module loading restrictions: %m");
×
5628
                }
5629

5630
                r = apply_protect_kernel_logs(context, params);
10,997✔
5631
                if (r < 0) {
10,997✔
5632
                        *exit_status = EXIT_SECCOMP;
×
5633
                        return log_exec_error_errno(context, params, r, "Failed to apply kernel log restrictions: %m");
×
5634
                }
5635

5636
                r = apply_protect_clock(context, params);
10,997✔
5637
                if (r < 0) {
10,997✔
5638
                        *exit_status = EXIT_SECCOMP;
×
5639
                        return log_exec_error_errno(context, params, r, "Failed to apply clock restrictions: %m");
×
5640
                }
5641

5642
                r = apply_private_devices(context, params);
10,997✔
5643
                if (r < 0) {
10,997✔
5644
                        *exit_status = EXIT_SECCOMP;
×
5645
                        return log_exec_error_errno(context, params, r, "Failed to set up private devices: %m");
×
5646
                }
5647

5648
                r = apply_syscall_archs(context, params);
10,997✔
5649
                if (r < 0) {
10,997✔
5650
                        *exit_status = EXIT_SECCOMP;
×
5651
                        return log_exec_error_errno(context, params, r, "Failed to apply syscall architecture restrictions: %m");
×
5652
                }
5653

5654
                r = apply_lock_personality(context, params);
10,997✔
5655
                if (r < 0) {
10,997✔
5656
                        *exit_status = EXIT_SECCOMP;
×
5657
                        return log_exec_error_errno(context, params, r, "Failed to lock personalities: %m");
×
5658
                }
5659

5660
                r = apply_syscall_log(context, params);
10,997✔
5661
                if (r < 0) {
10,997✔
5662
                        *exit_status = EXIT_SECCOMP;
×
5663
                        return log_exec_error_errno(context, params, r, "Failed to apply system call log filters: %m");
×
5664
                }
5665
#endif
5666

5667
#if HAVE_LIBBPF
5668
                r = apply_restrict_filesystems(context, params);
10,997✔
5669
                if (r < 0) {
10,997✔
5670
                        *exit_status = EXIT_BPF;
×
5671
                        return log_exec_error_errno(context, params, r, "Failed to restrict filesystems: %m");
×
5672
                }
5673
#endif
5674

5675
#if HAVE_SECCOMP
5676
                /* This really should remain as close to the execve() as possible, to make sure our own code is affected
5677
                 * by the filter as little as possible. */
5678
                r = apply_syscall_filter(context, params);
10,997✔
5679
                if (r < 0) {
10,997✔
5680
                        *exit_status = EXIT_SECCOMP;
×
5681
                        return log_exec_error_errno(context, params, r, "Failed to apply system call filters: %m");
×
5682
                }
5683

5684
                if (keep_seccomp_privileges) {
10,997✔
5685
                        /* Restore the capability bounding set with what's expected from the service + the
5686
                         * ambient capabilities hack */
5687
                        if (!cap_test_all(saved_bset)) {
835✔
5688
                                r = capability_bounding_set_drop(saved_bset, /* right_now= */ false);
800✔
5689
                                if (r < 0) {
800✔
5690
                                        *exit_status = EXIT_CAPABILITIES;
×
5691
                                        return log_exec_error_errno(context, params, r, "Failed to drop bset capabilities: %m");
×
5692
                                }
5693
                        }
5694

5695
                        /* Only drop CAP_SYS_ADMIN if it's not in the bounding set, otherwise we'll break
5696
                         * applications that use it. */
5697
                        if (!BIT_SET(saved_bset, CAP_SYS_ADMIN)) {
835✔
5698
                                r = drop_capability(CAP_SYS_ADMIN);
382✔
5699
                                if (r < 0) {
382✔
5700
                                        *exit_status = EXIT_USER;
×
5701
                                        return log_exec_error_errno(context, params, r, "Failed to drop CAP_SYS_ADMIN: %m");
×
5702
                                }
5703
                        }
5704

5705
                        /* Only drop CAP_SETPCAP if it's not in the bounding set, otherwise we'll break
5706
                         * applications that use it. */
5707
                        if (!BIT_SET(saved_bset, CAP_SETPCAP)) {
835✔
5708
                                r = drop_capability(CAP_SETPCAP);
579✔
5709
                                if (r < 0) {
579✔
5710
                                        *exit_status = EXIT_USER;
×
5711
                                        return log_exec_error_errno(context, params, r, "Failed to drop CAP_SETPCAP: %m");
×
5712
                                }
5713
                        }
5714

5715
                        if (prctl(PR_SET_KEEPCAPS, 0) < 0) {
835✔
5716
                                *exit_status = EXIT_USER;
×
5717
                                return log_exec_error_errno(context, params, errno, "Failed to drop keep capabilities flag: %m");
×
5718
                        }
5719
                }
5720
#endif
5721

5722
        }
5723

5724
        if (!strv_isempty(context->unset_environment)) {
10,997✔
5725
                char **ee = NULL;
37✔
5726

5727
                ee = strv_env_delete(accum_env, 1, context->unset_environment);
37✔
5728
                if (!ee) {
37✔
5729
                        *exit_status = EXIT_MEMORY;
×
5730
                        return log_oom();
5✔
5731
                }
5732

5733
                strv_free_and_replace(accum_env, ee);
37✔
5734
        }
5735

5736
        if (!FLAGS_SET(command->flags, EXEC_COMMAND_NO_ENV_EXPAND)) {
10,997✔
5737
                _cleanup_strv_free_ char **unset_variables = NULL, **bad_variables = NULL;
10,897✔
5738

5739
                r = replace_env_argv(command->argv, accum_env, &replaced_argv, &unset_variables, &bad_variables);
10,897✔
5740
                if (r < 0) {
10,897✔
5741
                        *exit_status = EXIT_MEMORY;
×
5742
                        return log_exec_error_errno(context,
×
5743
                                                    params,
5744
                                                    r,
5745
                                                    "Failed to replace environment variables: %m");
5746
                }
5747
                final_argv = replaced_argv;
10,897✔
5748

5749
                if (!strv_isempty(unset_variables)) {
10,897✔
5750
                        _cleanup_free_ char *ju = strv_join(unset_variables, ", ");
10✔
5751
                        log_exec_warning(context,
15✔
5752
                                         params,
5753
                                         "Referenced but unset environment variable evaluates to an empty string: %s",
5754
                                         strna(ju));
5755
                }
5756

5757
                if (!strv_isempty(bad_variables)) {
10,897✔
5758
                        _cleanup_free_ char *jb = strv_join(bad_variables, ", ");
×
5759
                        log_exec_warning(context,
×
5760
                                         params,
5761
                                         "Invalid environment variable name evaluates to an empty string: %s",
5762
                                         strna(jb));
5763
                }
5764
        } else
5765
                final_argv = command->argv;
100✔
5766

5767
        log_command_line(context, params, "Executing", executable, final_argv);
10,997✔
5768

5769
        /* We have finished with all our initializations. Let's now let the manager know that. From this
5770
         * point on, if the manager sees POLLHUP on the exec_fd, then execve() was successful. */
5771

5772
        r = exec_fd_mark_hot(context, params, /* hot= */ true, exit_status);
10,997✔
5773
        if (r < 0)
10,997✔
5774
                return r;
5775

5776
        /* As last thing before the execve(), let's send the handoff timestamp */
5777
        r = send_handoff_timestamp(context, params, exit_status);
10,997✔
5778
        if (r < 0) {
10,997✔
5779
                /* If this handoff timestamp failed, let's undo the marking as hot */
5780
                (void) exec_fd_mark_hot(context, params, /* hot= */ false, /* reterr_exit_status= */ NULL);
×
5781
                return r;
5782
        }
5783

5784
        /* NB: we leave executable_fd, exec_fd, handoff_timestamp_fd open here. This is safe, because they
5785
         * have O_CLOEXEC set, and the execve() below will thus automatically close them. In fact, for
5786
         * exec_fd this is pretty much the whole raison d'etre. */
5787

5788
        r = fexecve_or_execve(executable_fd, executable, final_argv, accum_env);
10,997✔
5789

5790
        /* The execve() failed, let's undo the marking as hot */
5791
        (void) exec_fd_mark_hot(context, params, /* hot= */ false, /* reterr_exit_status= */ NULL);
3✔
5792

5793
        *exit_status = EXIT_EXEC;
3✔
5794
        return log_exec_error_errno(context, params, r, "Failed to execute %s: %m", executable);
9✔
5795
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc