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

systemd / systemd / 20417900562

21 Dec 2025 07:31PM UTC coverage: 72.5% (-0.2%) from 72.701%
20417900562

push

github

DaanDeMeyer
mkosi: Use initrd as exitrd

Let's speed up image builds by avoiding building
an exitrd and instead reusing the initrd image for
the same purpose.

309142 of 426400 relevant lines covered (72.5%)

1141502.27 hits per line

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

71.35
/src/core/execute-serialize.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <unistd.h>
4

5
#include "af-list.h"
6
#include "capability-util.h"
7
#include "cgroup.h"
8
#include "dissect-image.h"
9
#include "dynamic-user.h"
10
#include "escape.h"
11
#include "exec-credential.h"
12
#include "execute.h"
13
#include "execute-serialize.h"
14
#include "extract-word.h"
15
#include "fd-util.h"
16
#include "hexdecoct.h"
17
#include "image-policy.h"
18
#include "in-addr-prefix-util.h"
19
#include "log.h"
20
#include "nsflags.h"
21
#include "open-file.h"
22
#include "ordered-set.h"
23
#include "parse-helpers.h"
24
#include "parse-util.h"
25
#include "path-util.h"
26
#include "process-util.h"
27
#include "rlimit-util.h"
28
#include "serialize.h"
29
#include "set.h"
30
#include "string-util.h"
31
#include "strv.h"
32
#include "time-util.h"
33

34
static int exec_cgroup_context_serialize(const CGroupContext *c, FILE *f) {
2,430✔
35
        _cleanup_free_ char *disable_controllers_str = NULL, *delegate_controllers_str = NULL,
×
36
                            *cpuset_cpus = NULL, *cpuset_mems = NULL, *startup_cpuset_cpus = NULL,
×
37
                            *startup_cpuset_mems = NULL;
2,430✔
38
        char *iface;
2,430✔
39
        struct in_addr_prefix *iaai;
2,430✔
40
        int r;
2,430✔
41

42
        assert(f);
2,430✔
43

44
        if (!c)
2,430✔
45
                return 0;
46

47
        r = serialize_bool_elide(f, "exec-cgroup-context-io-accounting", c->io_accounting);
2,430✔
48
        if (r < 0)
2,430✔
49
                return r;
50

51
        r = serialize_bool_elide(f, "exec-cgroup-context-memory-accounting", c->memory_accounting);
2,430✔
52
        if (r < 0)
2,430✔
53
                return r;
54

55
        r = serialize_bool_elide(f, "exec-cgroup-context-tasks-accounting", c->tasks_accounting);
2,430✔
56
        if (r < 0)
2,430✔
57
                return r;
58

59
        r = serialize_bool_elide(f, "exec-cgroup-context-ip-accounting", c->ip_accounting);
2,430✔
60
        if (r < 0)
2,430✔
61
                return r;
62

63
        r = serialize_bool_elide(f, "exec-cgroup-context-memory-oom-group", c->memory_oom_group);
2,430✔
64
        if (r < 0)
2,430✔
65
                return r;
66

67
        if (c->cpu_weight != CGROUP_WEIGHT_INVALID) {
2,430✔
68
                r = serialize_item_format(f, "exec-cgroup-context-cpu-weight", "%" PRIu64, c->cpu_weight);
×
69
                if (r < 0)
×
70
                        return r;
71
        }
72

73
        if (c->startup_cpu_weight != CGROUP_WEIGHT_INVALID) {
2,430✔
74
                r = serialize_item_format(f, "exec-cgroup-context-startup-cpu-weight", "%" PRIu64, c->startup_cpu_weight);
×
75
                if (r < 0)
×
76
                        return r;
77
        }
78

79
        if (c->cpu_quota_per_sec_usec != USEC_INFINITY) {
2,430✔
80
                r = serialize_usec(f, "exec-cgroup-context-cpu-quota-per-sec-usec", c->cpu_quota_per_sec_usec);
×
81
                if (r < 0)
×
82
                        return r;
83
        }
84

85
        if (c->cpu_quota_period_usec != USEC_INFINITY) {
2,430✔
86
                r = serialize_usec(f, "exec-cgroup-context-cpu-quota-period-usec", c->cpu_quota_period_usec);
×
87
                if (r < 0)
×
88
                        return r;
89
        }
90

91
        cpuset_cpus = cpu_set_to_range_string(&c->cpuset_cpus);
2,430✔
92
        if (!cpuset_cpus)
2,430✔
93
                return log_oom_debug();
×
94

95
        r = serialize_item(f, "exec-cgroup-context-allowed-cpus", cpuset_cpus);
2,430✔
96
        if (r < 0)
2,430✔
97
                return r;
98

99
        startup_cpuset_cpus = cpu_set_to_range_string(&c->startup_cpuset_cpus);
2,430✔
100
        if (!startup_cpuset_cpus)
2,430✔
101
                return log_oom_debug();
×
102

103
        r = serialize_item(f, "exec-cgroup-context-startup-allowed-cpus", startup_cpuset_cpus);
2,430✔
104
        if (r < 0)
2,430✔
105
                return r;
106

107
        cpuset_mems = cpu_set_to_range_string(&c->cpuset_mems);
2,430✔
108
        if (!cpuset_mems)
2,430✔
109
                return log_oom_debug();
×
110

111
        r = serialize_item(f, "exec-cgroup-context-allowed-memory-nodes", cpuset_mems);
2,430✔
112
        if (r < 0)
2,430✔
113
                return r;
114

115
        startup_cpuset_mems = cpu_set_to_range_string(&c->startup_cpuset_mems);
2,430✔
116
        if (!startup_cpuset_mems)
2,430✔
117
                return log_oom_debug();
×
118

119
        r = serialize_item(f, "exec-cgroup-context-startup-allowed-memory-nodes", startup_cpuset_mems);
2,430✔
120
        if (r < 0)
2,430✔
121
                return r;
122

123
        if (c->io_weight != CGROUP_WEIGHT_INVALID) {
2,430✔
124
                r = serialize_item_format(f, "exec-cgroup-context-io-weight", "%" PRIu64, c->io_weight);
×
125
                if (r < 0)
×
126
                        return r;
127
        }
128

129
        if (c->startup_io_weight != CGROUP_WEIGHT_INVALID) {
2,430✔
130
                r = serialize_item_format(f, "exec-cgroup-context-startup-io-weight", "%" PRIu64, c->startup_io_weight);
×
131
                if (r < 0)
×
132
                        return r;
133
        }
134

135
        if (c->default_memory_min > 0) {
2,430✔
136
                r = serialize_item_format(f, "exec-cgroup-context-default-memory-min", "%" PRIu64, c->default_memory_min);
×
137
                if (r < 0)
×
138
                        return r;
139
        }
140

141
        if (c->default_memory_low > 0) {
2,430✔
142
                r = serialize_item_format(f, "exec-cgroup-context-default-memory-low", "%" PRIu64, c->default_memory_low);
×
143
                if (r < 0)
×
144
                        return r;
145
        }
146

147
        if (c->memory_min > 0) {
2,430✔
148
                r = serialize_item_format(f, "exec-cgroup-context-memory-min", "%" PRIu64, c->memory_min);
×
149
                if (r < 0)
×
150
                        return r;
151
        }
152

153
        if (c->memory_low > 0) {
2,430✔
154
                r = serialize_item_format(f, "exec-cgroup-context-memory-low", "%" PRIu64, c->memory_low);
×
155
                if (r < 0)
×
156
                        return r;
157
        }
158

159
        if (c->startup_memory_low > 0) {
2,430✔
160
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-low", "%" PRIu64, c->startup_memory_low);
×
161
                if (r < 0)
×
162
                        return r;
163
        }
164

165
        if (c->memory_high != CGROUP_LIMIT_MAX) {
2,430✔
166
                r = serialize_item_format(f, "exec-cgroup-context-memory-high", "%" PRIu64, c->memory_high);
2✔
167
                if (r < 0)
2✔
168
                        return r;
169
        }
170

171
        if (c->startup_memory_high != CGROUP_LIMIT_MAX) {
2,430✔
172
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-high", "%" PRIu64, c->startup_memory_high);
×
173
                if (r < 0)
×
174
                        return r;
175
        }
176

177
        if (c->memory_max != CGROUP_LIMIT_MAX) {
2,430✔
178
                r = serialize_item_format(f, "exec-cgroup-context-memory-max", "%" PRIu64, c->memory_max);
1✔
179
                if (r < 0)
1✔
180
                        return r;
181
        }
182

183
        if (c->startup_memory_max != CGROUP_LIMIT_MAX) {
2,430✔
184
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-max", "%" PRIu64, c->startup_memory_max);
×
185
                if (r < 0)
×
186
                        return r;
187
        }
188

189
        if (c->memory_swap_max != CGROUP_LIMIT_MAX) {
2,430✔
190
                r = serialize_item_format(f, "exec-cgroup-context-memory-swap-max", "%" PRIu64, c->memory_swap_max);
1✔
191
                if (r < 0)
1✔
192
                        return r;
193
        }
194

195
        if (c->startup_memory_swap_max != CGROUP_LIMIT_MAX) {
2,430✔
196
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-swap-max", "%" PRIu64, c->startup_memory_swap_max);
×
197
                if (r < 0)
×
198
                        return r;
199
        }
200

201
        if (c->memory_zswap_max != CGROUP_LIMIT_MAX) {
2,430✔
202
                r = serialize_item_format(f, "exec-cgroup-context-memory-zswap-max", "%" PRIu64, c->memory_zswap_max);
×
203
                if (r < 0)
×
204
                        return r;
205
        }
206

207
        if (c->startup_memory_zswap_max != CGROUP_LIMIT_MAX) {
2,430✔
208
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-zswap-max", "%" PRIu64, c->startup_memory_zswap_max);
×
209
                if (r < 0)
×
210
                        return r;
211
        }
212

213
        r = serialize_bool(f, "exec-cgroup-context-memory-zswap-writeback", c->memory_zswap_writeback);
2,430✔
214
        if (r < 0)
2,430✔
215
                return r;
216

217
        if (c->tasks_max.value != UINT64_MAX) {
2,430✔
218
                r = serialize_item_format(f, "exec-cgroup-context-tasks-max-value", "%" PRIu64, c->tasks_max.value);
2,378✔
219
                if (r < 0)
2,378✔
220
                        return r;
221
        }
222

223
        if (c->tasks_max.scale > 0) {
2,430✔
224
                r = serialize_item_format(f, "exec-cgroup-context-tasks-max-scale", "%" PRIu64, c->tasks_max.scale);
2,370✔
225
                if (r < 0)
2,370✔
226
                        return r;
227
        }
228

229
        r = serialize_bool_elide(f, "exec-cgroup-context-default-memory-min-set", c->default_memory_min_set);
2,430✔
230
        if (r < 0)
2,430✔
231
                return r;
232

233
        r = serialize_bool_elide(f, "exec-cgroup-context-default-memory-low-set", c->default_memory_low_set);
2,430✔
234
        if (r < 0)
2,430✔
235
                return r;
236

237
        r = serialize_bool_elide(f, "exec-cgroup-context-default-startup-memory-low-set", c->default_startup_memory_low_set);
2,430✔
238
        if (r < 0)
2,430✔
239
                return r;
240

241
        r = serialize_bool_elide(f, "exec-cgroup-context-memory-min-set", c->memory_min_set);
2,430✔
242
        if (r < 0)
2,430✔
243
                return r;
244

245
        r = serialize_bool_elide(f, "exec-cgroup-context-memory-low-set", c->memory_low_set);
2,430✔
246
        if (r < 0)
2,430✔
247
                return r;
248

249
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-low-set", c->startup_memory_low_set);
2,430✔
250
        if (r < 0)
2,430✔
251
                return r;
252

253
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-high-set", c->startup_memory_high_set);
2,430✔
254
        if (r < 0)
2,430✔
255
                return r;
256

257
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-max-set", c->startup_memory_max_set);
2,430✔
258
        if (r < 0)
2,430✔
259
                return r;
260

261
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-swap-max-set", c->startup_memory_swap_max_set);
2,430✔
262
        if (r < 0)
2,430✔
263
                return r;
264

265
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-zswap-max-set", c->startup_memory_zswap_max_set);
2,430✔
266
        if (r < 0)
2,430✔
267
                return r;
268

269
        r = serialize_item(f, "exec-cgroup-context-device-policy", cgroup_device_policy_to_string(c->device_policy));
2,430✔
270
        if (r < 0)
2,430✔
271
                return r;
272

273
        r = cg_mask_to_string(c->disable_controllers, &disable_controllers_str);
2,430✔
274
        if (r < 0)
2,430✔
275
                return r;
276

277
        r = serialize_item(f, "exec-cgroup-context-disable-controllers", disable_controllers_str);
2,430✔
278
        if (r < 0)
2,430✔
279
                return r;
280

281
        r = cg_mask_to_string(c->delegate_controllers, &delegate_controllers_str);
2,430✔
282
        if (r < 0)
2,430✔
283
                return r;
284

285
        r = serialize_item(f, "exec-cgroup-context-delegate-controllers", delegate_controllers_str);
2,430✔
286
        if (r < 0)
2,430✔
287
                return r;
288

289
        r = serialize_bool_elide(f, "exec-cgroup-context-delegate", c->delegate);
2,430✔
290
        if (r < 0)
2,430✔
291
                return r;
292

293
        r = serialize_item(f, "exec-cgroup-context-managed-oom-swap", managed_oom_mode_to_string(c->moom_swap));
2,430✔
294
        if (r < 0)
2,430✔
295
                return r;
296

297
        r = serialize_item(f, "exec-cgroup-context-managed-oom-memory-pressure", managed_oom_mode_to_string(c->moom_mem_pressure));
2,430✔
298
        if (r < 0)
2,430✔
299
                return r;
300

301
        r = serialize_item_format(f, "exec-cgroup-context-managed-oom-memory-pressure-limit", "%" PRIu32, c->moom_mem_pressure_limit);
2,430✔
302
        if (r < 0)
2,430✔
303
                return r;
304

305
        r = serialize_usec(f, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec", c->moom_mem_pressure_duration_usec);
2,430✔
306
        if (r < 0)
2,430✔
307
                return r;
308

309
        r = serialize_item(f, "exec-cgroup-context-managed-oom-preference", managed_oom_preference_to_string(c->moom_preference));
2,430✔
310
        if (r < 0)
2,430✔
311
                return r;
312

313
        r = serialize_item(f, "exec-cgroup-context-memory-pressure-watch", cgroup_pressure_watch_to_string(c->memory_pressure_watch));
2,430✔
314
        if (r < 0)
2,430✔
315
                return r;
316

317
        r = serialize_item(f, "exec-cgroup-context-delegate-subgroup", c->delegate_subgroup);
2,430✔
318
        if (r < 0)
2,430✔
319
                return r;
320

321
        if (c->memory_pressure_threshold_usec != USEC_INFINITY) {
2,430✔
322
                r = serialize_usec(f, "exec-cgroup-context-memory-pressure-threshold-usec", c->memory_pressure_threshold_usec);
2,430✔
323
                if (r < 0)
2,430✔
324
                        return r;
325
        }
326

327
        LIST_FOREACH(device_allow, a, c->device_allow) {
2,973✔
328
                r = serialize_item_format(f, "exec-cgroup-context-device-allow", "%s %s",
543✔
329
                                          a->path,
330
                                          cgroup_device_permissions_to_string(a->permissions));
331
                if (r < 0)
543✔
332
                        return r;
333
        }
334

335
        LIST_FOREACH(device_weights, iw, c->io_device_weights) {
2,430✔
336
                r = serialize_item_format(f, "exec-cgroup-context-io-device-weight", "%s %" PRIu64,
×
337
                                          iw->path,
338
                                          iw->weight);
339
                if (r < 0)
×
340
                        return r;
341
        }
342

343
        LIST_FOREACH(device_latencies, l, c->io_device_latencies) {
2,430✔
344
                r = serialize_item_format(f, "exec-cgroup-context-io-device-latency-target-usec", "%s " USEC_FMT,
×
345
                                          l->path,
346
                                          l->target_usec);
347
                if (r < 0)
×
348
                        return r;
349
        }
350

351
        LIST_FOREACH(device_limits, il, c->io_device_limits)
2,430✔
352
                for (CGroupIOLimitType type = 0; type < _CGROUP_IO_LIMIT_TYPE_MAX; type++) {
×
353
                        _cleanup_free_ char *key = NULL;
×
354

355
                        if (il->limits[type] == cgroup_io_limit_defaults[type])
×
356
                                continue;
×
357

358
                        key = strjoin("exec-cgroup-context-io-device-limit-", cgroup_io_limit_type_to_string(type));
×
359
                        if (!key)
×
360
                                return -ENOMEM;
361

362
                        r = serialize_item_format(f, key, "%s %" PRIu64, il->path, il->limits[type]);
×
363
                        if (r < 0)
×
364
                                return r;
365
                }
366

367
        SET_FOREACH(iaai, c->ip_address_allow) {
2,430✔
368
                r = serialize_item(f,
×
369
                                   "exec-cgroup-context-ip-address-allow",
370
                                   IN_ADDR_PREFIX_TO_STRING(iaai->family, &iaai->address, iaai->prefixlen));
×
371
                if (r < 0)
×
372
                        return r;
×
373
        }
374
        SET_FOREACH(iaai, c->ip_address_deny) {
2,700✔
375
                r = serialize_item(f,
270✔
376
                                   "exec-cgroup-context-ip-address-deny",
377
                                   IN_ADDR_PREFIX_TO_STRING(iaai->family, &iaai->address, iaai->prefixlen));
270✔
378
                if (r < 0)
270✔
379
                        return r;
×
380
        }
381

382
        r = serialize_bool_elide(f, "exec-cgroup-context-ip-address-allow-reduced", c->ip_address_allow_reduced);
2,430✔
383
        if (r < 0)
2,430✔
384
                return r;
385

386
        r = serialize_bool_elide(f, "exec-cgroup-context-ip-address-deny-reduced", c->ip_address_deny_reduced);
2,430✔
387
        if (r < 0)
2,430✔
388
                return r;
389

390
        r = serialize_strv(f, "exec-cgroup-context-ip-ingress-filter-path", c->ip_filters_ingress);
2,430✔
391
        if (r < 0)
2,430✔
392
                return r;
393

394
        r = serialize_strv(f, "exec-cgroup-context-ip-egress-filter-path", c->ip_filters_egress);
2,430✔
395
        if (r < 0)
2,430✔
396
                return r;
397

398
        LIST_FOREACH(programs, p, c->bpf_foreign_programs) {
2,430✔
399
                r = serialize_item_format(f, "exec-cgroup-context-bpf-program", "%" PRIu32 " %s",
×
400
                                          p->attach_type,
401
                                          p->bpffs_path);
402
                if (r < 0)
×
403
                        return r;
404
        }
405

406
        LIST_FOREACH(socket_bind_items, bi, c->socket_bind_allow) {
2,430✔
407
                fprintf(f, "exec-cgroup-context-socket-bind-allow=");
×
408
                cgroup_context_dump_socket_bind_item(bi, f);
×
409
                fputc('\n', f);
×
410
        }
411

412
        LIST_FOREACH(socket_bind_items, bi, c->socket_bind_deny) {
2,430✔
413
                fprintf(f, "exec-cgroup-context-socket-bind-deny=");
×
414
                cgroup_context_dump_socket_bind_item(bi, f);
×
415
                fputc('\n', f);
×
416
        }
417

418
        SET_FOREACH(iface, c->restrict_network_interfaces) {
2,430✔
419
                r = serialize_item(f, "exec-cgroup-context-restrict-network-interfaces", iface);
×
420
                if (r < 0)
×
421
                        return r;
×
422
        }
423

424
        r = serialize_bool_elide(
4,860✔
425
                        f,
426
                        "exec-cgroup-context-restrict-network-interfaces-is-allow-list",
427
                        c->restrict_network_interfaces_is_allow_list);
2,430✔
428
        if (r < 0)
2,430✔
429
                return r;
430

431
        fputc('\n', f); /* End marker */
2,430✔
432

433
        return 0;
434
}
435

436
static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
10,033✔
437
        int r;
10,033✔
438

439
        assert(f);
10,033✔
440

441
        if (!c)
10,033✔
442
                return 0;
443

444
        for (;;) {
374,241✔
445
                _cleanup_free_ char *l = NULL;
182,104✔
446
                const char *val;
192,137✔
447

448
                r = deserialize_read_line(f, &l);
192,137✔
449
                if (r < 0)
192,137✔
450
                        return r;
451
                if (r == 0) /* eof or end marker */
192,137✔
452
                        break;
453

454
                if ((val = startswith(l, "exec-cgroup-context-io-accounting="))) {
182,104✔
455
                        r = parse_boolean(val);
2✔
456
                        if (r < 0)
2✔
457
                                return r;
458
                        c->io_accounting = r;
2✔
459
                } else if ((val = startswith(l, "exec-cgroup-context-memory-accounting="))) {
182,102✔
460
                        r = parse_boolean(val);
9,708✔
461
                        if (r < 0)
9,708✔
462
                                return r;
463
                        c->memory_accounting = r;
9,708✔
464
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-accounting="))) {
172,394✔
465
                        r = parse_boolean(val);
10,033✔
466
                        if (r < 0)
10,033✔
467
                                return r;
468
                        c->tasks_accounting = r;
10,033✔
469
                } else if ((val = startswith(l, "exec-cgroup-context-ip-accounting="))) {
162,361✔
470
                        r = parse_boolean(val);
×
471
                        if (r < 0)
×
472
                                return r;
473
                        c->ip_accounting = r;
×
474
                } else if ((val = startswith(l, "exec-cgroup-context-memory-oom-group="))) {
162,361✔
475
                        r = parse_boolean(val);
2✔
476
                        if (r < 0)
2✔
477
                                return r;
478
                        c->memory_oom_group = r;
2✔
479
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-weight="))) {
162,359✔
480
                        r = safe_atou64(val, &c->cpu_weight);
1✔
481
                        if (r < 0)
1✔
482
                                return r;
483
                } else if ((val = startswith(l, "exec-cgroup-context-startup-cpu-weight="))) {
162,358✔
484
                        r = safe_atou64(val, &c->startup_cpu_weight);
×
485
                        if (r < 0)
×
486
                                return r;
487
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-quota-per-sec-usec="))) {
162,358✔
488
                        r = deserialize_usec(val, &c->cpu_quota_per_sec_usec);
×
489
                        if (r < 0)
×
490
                                return r;
491
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-quota-period-usec="))) {
162,358✔
492
                        r = deserialize_usec(val, &c->cpu_quota_period_usec);
×
493
                        if (r < 0)
×
494
                                return r;
495
                } else if ((val = startswith(l, "exec-cgroup-context-allowed-cpus="))) {
162,358✔
496
                        if (c->cpuset_cpus.set)
10,033✔
497
                                return -EINVAL; /* duplicated */
498

499
                        r = parse_cpu_set(val, &c->cpuset_cpus);
10,033✔
500
                        if (r < 0)
10,033✔
501
                                return r;
502
                } else if ((val = startswith(l, "exec-cgroup-context-startup-allowed-cpus="))) {
152,325✔
503
                        if (c->startup_cpuset_cpus.set)
10,033✔
504
                                return -EINVAL; /* duplicated */
505

506
                        r = parse_cpu_set(val, &c->startup_cpuset_cpus);
10,033✔
507
                        if (r < 0)
10,033✔
508
                                return r;
509
                } else if ((val = startswith(l, "exec-cgroup-context-allowed-memory-nodes="))) {
142,292✔
510
                        if (c->cpuset_mems.set)
10,033✔
511
                                return -EINVAL; /* duplicated */
512

513
                        r = parse_cpu_set(val, &c->cpuset_mems);
10,033✔
514
                        if (r < 0)
10,033✔
515
                                return r;
516
                } else if ((val = startswith(l, "exec-cgroup-context-startup-allowed-memory-nodes="))) {
132,259✔
517
                        if (c->startup_cpuset_mems.set)
10,033✔
518
                                return -EINVAL; /* duplicated */
519

520
                        r = parse_cpu_set(val, &c->startup_cpuset_mems);
10,033✔
521
                        if (r < 0)
10,033✔
522
                                return r;
523
                } else if ((val = startswith(l, "exec-cgroup-context-io-weight="))) {
122,226✔
524
                        r = safe_atou64(val, &c->io_weight);
×
525
                        if (r < 0)
×
526
                                return r;
527
                } else if ((val = startswith(l, "exec-cgroup-context-startup-io-weight="))) {
122,226✔
528
                        r = safe_atou64(val, &c->startup_io_weight);
×
529
                        if (r < 0)
×
530
                                return r;
531
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-min="))) {
122,226✔
532
                        r = safe_atou64(val, &c->default_memory_min);
×
533
                        if (r < 0)
×
534
                                return r;
535
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-low="))) {
122,226✔
536
                        r = safe_atou64(val, &c->default_memory_low);
×
537
                        if (r < 0)
×
538
                                return r;
539
                } else if ((val = startswith(l, "exec-cgroup-context-memory-min="))) {
122,226✔
540
                        r = safe_atou64(val, &c->memory_min);
1✔
541
                        if (r < 0)
1✔
542
                                return r;
543
                } else if ((val = startswith(l, "exec-cgroup-context-memory-low="))) {
122,225✔
544
                        r = safe_atou64(val, &c->memory_low);
1✔
545
                        if (r < 0)
1✔
546
                                return r;
547
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low="))) {
122,224✔
548
                        r = safe_atou64(val, &c->startup_memory_low);
×
549
                        if (r < 0)
×
550
                                return r;
551
                } else if ((val = startswith(l, "exec-cgroup-context-memory-high="))) {
122,224✔
552
                        r = safe_atou64(val, &c->memory_high);
10✔
553
                        if (r < 0)
10✔
554
                                return r;
555
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high="))) {
122,214✔
556
                        r = safe_atou64(val, &c->startup_memory_high);
×
557
                        if (r < 0)
×
558
                                return r;
559
                } else if ((val = startswith(l, "exec-cgroup-context-memory-max="))) {
122,214✔
560
                        r = safe_atou64(val, &c->memory_max);
10✔
561
                        if (r < 0)
10✔
562
                                return r;
563
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max="))) {
122,204✔
564
                        r = safe_atou64(val, &c->startup_memory_max);
×
565
                        if (r < 0)
×
566
                                return r;
567
                } else if ((val = startswith(l, "exec-cgroup-context-memory-swap-max="))) {
122,204✔
568
                        r = safe_atou64(val, &c->memory_swap_max);
9✔
569
                        if (r < 0)
9✔
570
                                return r;
571
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max="))) {
122,195✔
572
                        r = safe_atou64(val, &c->startup_memory_swap_max);
×
573
                        if (r < 0)
×
574
                                return r;
575
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-max="))) {
122,195✔
576
                        r = safe_atou64(val, &c->memory_zswap_max);
1✔
577
                        if (r < 0)
1✔
578
                                return r;
579
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max="))) {
122,194✔
580
                        r = safe_atou64(val, &c->startup_memory_zswap_max);
×
581
                        if (r < 0)
×
582
                                return r;
583
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-writeback="))) {
122,194✔
584
                        r = parse_boolean(val);
10,033✔
585
                        if (r < 0)
10,033✔
586
                                return r;
587
                        c->memory_zswap_writeback = r;
10,033✔
588
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-value="))) {
112,161✔
589
                        r = safe_atou64(val, &c->tasks_max.value);
9,731✔
590
                        if (r < 0)
9,731✔
591
                                return r;
592
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-scale="))) {
102,430✔
593
                        r = safe_atou64(val, &c->tasks_max.scale);
9,690✔
594
                        if (r < 0)
9,690✔
595
                                return r;
596
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-min-set="))) {
92,740✔
597
                        r = parse_boolean(val);
×
598
                        if (r < 0)
×
599
                                return r;
600
                        c->default_memory_min_set = r;
×
601
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-low-set="))) {
92,740✔
602
                        r = parse_boolean(val);
×
603
                        if (r < 0)
×
604
                                return r;
605
                        c->default_memory_low_set = r;
×
606
                } else if ((val = startswith(l, "exec-cgroup-context-default-startup-memory-low-set="))) {
92,740✔
607
                        r = parse_boolean(val);
×
608
                        if (r < 0)
×
609
                                return r;
610
                        c->default_startup_memory_low_set = r;
×
611
                } else if ((val = startswith(l, "exec-cgroup-context-memory-min-set="))) {
92,740✔
612
                        r = parse_boolean(val);
1✔
613
                        if (r < 0)
1✔
614
                                return r;
615
                        c->memory_min_set = r;
1✔
616
                } else if ((val = startswith(l, "exec-cgroup-context-memory-low-set="))) {
92,739✔
617
                        r = parse_boolean(val);
1✔
618
                        if (r < 0)
1✔
619
                                return r;
620
                        c->memory_low_set = r;
1✔
621
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low-set="))) {
92,738✔
622
                        r = parse_boolean(val);
×
623
                        if (r < 0)
×
624
                                return r;
625
                        c->startup_memory_low_set = r;
×
626
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high-set="))) {
92,738✔
627
                        r = parse_boolean(val);
×
628
                        if (r < 0)
×
629
                                return r;
630
                        c->startup_memory_high_set = r;
×
631
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max-set="))) {
92,738✔
632
                        r = parse_boolean(val);
×
633
                        if (r < 0)
×
634
                                return r;
635
                        c->startup_memory_max_set = r;
×
636
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max-set="))) {
92,738✔
637
                        r = parse_boolean(val);
×
638
                        if (r < 0)
×
639
                                return r;
640
                        c->startup_memory_swap_max_set = r;
×
641
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max-set="))) {
92,738✔
642
                        r = parse_boolean(val);
×
643
                        if (r < 0)
×
644
                                return r;
645
                        c->startup_memory_zswap_max_set = r;
×
646
                } else if ((val = startswith(l, "exec-cgroup-context-device-policy="))) {
92,738✔
647
                        c->device_policy = cgroup_device_policy_from_string(val);
10,033✔
648
                        if (c->device_policy < 0)
10,033✔
649
                                return -EINVAL;
650
                } else if ((val = startswith(l, "exec-cgroup-context-disable-controllers="))) {
82,705✔
651
                        r = cg_mask_from_string(val, &c->disable_controllers);
×
652
                        if (r < 0)
×
653
                                return r;
654
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-controllers="))) {
82,705✔
655
                        r = cg_mask_from_string(val, &c->delegate_controllers);
583✔
656
                        if (r < 0)
583✔
657
                                return r;
658
                } else if ((val = startswith(l, "exec-cgroup-context-delegate="))) {
82,122✔
659
                        r = parse_boolean(val);
699✔
660
                        if (r < 0)
699✔
661
                                return r;
662
                        c->delegate = r;
699✔
663
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-swap="))) {
81,423✔
664
                        c->moom_swap = managed_oom_mode_from_string(val);
10,033✔
665
                        if (c->moom_swap < 0)
10,033✔
666
                                return -EINVAL;
667
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure="))) {
71,390✔
668
                        c->moom_mem_pressure = managed_oom_mode_from_string(val);
10,033✔
669
                        if (c->moom_mem_pressure < 0)
10,033✔
670
                                return -EINVAL;
671
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-limit="))) {
61,357✔
672
                        r = safe_atou32(val, &c->moom_mem_pressure_limit);
10,033✔
673
                        if (r < 0)
10,033✔
674
                                return r;
675
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-preference="))) {
51,324✔
676
                        c->moom_preference = managed_oom_preference_from_string(val);
10,033✔
677
                        if (c->moom_preference < 0)
10,033✔
678
                                return -EINVAL;
679
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec="))) {
41,291✔
680
                        r = deserialize_usec(val, &c->moom_mem_pressure_duration_usec);
1✔
681
                        if (r < 0)
1✔
682
                                return r;
683
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-watch="))) {
41,290✔
684
                        c->memory_pressure_watch = cgroup_pressure_watch_from_string(val);
10,033✔
685
                        if (c->memory_pressure_watch < 0)
10,033✔
686
                                return -EINVAL;
687
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-subgroup="))) {
31,257✔
688
                        r = free_and_strdup(&c->delegate_subgroup, val);
352✔
689
                        if (r < 0)
352✔
690
                                return r;
691
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-threshold-usec="))) {
30,905✔
692
                        r = deserialize_usec(val, &c->memory_pressure_threshold_usec);
10,033✔
693
                        if (r < 0)
10,033✔
694
                                return r;
695
                } else if ((val = startswith(l, "exec-cgroup-context-device-allow="))) {
20,872✔
696
                        _cleanup_free_ char *path = NULL, *rwm = NULL;
3,338✔
697
                        CGroupDevicePermissions p;
3,338✔
698

699
                        r = extract_many_words(&val, " ", 0, &path, &rwm);
3,338✔
700
                        if (r < 0)
3,338✔
701
                                return r;
702
                        if (r == 0)
3,338✔
703
                                return -EINVAL;
704

705
                        p = isempty(rwm) ? 0 : cgroup_device_permissions_from_string(rwm);
6,676✔
706
                        if (p < 0)
3,338✔
707
                                return p;
708

709
                        r = cgroup_context_add_or_update_device_allow(c, path, p);
3,338✔
710
                        if (r < 0)
3,338✔
711
                                return r;
712
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-weight="))) {
17,534✔
713
                        _cleanup_free_ char *path = NULL, *weight = NULL;
×
714
                        CGroupIODeviceWeight *a = NULL;
×
715

716
                        r = extract_many_words(&val, " ", 0, &path, &weight);
×
717
                        if (r < 0)
×
718
                                return r;
719
                        if (r != 2)
×
720
                                return -EINVAL;
721

722
                        LIST_FOREACH(device_weights, b, c->io_device_weights)
×
723
                                if (path_equal(b->path, path)) {
×
724
                                        a = b;
725
                                        break;
726
                                }
727

728
                        if (!a) {
×
729
                                a = new0(CGroupIODeviceWeight, 1);
×
730
                                if (!a)
×
731
                                        return log_oom_debug();
×
732

733
                                a->path = TAKE_PTR(path);
×
734

735
                                LIST_PREPEND(device_weights, c->io_device_weights, a);
×
736
                        }
737

738
                        r = safe_atou64(weight, &a->weight);
×
739
                        if (r < 0)
×
740
                                return r;
741
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-latency-target-usec="))) {
17,534✔
742
                        _cleanup_free_ char *path = NULL, *target = NULL;
×
743
                        CGroupIODeviceLatency *a = NULL;
×
744

745
                        r = extract_many_words(&val, " ", 0, &path, &target);
×
746
                        if (r < 0)
×
747
                                return r;
748
                        if (r != 2)
×
749
                                return -EINVAL;
750

751
                        LIST_FOREACH(device_latencies, b, c->io_device_latencies)
×
752
                                if (path_equal(b->path, path)) {
×
753
                                        a = b;
754
                                        break;
755
                                }
756

757
                        if (!a) {
×
758
                                a = new0(CGroupIODeviceLatency, 1);
×
759
                                if (!a)
×
760
                                        return log_oom_debug();
×
761

762
                                a->path = TAKE_PTR(path);
×
763

764
                                LIST_PREPEND(device_latencies, c->io_device_latencies, a);
×
765
                        }
766

767
                        r = deserialize_usec(target, &a->target_usec);
×
768
                        if (r < 0)
×
769
                                return r;
770
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-limit-"))) {
17,534✔
771
                        _cleanup_free_ char *type = NULL, *path = NULL, *limits = NULL;
×
772
                        CGroupIODeviceLimit *limit = NULL;
×
773
                        CGroupIOLimitType t;
×
774

775
                        r = extract_many_words(&val, "= ", 0, &type, &path, &limits);
×
776
                        if (r < 0)
×
777
                                return r;
778
                        if (r != 3)
×
779
                                return -EINVAL;
780

781
                        t = cgroup_io_limit_type_from_string(type);
×
782
                        if (t < 0)
×
783
                                return t;
784

785
                        LIST_FOREACH(device_limits, i, c->io_device_limits)
×
786
                                if (path_equal(path, i->path)) {
×
787
                                        limit = i;
788
                                        break;
789
                                }
790

791
                        if (!limit) {
×
792
                                limit = new0(CGroupIODeviceLimit, 1);
×
793
                                if (!limit)
×
794
                                        return log_oom_debug();
×
795

796
                                limit->path = TAKE_PTR(path);
×
797
                                for (CGroupIOLimitType i = 0; i < _CGROUP_IO_LIMIT_TYPE_MAX; i++)
×
798
                                        limit->limits[i] = cgroup_io_limit_defaults[i];
×
799

800
                                LIST_PREPEND(device_limits, c->io_device_limits, limit);
×
801
                        }
802

803
                        r = safe_atou64(limits, &limit->limits[t]);
×
804
                        if (r < 0)
×
805
                                return r;
806
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow="))) {
17,534✔
807
                        struct in_addr_prefix a;
×
808

809
                        r = in_addr_prefix_from_string_auto(val, &a.family, &a.address, &a.prefixlen);
×
810
                        if (r < 0)
×
811
                                return r;
×
812

813
                        r = in_addr_prefix_add(&c->ip_address_allow, &a);
×
814
                        if (r < 0)
×
815
                                return r;
816
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny="))) {
17,534✔
817
                        struct in_addr_prefix a;
1,368✔
818

819
                        r = in_addr_prefix_from_string_auto(val, &a.family, &a.address, &a.prefixlen);
1,368✔
820
                        if (r < 0)
1,368✔
821
                                return r;
×
822

823
                        r = in_addr_prefix_add(&c->ip_address_deny, &a);
1,368✔
824
                        if (r < 0)
1,368✔
825
                                return r;
826
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow-reduced="))) {
16,166✔
827
                        r = parse_boolean(val);
8,071✔
828
                        if (r < 0)
8,071✔
829
                                return r;
830
                        c->ip_address_allow_reduced = r;
8,071✔
831
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny-reduced="))) {
8,095✔
832
                        r = parse_boolean(val);
8,071✔
833
                        if (r < 0)
8,071✔
834
                                return r;
835
                        c->ip_address_deny_reduced = r;
8,071✔
836
                } else if ((val = startswith(l, "exec-cgroup-context-ip-ingress-filter-path="))) {
24✔
837
                        r = deserialize_strv(val, &c->ip_filters_ingress);
×
838
                        if (r < 0)
×
839
                                return r;
840
                } else if ((val = startswith(l, "exec-cgroup-context-ip-egress-filter-path="))) {
24✔
841
                        r = deserialize_strv(val, &c->ip_filters_egress);
×
842
                        if (r < 0)
×
843
                                return r;
844
                } else if ((val = startswith(l, "exec-cgroup-context-bpf-program="))) {
24✔
845
                        _cleanup_free_ char *type = NULL, *path = NULL;
×
846
                        uint32_t t;
×
847

848
                        r = extract_many_words(&val, " ", 0, &type, &path);
×
849
                        if (r < 0)
×
850
                                return r;
851
                        if (r != 2)
×
852
                                return -EINVAL;
853

854
                        r = safe_atou32(type, &t);
×
855
                        if (r < 0)
×
856
                                return r;
857

858
                        r = cgroup_context_add_bpf_foreign_program(c, t, path);
×
859
                        if (r < 0)
×
860
                                return r;
861
                } else if ((val = startswith(l, "exec-cgroup-context-socket-bind-allow="))) {
24✔
862
                        CGroupSocketBindItem *item;
×
863
                        uint16_t nr_ports, port_min;
×
864
                        int af, ip_protocol;
×
865

866
                        r = parse_socket_bind_item(val, &af, &ip_protocol, &nr_ports, &port_min);
×
867
                        if (r < 0)
×
868
                                return r;
×
869

870
                        item = new(CGroupSocketBindItem, 1);
×
871
                        if (!item)
×
872
                                return log_oom_debug();
×
873
                        *item = (CGroupSocketBindItem) {
×
874
                                .address_family = af,
875
                                .ip_protocol = ip_protocol,
876
                                .nr_ports = nr_ports,
877
                                .port_min = port_min,
878
                        };
879

880
                        LIST_PREPEND(socket_bind_items, c->socket_bind_allow, item);
×
881
                } else if ((val = startswith(l, "exec-cgroup-context-socket-bind-deny="))) {
24✔
882
                        CGroupSocketBindItem *item;
×
883
                        uint16_t nr_ports, port_min;
×
884
                        int af, ip_protocol;
×
885

886
                        r = parse_socket_bind_item(val, &af, &ip_protocol, &nr_ports, &port_min);
×
887
                        if (r < 0)
×
888
                                return r;
×
889

890
                        item = new(CGroupSocketBindItem, 1);
×
891
                        if (!item)
×
892
                                return log_oom_debug();
×
893
                        *item = (CGroupSocketBindItem) {
×
894
                                .address_family = af,
895
                                .ip_protocol = ip_protocol,
896
                                .nr_ports = nr_ports,
897
                                .port_min = port_min,
898
                        };
899

900
                        LIST_PREPEND(socket_bind_items, c->socket_bind_deny, item);
×
901
                } else if ((val = startswith(l, "exec-cgroup-context-restrict-network-interfaces="))) {
24✔
902
                        r = set_put_strdup(&c->restrict_network_interfaces, val);
15✔
903
                        if (r < 0)
15✔
904
                                return r;
905
                } else if ((val = startswith(l, "exec-cgroup-context-restrict-network-interfaces-is-allow-list="))) {
9✔
906
                        r = parse_boolean(val);
9✔
907
                        if (r < 0)
9✔
908
                                return r;
909
                        c->restrict_network_interfaces_is_allow_list = r;
9✔
910
                } else
911
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
912
        }
913

914
        return 0;
10,033✔
915
}
916

917
static int exec_runtime_serialize(const ExecRuntime *rt, FILE *f, FDSet *fds) {
2,430✔
918
        int r;
2,430✔
919

920
        assert(f);
2,430✔
921
        assert(fds);
2,430✔
922

923
        if (!rt) {
2,430✔
924
                fputc('\n', f); /* End marker */
2,353✔
925
                return 0;
2,353✔
926
        }
927

928
        if (rt->shared) {
77✔
929
                r = serialize_item(f, "exec-runtime-id", rt->shared->id);
75✔
930
                if (r < 0)
75✔
931
                        return r;
932

933
                r = serialize_item(f, "exec-runtime-tmp-dir", rt->shared->tmp_dir);
75✔
934
                if (r < 0)
75✔
935
                        return r;
936

937
                r = serialize_item(f, "exec-runtime-var-tmp-dir", rt->shared->var_tmp_dir);
75✔
938
                if (r < 0)
75✔
939
                        return r;
940

941
                if (rt->shared->userns_storage_socket[0] >= 0 && rt->shared->userns_storage_socket[1] >= 0) {
75✔
942
                        r = serialize_fd_many(f, fds, "exec-runtime-userns-storage-socket", rt->shared->userns_storage_socket, 2);
×
943
                        if (r < 0)
×
944
                                return r;
945
                }
946

947
                if (rt->shared->netns_storage_socket[0] >= 0 && rt->shared->netns_storage_socket[1] >= 0) {
75✔
948
                        r = serialize_fd_many(f, fds, "exec-runtime-netns-storage-socket", rt->shared->netns_storage_socket, 2);
8✔
949
                        if (r < 0)
8✔
950
                                return r;
951
                }
952

953
                if (rt->shared->ipcns_storage_socket[0] >= 0 && rt->shared->ipcns_storage_socket[1] >= 0) {
75✔
954
                        r = serialize_fd_many(f, fds, "exec-runtime-ipcns-storage-socket", rt->shared->ipcns_storage_socket, 2);
2✔
955
                        if (r < 0)
2✔
956
                                return r;
957
                }
958
        }
959

960
        if (rt->dynamic_creds) {
77✔
961
                r = dynamic_user_serialize_one(rt->dynamic_creds->user, "exec-runtime-dynamic-creds-user", f, fds);
2✔
962
                if (r < 0)
2✔
963
                        return r;
964
        }
965

966
        if (rt->dynamic_creds && rt->dynamic_creds->group && rt->dynamic_creds->group == rt->dynamic_creds->user) {
77✔
967
                r = serialize_bool(f, "exec-runtime-dynamic-creds-group-copy", true);
2✔
968
                if (r < 0)
2✔
969
                        return r;
970
        } else if (rt->dynamic_creds) {
75✔
971
                r = dynamic_user_serialize_one(rt->dynamic_creds->group, "exec-runtime-dynamic-creds-group", f, fds);
×
972
                if (r < 0)
×
973
                        return r;
974
        }
975

976
        r = serialize_item(f, "exec-runtime-ephemeral-copy", rt->ephemeral_copy);
77✔
977
        if (r < 0)
77✔
978
                return r;
979

980
        if (rt->ephemeral_storage_socket[0] >= 0 && rt->ephemeral_storage_socket[1] >= 0) {
77✔
981
                r = serialize_fd_many(f, fds, "exec-runtime-ephemeral-storage-socket", rt->ephemeral_storage_socket, 2);
×
982
                if (r < 0)
×
983
                        return r;
984
        }
985

986
        fputc('\n', f); /* End marker */
77✔
987

988
        return 0;
77✔
989
}
990

991
static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) {
10,033✔
992
        int r;
10,033✔
993

994
        assert(rt);
10,033✔
995
        assert(rt->shared);
10,033✔
996
        assert(rt->dynamic_creds);
10,033✔
997
        assert(f);
10,033✔
998
        assert(fds);
10,033✔
999

1000
        for (;;) {
11,281✔
1001
                _cleanup_free_ char *l = NULL;
1,248✔
1002
                const char *val;
11,281✔
1003

1004
                r = deserialize_read_line(f, &l);
11,281✔
1005
                if (r < 0)
11,281✔
1006
                        return r;
1007
                if (r == 0) /* eof or end marker */
11,281✔
1008
                        break;
1009

1010
                if ((val = startswith(l, "exec-runtime-id="))) {
1,248✔
1011
                        r = free_and_strdup(&rt->shared->id, val);
374✔
1012
                        if (r < 0)
374✔
1013
                                return r;
1014
                } else if ((val = startswith(l, "exec-runtime-tmp-dir="))) {
874✔
1015
                        r = free_and_strdup(&rt->shared->tmp_dir, val);
350✔
1016
                        if (r < 0)
350✔
1017
                                return r;
1018
                } else if ((val = startswith(l, "exec-runtime-var-tmp-dir="))) {
524✔
1019
                        r = free_and_strdup(&rt->shared->var_tmp_dir, val);
350✔
1020
                        if (r < 0)
350✔
1021
                                return r;
1022
                } else if ((val = startswith(l, "exec-runtime-userns-storage-socket="))) {
174✔
1023

1024
                        r = deserialize_fd_many(fds, val, 2, rt->shared->userns_storage_socket);
3✔
1025
                        if (r < 0)
3✔
1026
                                continue;
×
1027

1028
                } else if ((val = startswith(l, "exec-runtime-netns-storage-socket="))) {
171✔
1029

1030
                        r = deserialize_fd_many(fds, val, 2, rt->shared->netns_storage_socket);
71✔
1031
                        if (r < 0)
71✔
1032
                                continue;
×
1033

1034
                } else if ((val = startswith(l, "exec-runtime-ipcns-storage-socket="))) {
100✔
1035

1036
                        r = deserialize_fd_many(fds, val, 2, rt->shared->ipcns_storage_socket);
6✔
1037
                        if (r < 0)
6✔
1038
                                continue;
×
1039

1040
                } else if ((val = startswith(l, "exec-runtime-dynamic-creds-user=")))
94✔
1041
                        dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->user);
47✔
1042
                else if ((val = startswith(l, "exec-runtime-dynamic-creds-group=")))
47✔
1043
                        dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->group);
×
1044
                else if ((val = startswith(l, "exec-runtime-dynamic-creds-group-copy="))) {
47✔
1045
                        r = parse_boolean(val);
47✔
1046
                        if (r < 0)
47✔
1047
                                return r;
1048
                        if (!r)
47✔
1049
                                continue; /* Nothing to do */
×
1050

1051
                        if (!rt->dynamic_creds->user)
47✔
1052
                                return -EINVAL;
1053

1054
                        rt->dynamic_creds->group = dynamic_user_ref(rt->dynamic_creds->user);
47✔
1055
                } else if ((val = startswith(l, "exec-runtime-ephemeral-copy="))) {
×
1056
                        r = free_and_strdup(&rt->ephemeral_copy, val);
×
1057
                        if (r < 0)
×
1058
                                return r;
1059
                } else if ((val = startswith(l, "exec-runtime-ephemeral-storage-socket="))) {
×
1060

1061
                        r = deserialize_fd_many(fds, val, 2, rt->ephemeral_storage_socket);
×
1062
                        if (r < 0)
×
1063
                                continue;
×
1064
                } else
1065
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
1066
        }
1067

1068
        return 0;
10,033✔
1069
}
1070

1071
static bool exec_parameters_is_idle_pipe_set(const ExecParameters *p) {
2,430✔
1072
        assert(p);
2,430✔
1073

1074
        return p->idle_pipe &&
2,459✔
1075
                p->idle_pipe[0] >= 0 &&
29✔
1076
                p->idle_pipe[1] >= 0 &&
27✔
1077
                p->idle_pipe[2] >= 0 &&
2,457✔
1078
                p->idle_pipe[3] >= 0;
27✔
1079
}
1080

1081
static int exec_parameters_serialize(const ExecParameters *p, const ExecContext *c, FILE *f, FDSet *fds) {
2,430✔
1082
        int r;
2,430✔
1083

1084
        assert(f);
2,430✔
1085
        assert(fds);
2,430✔
1086

1087
        if (!p)
2,430✔
1088
                return 0;
1089

1090
        r = serialize_item(f, "exec-parameters-runtime-scope", runtime_scope_to_string(p->runtime_scope));
2,430✔
1091
        if (r < 0)
2,430✔
1092
                return r;
1093

1094
        r = serialize_strv(f, "exec-parameters-environment", p->environment);
2,430✔
1095
        if (r < 0)
2,430✔
1096
                return r;
1097

1098
        if (p->fds) {
2,430✔
1099
                if (p->n_socket_fds > 0) {
535✔
1100
                        r = serialize_item_format(f, "exec-parameters-n-socket-fds", "%zu", p->n_socket_fds);
534✔
1101
                        if (r < 0)
534✔
1102
                                return r;
1103
                }
1104

1105
                if (p->n_stashed_fds > 0) {
535✔
1106
                        r = serialize_item_format(f, "exec-parameters-n-stashed-fds", "%zu", p->n_stashed_fds);
4✔
1107
                        if (r < 0)
4✔
1108
                                return r;
1109
                }
1110

1111
                r = serialize_fd_many(f, fds, "exec-parameters-fds", p->fds, p->n_socket_fds + p->n_stashed_fds);
535✔
1112
                if (r < 0)
535✔
1113
                        return r;
1114

1115
                r = serialize_strv(f, "exec-parameters-fd-names", p->fd_names);
535✔
1116
                if (r < 0)
535✔
1117
                        return r;
1118
        }
1119

1120
        if (p->flags != 0) {
2,430✔
1121
                r = serialize_item_format(f, "exec-parameters-flags", "%u", (unsigned) p->flags);
2,430✔
1122
                if (r < 0)
2,430✔
1123
                        return r;
1124
        }
1125

1126
        r = serialize_bool_elide(f, "exec-parameters-selinux-context-net", p->selinux_context_net);
2,430✔
1127
        if (r < 0)
2,430✔
1128
                return r;
1129

1130
        r = serialize_item(f, "exec-parameters-cgroup-path", p->cgroup_path);
2,430✔
1131
        if (r < 0)
2,430✔
1132
                return r;
1133

1134
        r = serialize_item_format(f, "exec-parameters-cgroup-id", "%" PRIu64, p->cgroup_id);
2,430✔
1135
        if (r < 0)
2,430✔
1136
                return r;
1137

1138
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
14,580✔
1139
                _cleanup_free_ char *key = NULL;
12,150✔
1140

1141
                key = strjoin("exec-parameters-prefix-directories-", exec_directory_type_to_string(dt));
12,150✔
1142
                if (!key)
12,150✔
1143
                        return log_oom_debug();
×
1144

1145
                /* Always serialize, even an empty prefix, as this is a fixed array and we always expect
1146
                 * to have all elements (unless fuzzing is happening, hence the NULL check). */
1147
                r = serialize_item(f, key, strempty(p->prefix ? p->prefix[dt] : NULL));
12,150✔
1148
                if (r < 0)
12,150✔
1149
                        return r;
1150
        }
1151

1152
        r = serialize_item(f, "exec-parameters-received-credentials-directory", p->received_credentials_directory);
2,430✔
1153
        if (r < 0)
2,430✔
1154
                return r;
1155

1156
        r = serialize_item(f, "exec-parameters-received-encrypted-credentials-directory", p->received_encrypted_credentials_directory);
2,430✔
1157
        if (r < 0)
2,430✔
1158
                return r;
1159

1160
        r = serialize_item(f, "exec-parameters-confirm-spawn", p->confirm_spawn);
2,430✔
1161
        if (r < 0)
2,430✔
1162
                return r;
1163

1164
        r = serialize_bool_elide(f, "exec-parameters-shall-confirm-spawn", p->shall_confirm_spawn);
2,430✔
1165
        if (r < 0)
2,430✔
1166
                return r;
1167

1168
        if (p->watchdog_usec > 0) {
2,430✔
1169
                r = serialize_usec(f, "exec-parameters-watchdog-usec", p->watchdog_usec);
232✔
1170
                if (r < 0)
232✔
1171
                        return r;
1172
        }
1173

1174
        if (exec_parameters_is_idle_pipe_set(p)) {
2,430✔
1175
                r = serialize_fd_many(f, fds, "exec-parameters-idle-pipe", p->idle_pipe, 4);
27✔
1176
                if (r < 0)
27✔
1177
                        return r;
1178
        }
1179

1180
        r = serialize_fd(f, fds, "exec-parameters-stdin-fd", p->stdin_fd);
2,430✔
1181
        if (r < 0)
2,430✔
1182
                return r;
1183

1184
        r = serialize_fd(f, fds, "exec-parameters-stdout-fd", p->stdout_fd);
2,430✔
1185
        if (r < 0)
2,430✔
1186
                return r;
1187

1188
        r = serialize_fd(f, fds, "exec-parameters-stderr-fd", p->stderr_fd);
2,430✔
1189
        if (r < 0)
2,430✔
1190
                return r;
1191

1192
        r = serialize_fd(f, fds, "exec-parameters-root-directory-fd", p->root_directory_fd);
2,430✔
1193
        if (r < 0)
2,430✔
1194
                return r;
1195

1196
        r = serialize_fd(f, fds, "exec-parameters-exec-fd", p->exec_fd);
2,430✔
1197
        if (r < 0)
2,430✔
1198
                return r;
1199

1200
        r = serialize_fd(f, fds, "exec-parameters-handoff-timestamp-fd", p->handoff_timestamp_fd);
2,430✔
1201
        if (r < 0)
2,430✔
1202
                return r;
1203

1204
        r = serialize_fd(f, fds, "exec-parameters-pidref-transport-fd", p->pidref_transport_fd);
2,430✔
1205
        if (r < 0)
2,430✔
1206
                return r;
1207

1208
        if (c && exec_context_restrict_filesystems_set(c)) {
2,430✔
1209
                r = serialize_fd(f, fds, "exec-parameters-bpf-outer-map-fd", p->bpf_restrict_fs_map_fd);
×
1210
                if (r < 0)
×
1211
                        return r;
1212
        }
1213

1214
        r = serialize_item(f, "exec-parameters-notify-socket", p->notify_socket);
2,430✔
1215
        if (r < 0)
2,430✔
1216
                return r;
1217

1218
        LIST_FOREACH(open_files, file, p->open_files) {
2,430✔
1219
                _cleanup_free_ char *ofs = NULL;
×
1220

1221
                r = open_file_to_string(file, &ofs);
×
1222
                if (r < 0)
×
1223
                        return r;
1224

1225
                r = serialize_item(f, "exec-parameters-open-file", ofs);
×
1226
                if (r < 0)
×
1227
                        return r;
1228
        }
1229

1230
        r = serialize_item(f, "exec-parameters-fallback-smack-process-label", p->fallback_smack_process_label);
2,430✔
1231
        if (r < 0)
2,430✔
1232
                return r;
1233

1234
        r = serialize_fd(f, fds, "exec-parameters-user-lookup-fd", p->user_lookup_fd);
2,430✔
1235
        if (r < 0)
2,430✔
1236
                return r;
1237

1238
        r = serialize_strv(f, "exec-parameters-files-env", p->files_env);
2,430✔
1239
        if (r < 0)
2,430✔
1240
                return r;
1241

1242
        r = serialize_item(f, "exec-parameters-unit-id", p->unit_id);
2,430✔
1243
        if (r < 0)
2,430✔
1244
                return r;
1245

1246
        r = serialize_item(f, "exec-parameters-invocation-id-string", p->invocation_id_string);
2,430✔
1247
        if (r < 0)
2,430✔
1248
                return r;
1249

1250
        r = serialize_bool_elide(f, "exec-parameters-debug-invocation", p->debug_invocation);
2,430✔
1251
        if (r < 0)
2,430✔
1252
                return r;
1253

1254
        fputc('\n', f); /* End marker */
2,430✔
1255

1256
        return 0;
2,430✔
1257
}
1258

1259
static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
10,033✔
1260
        int r;
10,033✔
1261

1262
        assert(p);
10,033✔
1263
        assert(f);
10,033✔
1264
        assert(fds);
10,033✔
1265

1266
        unsigned nr_open = MAX(read_nr_open(), NR_OPEN_MINIMUM);
10,033✔
1267

1268
        for (;;) {
214,271✔
1269
                _cleanup_free_ char *l = NULL;
204,238✔
1270
                const char *val;
214,271✔
1271

1272
                r = deserialize_read_line(f, &l);
214,271✔
1273
                if (r < 0)
214,271✔
1274
                        return r;
1275
                if (r == 0) /* eof or end marker */
214,271✔
1276
                        break;
1277

1278
                if ((val = startswith(l, "exec-parameters-runtime-scope="))) {
204,238✔
1279
                        p->runtime_scope = runtime_scope_from_string(val);
10,033✔
1280
                        if (p->runtime_scope < 0)
10,033✔
1281
                                return p->runtime_scope;
1282
                } else if ((val = startswith(l, "exec-parameters-environment="))) {
194,205✔
1283
                        r = deserialize_strv(val, &p->environment);
42,797✔
1284
                        if (r < 0)
42,797✔
1285
                                return r;
1286
                } else if ((val = startswith(l, "exec-parameters-n-socket-fds="))) {
151,408✔
1287
                        if (p->fds)
1,745✔
1288
                                return -EINVAL; /* Already received */
1289

1290
                        r = safe_atozu(val, &p->n_socket_fds);
1,745✔
1291
                        if (r < 0)
1,745✔
1292
                                return r;
1293

1294
                        if (p->n_socket_fds > nr_open)
1,745✔
1295
                                return -EINVAL; /* too many, someone is playing games with us */
1296
                } else if ((val = startswith(l, "exec-parameters-n-stashed-fds="))) {
149,663✔
1297
                        if (p->fds)
110✔
1298
                                return -EINVAL; /* Already received */
1299

1300
                        r = safe_atozu(val, &p->n_stashed_fds);
110✔
1301
                        if (r < 0)
110✔
1302
                                return r;
1303

1304
                        if (p->n_stashed_fds > nr_open)
110✔
1305
                                return -EINVAL; /* too many, someone is playing games with us */
1306
                } else if ((val = startswith(l, "exec-parameters-fds="))) {
149,553✔
1307
                        if (p->n_socket_fds + p->n_stashed_fds == 0)
1,750✔
1308
                                return log_warning_errno(
×
1309
                                                SYNTHETIC_ERRNO(EINVAL),
1310
                                                "Got exec-parameters-fds= without "
1311
                                                "prior exec-parameters-n-socket-fds= or exec-parameters-n-stashed-fds=");
1312
                        if (p->n_socket_fds + p->n_stashed_fds > nr_open)
1,750✔
1313
                                return -EINVAL; /* too many, someone is playing games with us */
1314

1315
                        if (p->fds)
1,750✔
1316
                                return -EINVAL; /* duplicated */
1317

1318
                        p->fds = new(int, p->n_socket_fds + p->n_stashed_fds);
1,750✔
1319
                        if (!p->fds)
1,750✔
1320
                                return log_oom_debug();
×
1321

1322
                        /* Ensure we don't leave any FD uninitialized on error, it makes the fuzzer sad */
1323
                        FOREACH_ARRAY(i, p->fds, p->n_socket_fds + p->n_stashed_fds)
5,432✔
1324
                                *i = -EBADF;
3,682✔
1325

1326
                        r = deserialize_fd_many(fds, val, p->n_socket_fds + p->n_stashed_fds, p->fds);
1,750✔
1327
                        if (r < 0)
1,750✔
1328
                                continue;
×
1329

1330
                } else if ((val = startswith(l, "exec-parameters-fd-names="))) {
147,803✔
1331
                        r = deserialize_strv(val, &p->fd_names);
3,682✔
1332
                        if (r < 0)
3,682✔
1333
                                return r;
1334
                } else if ((val = startswith(l, "exec-parameters-flags="))) {
144,121✔
1335
                        unsigned flags;
10,033✔
1336

1337
                        r = safe_atou(val, &flags);
10,033✔
1338
                        if (r < 0)
10,033✔
1339
                                return r;
×
1340
                        p->flags = flags;
10,033✔
1341
                } else if ((val = startswith(l, "exec-parameters-selinux-context-net="))) {
134,088✔
1342
                        r = parse_boolean(val);
×
1343
                        if (r < 0)
×
1344
                                return r;
1345

1346
                        p->selinux_context_net = r;
×
1347
                } else if ((val = startswith(l, "exec-parameters-cgroup-path="))) {
134,088✔
1348
                        r = free_and_strdup(&p->cgroup_path, val);
10,033✔
1349
                        if (r < 0)
10,033✔
1350
                                return r;
1351
                } else if ((val = startswith(l, "exec-parameters-cgroup-id="))) {
124,055✔
1352
                        r = safe_atou64(val, &p->cgroup_id);
10,033✔
1353
                        if (r < 0)
10,033✔
1354
                                return r;
1355
                } else if ((val = startswith(l, "exec-parameters-prefix-directories-"))) {
114,022✔
1356
                        _cleanup_free_ char *type = NULL, *prefix = NULL;
50,165✔
1357
                        ExecDirectoryType dt;
50,165✔
1358

1359
                        r = extract_many_words(&val, "= ", 0, &type, &prefix);
50,165✔
1360
                        if (r < 0)
50,165✔
1361
                                return r;
1362
                        if (r == 0)
50,165✔
1363
                                return -EINVAL;
1364

1365
                        dt = exec_directory_type_from_string(type);
50,165✔
1366
                        if (dt < 0)
50,165✔
1367
                                return -EINVAL;
1368

1369
                        if (!p->prefix) {
50,165✔
1370
                                p->prefix = new0(char*, _EXEC_DIRECTORY_TYPE_MAX+1);
10,033✔
1371
                                if (!p->prefix)
10,033✔
1372
                                        return log_oom_debug();
×
1373
                        }
1374

1375
                        if (isempty(prefix))
50,165✔
1376
                                p->prefix[dt] = mfree(p->prefix[dt]);
×
1377
                        else
1378
                                free_and_replace(p->prefix[dt], prefix);
50,165✔
1379
                } else if ((val = startswith(l, "exec-parameters-received-credentials-directory="))) {
63,857✔
1380
                        r = free_and_strdup(&p->received_credentials_directory, val);
9,334✔
1381
                        if (r < 0)
9,334✔
1382
                                return r;
1383
                } else if ((val = startswith(l, "exec-parameters-received-encrypted-credentials-directory="))) {
54,523✔
1384
                        r = free_and_strdup(&p->received_encrypted_credentials_directory, val);
×
1385
                        if (r < 0)
×
1386
                                return r;
1387
                } else if ((val = startswith(l, "exec-parameters-confirm-spawn="))) {
54,523✔
1388
                        r = free_and_strdup(&p->confirm_spawn, val);
×
1389
                        if (r < 0)
×
1390
                                return r;
1391
                } else if ((val = startswith(l, "exec-parameters-shall-confirm-spawn="))) {
54,523✔
1392
                        r = parse_boolean(val);
×
1393
                        if (r < 0)
×
1394
                                return r;
1395

1396
                        p->shall_confirm_spawn = r;
×
1397
                } else if ((val = startswith(l, "exec-parameters-watchdog-usec="))) {
54,523✔
1398
                        r = deserialize_usec(val, &p->watchdog_usec);
1,482✔
1399
                        if (r < 0)
1,482✔
1400
                                return r;
1401
                } else if ((val = startswith(l, "exec-parameters-idle-pipe="))) {
53,041✔
1402
                        if (p->idle_pipe)
85✔
1403
                                return -EINVAL; /* duplicated */
1404

1405
                        p->idle_pipe = new(int, 4);
85✔
1406
                        if (!p->idle_pipe)
85✔
1407
                                return log_oom_debug();
×
1408

1409
                        p->idle_pipe[0] = p->idle_pipe[1] = p->idle_pipe[2] = p->idle_pipe[3] = -EBADF;
85✔
1410

1411
                        r = deserialize_fd_many(fds, val, 4, p->idle_pipe);
85✔
1412
                        if (r < 0)
85✔
1413
                                continue;
×
1414

1415
                } else if ((val = startswith(l, "exec-parameters-stdin-fd="))) {
52,956✔
1416
                        int fd;
543✔
1417

1418
                        fd = deserialize_fd(fds, val);
543✔
1419
                        if (fd < 0)
543✔
1420
                                continue;
×
1421

1422
                        close_and_replace(p->stdin_fd, fd);
543✔
1423

1424
                } else if ((val = startswith(l, "exec-parameters-stdout-fd="))) {
52,413✔
1425
                        int fd;
543✔
1426

1427
                        fd = deserialize_fd(fds, val);
543✔
1428
                        if (fd < 0)
543✔
1429
                                continue;
×
1430

1431
                        close_and_replace(p->stdout_fd, fd);
543✔
1432

1433
                } else if ((val = startswith(l, "exec-parameters-stderr-fd="))) {
51,870✔
1434
                        int fd;
543✔
1435

1436
                        fd = deserialize_fd(fds, val);
543✔
1437
                        if (fd < 0)
543✔
1438
                                continue;
×
1439

1440
                        close_and_replace(p->stderr_fd, fd);
543✔
1441

1442
                } else if ((val = startswith(l, "exec-parameters-root-directory-fd="))) {
51,327✔
1443
                        int fd;
2✔
1444

1445
                        fd = deserialize_fd(fds, val);
2✔
1446
                        if (fd < 0)
2✔
1447
                                continue;
×
1448

1449
                        close_and_replace(p->root_directory_fd, fd);
2✔
1450

1451
                } else if ((val = startswith(l, "exec-parameters-exec-fd="))) {
51,325✔
1452
                        int fd;
428✔
1453

1454
                        fd = deserialize_fd(fds, val);
428✔
1455
                        if (fd < 0)
428✔
1456
                                continue;
×
1457

1458
                        close_and_replace(p->exec_fd, fd);
428✔
1459
                } else if ((val = startswith(l, "exec-parameters-handoff-timestamp-fd="))) {
50,897✔
1460
                        int fd;
10,033✔
1461

1462
                        fd = deserialize_fd(fds, val);
10,033✔
1463
                        if (fd < 0)
10,033✔
1464
                                continue;
×
1465

1466
                        close_and_replace(p->handoff_timestamp_fd, fd);
10,033✔
1467
                } else if ((val = startswith(l, "exec-parameters-pidref-transport-fd="))) {
40,864✔
1468
                        int fd;
8,872✔
1469

1470
                        fd = deserialize_fd(fds, val);
8,872✔
1471
                        if (fd < 0)
8,872✔
1472
                                continue;
×
1473

1474
                        close_and_replace(p->pidref_transport_fd, fd);
8,872✔
1475
                } else if ((val = startswith(l, "exec-parameters-bpf-outer-map-fd="))) {
31,992✔
1476
                        int fd;
×
1477

1478
                        fd = deserialize_fd(fds, val);
×
1479
                        if (fd < 0)
×
1480
                                continue;
×
1481

1482
                        close_and_replace(p->bpf_restrict_fs_map_fd, fd);
×
1483
                } else if ((val = startswith(l, "exec-parameters-notify-socket="))) {
31,992✔
1484
                        r = free_and_strdup(&p->notify_socket, val);
1,884✔
1485
                        if (r < 0)
1,884✔
1486
                                return r;
1487
                } else if ((val = startswith(l, "exec-parameters-open-file="))) {
30,108✔
1488
                        OpenFile *of;
5✔
1489

1490
                        r = open_file_parse(val, &of);
5✔
1491
                        if (r < 0)
5✔
1492
                                return r;
×
1493

1494
                        LIST_APPEND(open_files, p->open_files, of);
5✔
1495
                } else if ((val = startswith(l, "exec-parameters-fallback-smack-process-label="))) {
30,103✔
1496
                        r = free_and_strdup(&p->fallback_smack_process_label, val);
×
1497
                        if (r < 0)
×
1498
                                return r;
1499
                } else if ((val = startswith(l, "exec-parameters-user-lookup-fd="))) {
30,103✔
1500
                        int fd;
10,033✔
1501

1502
                        fd = deserialize_fd(fds, val);
10,033✔
1503
                        if (fd < 0)
10,033✔
1504
                                continue;
×
1505

1506
                        close_and_replace(p->user_lookup_fd, fd);
10,033✔
1507
                } else if ((val = startswith(l, "exec-parameters-files-env="))) {
20,070✔
1508
                        r = deserialize_strv(val, &p->files_env);
2✔
1509
                        if (r < 0)
2✔
1510
                                return r;
1511
                } else if ((val = startswith(l, "exec-parameters-unit-id="))) {
20,068✔
1512
                        r = free_and_strdup(&p->unit_id, val);
10,033✔
1513
                        if (r < 0)
10,033✔
1514
                                return r;
1515
                } else if ((val = startswith(l, "exec-parameters-invocation-id-string="))) {
10,035✔
1516
                        if (strlen(val) > SD_ID128_STRING_MAX - 1)
10,033✔
1517
                                return -EINVAL;
1518

1519
                        r = sd_id128_from_string(val, &p->invocation_id);
10,033✔
1520
                        if (r < 0)
10,033✔
1521
                                return r;
1522

1523
                        sd_id128_to_string(p->invocation_id, p->invocation_id_string);
10,033✔
1524
                } else if ((val = startswith(l, "exec-parameters-debug-invocation="))) {
2✔
1525
                        r = parse_boolean(val);
2✔
1526
                        if (r < 0)
2✔
1527
                                return r;
1528

1529
                        p->debug_invocation = r;
2✔
1530
                } else
1531
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
1532
        }
1533

1534
        /* Bail out if we got exec-parameters-n-{socket/stashed}-fds= but no corresponding
1535
         * exec-parameters-fds= */
1536
        if (p->n_socket_fds + p->n_stashed_fds > 0 && !p->fds)
10,033✔
1537
                return -EINVAL;
×
1538

1539
        return 0;
1540
}
1541

1542
static int exec_context_serialize(const ExecContext *c, FILE *f) {
2,430✔
1543
        int r;
2,430✔
1544

1545
        assert(f);
2,430✔
1546

1547
        if (!c)
2,430✔
1548
                return 0;
2,430✔
1549

1550
        r = serialize_strv(f, "exec-context-environment", c->environment);
2,430✔
1551
        if (r < 0)
2,430✔
1552
                return r;
1553

1554
        r = serialize_strv(f, "exec-context-environment-files", c->environment_files);
2,430✔
1555
        if (r < 0)
2,430✔
1556
                return r;
1557

1558
        r = serialize_strv(f, "exec-context-pass-environment", c->pass_environment);
2,430✔
1559
        if (r < 0)
2,430✔
1560
                return r;
1561

1562
        r = serialize_strv(f, "exec-context-unset-environment", c->unset_environment);
2,430✔
1563
        if (r < 0)
2,430✔
1564
                return r;
1565

1566
        r = serialize_item_escaped(f, "exec-context-working-directory", c->working_directory);
2,430✔
1567
        if (r < 0)
2,430✔
1568
                return r;
1569

1570
        r = serialize_bool_elide(f, "exec-context-working-directory-missing-ok", c->working_directory_missing_ok);
2,430✔
1571
        if (r < 0)
2,430✔
1572
                return r;
1573

1574
        r = serialize_bool_elide(f, "exec-context-working-directory-home", c->working_directory_home);
2,430✔
1575
        if (r < 0)
2,430✔
1576
                return r;
1577

1578
        r = serialize_item_escaped(f, "exec-context-root-directory", c->root_directory);
2,430✔
1579
        if (r < 0)
2,430✔
1580
                return r;
1581

1582
        r = serialize_item_escaped(f, "exec-context-root-image", c->root_image);
2,430✔
1583
        if (r < 0)
2,430✔
1584
                return r;
1585

1586
        if (c->root_image_options) {
2,430✔
1587
                _cleanup_free_ char *options = NULL;
×
1588

1589
                LIST_FOREACH(mount_options, o, c->root_image_options) {
×
1590
                        if (isempty(o->options))
×
1591
                                continue;
×
1592

1593
                        _cleanup_free_ char *escaped = NULL;
×
1594
                        escaped = shell_escape(o->options, ":");
×
1595
                        if (!escaped)
×
1596
                                return log_oom_debug();
×
1597

1598
                        if (!strextend(&options,
×
1599
                                        " ",
1600
                                        partition_designator_to_string(o->partition_designator),
1601
                                               ":",
1602
                                               escaped))
1603
                                        return log_oom_debug();
×
1604
                }
1605

1606
                r = serialize_item(f, "exec-context-root-image-options", options);
×
1607
                if (r < 0)
×
1608
                        return r;
1609
        }
1610

1611
        r = serialize_item(f, "exec-context-root-verity", c->root_verity);
2,430✔
1612
        if (r < 0)
2,430✔
1613
                return r;
1614

1615
        r = serialize_item(f, "exec-context-root-hash-path", c->root_hash_path);
2,430✔
1616
        if (r < 0)
2,430✔
1617
                return r;
1618

1619
        r = serialize_item(f, "exec-context-root-hash-sig-path", c->root_hash_sig_path);
2,430✔
1620
        if (r < 0)
2,430✔
1621
                return r;
1622

1623
        r = serialize_item_hexmem(f, "exec-context-root-hash", c->root_hash.iov_base, c->root_hash.iov_len);
2,430✔
1624
        if (r < 0)
2,430✔
1625
                return r;
1626

1627
        r = serialize_item_base64mem(f, "exec-context-root-hash-sig", c->root_hash_sig.iov_base, c->root_hash_sig.iov_len);
2,430✔
1628
        if (r < 0)
2,430✔
1629
                return r;
1630

1631
        r = serialize_bool_elide(f, "exec-context-root-ephemeral", c->root_ephemeral);
2,430✔
1632
        if (r < 0)
2,430✔
1633
                return r;
1634

1635
        r = serialize_item_format(f, "exec-context-umask", "%04o", c->umask);
2,430✔
1636
        if (r < 0)
2,430✔
1637
                return r;
1638

1639
        r = serialize_bool_elide(f, "exec-context-non-blocking", c->non_blocking);
2,430✔
1640
        if (r < 0)
2,430✔
1641
                return r;
1642

1643
        r = serialize_item_tristate(f, "exec-context-private-mounts", c->private_mounts);
2,430✔
1644
        if (r < 0)
28✔
1645
                return r;
1646

1647
        r = serialize_item_tristate(f, "exec-context-mount-api-vfs", c->mount_apivfs);
2,430✔
1648
        if (r < 0)
2✔
1649
                return r;
1650

1651
        r = serialize_item_tristate(f, "exec-context-bind-log-sockets", c->bind_log_sockets);
2,430✔
1652
        if (r < 0)
×
1653
                return r;
1654

1655
        r = serialize_item_tristate(f, "exec-context-memory-ksm", c->memory_ksm);
2,430✔
1656
        if (r < 0)
×
1657
                return r;
1658

1659
        r = serialize_item(f, "exec-context-private-tmp", private_tmp_to_string(c->private_tmp));
2,430✔
1660
        if (r < 0)
2,430✔
1661
                return r;
1662

1663
        /* This must be set in unit_patch_contexts() before executing a command. */
1664
        assert(c->private_var_tmp >= 0 && c->private_var_tmp < _PRIVATE_TMP_MAX);
2,430✔
1665
        r = serialize_item(f, "exec-context-private-var-tmp", private_tmp_to_string(c->private_var_tmp));
2,430✔
1666
        if (r < 0)
2,430✔
1667
                return r;
1668

1669
        r = serialize_bool_elide(f, "exec-context-private-devices", c->private_devices);
2,430✔
1670
        if (r < 0)
2,430✔
1671
                return r;
1672

1673
        r = serialize_bool_elide(f, "exec-context-protect-kernel-tunables", c->protect_kernel_tunables);
2,430✔
1674
        if (r < 0)
2,430✔
1675
                return r;
1676

1677
        r = serialize_bool_elide(f, "exec-context-protect-kernel-modules", c->protect_kernel_modules);
2,430✔
1678
        if (r < 0)
2,430✔
1679
                return r;
1680

1681
        r = serialize_bool_elide(f, "exec-context-protect-kernel-logs", c->protect_kernel_logs);
2,430✔
1682
        if (r < 0)
2,430✔
1683
                return r;
1684

1685
        r = serialize_bool_elide(f, "exec-context-protect-clock", c->protect_clock);
2,430✔
1686
        if (r < 0)
2,430✔
1687
                return r;
1688

1689
        r = serialize_item(f, "exec-context-protect-control-groups", protect_control_groups_to_string(c->protect_control_groups));
2,430✔
1690
        if (r < 0)
2,430✔
1691
                return r;
1692

1693
        r = serialize_bool_elide(f, "exec-context-private-network", c->private_network);
2,430✔
1694
        if (r < 0)
2,430✔
1695
                return r;
1696

1697
        r = serialize_item(f, "exec-context-private-users", private_users_to_string(c->private_users));
2,430✔
1698
        if (r < 0)
2,430✔
1699
                return r;
1700

1701
        r = serialize_bool_elide(f, "exec-context-private-ipc", c->private_ipc);
2,430✔
1702
        if (r < 0)
2,430✔
1703
                return r;
1704

1705
        r = serialize_item(f, "exec-context-private-pids", private_pids_to_string(c->private_pids));
2,430✔
1706
        if (r < 0)
2,430✔
1707
                return r;
1708

1709
        r = serialize_bool_elide(f, "exec-context-remove-ipc", c->remove_ipc);
2,430✔
1710
        if (r < 0)
2,430✔
1711
                return r;
1712

1713
        r = serialize_item(f, "exec-context-protect-home", protect_home_to_string(c->protect_home));
2,430✔
1714
        if (r < 0)
2,430✔
1715
                return r;
1716

1717
        r = serialize_item(f, "exec-context-protect-system", protect_system_to_string(c->protect_system));
2,430✔
1718
        if (r < 0)
2,430✔
1719
                return r;
1720

1721
        r = serialize_bool_elide(f, "exec-context-same-pgrp", c->same_pgrp);
2,430✔
1722
        if (r < 0)
2,430✔
1723
                return r;
1724

1725
        r = serialize_bool(f, "exec-context-ignore-sigpipe", c->ignore_sigpipe);
2,430✔
1726
        if (r < 0)
2,430✔
1727
                return r;
1728

1729
        r = serialize_bool_elide(f, "exec-context-memory-deny-write-execute", c->memory_deny_write_execute);
2,430✔
1730
        if (r < 0)
2,430✔
1731
                return r;
1732

1733
        r = serialize_bool_elide(f, "exec-context-restrict-realtime", c->restrict_realtime);
2,430✔
1734
        if (r < 0)
2,430✔
1735
                return r;
1736

1737
        r = serialize_bool_elide(f, "exec-context-restrict-suid-sgid", c->restrict_suid_sgid);
2,430✔
1738
        if (r < 0)
2,430✔
1739
                return r;
1740

1741
        r = serialize_item(f, "exec-context-keyring-mode", exec_keyring_mode_to_string(c->keyring_mode));
2,430✔
1742
        if (r < 0)
2,430✔
1743
                return r;
1744

1745
        r = serialize_item(f, "exec-context-protect-hostname", protect_hostname_to_string(c->protect_hostname));
2,430✔
1746
        if (r < 0)
2,430✔
1747
                return r;
1748

1749
        r = serialize_item(f, "exec-context-private-hostname", c->private_hostname);
2,430✔
1750
        if (r < 0)
2,430✔
1751
                return r;
1752

1753
        r = serialize_item(f, "exec-context-protect-proc", protect_proc_to_string(c->protect_proc));
2,430✔
1754
        if (r < 0)
2,430✔
1755
                return r;
1756

1757
        r = serialize_item(f, "exec-context-proc-subset", proc_subset_to_string(c->proc_subset));
2,430✔
1758
        if (r < 0)
2,430✔
1759
                return r;
1760

1761
        r = serialize_item(f, "exec-context-private-bpf", private_bpf_to_string(c->private_bpf));
2,430✔
1762
        if (r < 0)
2,430✔
1763
                return r;
1764

1765
        if (c->bpf_delegate_commands != 0) {
2,430✔
1766
                r = serialize_item_format(f, "exec-context-bpf-delegate-commands", "0x%"PRIx64, c->bpf_delegate_commands);
×
1767
                if (r < 0)
×
1768
                        return r;
1769
        }
1770

1771
        if (c->bpf_delegate_maps != 0) {
2,430✔
1772
                r = serialize_item_format(f, "exec-context-bpf-delegate-maps", "0x%"PRIx64, c->bpf_delegate_maps);
×
1773
                if (r < 0)
×
1774
                        return r;
1775
        }
1776

1777
        if (c->bpf_delegate_programs != 0) {
2,430✔
1778
                r = serialize_item_format(f, "exec-context-bpf-delegate-programs", "0x%"PRIx64, c->bpf_delegate_programs);
×
1779
                if (r < 0)
×
1780
                        return r;
1781
        }
1782

1783
        if (c->bpf_delegate_attachments != 0) {
2,430✔
1784
                r = serialize_item_format(f, "exec-context-bpf-delegate-attachments", "0x%"PRIx64, c->bpf_delegate_attachments);
×
1785
                if (r < 0)
×
1786
                        return r;
1787
        }
1788

1789
        r = serialize_item(f, "exec-context-runtime-directory-preserve-mode", exec_preserve_mode_to_string(c->runtime_directory_preserve_mode));
2,430✔
1790
        if (r < 0)
2,430✔
1791
                return r;
1792

1793
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
14,580✔
1794
                _cleanup_free_ char *key = NULL, *value = NULL;
12,150✔
1795

1796
                key = strjoin("exec-context-directories-", exec_directory_type_to_string(dt));
12,150✔
1797
                if (!key)
12,150✔
1798
                        return log_oom_debug();
×
1799

1800
                if (asprintf(&value, "%04o", c->directories[dt].mode) < 0)
12,150✔
1801
                        return log_oom_debug();
×
1802

1803
                FOREACH_ARRAY(i, c->directories[dt].items, c->directories[dt].n_items) {
12,575✔
1804
                        _cleanup_free_ char *path_escaped = NULL;
425✔
1805

1806
                        path_escaped = shell_escape(i->path, ":" WHITESPACE);
425✔
1807
                        if (!path_escaped)
425✔
1808
                                return log_oom_debug();
×
1809

1810
                        if (!strextend(&value, " ", path_escaped))
425✔
1811
                                return log_oom_debug();
×
1812

1813
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE))))
845✔
1814
                                return log_oom_debug();
×
1815

1816
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_READ_ONLY))))
848✔
1817
                                return log_oom_debug();
×
1818

1819
                        STRV_FOREACH(d, i->symlinks) {
431✔
1820
                                _cleanup_free_ char *link_escaped = NULL;
6✔
1821

1822
                                link_escaped = shell_escape(*d, ":" WHITESPACE);
6✔
1823
                                if (!link_escaped)
6✔
1824
                                        return log_oom_debug();
×
1825

1826
                                if (!strextend(&value, ":", link_escaped))
6✔
1827
                                        return log_oom_debug();
×
1828
                        }
1829
                }
1830

1831
                r = serialize_item(f, key, value);
12,150✔
1832
                if (r < 0)
12,150✔
1833
                        return r;
1834

1835
                if (c->directories[dt].exec_quota.quota_enforce) {
12,150✔
1836
                        _cleanup_free_ char *key_quota = NULL;
×
1837
                        key_quota = strjoin("exec-context-quota-directories-", exec_directory_type_to_string(dt));
×
1838
                        if (!key_quota)
×
1839
                                return log_oom_debug();
×
1840

1841
                        r = serialize_item_format(f, key_quota, "%" PRIu64 " %" PRIu32, c->directories[dt].exec_quota.quota_absolute,
×
1842
                                                                                        c->directories[dt].exec_quota.quota_scale);
×
1843
                        if (r < 0)
×
1844
                                return r;
1845

1846
                } else if (c->directories[dt].exec_quota.quota_accounting) {
12,150✔
1847
                        _cleanup_free_ char *key_quota = NULL;
×
1848
                        key_quota = strjoin("exec-context-quota-accounting-directories-", exec_directory_type_to_string(dt));
×
1849
                        if (!key_quota)
×
1850
                                return log_oom_debug();
×
1851

1852
                        r = serialize_bool(f, key_quota, c->directories[dt].exec_quota.quota_accounting);
×
1853
                        if (r < 0)
×
1854
                                return r;
1855
                }
1856
        }
1857

1858
        r = serialize_usec(f, "exec-context-timeout-clean-usec", c->timeout_clean_usec);
2,430✔
1859
        if (r < 0)
2,430✔
1860
                return r;
1861

1862
        if (c->nice_set) {
2,430✔
1863
                r = serialize_item_format(f, "exec-context-nice", "%i", c->nice);
3✔
1864
                if (r < 0)
3✔
1865
                        return r;
1866
        }
1867

1868
        if (c->oom_score_adjust_set) {
2,430✔
1869
                r = serialize_item_format(f, "exec-context-oom-score-adjust", "%i", c->oom_score_adjust);
598✔
1870
                if (r < 0)
598✔
1871
                        return r;
1872
        }
1873

1874
        if (c->coredump_filter_set) {
2,430✔
1875
                r = serialize_item_format(f, "exec-context-coredump-filter", "%"PRIx64, c->coredump_filter);
×
1876
                if (r < 0)
×
1877
                        return r;
1878
        }
1879

1880
        for (unsigned i = 0; i < RLIM_NLIMITS; i++) {
41,310✔
1881
                _cleanup_free_ char *key = NULL, *limit = NULL;
4,854✔
1882

1883
                if (!c->rlimit[i])
38,880✔
1884
                        continue;
34,026✔
1885

1886
                key = strjoin("exec-context-limit-", rlimit_to_string(i));
4,854✔
1887
                if (!key)
4,854✔
1888
                        return log_oom_debug();
×
1889

1890
                r = rlimit_format(c->rlimit[i], &limit);
4,854✔
1891
                if (r < 0)
4,854✔
1892
                        return r;
1893

1894
                r = serialize_item(f, key, limit);
4,854✔
1895
                if (r < 0)
4,854✔
1896
                        return r;
1897
        }
1898

1899
        if (c->ioprio_is_set) {
2,430✔
1900
                r = serialize_item_format(f, "exec-context-ioprio", "%d", c->ioprio);
8✔
1901
                if (r < 0)
8✔
1902
                        return r;
1903
        }
1904

1905
        if (c->cpu_sched_set) {
2,430✔
1906
                _cleanup_free_ char *policy_str = NULL;
×
1907

1908
                r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
×
1909
                if (r < 0)
×
1910
                        return r;
1911

1912
                r = serialize_item(f, "exec-context-cpu-scheduling-policy", policy_str);
×
1913
                if (r < 0)
×
1914
                        return r;
1915

1916
                r = serialize_item_format(f, "exec-context-cpu-scheduling-priority", "%i", c->cpu_sched_priority);
×
1917
                if (r < 0)
×
1918
                        return r;
1919

1920
                r = serialize_bool_elide(f, "exec-context-cpu-scheduling-reset-on-fork", c->cpu_sched_reset_on_fork);
×
1921
                if (r < 0)
×
1922
                        return r;
1923
        }
1924

1925
        if (c->cpu_set.set) {
2,430✔
1926
                _cleanup_free_ char *affinity = NULL;
×
1927

1928
                affinity = cpu_set_to_range_string(&c->cpu_set);
×
1929
                if (!affinity)
×
1930
                        return log_oom_debug();
×
1931

1932
                r = serialize_item(f, "exec-context-cpu-affinity", affinity);
×
1933
                if (r < 0)
×
1934
                        return r;
1935
        }
1936

1937
        if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) {
2,430✔
1938
                _cleanup_free_ char *nodes = NULL;
×
1939

1940
                nodes = cpu_set_to_range_string(&c->numa_policy.nodes);
×
1941
                if (!nodes)
×
1942
                        return log_oom_debug();
×
1943

1944
                if (nodes) {
×
1945
                        r = serialize_item(f, "exec-context-numa-mask", nodes);
×
1946
                        if (r < 0)
×
1947
                                return r;
1948
                }
1949

1950
                r = serialize_item_format(f, "exec-context-numa-policy", "%d", c->numa_policy.type);
×
1951
                if (r < 0)
×
1952
                        return r;
1953
        }
1954

1955
        r = serialize_bool_elide(f, "exec-context-cpu-affinity-from-numa", c->cpu_affinity_from_numa);
2,430✔
1956
        if (r < 0)
2,430✔
1957
                return r;
1958

1959
        if (c->timer_slack_nsec != NSEC_INFINITY) {
2,430✔
1960
                r = serialize_item_format(f, "exec-context-timer-slack-nsec", NSEC_FMT, c->timer_slack_nsec);
×
1961
                if (r < 0)
×
1962
                        return r;
1963
        }
1964

1965
        r = serialize_bool_elide(f, "exec-context-root-directory-as-fd", c->root_directory_as_fd);
2,430✔
1966
        if (r < 0)
2,430✔
1967
                return r;
1968

1969
        r = serialize_item(f, "exec-context-std-input", exec_input_to_string(c->std_input));
2,430✔
1970
        if (r < 0)
2,430✔
1971
                return r;
1972

1973
        r = serialize_item(f, "exec-context-std-output", exec_output_to_string(c->std_output));
2,430✔
1974
        if (r < 0)
2,430✔
1975
                return r;
1976

1977
        r = serialize_item(f, "exec-context-std-error", exec_output_to_string(c->std_error));
2,430✔
1978
        if (r < 0)
2,430✔
1979
                return r;
1980

1981
        r = serialize_bool_elide(f, "exec-context-stdio-as-fds", c->stdio_as_fds);
2,430✔
1982
        if (r < 0)
2,430✔
1983
                return r;
1984

1985
        switch (c->std_input) {
2,430✔
1986

1987
        case EXEC_INPUT_NAMED_FD:
×
1988
                r = serialize_item(f, "exec-context-std-input-fd-name", c->stdio_fdname[STDIN_FILENO]);
×
1989
                break;
1990

1991
        case EXEC_INPUT_FILE:
×
1992
                r = serialize_item_escaped(f, "exec-context-std-input-file", c->stdio_file[STDIN_FILENO]);
×
1993
                break;
1994

1995
        case EXEC_INPUT_DATA:
×
1996
                r = serialize_item_base64mem(f, "exec-context-std-input-data", c->stdin_data, c->stdin_data_size);
×
1997
                break;
1998

1999
        default:
2000
                r = 0;
2001
        }
2002
        if (r < 0)
×
2003
                return r;
2004

2005
        switch (c->std_output) {
2,430✔
2006

2007
        case EXEC_OUTPUT_NAMED_FD:
×
2008
                r = serialize_item(f, "exec-context-std-output-fd-name", c->stdio_fdname[STDOUT_FILENO]);
×
2009
                break;
2010

2011
        case EXEC_OUTPUT_FILE:
2✔
2012
        case EXEC_OUTPUT_FILE_APPEND:
2013
        case EXEC_OUTPUT_FILE_TRUNCATE:
2014
                r = serialize_item_escaped(f, "exec-context-std-output-file", c->stdio_file[STDOUT_FILENO]);
2✔
2015
                break;
2016

2017
        default:
2018
                r = 0;
2019
        }
2020
        if (r < 0)
2✔
2021
                return r;
2022

2023

2024
        switch (c->std_error) {
2,430✔
2025

2026
        case EXEC_OUTPUT_NAMED_FD:
×
2027
                r = serialize_item(f, "exec-context-std-error-fd-name", c->stdio_fdname[STDERR_FILENO]);
×
2028
                break;
2029

2030
        case EXEC_OUTPUT_FILE:
×
2031
        case EXEC_OUTPUT_FILE_APPEND:
2032
        case EXEC_OUTPUT_FILE_TRUNCATE:
2033
                r = serialize_item_escaped(f, "exec-context-std-error-file", c->stdio_file[STDERR_FILENO]);
×
2034
                break;
2035

2036
        default:
2037
                r = 0;
2038
        }
2039
        if (r < 0)
×
2040
                return r;
2041

2042
        r = serialize_item(f, "exec-context-tty-path", c->tty_path);
2,430✔
2043
        if (r < 0)
2,430✔
2044
                return r;
2045

2046
        r = serialize_bool_elide(f, "exec-context-tty-reset", c->tty_reset);
2,430✔
2047
        if (r < 0)
2,430✔
2048
                return r;
2049

2050
        r = serialize_bool_elide(f, "exec-context-tty-vhangup", c->tty_vhangup);
2,430✔
2051
        if (r < 0)
2,430✔
2052
                return r;
2053

2054
        r = serialize_bool_elide(f, "exec-context-tty-vt-disallocate", c->tty_vt_disallocate);
2,430✔
2055
        if (r < 0)
2,430✔
2056
                return r;
2057

2058
        r = serialize_item_format(f, "exec-context-tty-rows", "%u", c->tty_rows);
2,430✔
2059
        if (r < 0)
2,430✔
2060
                return r;
2061

2062
        r = serialize_item_format(f, "exec-context-tty-columns", "%u", c->tty_cols);
2,430✔
2063
        if (r < 0)
2,430✔
2064
                return r;
2065

2066
        r = serialize_item_format(f, "exec-context-syslog-priority", "%i", c->syslog_priority);
2,430✔
2067
        if (r < 0)
2,430✔
2068
                return r;
2069

2070
        r = serialize_bool(f, "exec-context-syslog-level-prefix", c->syslog_level_prefix);
2,430✔
2071
        if (r < 0)
2,430✔
2072
                return r;
2073

2074
        r = serialize_item(f, "exec-context-syslog-identifier", c->syslog_identifier);
2,430✔
2075
        if (r < 0)
2,430✔
2076
                return r;
2077

2078
        /* This is also passed to executor as an argument. So, the information should be redundant in general.
2079
         * But, let's keep this as is for consistency with other elements of ExecContext. See exec_spawn(). */
2080
        r = serialize_item_format(f, "exec-context-log-level-max", "%d", c->log_level_max);
2,430✔
2081
        if (r < 0)
2,430✔
2082
                return r;
2083

2084
        if (c->log_ratelimit.interval > 0) {
2,430✔
2085
                r = serialize_usec(f, "exec-context-log-ratelimit-interval-usec", c->log_ratelimit.interval);
×
2086
                if (r < 0)
×
2087
                        return r;
2088
        }
2089

2090
        if (c->log_ratelimit.burst > 0) {
2,430✔
2091
                r = serialize_item_format(f, "exec-context-log-ratelimit-burst", "%u", c->log_ratelimit.burst);
×
2092
                if (r < 0)
×
2093
                        return r;
2094
        }
2095

2096
        r = serialize_string_set(f, "exec-context-log-filter-allowed-patterns", c->log_filter_allowed_patterns);
2,430✔
2097
        if (r < 0)
2,430✔
2098
                return r;
2099

2100
        r = serialize_string_set(f, "exec-context-log-filter-denied-patterns", c->log_filter_denied_patterns);
2,430✔
2101
        if (r < 0)
2,430✔
2102
                return r;
2103

2104
        FOREACH_ARRAY(field, c->log_extra_fields, c->n_log_extra_fields) {
2,671✔
2105
                r = serialize_item(f, "exec-context-log-extra-fields", field->iov_base);
241✔
2106
                if (r < 0)
241✔
2107
                        return r;
2108
        }
2109

2110
        r = serialize_item(f, "exec-context-log-namespace", c->log_namespace);
2,430✔
2111
        if (r < 0)
2,430✔
2112
                return r;
2113

2114
        if (c->secure_bits != 0) {
2,430✔
2115
                r = serialize_item_format(f, "exec-context-secure-bits", "%d", c->secure_bits);
×
2116
                if (r < 0)
×
2117
                        return r;
2118
        }
2119

2120
        if (c->capability_bounding_set != CAP_MASK_UNSET) {
2,430✔
2121
                r = serialize_item_format(f, "exec-context-capability-bounding-set", "%" PRIu64, c->capability_bounding_set);
2,430✔
2122
                if (r < 0)
2,430✔
2123
                        return r;
2124
        }
2125

2126
        if (c->capability_ambient_set != 0) {
2,430✔
2127
                r = serialize_item_format(f, "exec-context-capability-ambient-set", "%" PRIu64, c->capability_ambient_set);
69✔
2128
                if (r < 0)
69✔
2129
                        return r;
2130
        }
2131

2132
        if (c->user) {
2,430✔
2133
                r = serialize_item(f, "exec-context-user", c->user);
199✔
2134
                if (r < 0)
199✔
2135
                        return r;
2136
        }
2137

2138
        r = serialize_item(f, "exec-context-group", c->group);
2,430✔
2139
        if (r < 0)
2,430✔
2140
                return r;
2141

2142
        r = serialize_bool_elide(f, "exec-context-dynamic-user", c->dynamic_user);
2,430✔
2143
        if (r < 0)
2,430✔
2144
                return r;
2145

2146
        r = serialize_strv(f, "exec-context-supplementary-groups", c->supplementary_groups);
2,430✔
2147
        if (r < 0)
2,430✔
2148
                return r;
2149

2150
        r = serialize_item_tristate(f, "exec-context-set-login-environment", c->set_login_environment);
2,430✔
2151
        if (r < 0)
×
2152
                return r;
2153

2154
        r = serialize_item(f, "exec-context-pam-name", c->pam_name);
2,430✔
2155
        if (r < 0)
2,430✔
2156
                return r;
2157

2158
        r = serialize_strv(f, "exec-context-read-write-paths", c->read_write_paths);
2,430✔
2159
        if (r < 0)
2,430✔
2160
                return r;
2161

2162
        r = serialize_strv(f, "exec-context-read-only-paths", c->read_only_paths);
2,430✔
2163
        if (r < 0)
2,430✔
2164
                return r;
2165

2166
        r = serialize_strv(f, "exec-context-inaccessible-paths", c->inaccessible_paths);
2,430✔
2167
        if (r < 0)
2,430✔
2168
                return r;
2169

2170
        r = serialize_strv(f, "exec-context-exec-paths", c->exec_paths);
2,430✔
2171
        if (r < 0)
2,430✔
2172
                return r;
2173

2174
        r = serialize_strv(f, "exec-context-no-exec-paths", c->no_exec_paths);
2,430✔
2175
        if (r < 0)
2,430✔
2176
                return r;
2177

2178
        r = serialize_strv(f, "exec-context-exec-search-path", c->exec_search_path);
2,430✔
2179
        if (r < 0)
2,430✔
2180
                return r;
2181

2182
        r = serialize_item_format(f, "exec-context-mount-propagation-flag", "%lu", c->mount_propagation_flag);
2,430✔
2183
        if (r < 0)
2,430✔
2184
                return r;
2185

2186
        FOREACH_ARRAY(mount, c->bind_mounts, c->n_bind_mounts) {
2,445✔
2187
                _cleanup_free_ char *src_escaped = NULL, *dst_escaped = NULL;
15✔
2188

2189
                src_escaped = shell_escape(mount->source, ":" WHITESPACE);
15✔
2190
                if (!src_escaped)
15✔
2191
                        return log_oom_debug();
×
2192

2193
                dst_escaped = shell_escape(mount->destination, ":" WHITESPACE);
15✔
2194
                if (!dst_escaped)
15✔
2195
                        return log_oom_debug();
×
2196

2197
                r = serialize_item_format(f,
15✔
2198
                                          mount->read_only ? "exec-context-bind-read-only-path" : "exec-context-bind-path",
15✔
2199
                                          "%s%s:%s:%s",
2200
                                          mount->ignore_enoent ? "-" : "",
15✔
2201
                                          src_escaped,
2202
                                          dst_escaped,
2203
                                          mount->recursive ? "rbind" : "norbind");
15✔
2204
                if (r < 0)
15✔
2205
                        return r;
2206
        }
2207

2208
        FOREACH_ARRAY(tmpfs, c->temporary_filesystems, c->n_temporary_filesystems) {
2,434✔
2209
                _cleanup_free_ char *escaped = NULL;
4✔
2210

2211
                if (!isempty(tmpfs->options)) {
4✔
2212
                        escaped = shell_escape(tmpfs->options, ":");
×
2213
                        if (!escaped)
×
2214
                                return log_oom_debug();
×
2215
                }
2216

2217
                r = serialize_item_format(f, "exec-context-temporary-filesystems", "%s%s%s",
×
2218
                                          tmpfs->path,
2219
                                          isempty(escaped) ? "" : ":",
4✔
2220
                                          strempty(escaped));
2221
                if (r < 0)
4✔
2222
                        return r;
2223
        }
2224

2225
        r = serialize_item(f, "exec-context-utmp-id", c->utmp_id);
2,430✔
2226
        if (r < 0)
2,430✔
2227
                return r;
2228

2229
        r = serialize_item(f, "exec-context-utmp-mode", exec_utmp_mode_to_string(c->utmp_mode));
2,430✔
2230
        if (r < 0)
2,430✔
2231
                return r;
2232

2233
        r = serialize_bool_elide(f, "exec-context-no-new-privileges", c->no_new_privileges);
2,430✔
2234
        if (r < 0)
2,430✔
2235
                return r;
2236

2237
        if (c->selinux_context) {
2,430✔
2238
                r = serialize_item_format(f, "exec-context-selinux-context",
×
2239
                                          "%s%s",
2240
                                          c->selinux_context_ignore ? "-" : "",
×
2241
                                          c->selinux_context);
2242
                if (r < 0)
×
2243
                        return r;
2244
        }
2245

2246
        if (c->apparmor_profile) {
2,430✔
2247
                r = serialize_item_format(f, "exec-context-apparmor-profile",
×
2248
                                          "%s%s",
2249
                                          c->apparmor_profile_ignore ? "-" : "",
×
2250
                                          c->apparmor_profile);
2251
                if (r < 0)
×
2252
                        return r;
2253
        }
2254

2255
        if (c->smack_process_label) {
2,430✔
2256
                r = serialize_item_format(f, "exec-context-smack-process-label",
×
2257
                                          "%s%s",
2258
                                          c->smack_process_label_ignore ? "-" : "",
×
2259
                                          c->smack_process_label);
2260
                if (r < 0)
×
2261
                        return r;
2262
        }
2263

2264
        if (c->personality != PERSONALITY_INVALID) {
2,430✔
2265
                r = serialize_item(f, "exec-context-personality", personality_to_string(c->personality));
×
2266
                if (r < 0)
×
2267
                        return r;
2268
        }
2269

2270
        r = serialize_bool_elide(f, "exec-context-lock-personality", c->lock_personality);
2,430✔
2271
        if (r < 0)
2,430✔
2272
                return r;
2273

2274
#if HAVE_SECCOMP
2275
        if (!hashmap_isempty(c->syscall_filter)) {
2,430✔
2276
                void *errno_num, *id;
231✔
2277
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_filter) {
88,616✔
2278
                        r = serialize_item_format(f, "exec-context-syscall-filter", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
88,385✔
2279
                        if (r < 0)
88,385✔
2280
                                return r;
×
2281
                }
2282
        }
2283

2284
        if (!set_isempty(c->syscall_archs)) {
2,430✔
2285
                void *id;
227✔
2286
                SET_FOREACH(id, c->syscall_archs) {
454✔
2287
                        r = serialize_item_format(f, "exec-context-syscall-archs", "%u", PTR_TO_UINT(id) - 1);
227✔
2288
                        if (r < 0)
227✔
2289
                                return r;
×
2290
                }
2291
        }
2292

2293
        if (c->syscall_errno > 0) {
2,430✔
2294
                r = serialize_item_format(f, "exec-context-syscall-errno", "%d", c->syscall_errno);
2,430✔
2295
                if (r < 0)
2,430✔
2296
                        return r;
2297
        }
2298

2299
        r = serialize_bool_elide(f, "exec-context-syscall-allow-list", c->syscall_allow_list);
2,430✔
2300
        if (r < 0)
2,430✔
2301
                return r;
2302

2303
        if (!hashmap_isempty(c->syscall_log)) {
2,430✔
2304
                void *errno_num, *id;
×
2305
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_log) {
×
2306
                        r = serialize_item_format(f, "exec-context-syscall-log", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
×
2307
                        if (r < 0)
×
2308
                                return r;
×
2309
                }
2310
        }
2311

2312
        r = serialize_bool_elide(f, "exec-context-syscall-log-allow-list", c->syscall_log_allow_list);
2,430✔
2313
        if (r < 0)
2,430✔
2314
                return r;
2315
#endif
2316

2317
        if (c->restrict_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,430✔
2318
                r = serialize_item_format(f, "exec-context-restrict-namespaces", "%lu", c->restrict_namespaces);
178✔
2319
                if (r < 0)
178✔
2320
                        return r;
2321
        }
2322

2323
        if (c->delegate_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,430✔
2324
                r = serialize_item_format(f, "exec-context-delegate-namespaces", "%lu", c->delegate_namespaces);
9✔
2325
                if (r < 0)
9✔
2326
                        return r;
2327
        }
2328

2329
#if HAVE_LIBBPF
2330
        if (exec_context_restrict_filesystems_set(c)) {
2,430✔
2331
                char *fs;
×
2332
                SET_FOREACH(fs, c->restrict_filesystems) {
×
2333
                        r = serialize_item(f, "exec-context-restrict-filesystems", fs);
×
2334
                        if (r < 0)
×
2335
                                return r;
×
2336
                }
2337
        }
2338

2339
        r = serialize_bool_elide(f, "exec-context-restrict-filesystems-allow-list", c->restrict_filesystems_allow_list);
2,430✔
2340
        if (r < 0)
2,430✔
2341
                return r;
2342
#endif
2343

2344
        if (!set_isempty(c->address_families)) {
2,430✔
2345
                void *afp;
227✔
2346

2347
                SET_FOREACH(afp, c->address_families) {
1,109✔
2348
                        int af = PTR_TO_INT(afp);
882✔
2349

2350
                        if (af <= 0 || af >= af_max())
882✔
2351
                                continue;
×
2352

2353
                        r = serialize_item_format(f, "exec-context-address-families", "%d", af);
882✔
2354
                        if (r < 0)
882✔
2355
                                return r;
×
2356
                }
2357
        }
2358

2359
        r = serialize_bool_elide(f, "exec-context-address-families-allow-list", c->address_families_allow_list);
2,430✔
2360
        if (r < 0)
2,430✔
2361
                return r;
2362

2363
        r = serialize_item(f, "exec-context-user-namespace-path", c->user_namespace_path);
2,430✔
2364
        if (r < 0)
2,430✔
2365
                return r;
2366

2367
        r = serialize_item(f, "exec-context-network-namespace-path", c->network_namespace_path);
2,430✔
2368
        if (r < 0)
2,430✔
2369
                return r;
2370

2371
        r = serialize_item(f, "exec-context-ipc-namespace-path", c->ipc_namespace_path);
2,430✔
2372
        if (r < 0)
2,430✔
2373
                return r;
2374

2375
        FOREACH_ARRAY(mount, c->mount_images, c->n_mount_images) {
2,430✔
2376
                _cleanup_free_ char *s = NULL, *source_escaped = NULL, *dest_escaped = NULL;
×
2377

2378
                source_escaped = shell_escape(mount->source, WHITESPACE);
×
2379
                if (!source_escaped)
×
2380
                        return log_oom_debug();
×
2381

2382
                dest_escaped = shell_escape(mount->destination, WHITESPACE);
×
2383
                if (!dest_escaped)
×
2384
                        return log_oom_debug();
×
2385

2386
                s = strjoin(mount->ignore_enoent ? "-" : "",
×
2387
                            source_escaped,
2388
                            " ",
2389
                            dest_escaped);
2390
                if (!s)
×
2391
                        return log_oom_debug();
×
2392

2393
                LIST_FOREACH(mount_options, o, mount->mount_options) {
×
2394
                        _cleanup_free_ char *escaped = NULL;
×
2395

2396
                        if (isempty(o->options))
×
2397
                                continue;
×
2398

2399
                        escaped = shell_escape(o->options, ":");
×
2400
                        if (!escaped)
×
2401
                                return log_oom_debug();
×
2402

2403
                        if (!strextend(&s,
×
2404
                                       " ",
2405
                                       partition_designator_to_string(o->partition_designator),
2406
                                       ":",
2407
                                       escaped))
2408
                                return log_oom_debug();
×
2409
                }
2410

2411
                r = serialize_item(f, "exec-context-mount-image", s);
×
2412
                if (r < 0)
×
2413
                        return r;
2414
        }
2415

2416
        FOREACH_ARRAY(mount, c->extension_images, c->n_extension_images) {
2,435✔
2417
                _cleanup_free_ char *s = NULL, *source_escaped = NULL;
5✔
2418

2419
                source_escaped = shell_escape(mount->source, ":" WHITESPACE);
5✔
2420
                if (!source_escaped)
5✔
2421
                        return log_oom_debug();
×
2422

2423
                s = strjoin(mount->ignore_enoent ? "-" : "",
10✔
2424
                            source_escaped);
2425
                if (!s)
5✔
2426
                        return log_oom_debug();
×
2427

2428
                LIST_FOREACH(mount_options, o, mount->mount_options) {
5✔
2429
                        _cleanup_free_ char *escaped = NULL;
×
2430

2431
                        if (isempty(o->options))
×
2432
                                continue;
×
2433

2434
                        escaped = shell_escape(o->options, ":");
×
2435
                        if (!escaped)
×
2436
                                return log_oom_debug();
×
2437

2438
                        if (!strextend(&s,
×
2439
                                       " ",
2440
                                       partition_designator_to_string(o->partition_designator),
2441
                                       ":",
2442
                                       escaped))
2443
                                return log_oom_debug();
×
2444
                }
2445

2446
                r = serialize_item(f, "exec-context-extension-image", s);
5✔
2447
                if (r < 0)
5✔
2448
                        return r;
2449
        }
2450

2451
        r = serialize_strv(f, "exec-context-extension-directories", c->extension_directories);
2,430✔
2452
        if (r < 0)
2,430✔
2453
                return r;
2454

2455
        ExecSetCredential *sc;
2,430✔
2456
        HASHMAP_FOREACH(sc, c->set_credentials) {
2,436✔
2457
                _cleanup_free_ char *data = NULL;
6✔
2458

2459
                if (base64mem(sc->data, sc->size, &data) < 0)
6✔
2460
                        return log_oom_debug();
×
2461

2462
                r = serialize_item_format(f, "exec-context-set-credentials", "%s %s %s", sc->id, data, yes_no(sc->encrypted));
12✔
2463
                if (r < 0)
6✔
2464
                        return r;
2465
        }
2466

2467
        ExecLoadCredential *lc;
2,430✔
2468
        HASHMAP_FOREACH(lc, c->load_credentials) {
2,441✔
2469
                r = serialize_item_format(f, "exec-context-load-credentials", "%s %s %s", lc->id, lc->path, yes_no(lc->encrypted));
21✔
2470
                if (r < 0)
11✔
2471
                        return r;
×
2472
        }
2473

2474
        ExecImportCredential *ic;
2,430✔
2475
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
3,378✔
2476
                r = serialize_item_format(f, "exec-context-import-credentials", "%s%s%s",
1,846✔
2477
                                          ic->glob,
2478
                                          ic->rename ? " " : "",
2479
                                          strempty(ic->rename));
948✔
2480
                if (r < 0)
948✔
2481
                        return r;
×
2482
        }
2483

2484
        r = serialize_image_policy(f, "exec-context-root-image-policy", c->root_image_policy);
2,430✔
2485
        if (r < 0)
2,430✔
2486
                return r;
2487

2488
        r = serialize_image_policy(f, "exec-context-mount-image-policy", c->mount_image_policy);
2,430✔
2489
        if (r < 0)
2,430✔
2490
                return r;
2491

2492
        r = serialize_image_policy(f, "exec-context-extension-image-policy", c->extension_image_policy);
2,430✔
2493
        if (r < 0)
2,430✔
2494
                return r;
2495

2496
        fputc('\n', f); /* End marker */
2,430✔
2497

2498
        return 0;
2499
}
2500

2501
static int exec_context_deserialize(ExecContext *c, FILE *f) {
10,033✔
2502
        int r;
10,033✔
2503

2504
        assert(f);
10,033✔
2505

2506
        if (!c)
10,033✔
2507
                return 0;
2508

2509
        for (;;) {
959,455✔
2510
                _cleanup_free_ char *l = NULL;
949,422✔
2511
                const char *val;
959,455✔
2512

2513
                r = deserialize_read_line(f, &l);
959,455✔
2514
                if (r < 0)
959,455✔
2515
                        return r;
2516
                if (r == 0) /* eof or end marker */
959,455✔
2517
                        break;
2518

2519
                if ((val = startswith(l, "exec-context-environment="))) {
949,422✔
2520
                        r = deserialize_strv(val, &c->environment);
3,496✔
2521
                        if (r < 0)
3,496✔
2522
                                return r;
2523
                } else if ((val = startswith(l, "exec-context-environment-files="))) {
945,926✔
2524
                        r = deserialize_strv(val, &c->environment_files);
344✔
2525
                        if (r < 0)
344✔
2526
                                return r;
2527
                } else if ((val = startswith(l, "exec-context-pass-environment="))) {
945,582✔
2528
                        r = deserialize_strv(val, &c->pass_environment);
316✔
2529
                        if (r < 0)
316✔
2530
                                return r;
2531
                } else if ((val = startswith(l, "exec-context-unset-environment="))) {
945,266✔
2532
                        r = deserialize_strv(val, &c->unset_environment);
975✔
2533
                        if (r < 0)
975✔
2534
                                return r;
2535
                } else if ((val = startswith(l, "exec-context-working-directory="))) {
944,291✔
2536
                        ssize_t k;
765✔
2537
                        char *p;
765✔
2538

2539
                        k = cunescape(val, 0, &p);
765✔
2540
                        if (k < 0)
765✔
2541
                                return k;
×
2542
                        free_and_replace(c->working_directory, p);
765✔
2543
                } else if ((val = startswith(l, "exec-context-root-directory="))) {
943,526✔
2544
                        ssize_t k;
7✔
2545
                        char *p;
7✔
2546

2547
                        k = cunescape(val, 0, &p);
7✔
2548
                        if (k < 0)
7✔
2549
                                return k;
×
2550
                        free_and_replace(c->root_directory, p);
7✔
2551
                } else if ((val = startswith(l, "exec-context-root-image="))) {
943,519✔
2552
                        ssize_t k;
9✔
2553
                        char *p;
9✔
2554

2555
                        k = cunescape(val, 0, &p);
9✔
2556
                        if (k < 0)
9✔
2557
                                return k;
×
2558
                        free_and_replace(c->root_image, p);
9✔
2559
                } else if ((val = startswith(l, "exec-context-root-image-options="))) {
943,510✔
2560
                        for (;;) {
×
2561
                                _cleanup_free_ char *word = NULL, *mount_options = NULL, *partition = NULL;
×
2562
                                PartitionDesignator partition_designator;
×
2563
                                MountOptions *o = NULL;
×
2564
                                const char *p;
×
2565

2566
                                r = extract_first_word(&val, &word, NULL, 0);
×
2567
                                if (r < 0)
×
2568
                                        return r;
2569
                                if (r == 0)
×
2570
                                        break;
2571

2572
                                p = word;
×
2573
                                r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options);
×
2574
                                if (r < 0)
×
2575
                                        return r;
2576
                                if (r == 0)
×
2577
                                        continue;
×
2578

2579
                                partition_designator = partition_designator_from_string(partition);
×
2580
                                if (partition_designator < 0)
×
2581
                                        return -EINVAL;
2582

2583
                                o = new(MountOptions, 1);
×
2584
                                if (!o)
×
2585
                                        return log_oom_debug();
×
2586
                                *o = (MountOptions) {
×
2587
                                        .partition_designator = partition_designator,
2588
                                        .options = TAKE_PTR(mount_options),
×
2589
                                };
2590
                                LIST_APPEND(mount_options, c->root_image_options, o);
×
2591
                        }
2592
                } else if ((val = startswith(l, "exec-context-root-verity="))) {
943,510✔
2593
                        r = free_and_strdup(&c->root_verity, val);
×
2594
                        if (r < 0)
×
2595
                                return r;
2596
                } else if ((val = startswith(l, "exec-context-root-hash-path="))) {
943,510✔
2597
                        r = free_and_strdup(&c->root_hash_path, val);
×
2598
                        if (r < 0)
×
2599
                                return r;
2600
                } else if ((val = startswith(l, "exec-context-root-hash-sig-path="))) {
943,510✔
2601
                        r = free_and_strdup(&c->root_hash_sig_path, val);
×
2602
                        if (r < 0)
×
2603
                                return r;
2604
                } else if ((val = startswith(l, "exec-context-root-hash="))) {
943,510✔
2605
                        iovec_done(&c->root_hash);
4✔
2606
                        r = unhexmem(val, &c->root_hash.iov_base, &c->root_hash.iov_len);
4✔
2607
                        if (r < 0)
4✔
2608
                                return r;
2609
                } else if ((val = startswith(l, "exec-context-root-hash-sig="))) {
943,506✔
2610
                        iovec_done(&c->root_hash_sig);
×
2611
                        r = unbase64mem(val, &c->root_hash_sig.iov_base, &c->root_hash_sig.iov_len);
×
2612
                        if (r < 0)
×
2613
                                return r;
2614
                } else if ((val = startswith(l, "exec-context-root-ephemeral="))) {
943,506✔
2615
                        r = parse_boolean(val);
×
2616
                        if (r < 0)
×
2617
                                return r;
2618
                        c->root_ephemeral = r;
×
2619
                } else if ((val = startswith(l, "exec-context-umask="))) {
943,506✔
2620
                        r = parse_mode(val, &c->umask);
10,033✔
2621
                        if (r < 0)
10,033✔
2622
                                return r;
2623
                } else if ((val = startswith(l, "exec-context-private-non-blocking="))) {
933,473✔
2624
                        r = parse_boolean(val);
×
2625
                        if (r < 0)
×
2626
                                return r;
2627
                        c->non_blocking = r;
×
2628
                } else if ((val = startswith(l, "exec-context-private-mounts="))) {
933,473✔
2629
                        r = safe_atoi(val, &c->private_mounts);
139✔
2630
                        if (r < 0)
139✔
2631
                                return r;
2632
                } else if ((val = startswith(l, "exec-context-mount-api-vfs="))) {
933,334✔
2633
                        r = safe_atoi(val, &c->mount_apivfs);
29✔
2634
                        if (r < 0)
29✔
2635
                                return r;
2636
                } else if ((val = startswith(l, "exec-context-bind-log-sockets="))) {
933,305✔
2637
                        r = safe_atoi(val, &c->bind_log_sockets);
2✔
2638
                        if (r < 0)
2✔
2639
                                return r;
2640
                } else if ((val = startswith(l, "exec-context-memory-ksm="))) {
933,303✔
2641
                        r = safe_atoi(val, &c->memory_ksm);
×
2642
                        if (r < 0)
×
2643
                                return r;
2644
                } else if ((val = startswith(l, "exec-context-private-tmp="))) {
933,303✔
2645
                        c->private_tmp = private_tmp_from_string(val);
10,033✔
2646
                        if (c->private_tmp < 0)
10,033✔
2647
                                return c->private_tmp;
2648
                } else if ((val = startswith(l, "exec-context-private-var-tmp="))) {
923,270✔
2649
                        c->private_var_tmp = private_tmp_from_string(val);
10,033✔
2650
                        if (c->private_var_tmp < 0)
10,033✔
2651
                                return c->private_var_tmp;
2652
                } else if ((val = startswith(l, "exec-context-private-devices="))) {
913,237✔
2653
                        r = parse_boolean(val);
493✔
2654
                        if (r < 0)
493✔
2655
                                return r;
2656
                        c->private_devices = r;
493✔
2657
                } else if ((val = startswith(l, "exec-context-protect-kernel-tunables="))) {
912,744✔
2658
                        r = parse_boolean(val);
311✔
2659
                        if (r < 0)
311✔
2660
                                return r;
2661
                        c->protect_kernel_tunables = r;
311✔
2662
                } else if ((val = startswith(l, "exec-context-protect-kernel-modules="))) {
912,433✔
2663
                        r = parse_boolean(val);
1,105✔
2664
                        if (r < 0)
1,105✔
2665
                                return r;
2666
                        c->protect_kernel_modules = r;
1,105✔
2667
                } else if ((val = startswith(l, "exec-context-protect-kernel-logs="))) {
911,328✔
2668
                        r = parse_boolean(val);
1,105✔
2669
                        if (r < 0)
1,105✔
2670
                                return r;
2671
                        c->protect_kernel_logs = r;
1,105✔
2672
                } else if ((val = startswith(l, "exec-context-protect-clock="))) {
910,223✔
2673
                        r = parse_boolean(val);
899✔
2674
                        if (r < 0)
899✔
2675
                                return r;
2676
                        c->protect_clock = r;
899✔
2677
                } else if ((val = startswith(l, "exec-context-protect-control-groups="))) {
909,324✔
2678
                        r = protect_control_groups_from_string(val);
10,033✔
2679
                        if (r < 0)
10,033✔
2680
                                return r;
2681
                        c->protect_control_groups = r;
10,033✔
2682
                } else if ((val = startswith(l, "exec-context-private-network="))) {
899,291✔
2683
                        r = parse_boolean(val);
70✔
2684
                        if (r < 0)
70✔
2685
                                return r;
2686
                        c->private_network = r;
70✔
2687
                } else if ((val = startswith(l, "exec-context-private-users="))) {
899,221✔
2688
                        c->private_users = private_users_from_string(val);
10,033✔
2689
                        if (c->private_users < 0)
10,033✔
2690
                                return -EINVAL;
2691
                } else if ((val = startswith(l, "exec-context-private-ipc="))) {
889,188✔
2692
                        r = parse_boolean(val);
6✔
2693
                        if (r < 0)
6✔
2694
                                return r;
2695
                        c->private_ipc = r;
6✔
2696
                } else if ((val = startswith(l, "exec-context-private-pids="))) {
889,182✔
2697
                        c->private_pids = private_pids_from_string(val);
10,033✔
2698
                        if (c->private_pids < 0)
10,033✔
2699
                                return -EINVAL;
2700
                } else if ((val = startswith(l, "exec-context-remove-ipc="))) {
879,149✔
2701
                        r = parse_boolean(val);
55✔
2702
                        if (r < 0)
55✔
2703
                                return r;
2704
                        c->remove_ipc = r;
55✔
2705
                } else if ((val = startswith(l, "exec-context-protect-home="))) {
879,094✔
2706
                        c->protect_home = protect_home_from_string(val);
10,033✔
2707
                        if (c->protect_home < 0)
10,033✔
2708
                                return -EINVAL;
2709
                } else if ((val = startswith(l, "exec-context-protect-system="))) {
869,061✔
2710
                        c->protect_system = protect_system_from_string(val);
10,033✔
2711
                        if (c->protect_system < 0)
10,033✔
2712
                                return -EINVAL;
2713
                } else if ((val = startswith(l, "exec-context-same-pgrp="))) {
859,028✔
2714
                        r = parse_boolean(val);
836✔
2715
                        if (r < 0)
836✔
2716
                                return r;
2717
                        c->same_pgrp = r;
836✔
2718
                } else if ((val = startswith(l, "exec-context-non-blocking="))) {
858,192✔
2719
                        r = parse_boolean(val);
×
2720
                        if (r < 0)
×
2721
                                return r;
2722
                        c->non_blocking = r;
×
2723
                } else if ((val = startswith(l, "exec-context-ignore-sigpipe="))) {
858,192✔
2724
                        r = parse_boolean(val);
10,033✔
2725
                        if (r < 0)
10,033✔
2726
                                return r;
2727
                        c->ignore_sigpipe = r;
10,033✔
2728
                } else if ((val = startswith(l, "exec-context-memory-deny-write-execute="))) {
848,159✔
2729
                        r = parse_boolean(val);
1,467✔
2730
                        if (r < 0)
1,467✔
2731
                                return r;
2732
                        c->memory_deny_write_execute = r;
1,467✔
2733
                } else if ((val = startswith(l, "exec-context-restrict-realtime="))) {
846,692✔
2734
                        r = parse_boolean(val);
1,469✔
2735
                        if (r < 0)
1,469✔
2736
                                return r;
2737
                        c->restrict_realtime = r;
1,469✔
2738
                } else if ((val = startswith(l, "exec-context-restrict-suid-sgid="))) {
845,223✔
2739
                        r = parse_boolean(val);
1,371✔
2740
                        if (r < 0)
1,371✔
2741
                                return r;
2742
                        c->restrict_suid_sgid = r;
1,371✔
2743
                } else if ((val = startswith(l, "exec-context-keyring-mode="))) {
843,852✔
2744
                        c->keyring_mode = exec_keyring_mode_from_string(val);
10,033✔
2745
                        if (c->keyring_mode < 0)
10,033✔
2746
                                return -EINVAL;
2747
                } else if ((val = startswith(l, "exec-context-protect-hostname="))) {
833,819✔
2748
                        c->protect_hostname = protect_hostname_from_string(val);
10,033✔
2749
                        if (c->protect_hostname < 0)
10,033✔
2750
                                return -EINVAL;
2751
                } else if ((val = startswith(l, "exec-context-private-hostname="))) {
823,786✔
2752
                        r = free_and_strdup(&c->private_hostname, val);
5✔
2753
                        if (r < 0)
5✔
2754
                                return r;
2755
                } else if ((val = startswith(l, "exec-context-protect-proc="))) {
823,781✔
2756
                        c->protect_proc = protect_proc_from_string(val);
10,033✔
2757
                        if (c->protect_proc < 0)
10,033✔
2758
                                return -EINVAL;
2759
                } else if ((val = startswith(l, "exec-context-proc-subset="))) {
813,748✔
2760
                        c->proc_subset = proc_subset_from_string(val);
10,033✔
2761
                        if (c->proc_subset < 0)
10,033✔
2762
                                return -EINVAL;
2763
                } else if ((val = startswith(l, "exec-context-private-bpf="))) {
803,715✔
2764
                        c->private_bpf = private_bpf_from_string(val);
10,033✔
2765
                        if (c->private_bpf < 0)
10,033✔
2766
                                return -EINVAL;
2767
                } else if ((val = startswith(l, "exec-context-bpf-delegate-commands="))) {
793,682✔
2768
                        r = safe_atoux64(val, &c->bpf_delegate_commands);
2✔
2769
                        if (r < 0)
2✔
2770
                                return r;
2771
                } else if ((val = startswith(l, "exec-context-bpf-delegate-maps="))) {
793,680✔
2772
                        r = safe_atoux64(val, &c->bpf_delegate_maps);
1✔
2773
                        if (r < 0)
1✔
2774
                                return r;
2775
                } else if ((val = startswith(l, "exec-context-bpf-delegate-programs="))) {
793,679✔
2776
                        r = safe_atoux64(val, &c->bpf_delegate_programs);
1✔
2777
                        if (r < 0)
1✔
2778
                                return r;
2779
                } else if ((val = startswith(l, "exec-context-bpf-delegate-attachments="))) {
793,678✔
2780
                        r = safe_atoux64(val, &c->bpf_delegate_attachments);
1✔
2781
                        if (r < 0)
1✔
2782
                                return r;
2783
                } else if ((val = startswith(l, "exec-context-runtime-directory-preserve-mode="))) {
793,677✔
2784
                        c->runtime_directory_preserve_mode = exec_preserve_mode_from_string(val);
10,033✔
2785
                        if (c->runtime_directory_preserve_mode < 0)
10,033✔
2786
                                return -EINVAL;
2787
                } else if ((val = startswith(l, "exec-context-directories-"))) {
783,644✔
2788
                        _cleanup_free_ char *type = NULL, *mode = NULL;
×
2789
                        ExecDirectoryType dt;
50,165✔
2790

2791
                        r = extract_many_words(&val, "= ", 0, &type, &mode);
50,165✔
2792
                        if (r < 0)
50,165✔
2793
                                return r;
2794
                        if (r == 0 || !mode)
50,165✔
2795
                                return -EINVAL;
2796

2797
                        dt = exec_directory_type_from_string(type);
50,165✔
2798
                        if (dt < 0)
50,165✔
2799
                                return dt;
2800

2801
                        r = parse_mode(mode, &c->directories[dt].mode);
50,165✔
2802
                        if (r < 0)
50,165✔
2803
                                return r;
2804

2805
                        for (;;) {
53,116✔
2806
                                _cleanup_free_ char *tuple = NULL, *path = NULL, *only_create = NULL, *read_only = NULL;
53,009✔
2807
                                ExecDirectoryFlags exec_directory_flags = 0;
53,116✔
2808
                                const char *p;
53,116✔
2809

2810
                                /* Use EXTRACT_UNESCAPE_RELAX here, as we unescape the colons in subsequent calls */
2811
                                r = extract_first_word(&val, &tuple, WHITESPACE, EXTRACT_UNESCAPE_SEPARATORS|EXTRACT_UNESCAPE_RELAX);
53,116✔
2812
                                if (r < 0)
53,116✔
2813
                                        return r;
2814
                                if (r == 0)
53,116✔
2815
                                        break;
2816

2817
                                p = tuple;
2,951✔
2818
                                r = extract_many_words(&p, ":", EXTRACT_UNESCAPE_SEPARATORS, &path, &only_create, &read_only);
2,951✔
2819
                                if (r < 0)
2,951✔
2820
                                        return r;
2821
                                if (r < 2)
2,951✔
2822
                                        continue;
×
2823

2824
                                r = parse_boolean(only_create);
2,951✔
2825
                                if (r < 0)
2,951✔
2826
                                        return r;
2827
                                if (r > 0)
2,951✔
2828
                                        exec_directory_flags |= EXEC_DIRECTORY_ONLY_CREATE;
5✔
2829

2830
                                r = parse_boolean(read_only);
2,951✔
2831
                                if (r < 0)
2,951✔
2832
                                        return r;
2833
                                if (r > 0)
2,951✔
2834
                                        exec_directory_flags |= EXEC_DIRECTORY_READ_ONLY;
50✔
2835

2836
                                r = exec_directory_add(&c->directories[dt], path, /* symlink= */ NULL, exec_directory_flags);
2,951✔
2837
                                if (r < 0)
2,951✔
2838
                                        return r;
2839

2840
                                if (isempty(p))
2,951✔
2841
                                        continue;
2,844✔
2842

2843
                                for (;;) {
385✔
2844
                                        _cleanup_free_ char *link = NULL;
246✔
2845

2846
                                        r = extract_first_word(&p, &link, ":", EXTRACT_UNESCAPE_SEPARATORS);
246✔
2847
                                        if (r < 0)
246✔
2848
                                                return r;
2849
                                        if (r == 0)
246✔
2850
                                                break;
2851

2852
                                        r = strv_consume(&c->directories[dt].items[c->directories[dt].n_items - 1].symlinks, TAKE_PTR(link));
139✔
2853
                                        if (r < 0)
139✔
2854
                                                return r;
2855
                                }
2856
                        }
2857
                } else if ((val = startswith(l, "exec-context-quota-accounting-directories-"))) {
733,479✔
2858
                        _cleanup_free_ char *type = NULL, *quota_accounting = NULL;
×
2859
                        ExecDirectoryType dt;
×
2860

2861
                        r = split_pair(val, "=", &type, &quota_accounting);
×
2862
                        if (r < 0)
×
2863
                                return r;
2864

2865
                        dt = exec_directory_type_from_string(type);
×
2866
                        if (dt < 0)
×
2867
                                return dt;
2868

2869
                        r = parse_boolean(quota_accounting);
×
2870
                        if (r < 0)
×
2871
                                return r;
2872

2873
                        c->directories[dt].exec_quota.quota_accounting = r;
×
2874
                } else if ((val = startswith(l, "exec-context-quota-directories-"))) {
733,479✔
2875
                        _cleanup_free_ char *type = NULL, *quota_info = NULL, *quota_absolute = NULL, *quota_scale = NULL;
×
2876
                        ExecDirectoryType dt;
×
2877

2878
                        r = split_pair(val, "=", &type, &quota_info);
×
2879
                        if (r < 0)
×
2880
                                return r;
2881

2882
                        r = split_pair(quota_info, " ", &quota_absolute, &quota_scale);
×
2883
                        if (r < 0)
×
2884
                                return r;
2885

2886
                        dt = exec_directory_type_from_string(type);
×
2887
                        if (dt < 0)
×
2888
                                return dt;
2889

2890
                        r = safe_atou64(quota_absolute, &c->directories[dt].exec_quota.quota_absolute);
×
2891
                        if (r < 0)
×
2892
                               return r;
2893

2894
                        r = safe_atou32(quota_scale, &c->directories[dt].exec_quota.quota_scale);
×
2895
                        if (r < 0)
×
2896
                               return r;
2897

2898
                        c->directories[dt].exec_quota.quota_enforce = true;
×
2899
                } else if ((val = startswith(l, "exec-context-timeout-clean-usec="))) {
733,479✔
2900
                        r = deserialize_usec(val, &c->timeout_clean_usec);
×
2901
                        if (r < 0)
×
2902
                                return r;
2903
                } else if ((val = startswith(l, "exec-context-nice="))) {
733,479✔
2904
                        r = safe_atoi(val, &c->nice);
19✔
2905
                        if (r < 0)
19✔
2906
                                return r;
2907
                        c->nice_set = true;
19✔
2908
                } else if ((val = startswith(l, "exec-context-working-directory-missing-ok="))) {
733,460✔
2909
                        r = parse_boolean(val);
704✔
2910
                        if (r < 0)
704✔
2911
                                return r;
2912
                        c->working_directory_missing_ok = r;
704✔
2913
                } else if ((val = startswith(l, "exec-context-working-directory-home="))) {
732,756✔
2914
                        r = parse_boolean(val);
179✔
2915
                        if (r < 0)
179✔
2916
                                return r;
2917
                        c->working_directory_home = r;
179✔
2918
                } else if ((val = startswith(l, "exec-context-oom-score-adjust="))) {
732,577✔
2919
                        r = safe_atoi(val, &c->oom_score_adjust);
1,085✔
2920
                        if (r < 0)
1,085✔
2921
                                return r;
2922
                        c->oom_score_adjust_set = true;
1,085✔
2923
                } else if ((val = startswith(l, "exec-context-coredump-filter="))) {
731,492✔
2924
                        r = safe_atoux64(val, &c->coredump_filter);
2✔
2925
                        if (r < 0)
2✔
2926
                                return r;
2927
                        c->coredump_filter_set = true;
2✔
2928
                } else if ((val = startswith(l, "exec-context-limit-"))) {
731,490✔
2929
                        _cleanup_free_ struct rlimit *rlimit = NULL;
×
2930
                        _cleanup_free_ char *limit = NULL;
20,061✔
2931
                        int type;
20,061✔
2932

2933
                        r = extract_first_word(&val, &limit, "=", 0);
20,061✔
2934
                        if (r < 0)
20,061✔
2935
                                return r;
2936
                        if (r == 0 || !val)
20,061✔
2937
                                return -EINVAL;
2938

2939
                        type = rlimit_from_string(limit);
20,061✔
2940
                        if (type < 0)
20,061✔
2941
                                return -EINVAL;
2942

2943
                        if (!c->rlimit[type]) {
20,061✔
2944
                                rlimit = new0(struct rlimit, 1);
20,061✔
2945
                                if (!rlimit)
20,061✔
2946
                                        return log_oom_debug();
×
2947

2948
                                r = rlimit_parse(type, val, rlimit);
20,061✔
2949
                                if (r < 0)
20,061✔
2950
                                        return r;
2951

2952
                                c->rlimit[type] = TAKE_PTR(rlimit);
20,061✔
2953
                        } else {
2954
                                r = rlimit_parse(type, val, c->rlimit[type]);
×
2955
                                if (r < 0)
×
2956
                                        return r;
2957
                        }
2958
                } else if ((val = startswith(l, "exec-context-ioprio="))) {
711,429✔
2959
                        r = safe_atoi(val, &c->ioprio);
15✔
2960
                        if (r < 0)
15✔
2961
                                return r;
2962
                        c->ioprio_is_set = true;
15✔
2963
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-policy="))) {
711,414✔
2964
                        c->cpu_sched_policy = sched_policy_from_string(val);
×
2965
                        if (c->cpu_sched_policy < 0)
×
2966
                                return -EINVAL;
2967
                        c->cpu_sched_set = true;
×
2968
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-priority="))) {
711,414✔
2969
                        r = safe_atoi(val, &c->cpu_sched_priority);
×
2970
                        if (r < 0)
×
2971
                                return r;
2972
                        c->cpu_sched_set = true;
×
2973
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-reset-on-fork="))) {
711,414✔
2974
                        r = parse_boolean(val);
×
2975
                        if (r < 0)
×
2976
                                return r;
2977
                        c->cpu_sched_reset_on_fork = r;
×
2978
                        c->cpu_sched_set = true;
×
2979
                } else if ((val = startswith(l, "exec-context-cpu-affinity="))) {
711,414✔
2980
                        if (c->cpu_set.set)
×
2981
                                return -EINVAL; /* duplicated */
2982

2983
                        r = parse_cpu_set(val, &c->cpu_set);
×
2984
                        if (r < 0)
×
2985
                                return r;
2986
                } else if ((val = startswith(l, "exec-context-numa-mask="))) {
711,414✔
2987
                        if (c->numa_policy.nodes.set)
19✔
2988
                                return -EINVAL; /* duplicated */
2989

2990
                        r = parse_cpu_set(val, &c->numa_policy.nodes);
19✔
2991
                        if (r < 0)
19✔
2992
                                return r;
2993
                } else if ((val = startswith(l, "exec-context-numa-policy="))) {
711,395✔
2994
                        r = safe_atoi(val, &c->numa_policy.type);
19✔
2995
                        if (r < 0)
19✔
2996
                                return r;
2997
                } else if ((val = startswith(l, "exec-context-cpu-affinity-from-numa="))) {
711,376✔
2998
                        r = parse_boolean(val);
2✔
2999
                        if (r < 0)
2✔
3000
                                return r;
3001
                        c->cpu_affinity_from_numa = r;
2✔
3002
                } else if ((val = startswith(l, "exec-context-timer-slack-nsec="))) {
711,374✔
3003
                        r = deserialize_usec(val, (usec_t *)&c->timer_slack_nsec);
×
3004
                        if (r < 0)
×
3005
                                return r;
3006
                } else if ((val = startswith(l, "exec-context-root-directory-as-fd="))) {
711,374✔
3007
                        r = parse_boolean(val);
2✔
3008
                        if (r < 0)
2✔
3009
                                return r;
3010
                        c->root_directory_as_fd = r;
2✔
3011
                } else if ((val = startswith(l, "exec-context-std-input="))) {
711,372✔
3012
                        c->std_input = exec_input_from_string(val);
10,033✔
3013
                        if (c->std_input < 0)
10,033✔
3014
                                return c->std_input;
3015
                } else if ((val = startswith(l, "exec-context-std-output="))) {
701,339✔
3016
                        c->std_output = exec_output_from_string(val);
10,033✔
3017
                        if (c->std_output < 0)
10,033✔
3018
                                return c->std_output;
3019
                } else if ((val = startswith(l, "exec-context-std-error="))) {
691,306✔
3020
                        c->std_error = exec_output_from_string(val);
10,033✔
3021
                        if (c->std_error < 0)
10,033✔
3022
                                return c->std_error;
3023
                } else if ((val = startswith(l, "exec-context-stdio-as-fds="))) {
681,273✔
3024
                        r = parse_boolean(val);
543✔
3025
                        if (r < 0)
543✔
3026
                                return r;
3027
                        c->stdio_as_fds = r;
543✔
3028
                } else if ((val = startswith(l, "exec-context-std-input-data="))) {
680,730✔
3029
                        if (c->stdin_data)
1✔
3030
                                return -EINVAL; /* duplicated */
3031

3032
                        r = unbase64mem(val, &c->stdin_data, &c->stdin_data_size);
1✔
3033
                        if (r < 0)
1✔
3034
                                return r;
3035
                } else if ((val = startswith(l, "exec-context-std-input-fd-name="))) {
680,729✔
3036
                        r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], val);
×
3037
                        if (r < 0)
×
3038
                                return r;
3039
                } else if ((val = startswith(l, "exec-context-std-output-fd-name="))) {
680,729✔
3040
                        r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], val);
×
3041
                        if (r < 0)
×
3042
                                return r;
3043
                } else if ((val = startswith(l, "exec-context-std-error-fd-name="))) {
680,729✔
3044
                        r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], val);
×
3045
                        if (r < 0)
×
3046
                                return r;
3047
                } else if ((val = startswith(l, "exec-context-std-input-file="))) {
680,729✔
3048
                        ssize_t k;
×
3049
                        char *p;
×
3050

3051
                        k = cunescape(val, 0, &p);
×
3052
                        if (k < 0)
×
3053
                                return k;
×
3054

3055
                        free_and_replace(c->stdio_file[STDIN_FILENO], p);
×
3056

3057
                } else if ((val = startswith(l, "exec-context-std-output-file="))) {
680,729✔
3058
                        ssize_t k;
53✔
3059
                        char *p;
53✔
3060

3061
                        k = cunescape(val, 0, &p);
53✔
3062
                        if (k < 0)
53✔
3063
                                return k;
×
3064

3065
                        free_and_replace(c->stdio_file[STDOUT_FILENO], p);
53✔
3066

3067
                } else if ((val = startswith(l, "exec-context-std-error-file="))) {
680,676✔
3068
                        ssize_t k;
49✔
3069
                        char *p;
49✔
3070

3071
                        k = cunescape(val, 0, &p);
49✔
3072
                        if (k < 0)
49✔
3073
                                return k;
×
3074

3075
                        free_and_replace(c->stdio_file[STDERR_FILENO], p);
49✔
3076

3077
                } else if ((val = startswith(l, "exec-context-tty-path="))) {
680,627✔
3078
                        r = free_and_strdup(&c->tty_path, val);
104✔
3079
                        if (r < 0)
104✔
3080
                                return r;
3081
                } else if ((val = startswith(l, "exec-context-tty-reset="))) {
680,523✔
3082
                        r = parse_boolean(val);
192✔
3083
                        if (r < 0)
192✔
3084
                                return r;
3085
                        c->tty_reset = r;
192✔
3086
                } else if ((val = startswith(l, "exec-context-tty-vhangup="))) {
680,331✔
3087
                        r = parse_boolean(val);
83✔
3088
                        if (r < 0)
83✔
3089
                                return r;
3090
                        c->tty_vhangup = r;
83✔
3091
                } else if ((val = startswith(l, "exec-context-tty-vt-disallocate="))) {
680,248✔
3092
                        r = parse_boolean(val);
46✔
3093
                        if (r < 0)
46✔
3094
                                return r;
3095
                        c->tty_vt_disallocate = r;
46✔
3096
                } else if ((val = startswith(l, "exec-context-tty-rows="))) {
680,202✔
3097
                        r = safe_atou(val, &c->tty_rows);
10,033✔
3098
                        if (r < 0)
10,033✔
3099
                                return r;
3100
                } else if ((val = startswith(l, "exec-context-tty-columns="))) {
670,169✔
3101
                        r = safe_atou(val, &c->tty_cols);
10,033✔
3102
                        if (r < 0)
10,033✔
3103
                                return r;
3104
                } else if ((val = startswith(l, "exec-context-syslog-priority="))) {
660,136✔
3105
                        r = safe_atoi(val, &c->syslog_priority);
10,033✔
3106
                        if (r < 0)
10,033✔
3107
                                return r;
3108
                } else if ((val = startswith(l, "exec-context-syslog-level-prefix="))) {
650,103✔
3109
                        r = parse_boolean(val);
10,033✔
3110
                        if (r < 0)
10,033✔
3111
                                return r;
3112
                        c->syslog_level_prefix = r;
10,033✔
3113
                } else if ((val = startswith(l, "exec-context-syslog-identifier="))) {
640,070✔
3114
                        r = free_and_strdup(&c->syslog_identifier, val);
×
3115
                        if (r < 0)
×
3116
                                return r;
3117
                } else if ((val = startswith(l, "exec-context-log-level-max="))) {
640,070✔
3118
                        /* See comment in serialization. */
3119
                        r = safe_atoi(val, &c->log_level_max);
10,033✔
3120
                        if (r < 0)
10,033✔
3121
                                return r;
3122
                } else if ((val = startswith(l, "exec-context-log-ratelimit-interval-usec="))) {
630,037✔
3123
                        r = deserialize_usec(val, &c->log_ratelimit.interval);
×
3124
                        if (r < 0)
×
3125
                                return r;
3126
                } else if ((val = startswith(l, "exec-context-log-ratelimit-burst="))) {
630,037✔
3127
                        r = safe_atou(val, &c->log_ratelimit.burst);
×
3128
                        if (r < 0)
×
3129
                                return r;
3130
                } else if ((val = startswith(l, "exec-context-log-filter-allowed-patterns="))) {
630,037✔
3131
                        r = set_put_strdup(&c->log_filter_allowed_patterns, val);
20✔
3132
                        if (r < 0)
20✔
3133
                                return r;
3134
                } else if ((val = startswith(l, "exec-context-log-filter-denied-patterns="))) {
630,017✔
3135
                        r = set_put_strdup(&c->log_filter_denied_patterns, val);
13✔
3136
                        if (r < 0)
13✔
3137
                                return r;
3138
                } else if ((val = startswith(l, "exec-context-log-extra-fields="))) {
630,004✔
3139
                        if (!GREEDY_REALLOC(c->log_extra_fields, c->n_log_extra_fields + 1))
706✔
3140
                                return log_oom_debug();
×
3141

3142
                        c->log_extra_fields[c->n_log_extra_fields++].iov_base = strdup(val);
706✔
3143
                        if (!c->log_extra_fields[c->n_log_extra_fields-1].iov_base)
706✔
3144
                                return log_oom_debug();
×
3145
                } else if ((val = startswith(l, "exec-context-log-namespace="))) {
629,298✔
3146
                        r = free_and_strdup(&c->log_namespace, val);
2✔
3147
                        if (r < 0)
2✔
3148
                                return r;
3149
                } else if ((val = startswith(l, "exec-context-secure-bits="))) {
629,296✔
3150
                        r = safe_atoi(val, &c->secure_bits);
×
3151
                        if (r < 0)
×
3152
                                return r;
3153
                } else if ((val = startswith(l, "exec-context-capability-bounding-set="))) {
629,296✔
3154
                        r = safe_atou64(val, &c->capability_bounding_set);
10,033✔
3155
                        if (r < 0)
10,033✔
3156
                                return r;
3157
                } else if ((val = startswith(l, "exec-context-capability-ambient-set="))) {
619,263✔
3158
                        r = safe_atou64(val, &c->capability_ambient_set);
654✔
3159
                        if (r < 0)
654✔
3160
                                return r;
3161
                } else if ((val = startswith(l, "exec-context-user="))) {
618,609✔
3162
                        r = free_and_strdup(&c->user, val);
2,076✔
3163
                        if (r < 0)
2,076✔
3164
                                return r;
3165
                } else if ((val = startswith(l, "exec-context-group="))) {
616,533✔
3166
                        r = free_and_strdup(&c->group, val);
60✔
3167
                        if (r < 0)
60✔
3168
                                return r;
3169
                } else if ((val = startswith(l, "exec-context-dynamic-user="))) {
616,473✔
3170
                        r = parse_boolean(val);
47✔
3171
                        if (r < 0)
47✔
3172
                                return r;
3173
                        c->dynamic_user = r;
47✔
3174
                } else if ((val = startswith(l, "exec-context-supplementary-groups="))) {
616,426✔
3175
                        r = deserialize_strv(val, &c->supplementary_groups);
12✔
3176
                        if (r < 0)
12✔
3177
                                return r;
3178
                } else if ((val = startswith(l, "exec-context-set-login-environment="))) {
616,414✔
3179
                        r = safe_atoi(val, &c->set_login_environment);
×
3180
                        if (r < 0)
×
3181
                                return r;
3182
                } else if ((val = startswith(l, "exec-context-pam-name="))) {
616,414✔
3183
                        r = free_and_strdup(&c->pam_name, val);
509✔
3184
                        if (r < 0)
509✔
3185
                                return r;
3186
                } else if ((val = startswith(l, "exec-context-read-write-paths="))) {
615,905✔
3187
                        r = deserialize_strv(val, &c->read_write_paths);
830✔
3188
                        if (r < 0)
830✔
3189
                                return r;
3190
                } else if ((val = startswith(l, "exec-context-read-only-paths="))) {
615,075✔
3191
                        r = deserialize_strv(val, &c->read_only_paths);
2✔
3192
                        if (r < 0)
2✔
3193
                                return r;
3194
                } else if ((val = startswith(l, "exec-context-inaccessible-paths="))) {
615,073✔
3195
                        r = deserialize_strv(val, &c->inaccessible_paths);
5✔
3196
                        if (r < 0)
5✔
3197
                                return r;
3198
                } else if ((val = startswith(l, "exec-context-exec-paths="))) {
615,068✔
3199
                        r = deserialize_strv(val, &c->exec_paths);
1✔
3200
                        if (r < 0)
1✔
3201
                                return r;
3202
                } else if ((val = startswith(l, "exec-context-no-exec-paths="))) {
615,067✔
3203
                        r = deserialize_strv(val, &c->no_exec_paths);
1✔
3204
                        if (r < 0)
1✔
3205
                                return r;
3206
                } else if ((val = startswith(l, "exec-context-exec-search-path="))) {
615,066✔
3207
                        r = deserialize_strv(val, &c->exec_search_path);
×
3208
                        if (r < 0)
×
3209
                                return r;
3210
                } else if ((val = startswith(l, "exec-context-mount-propagation-flag="))) {
615,066✔
3211
                        r = safe_atolu(val, &c->mount_propagation_flag);
10,033✔
3212
                        if (r < 0)
10,033✔
3213
                                return r;
3214
                } else if ((val = startswith(l, "exec-context-bind-read-only-path="))) {
605,033✔
3215
                        _cleanup_free_ char *source = NULL, *destination = NULL;
7✔
3216
                        bool rbind = true, ignore_enoent = false;
7✔
3217
                        char *s = NULL, *d = NULL;
7✔
3218

3219
                        r = extract_first_word(&val,
7✔
3220
                                               &source,
3221
                                               ":" WHITESPACE,
3222
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3223
                        if (r < 0)
7✔
3224
                                return r;
3225
                        if (r == 0)
7✔
3226
                                return -EINVAL;
3227

3228
                        s = source;
7✔
3229
                        if (s[0] == '-') {
7✔
3230
                                ignore_enoent = true;
1✔
3231
                                s++;
1✔
3232
                        }
3233

3234
                        if (val && val[-1] == ':') {
7✔
3235
                                r = extract_first_word(&val,
7✔
3236
                                                       &destination,
3237
                                                       ":" WHITESPACE,
3238
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3239
                                if (r < 0)
7✔
3240
                                        return r;
3241
                                if (r == 0)
7✔
3242
                                        continue;
×
3243

3244
                                d = destination;
7✔
3245

3246
                                if (val && val[-1] == ':') {
7✔
3247
                                        _cleanup_free_ char *options = NULL;
7✔
3248

3249
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
7✔
3250
                                        if (r < 0)
7✔
3251
                                                return -r;
×
3252

3253
                                        if (isempty(options) || streq(options, "rbind"))
15✔
3254
                                                rbind = true;
3255
                                        else if (streq(options, "norbind"))
1✔
3256
                                                rbind = false;
3257
                                        else
3258
                                                continue;
×
3259
                                }
3260
                        } else
3261
                                d = s;
3262

3263
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
14✔
3264
                                        &(BindMount) {
7✔
3265
                                                .source = s,
3266
                                                .destination = d,
3267
                                                .read_only = true,
3268
                                                .recursive = rbind,
3269
                                                .ignore_enoent = ignore_enoent,
3270
                                        });
3271
                        if (r < 0)
7✔
3272
                                return log_oom_debug();
×
3273
                } else if ((val = startswith(l, "exec-context-bind-path="))) {
605,026✔
3274
                        _cleanup_free_ char *source = NULL, *destination = NULL;
20✔
3275
                        bool rbind = true, ignore_enoent = false;
20✔
3276
                        char *s = NULL, *d = NULL;
20✔
3277

3278
                        r = extract_first_word(&val,
20✔
3279
                                               &source,
3280
                                               ":" WHITESPACE,
3281
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3282
                        if (r < 0)
20✔
3283
                                return r;
3284
                        if (r == 0)
20✔
3285
                                return -EINVAL;
3286

3287
                        s = source;
20✔
3288
                        if (s[0] == '-') {
20✔
3289
                                ignore_enoent = true;
1✔
3290
                                s++;
1✔
3291
                        }
3292

3293
                        if (val && val[-1] == ':') {
20✔
3294
                                r = extract_first_word(&val,
20✔
3295
                                                       &destination,
3296
                                                       ":" WHITESPACE,
3297
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3298
                                if (r < 0)
20✔
3299
                                        return r;
3300
                                if (r == 0)
20✔
3301
                                        continue;
×
3302

3303
                                d = destination;
20✔
3304

3305
                                if (val && val[-1] == ':') {
20✔
3306
                                        _cleanup_free_ char *options = NULL;
20✔
3307

3308
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
20✔
3309
                                        if (r < 0)
20✔
3310
                                                return -r;
×
3311

3312
                                        if (isempty(options) || streq(options, "rbind"))
43✔
3313
                                                rbind = true;
3314
                                        else if (streq(options, "norbind"))
3✔
3315
                                                rbind = false;
3316
                                        else
3317
                                                continue;
×
3318
                                }
3319
                        } else
3320
                                d = s;
3321

3322
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
40✔
3323
                                        &(BindMount) {
20✔
3324
                                                .source = s,
3325
                                                .destination = d,
3326
                                                .read_only = false,
3327
                                                .recursive = rbind,
3328
                                                .ignore_enoent = ignore_enoent,
3329
                                        });
3330
                        if (r < 0)
20✔
3331
                                return log_oom_debug();
×
3332
                } else if ((val = startswith(l, "exec-context-temporary-filesystems="))) {
605,006✔
3333
                        _cleanup_free_ char *path = NULL, *options = NULL;
61✔
3334

3335
                        r = extract_many_words(&val, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &path, &options);
61✔
3336
                        if (r < 0)
61✔
3337
                                return r;
3338
                        if (r < 1)
61✔
3339
                                continue;
×
3340

3341
                        r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
61✔
3342
                        if (r < 0)
61✔
3343
                                return log_oom_debug();
×
3344
                } else if ((val = startswith(l, "exec-context-utmp-id="))) {
604,945✔
3345
                        r = free_and_strdup(&c->utmp_id, val);
90✔
3346
                        if (r < 0)
90✔
3347
                                return r;
3348
                } else if ((val = startswith(l, "exec-context-utmp-mode="))) {
604,855✔
3349
                        c->utmp_mode = exec_utmp_mode_from_string(val);
10,033✔
3350
                        if (c->utmp_mode < 0)
10,033✔
3351
                                return c->utmp_mode;
3352
                } else if ((val = startswith(l, "exec-context-no-new-privileges="))) {
594,822✔
3353
                        r = parse_boolean(val);
1,398✔
3354
                        if (r < 0)
1,398✔
3355
                                return r;
3356
                        c->no_new_privileges = r;
1,398✔
3357
                } else if ((val = startswith(l, "exec-context-selinux-context="))) {
593,424✔
3358
                        if (val[0] == '-') {
×
3359
                                c->selinux_context_ignore = true;
×
3360
                                val++;
×
3361
                        } else
3362
                                c->selinux_context_ignore = false;
×
3363

3364
                        r = free_and_strdup(&c->selinux_context, val);
×
3365
                        if (r < 0)
×
3366
                                return r;
3367
                } else if ((val = startswith(l, "exec-context-apparmor-profile="))) {
593,424✔
3368
                        if (val[0] == '-') {
×
3369
                                c->apparmor_profile_ignore = true;
×
3370
                                val++;
×
3371
                        } else
3372
                                c->apparmor_profile_ignore = false;
×
3373

3374
                        r = free_and_strdup(&c->apparmor_profile, val);
×
3375
                        if (r < 0)
×
3376
                                return r;
3377
                } else if ((val = startswith(l, "exec-context-smack-process-label="))) {
593,424✔
3378
                        if (val[0] == '-') {
×
3379
                                c->smack_process_label_ignore = true;
×
3380
                                val++;
×
3381
                        } else
3382
                                c->smack_process_label_ignore = false;
×
3383

3384
                        r = free_and_strdup(&c->smack_process_label, val);
×
3385
                        if (r < 0)
×
3386
                                return r;
3387
                } else if ((val = startswith(l, "exec-context-personality="))) {
593,424✔
3388
                        c->personality = personality_from_string(val);
×
3389
                        if (c->personality == PERSONALITY_INVALID)
×
3390
                                return -EINVAL;
3391
                } else if ((val = startswith(l, "exec-context-lock-personality="))) {
593,424✔
3392
                        r = parse_boolean(val);
1,472✔
3393
                        if (r < 0)
1,472✔
3394
                                return r;
3395
                        c->lock_personality = r;
1,472✔
3396
#if HAVE_SECCOMP
3397
                } else if ((val = startswith(l, "exec-context-syscall-filter="))) {
591,952✔
3398
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
566,302✔
3399
                        int id, errno_num;
566,302✔
3400

3401
                        r = extract_many_words(&val, NULL, 0, &s_id, &s_errno_num);
566,302✔
3402
                        if (r < 0)
566,302✔
3403
                                return r;
3404
                        if (r != 2)
566,302✔
3405
                                continue;
×
3406

3407
                        r = safe_atoi(s_id, &id);
566,302✔
3408
                        if (r < 0)
566,302✔
3409
                                return r;
3410

3411
                        r = safe_atoi(s_errno_num, &errno_num);
566,302✔
3412
                        if (r < 0)
566,302✔
3413
                                return r;
3414

3415
                        r = hashmap_ensure_put(&c->syscall_filter, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
566,302✔
3416
                        if (r < 0)
566,302✔
3417
                                return r;
3418
                } else if ((val = startswith(l, "exec-context-syscall-archs="))) {
25,650✔
3419
                        unsigned id;
1,473✔
3420

3421
                        r = safe_atou(val, &id);
1,473✔
3422
                        if (r < 0)
1,473✔
3423
                                return r;
×
3424

3425
                        r = set_ensure_put(&c->syscall_archs, NULL, UINT_TO_PTR(id + 1));
1,473✔
3426
                        if (r < 0)
1,473✔
3427
                                return r;
3428
                } else if ((val = startswith(l, "exec-context-syscall-errno="))) {
24,177✔
3429
                        r = safe_atoi(val, &c->syscall_errno);
10,033✔
3430
                        if (r < 0)
10,033✔
3431
                                return r;
3432
                } else if ((val = startswith(l, "exec-context-syscall-allow-list="))) {
14,144✔
3433
                        r = parse_boolean(val);
1,449✔
3434
                        if (r < 0)
1,449✔
3435
                                return r;
3436
                        c->syscall_allow_list = r;
1,449✔
3437
                } else if ((val = startswith(l, "exec-context-syscall-log="))) {
12,695✔
3438
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
×
3439
                        int id, errno_num;
×
3440

3441
                        r = extract_many_words(&val, " ", 0, &s_id, &s_errno_num);
×
3442
                        if (r < 0)
×
3443
                                return r;
3444
                        if (r != 2)
×
3445
                                continue;
×
3446

3447
                        r = safe_atoi(s_id, &id);
×
3448
                        if (r < 0)
×
3449
                                return r;
3450

3451
                        r = safe_atoi(s_errno_num, &errno_num);
×
3452
                        if (r < 0)
×
3453
                                return r;
3454

3455
                        r = hashmap_ensure_put(&c->syscall_log, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
×
3456
                        if (r < 0)
×
3457
                                return r;
3458
                } else if ((val = startswith(l, "exec-context-syscall-log-allow-list="))) {
12,695✔
3459
                        r = parse_boolean(val);
×
3460
                        if (r < 0)
×
3461
                                return r;
3462
                        c->syscall_log_allow_list = r;
×
3463
#endif
3464
                } else if ((val = startswith(l, "exec-context-restrict-namespaces="))) {
12,695✔
3465
                        r = safe_atolu(val, &c->restrict_namespaces);
1,220✔
3466
                        if (r < 0)
1,220✔
3467
                                return r;
3468
                } else if ((val = startswith(l, "exec-context-delegate-namespaces="))) {
11,475✔
3469
                        r = safe_atolu(val, &c->delegate_namespaces);
21✔
3470
                        if (r < 0)
21✔
3471
                                return r;
3472
                } else if ((val = startswith(l, "exec-context-restrict-filesystems="))) {
11,454✔
3473
                        r = set_put_strdup(&c->restrict_filesystems, val);
×
3474
                        if (r < 0)
×
3475
                                return r;
3476
                } else if ((val = startswith(l, "exec-context-restrict-filesystems-allow-list="))) {
11,454✔
3477
                        r = parse_boolean(val);
×
3478
                        if (r < 0)
×
3479
                                return r;
3480
                        c->restrict_filesystems_allow_list = r;
×
3481
                } else if ((val = startswith(l, "exec-context-address-families="))) {
11,454✔
3482
                        int af;
5,783✔
3483

3484
                        r = safe_atoi(val, &af);
5,783✔
3485
                        if (r < 0)
5,783✔
3486
                                return r;
×
3487

3488
                        r = set_ensure_put(&c->address_families, NULL, INT_TO_PTR(af));
5,783✔
3489
                        if (r < 0)
5,783✔
3490
                                return r;
3491
                } else if ((val = startswith(l, "exec-context-address-families-allow-list="))) {
5,671✔
3492
                        r = parse_boolean(val);
1,467✔
3493
                        if (r < 0)
1,467✔
3494
                                return r;
3495
                        c->address_families_allow_list = r;
1,467✔
3496
                } else if ((val = startswith(l, "exec-context-network-namespace-path="))) {
4,204✔
3497
                        r = free_and_strdup(&c->network_namespace_path, val);
1✔
3498
                        if (r < 0)
1✔
3499
                                return r;
3500
                } else if ((val = startswith(l, "exec-context-user-namespace-path="))) {
4,203✔
3501
                        r = free_and_strdup(&c->user_namespace_path, val);
3✔
3502
                        if (r < 0)
3✔
3503
                                return r;
3504
                } else if ((val = startswith(l, "exec-context-ipc-namespace-path="))) {
4,200✔
3505
                        r = free_and_strdup(&c->ipc_namespace_path, val);
×
3506
                        if (r < 0)
×
3507
                                return r;
3508
                } else if ((val = startswith(l, "exec-context-mount-image="))) {
4,200✔
3509
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3510
                        _cleanup_free_ char *source = NULL, *destination = NULL;
61✔
3511
                        bool permissive = false;
61✔
3512
                        char *s;
61✔
3513

3514
                        r = extract_many_words(&val,
61✔
3515
                                               NULL,
3516
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3517
                                               &source,
3518
                                               &destination);
3519
                        if (r < 0)
61✔
3520
                                return r;
3521
                        if (r == 0)
61✔
3522
                                return -EINVAL;
3523

3524
                        s = source;
61✔
3525
                        if (s[0] == '-') {
61✔
3526
                                permissive = true;
×
3527
                                s++;
×
3528
                        }
3529

3530
                        if (isempty(destination))
61✔
3531
                                continue;
×
3532

3533
                        for (;;) {
66✔
3534
                                _cleanup_free_ char *tuple = NULL, *partition = NULL, *opts = NULL;
5✔
3535
                                PartitionDesignator partition_designator;
66✔
3536
                                MountOptions *o = NULL;
66✔
3537
                                const char *p;
66✔
3538

3539
                                r = extract_first_word(&val, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
66✔
3540
                                if (r < 0)
66✔
3541
                                        return r;
3542
                                if (r == 0)
66✔
3543
                                        break;
3544

3545
                                p = tuple;
5✔
3546
                                r = extract_many_words(&p,
5✔
3547
                                                       ":",
3548
                                                       EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3549
                                                       &partition,
3550
                                                       &opts);
3551
                                if (r < 0)
5✔
3552
                                        return r;
3553
                                if (r == 0)
5✔
3554
                                        continue;
×
3555
                                if (r == 1) {
5✔
3556
                                        o = new(MountOptions, 1);
×
3557
                                        if (!o)
×
3558
                                                return log_oom_debug();
×
3559
                                        *o = (MountOptions) {
×
3560
                                                .partition_designator = PARTITION_ROOT,
3561
                                                .options = TAKE_PTR(partition),
×
3562
                                        };
3563
                                        LIST_APPEND(mount_options, options, o);
×
3564

3565
                                        continue;
×
3566
                                }
3567

3568
                                partition_designator = partition_designator_from_string(partition);
5✔
3569
                                if (partition_designator < 0)
5✔
3570
                                        continue;
×
3571

3572
                                o = new(MountOptions, 1);
5✔
3573
                                if (!o)
5✔
3574
                                        return log_oom_debug();
×
3575
                                *o = (MountOptions) {
5✔
3576
                                        .partition_designator = partition_designator,
3577
                                        .options = TAKE_PTR(opts),
5✔
3578
                                };
3579
                                LIST_APPEND(mount_options, options, o);
5✔
3580
                        }
3581

3582
                        r = mount_image_add(&c->mount_images, &c->n_mount_images,
122✔
3583
                                        &(MountImage) {
61✔
3584
                                                .source = s,
3585
                                                .destination = destination,
3586
                                                .mount_options = options,
3587
                                                .ignore_enoent = permissive,
3588
                                                .type = MOUNT_IMAGE_DISCRETE,
3589
                                        });
3590
                        if (r < 0)
61✔
3591
                                return log_oom_debug();
×
3592
                } else if ((val = startswith(l, "exec-context-extension-image="))) {
4,139✔
3593
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3594
                        _cleanup_free_ char *source = NULL;
13✔
3595
                        bool permissive = false;
13✔
3596
                        char *s;
13✔
3597

3598
                        r = extract_first_word(&val,
13✔
3599
                                               &source,
3600
                                               NULL,
3601
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS);
3602
                        if (r < 0)
13✔
3603
                                return r;
3604
                        if (r == 0)
13✔
3605
                                return -EINVAL;
3606

3607
                        s = source;
13✔
3608
                        if (s[0] == '-') {
13✔
3609
                                permissive = true;
3✔
3610
                                s++;
3✔
3611
                        }
3612

3613
                        for (;;) {
13✔
3614
                                _cleanup_free_ char *tuple = NULL, *partition = NULL, *opts = NULL;
×
3615
                                PartitionDesignator partition_designator;
13✔
3616
                                MountOptions *o = NULL;
13✔
3617
                                const char *p;
13✔
3618

3619
                                r = extract_first_word(&val, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
13✔
3620
                                if (r < 0)
13✔
3621
                                        return r;
3622
                                if (r == 0)
13✔
3623
                                        break;
3624

3625
                                p = tuple;
×
3626
                                r = extract_many_words(&p,
×
3627
                                                       ":",
3628
                                                       EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3629
                                                       &partition,
3630
                                                       &opts);
3631
                                if (r < 0)
×
3632
                                        return r;
3633
                                if (r == 0)
×
3634
                                        continue;
×
3635
                                if (r == 1) {
×
3636
                                        o = new(MountOptions, 1);
×
3637
                                        if (!o)
×
3638
                                                return log_oom_debug();
×
3639
                                        *o = (MountOptions) {
×
3640
                                                .partition_designator = PARTITION_ROOT,
3641
                                                .options = TAKE_PTR(partition),
×
3642
                                        };
3643
                                        LIST_APPEND(mount_options, options, o);
×
3644

3645
                                        continue;
×
3646
                                }
3647

3648
                                partition_designator = partition_designator_from_string(partition);
×
3649
                                if (partition_designator < 0)
×
3650
                                        continue;
×
3651

3652
                                o = new(MountOptions, 1);
×
3653
                                if (!o)
×
3654
                                        return log_oom_debug();
×
3655
                                *o = (MountOptions) {
×
3656
                                        .partition_designator = partition_designator,
3657
                                        .options = TAKE_PTR(opts),
×
3658
                                };
3659
                                LIST_APPEND(mount_options, options, o);
×
3660
                        }
3661

3662
                        r = mount_image_add(&c->extension_images, &c->n_extension_images,
26✔
3663
                                        &(MountImage) {
13✔
3664
                                                .source = s,
3665
                                                .mount_options = options,
3666
                                                .ignore_enoent = permissive,
3667
                                                .type = MOUNT_IMAGE_EXTENSION,
3668
                                        });
3669
                        if (r < 0)
13✔
3670
                                return log_oom_debug();
×
3671
                } else if ((val = startswith(l, "exec-context-extension-directories="))) {
4,126✔
3672
                        r = deserialize_strv(val, &c->extension_directories);
8✔
3673
                        if (r < 0)
8✔
3674
                                return r;
3675
                } else if ((val = startswith(l, "exec-context-set-credentials="))) {
4,118✔
3676
                        _cleanup_free_ char *id = NULL, *data = NULL, *encrypted = NULL;
×
3677

3678
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &data, &encrypted);
93✔
3679
                        if (r < 0)
93✔
3680
                                return r;
3681
                        if (r != 3)
93✔
3682
                                return -EINVAL;
3683

3684
                        r = parse_boolean(encrypted);
93✔
3685
                        if (r < 0)
93✔
3686
                                return r;
3687
                        bool e = r;
93✔
3688

3689
                        _cleanup_free_ void *d = NULL;
93✔
3690
                        size_t size;
93✔
3691

3692
                        r = unbase64mem_full(data, SIZE_MAX, /* secure= */ true, &d, &size);
93✔
3693
                        if (r < 0)
93✔
3694
                                return r;
3695

3696
                        r = exec_context_put_set_credential(c, id, TAKE_PTR(d), size, e);
93✔
3697
                        if (r < 0)
93✔
3698
                                return r;
3699
                } else if ((val = startswith(l, "exec-context-load-credentials="))) {
4,025✔
3700
                        _cleanup_free_ char *id = NULL, *path = NULL, *encrypted = NULL;
34✔
3701

3702
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &path, &encrypted);
34✔
3703
                        if (r < 0)
34✔
3704
                                return r;
3705
                        if (r != 3)
34✔
3706
                                return -EINVAL;
3707

3708
                        r = parse_boolean(encrypted);
34✔
3709
                        if (r < 0)
34✔
3710
                                return r;
3711

3712
                        r = exec_context_put_load_credential(c, id, path, r > 0);
34✔
3713
                        if (r < 0)
34✔
3714
                                return r;
3715
                } else if ((val = startswith(l, "exec-context-import-credentials="))) {
3,991✔
3716
                        _cleanup_free_ char *glob = NULL, *rename = NULL;
3,985✔
3717

3718
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &glob, &rename);
3,985✔
3719
                        if (r < 0)
3,985✔
3720
                                return r;
3721
                        if (r == 0)
3,985✔
3722
                                return -EINVAL;
3723

3724
                        r = exec_context_put_import_credential(c, glob, rename);
3,985✔
3725
                        if (r < 0)
3,985✔
3726
                                return r;
3727
                } else if ((val = startswith(l, "exec-context-root-image-policy="))) {
6✔
3728
                        if (c->root_image_policy)
4✔
3729
                                return -EINVAL; /* duplicated */
3730

3731
                        r = image_policy_from_string(val, /* graceful= */ false, &c->root_image_policy);
4✔
3732
                        if (r < 0)
4✔
3733
                                return r;
3734
                } else if ((val = startswith(l, "exec-context-mount-image-policy="))) {
2✔
3735
                        if (c->mount_image_policy)
×
3736
                                return -EINVAL; /* duplicated */
3737

3738
                        r = image_policy_from_string(val, /* graceful= */ false, &c->mount_image_policy);
×
3739
                        if (r < 0)
×
3740
                                return r;
3741
                } else if ((val = startswith(l, "exec-context-extension-image-policy="))) {
2✔
3742
                        if (c->extension_image_policy)
2✔
3743
                                return -EINVAL; /* duplicated */
3744

3745
                        r = image_policy_from_string(val, /* graceful= */ false, &c->extension_image_policy);
2✔
3746
                        if (r < 0)
2✔
3747
                                return r;
3748
                } else
3749
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3750
        }
3751

3752
        return 0;
10,033✔
3753
}
3754

3755
static int exec_command_serialize(const ExecCommand *c, FILE *f) {
2,430✔
3756
        int r;
2,430✔
3757

3758
        assert(c);
2,430✔
3759
        assert(f);
2,430✔
3760

3761
        r = serialize_item(f, "exec-command-path", c->path);
2,430✔
3762
        if (r < 0)
2,430✔
3763
                return r;
3764

3765
        r = serialize_strv(f, "exec-command-argv", c->argv);
2,430✔
3766
        if (r < 0)
2,430✔
3767
                return r;
3768

3769
        r = serialize_item_format(f, "exec-command-flags", "%d", (int) c->flags);
2,430✔
3770
        if (r < 0)
2,430✔
3771
                return r;
3772

3773
        fputc('\n', f); /* End marker */
2,430✔
3774

3775
        return 0;
2,430✔
3776
}
3777

3778
static int exec_command_deserialize(ExecCommand *c, FILE *f) {
10,033✔
3779
        int r;
10,033✔
3780

3781
        assert(c);
10,033✔
3782
        assert(f);
10,033✔
3783

3784
        for (;;) {
108,569✔
3785
                _cleanup_free_ char *l = NULL;
49,268✔
3786
                const char *val;
59,301✔
3787

3788
                r = deserialize_read_line(f, &l);
59,301✔
3789
                if (r < 0)
59,301✔
3790
                        return r;
3791
                if (r == 0) /* eof or end marker */
59,301✔
3792
                        break;
3793

3794
                if ((val = startswith(l, "exec-command-path="))) {
49,268✔
3795
                        r = free_and_strdup(&c->path, val);
10,033✔
3796
                        if (r < 0)
10,033✔
3797
                                return r;
3798
                } else if ((val = startswith(l, "exec-command-argv="))) {
39,235✔
3799
                        r = deserialize_strv(val, &c->argv);
29,202✔
3800
                        if (r < 0)
29,202✔
3801
                                return r;
3802
                } else if ((val = startswith(l, "exec-command-flags="))) {
10,033✔
3803
                        r = safe_atoi(val, &c->flags);
10,033✔
3804
                        if (r < 0)
10,033✔
3805
                                return r;
3806
                } else
3807
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3808

3809
        }
3810

3811
        return 0;
10,033✔
3812
}
3813

3814
int exec_serialize_invocation(
2,430✔
3815
                FILE *f,
3816
                FDSet *fds,
3817
                const ExecContext *ctx,
3818
                const ExecCommand *cmd,
3819
                const ExecParameters *p,
3820
                const ExecRuntime *rt,
3821
                const CGroupContext *cg) {
3822

3823
        int r;
2,430✔
3824

3825
        assert(f);
2,430✔
3826
        assert(fds);
2,430✔
3827

3828
        r = exec_context_serialize(ctx, f);
2,430✔
3829
        if (r < 0)
2,430✔
3830
                return log_debug_errno(r, "Failed to serialize context: %m");
×
3831

3832
        r = exec_command_serialize(cmd, f);
2,430✔
3833
        if (r < 0)
2,430✔
3834
                return log_debug_errno(r, "Failed to serialize command: %m");
×
3835

3836
        r = exec_parameters_serialize(p, ctx, f, fds);
2,430✔
3837
        if (r < 0)
2,430✔
3838
                return log_debug_errno(r, "Failed to serialize parameters: %m");
×
3839

3840
        r = exec_runtime_serialize(rt, f, fds);
2,430✔
3841
        if (r < 0)
2,430✔
3842
                return log_debug_errno(r, "Failed to serialize runtime: %m");
×
3843

3844
        r = exec_cgroup_context_serialize(cg, f);
2,430✔
3845
        if (r < 0)
2,430✔
3846
                return log_debug_errno(r, "Failed to serialize cgroup context: %m");
×
3847

3848
        return 0;
3849
}
3850

3851
int exec_deserialize_invocation(
10,033✔
3852
                FILE *f,
3853
                FDSet *fds,
3854
                ExecContext *ctx,
3855
                ExecCommand *cmd,
3856
                ExecParameters *p,
3857
                ExecRuntime *rt,
3858
                CGroupContext *cg) {
3859

3860
        int r;
10,033✔
3861

3862
        assert(f);
10,033✔
3863
        assert(fds);
10,033✔
3864

3865
        r = exec_context_deserialize(ctx, f);
10,033✔
3866
        if (r < 0)
10,033✔
3867
                return log_debug_errno(r, "Failed to deserialize context: %m");
×
3868

3869
        r = exec_command_deserialize(cmd, f);
10,033✔
3870
        if (r < 0)
10,033✔
3871
                return log_debug_errno(r, "Failed to deserialize command: %m");
×
3872

3873
        r = exec_parameters_deserialize(p, f, fds);
10,033✔
3874
        if (r < 0)
10,033✔
3875
                return log_debug_errno(r, "Failed to deserialize parameters: %m");
×
3876

3877
        r = exec_runtime_deserialize(rt, f, fds);
10,033✔
3878
        if (r < 0)
10,033✔
3879
                return log_debug_errno(r, "Failed to deserialize runtime: %m");
×
3880

3881
        r = exec_cgroup_context_deserialize(cg, f);
10,033✔
3882
        if (r < 0)
10,033✔
3883
                return log_debug_errno(r, "Failed to deserialize cgroup context: %m");
×
3884

3885
        return 0;
3886
}
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