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

systemd / systemd / 20151578145

11 Dec 2025 05:38AM UTC coverage: 72.698% (-0.02%) from 72.713%
20151578145

push

github

web-flow
core: gracefully skip unknown policy designators in RootImagePolicy et al (#40060)

Usually we gracefully ignore unknown configuration parameters, so that
service files can be written by upstreams and used across a variegated
range of distributions with various versions of systemd, to avoid
forcing users to the minimum common denominator and only adding settings
that are supported by the oldest distro supported.

Image policies do not behave like this, and any unknown partition or
policy designator causes the whole unit to fail to parse and a hard
error.

Change it so that parsing RootImagePolicy and friends via unit file or
D-Bus logs but otherwise ignores unknown specifiers, like other options
do.

This allows us to add new specifiers in the future, and users to adopt
them immediately.

Follow-up for d452335aa

44 of 49 new or added lines in 7 files covered. (89.8%)

297 existing lines in 37 files now uncovered.

309479 of 425707 relevant lines covered (72.7%)

1150153.67 hits per line

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

71.21
/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,556✔
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,556✔
38
        char *iface;
2,556✔
39
        struct in_addr_prefix *iaai;
2,556✔
40
        int r;
2,556✔
41

42
        assert(f);
2,556✔
43

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

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

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

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

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

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

67
        if (c->cpu_weight != CGROUP_WEIGHT_INVALID) {
2,556✔
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,556✔
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,556✔
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,556✔
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,556✔
92
        if (!cpuset_cpus)
2,556✔
93
                return log_oom_debug();
×
94

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

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

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

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

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

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

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

123
        if (c->io_weight != CGROUP_WEIGHT_INVALID) {
2,556✔
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,556✔
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,556✔
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,556✔
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,556✔
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,556✔
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,556✔
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,556✔
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,556✔
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,556✔
178
                r = serialize_item_format(f, "exec-cgroup-context-memory-max", "%" PRIu64, c->memory_max);
×
179
                if (r < 0)
×
180
                        return r;
181
        }
182

183
        if (c->startup_memory_max != CGROUP_LIMIT_MAX) {
2,556✔
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,556✔
190
                r = serialize_item_format(f, "exec-cgroup-context-memory-swap-max", "%" PRIu64, c->memory_swap_max);
×
191
                if (r < 0)
×
192
                        return r;
193
        }
194

195
        if (c->startup_memory_swap_max != CGROUP_LIMIT_MAX) {
2,556✔
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,556✔
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,556✔
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,556✔
214
        if (r < 0)
2,556✔
215
                return r;
216

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

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

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

233
        r = serialize_bool_elide(f, "exec-cgroup-context-default-memory-low-set", c->default_memory_low_set);
2,556✔
234
        if (r < 0)
2,556✔
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,556✔
238
        if (r < 0)
2,556✔
239
                return r;
240

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

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

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

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

257
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-max-set", c->startup_memory_max_set);
2,556✔
258
        if (r < 0)
2,556✔
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,556✔
262
        if (r < 0)
2,556✔
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,556✔
266
        if (r < 0)
2,556✔
267
                return r;
268

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

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

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

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

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

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

293
        r = serialize_item(f, "exec-cgroup-context-managed-oom-swap", managed_oom_mode_to_string(c->moom_swap));
2,556✔
294
        if (r < 0)
2,556✔
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,556✔
298
        if (r < 0)
2,556✔
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,556✔
302
        if (r < 0)
2,556✔
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,556✔
306
        if (r < 0)
2,556✔
307
                return r;
308

309
        r = serialize_item(f, "exec-cgroup-context-managed-oom-preference", managed_oom_preference_to_string(c->moom_preference));
2,556✔
310
        if (r < 0)
2,556✔
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,556✔
314
        if (r < 0)
2,556✔
315
                return r;
316

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

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

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

335
        LIST_FOREACH(device_weights, iw, c->io_device_weights) {
2,556✔
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,556✔
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,556✔
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,556✔
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,850✔
375
                r = serialize_item(f,
294✔
376
                                   "exec-cgroup-context-ip-address-deny",
377
                                   IN_ADDR_PREFIX_TO_STRING(iaai->family, &iaai->address, iaai->prefixlen));
294✔
378
                if (r < 0)
294✔
379
                        return r;
×
380
        }
381

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

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

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

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

398
        LIST_FOREACH(programs, p, c->bpf_foreign_programs) {
2,556✔
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,556✔
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,556✔
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,556✔
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(
5,112✔
425
                        f,
426
                        "exec-cgroup-context-restrict-network-interfaces-is-allow-list",
427
                        c->restrict_network_interfaces_is_allow_list);
2,556✔
428
        if (r < 0)
2,556✔
429
                return r;
430

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

433
        return 0;
434
}
435

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

439
        assert(f);
10,226✔
440

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

444
        for (;;) {
381,492✔
445
                _cleanup_free_ char *l = NULL;
185,633✔
446
                const char *val;
195,859✔
447

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

454
                if ((val = startswith(l, "exec-cgroup-context-io-accounting="))) {
185,633✔
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="))) {
185,631✔
460
                        r = parse_boolean(val);
9,888✔
461
                        if (r < 0)
9,888✔
462
                                return r;
463
                        c->memory_accounting = r;
9,888✔
464
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-accounting="))) {
175,743✔
465
                        r = parse_boolean(val);
10,226✔
466
                        if (r < 0)
10,226✔
467
                                return r;
468
                        c->tasks_accounting = r;
10,226✔
469
                } else if ((val = startswith(l, "exec-cgroup-context-ip-accounting="))) {
165,517✔
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="))) {
165,517✔
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="))) {
165,515✔
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="))) {
165,514✔
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="))) {
165,514✔
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="))) {
165,514✔
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="))) {
165,514✔
496
                        if (c->cpuset_cpus.set)
10,226✔
497
                                return -EINVAL; /* duplicated */
498

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

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

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

520
                        r = parse_cpu_set(val, &c->startup_cpuset_mems);
10,226✔
521
                        if (r < 0)
10,226✔
522
                                return r;
523
                } else if ((val = startswith(l, "exec-cgroup-context-io-weight="))) {
124,610✔
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="))) {
124,610✔
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="))) {
124,610✔
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="))) {
124,610✔
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="))) {
124,610✔
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="))) {
124,609✔
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="))) {
124,608✔
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="))) {
124,608✔
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="))) {
124,598✔
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="))) {
124,598✔
560
                        r = safe_atou64(val, &c->memory_max);
2✔
561
                        if (r < 0)
2✔
562
                                return r;
563
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max="))) {
124,596✔
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="))) {
124,596✔
568
                        r = safe_atou64(val, &c->memory_swap_max);
1✔
569
                        if (r < 0)
1✔
570
                                return r;
571
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max="))) {
124,595✔
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="))) {
124,595✔
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="))) {
124,594✔
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="))) {
124,594✔
584
                        r = parse_boolean(val);
10,226✔
585
                        if (r < 0)
10,226✔
586
                                return r;
587
                        c->memory_zswap_writeback = r;
10,226✔
588
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-value="))) {
114,368✔
589
                        r = safe_atou64(val, &c->tasks_max.value);
9,920✔
590
                        if (r < 0)
9,920✔
591
                                return r;
592
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-scale="))) {
104,448✔
593
                        r = safe_atou64(val, &c->tasks_max.scale);
9,879✔
594
                        if (r < 0)
9,879✔
595
                                return r;
596
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-min-set="))) {
94,569✔
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="))) {
94,569✔
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="))) {
94,569✔
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="))) {
94,569✔
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="))) {
94,568✔
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="))) {
94,567✔
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="))) {
94,567✔
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="))) {
94,567✔
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="))) {
94,567✔
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="))) {
94,567✔
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="))) {
94,567✔
647
                        c->device_policy = cgroup_device_policy_from_string(val);
10,226✔
648
                        if (c->device_policy < 0)
10,226✔
649
                                return -EINVAL;
650
                } else if ((val = startswith(l, "exec-cgroup-context-disable-controllers="))) {
84,341✔
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="))) {
84,341✔
655
                        r = cg_mask_from_string(val, &c->delegate_controllers);
582✔
656
                        if (r < 0)
582✔
657
                                return r;
658
                } else if ((val = startswith(l, "exec-cgroup-context-delegate="))) {
83,759✔
659
                        r = parse_boolean(val);
703✔
660
                        if (r < 0)
703✔
661
                                return r;
662
                        c->delegate = r;
703✔
663
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-swap="))) {
83,056✔
664
                        c->moom_swap = managed_oom_mode_from_string(val);
10,226✔
665
                        if (c->moom_swap < 0)
10,226✔
666
                                return -EINVAL;
667
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure="))) {
72,830✔
668
                        c->moom_mem_pressure = managed_oom_mode_from_string(val);
10,226✔
669
                        if (c->moom_mem_pressure < 0)
10,226✔
670
                                return -EINVAL;
671
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-limit="))) {
62,604✔
672
                        r = safe_atou32(val, &c->moom_mem_pressure_limit);
10,226✔
673
                        if (r < 0)
10,226✔
674
                                return r;
675
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-preference="))) {
52,378✔
676
                        c->moom_preference = managed_oom_preference_from_string(val);
10,226✔
677
                        if (c->moom_preference < 0)
10,226✔
678
                                return -EINVAL;
679
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec="))) {
42,152✔
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="))) {
42,151✔
684
                        c->memory_pressure_watch = cgroup_pressure_watch_from_string(val);
10,226✔
685
                        if (c->memory_pressure_watch < 0)
10,226✔
686
                                return -EINVAL;
687
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-subgroup="))) {
31,925✔
688
                        r = free_and_strdup(&c->delegate_subgroup, val);
356✔
689
                        if (r < 0)
356✔
690
                                return r;
691
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-threshold-usec="))) {
31,569✔
692
                        r = deserialize_usec(val, &c->memory_pressure_threshold_usec);
10,226✔
693
                        if (r < 0)
10,226✔
694
                                return r;
695
                } else if ((val = startswith(l, "exec-cgroup-context-device-allow="))) {
21,343✔
696
                        _cleanup_free_ char *path = NULL, *rwm = NULL;
3,357✔
697
                        CGroupDevicePermissions p;
3,357✔
698

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

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

709
                        r = cgroup_context_add_or_update_device_allow(c, path, p);
3,357✔
710
                        if (r < 0)
3,357✔
711
                                return r;
712
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-weight="))) {
17,986✔
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,986✔
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,986✔
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,986✔
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,986✔
817
                        struct in_addr_prefix a;
1,406✔
818

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

823
                        r = in_addr_prefix_add(&c->ip_address_deny, &a);
1,406✔
824
                        if (r < 0)
1,406✔
825
                                return r;
826
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow-reduced="))) {
16,580✔
827
                        r = parse_boolean(val);
8,278✔
828
                        if (r < 0)
8,278✔
829
                                return r;
830
                        c->ip_address_allow_reduced = r;
8,278✔
831
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny-reduced="))) {
8,302✔
832
                        r = parse_boolean(val);
8,278✔
833
                        if (r < 0)
8,278✔
834
                                return r;
835
                        c->ip_address_deny_reduced = r;
8,278✔
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,226✔
915
}
916

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

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

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

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

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

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

941
                if (rt->shared->userns_storage_socket[0] >= 0 && rt->shared->userns_storage_socket[1] >= 0) {
78✔
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) {
78✔
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) {
78✔
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) {
80✔
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) {
80✔
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) {
78✔
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);
80✔
977
        if (r < 0)
80✔
978
                return r;
979

980
        if (rt->ephemeral_storage_socket[0] >= 0 && rt->ephemeral_storage_socket[1] >= 0) {
80✔
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 */
80✔
987

988
        return 0;
80✔
989
}
990

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

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

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

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

1010
                if ((val = startswith(l, "exec-runtime-id="))) {
1,260✔
1011
                        r = free_and_strdup(&rt->shared->id, val);
378✔
1012
                        if (r < 0)
378✔
1013
                                return r;
1014
                } else if ((val = startswith(l, "exec-runtime-tmp-dir="))) {
882✔
1015
                        r = free_and_strdup(&rt->shared->tmp_dir, val);
354✔
1016
                        if (r < 0)
354✔
1017
                                return r;
1018
                } else if ((val = startswith(l, "exec-runtime-var-tmp-dir="))) {
528✔
1019
                        r = free_and_strdup(&rt->shared->var_tmp_dir, val);
354✔
1020
                        if (r < 0)
354✔
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,226✔
1069
}
1070

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

1074
        return p->idle_pipe &&
2,586✔
1075
                p->idle_pipe[0] >= 0 &&
30✔
1076
                p->idle_pipe[1] >= 0 &&
28✔
1077
                p->idle_pipe[2] >= 0 &&
2,584✔
1078
                p->idle_pipe[3] >= 0;
28✔
1079
}
1080

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

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

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

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

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

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

1105
                if (p->n_stashed_fds > 0) {
552✔
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);
552✔
1112
                if (r < 0)
552✔
1113
                        return r;
1114

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

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

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

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

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

1138
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
15,336✔
1139
                _cleanup_free_ char *key = NULL;
12,780✔
1140

1141
                key = strjoin("exec-parameters-prefix-directories-", exec_directory_type_to_string(dt));
12,780✔
1142
                if (!key)
12,780✔
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,780✔
1148
                if (r < 0)
12,780✔
1149
                        return r;
1150
        }
1151

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

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

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

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

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

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

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

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

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

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

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

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

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

1208
        if (c && exec_context_restrict_filesystems_set(c)) {
2,556✔
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,556✔
1215
        if (r < 0)
2,556✔
1216
                return r;
1217

1218
        LIST_FOREACH(open_files, file, p->open_files) {
2,556✔
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,556✔
1231
        if (r < 0)
2,556✔
1232
                return r;
1233

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

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

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

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

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

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

1256
        return 0;
2,556✔
1257
}
1258

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

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

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

1268
        for (;;) {
217,944✔
1269
                _cleanup_free_ char *l = NULL;
207,718✔
1270
                const char *val;
217,944✔
1271

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

1278
                if ((val = startswith(l, "exec-parameters-runtime-scope="))) {
207,718✔
1279
                        p->runtime_scope = runtime_scope_from_string(val);
10,226✔
1280
                        if (p->runtime_scope < 0)
10,226✔
1281
                                return p->runtime_scope;
1282
                } else if ((val = startswith(l, "exec-parameters-environment="))) {
197,492✔
1283
                        r = deserialize_strv(val, &p->environment);
43,307✔
1284
                        if (r < 0)
43,307✔
1285
                                return r;
1286
                } else if ((val = startswith(l, "exec-parameters-n-socket-fds="))) {
154,185✔
1287
                        if (p->fds)
1,768✔
1288
                                return -EINVAL; /* Already received */
1289

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

1294
                        if (p->n_socket_fds > nr_open)
1,768✔
1295
                                return -EINVAL; /* too many, someone is playing games with us */
1296
                } else if ((val = startswith(l, "exec-parameters-n-stashed-fds="))) {
152,417✔
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="))) {
152,307✔
1307
                        if (p->n_socket_fds + p->n_stashed_fds == 0)
1,773✔
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,773✔
1313
                                return -EINVAL; /* too many, someone is playing games with us */
1314

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

1318
                        p->fds = new(int, p->n_socket_fds + p->n_stashed_fds);
1,773✔
1319
                        if (!p->fds)
1,773✔
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,508✔
1324
                                *i = -EBADF;
3,735✔
1325

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

1330
                } else if ((val = startswith(l, "exec-parameters-fd-names="))) {
150,534✔
1331
                        r = deserialize_strv(val, &p->fd_names);
3,735✔
1332
                        if (r < 0)
3,735✔
1333
                                return r;
1334
                } else if ((val = startswith(l, "exec-parameters-flags="))) {
146,799✔
1335
                        unsigned flags;
10,226✔
1336

1337
                        r = safe_atou(val, &flags);
10,226✔
1338
                        if (r < 0)
10,226✔
1339
                                return r;
×
1340
                        p->flags = flags;
10,226✔
1341
                } else if ((val = startswith(l, "exec-parameters-selinux-context-net="))) {
136,573✔
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="))) {
136,573✔
1348
                        r = free_and_strdup(&p->cgroup_path, val);
10,226✔
1349
                        if (r < 0)
10,226✔
1350
                                return r;
1351
                } else if ((val = startswith(l, "exec-parameters-cgroup-id="))) {
126,347✔
1352
                        r = safe_atou64(val, &p->cgroup_id);
10,226✔
1353
                        if (r < 0)
10,226✔
1354
                                return r;
1355
                } else if ((val = startswith(l, "exec-parameters-prefix-directories-"))) {
116,121✔
1356
                        _cleanup_free_ char *type = NULL, *prefix = NULL;
51,130✔
1357
                        ExecDirectoryType dt;
51,130✔
1358

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

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

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

1375
                        if (isempty(prefix))
51,130✔
1376
                                p->prefix[dt] = mfree(p->prefix[dt]);
×
1377
                        else
1378
                                free_and_replace(p->prefix[dt], prefix);
51,130✔
1379
                } else if ((val = startswith(l, "exec-parameters-received-credentials-directory="))) {
64,991✔
1380
                        r = free_and_strdup(&p->received_credentials_directory, val);
9,537✔
1381
                        if (r < 0)
9,537✔
1382
                                return r;
1383
                } else if ((val = startswith(l, "exec-parameters-received-encrypted-credentials-directory="))) {
55,454✔
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="))) {
55,454✔
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="))) {
55,454✔
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="))) {
55,454✔
1398
                        r = deserialize_usec(val, &p->watchdog_usec);
1,506✔
1399
                        if (r < 0)
1,506✔
1400
                                return r;
1401
                } else if ((val = startswith(l, "exec-parameters-idle-pipe="))) {
53,948✔
1402
                        if (p->idle_pipe)
86✔
1403
                                return -EINVAL; /* duplicated */
1404

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

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

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

1415
                } else if ((val = startswith(l, "exec-parameters-stdin-fd="))) {
53,862✔
1416
                        int fd;
536✔
1417

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

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

1424
                } else if ((val = startswith(l, "exec-parameters-stdout-fd="))) {
53,326✔
1425
                        int fd;
536✔
1426

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

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

1433
                } else if ((val = startswith(l, "exec-parameters-stderr-fd="))) {
52,790✔
1434
                        int fd;
536✔
1435

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

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

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

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

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

1451
                } else if ((val = startswith(l, "exec-parameters-exec-fd="))) {
52,254✔
1452
                        int fd;
422✔
1453

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

1458
                        close_and_replace(p->exec_fd, fd);
422✔
1459
                } else if ((val = startswith(l, "exec-parameters-handoff-timestamp-fd="))) {
51,832✔
1460
                        int fd;
10,226✔
1461

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

1466
                        close_and_replace(p->handoff_timestamp_fd, fd);
10,226✔
1467
                } else if ((val = startswith(l, "exec-parameters-pidref-transport-fd="))) {
41,606✔
1468
                        int fd;
9,007✔
1469

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

1474
                        close_and_replace(p->pidref_transport_fd, fd);
9,007✔
1475
                } else if ((val = startswith(l, "exec-parameters-bpf-outer-map-fd="))) {
32,599✔
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="))) {
32,599✔
1484
                        r = free_and_strdup(&p->notify_socket, val);
1,912✔
1485
                        if (r < 0)
1,912✔
1486
                                return r;
1487
                } else if ((val = startswith(l, "exec-parameters-open-file="))) {
30,687✔
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,682✔
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,682✔
1500
                        int fd;
10,226✔
1501

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

1506
                        close_and_replace(p->user_lookup_fd, fd);
10,226✔
1507
                } else if ((val = startswith(l, "exec-parameters-files-env="))) {
20,456✔
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,454✔
1512
                        r = free_and_strdup(&p->unit_id, val);
10,226✔
1513
                        if (r < 0)
10,226✔
1514
                                return r;
1515
                } else if ((val = startswith(l, "exec-parameters-invocation-id-string="))) {
10,228✔
1516
                        if (strlen(val) > SD_ID128_STRING_MAX - 1)
10,226✔
1517
                                return -EINVAL;
1518

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

1523
                        sd_id128_to_string(p->invocation_id, p->invocation_id_string);
10,226✔
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,226✔
1537
                return -EINVAL;
×
1538

1539
        return 0;
1540
}
1541

1542
static int serialize_std_out_err(const ExecContext *c, FILE *f, int fileno) {
5,112✔
1543
        char *key, *value;
5,112✔
1544
        const char *type;
5,112✔
1545

1546
        assert(c);
5,112✔
1547
        assert(f);
5,112✔
1548
        assert(IN_SET(fileno, STDOUT_FILENO, STDERR_FILENO));
5,112✔
1549

1550
        type = fileno == STDOUT_FILENO ? "output" : "error";
5,112✔
1551

1552
        switch (fileno == STDOUT_FILENO ? c->std_output : c->std_error) {
5,112✔
1553
        case EXEC_OUTPUT_NAMED_FD:
×
1554
                key = strjoina("exec-context-std-", type, "-fd-name");
×
1555
                value = c->stdio_fdname[fileno];
×
1556

1557
                break;
×
1558

1559
        case EXEC_OUTPUT_FILE:
2✔
1560
                key = strjoina("exec-context-std-", type, "-file");
14✔
1561
                value = c->stdio_file[fileno];
2✔
1562

1563
                break;
2✔
1564

1565
        case EXEC_OUTPUT_FILE_APPEND:
×
1566
                key = strjoina("exec-context-std-", type, "-file-append");
×
1567
                value = c->stdio_file[fileno];
×
1568

1569
                break;
×
1570

1571
        case EXEC_OUTPUT_FILE_TRUNCATE:
×
1572
                key = strjoina("exec-context-std-", type, "-file-truncate");
×
1573
                value = c->stdio_file[fileno];
×
1574

1575
                break;
×
1576

1577
        default:
1578
                return 0;
1579
        }
1580

1581
        return serialize_item(f, key, value);
2✔
1582
}
1583

1584
static int exec_context_serialize(const ExecContext *c, FILE *f) {
2,556✔
1585
        int r;
2,556✔
1586

1587
        assert(f);
2,556✔
1588

1589
        if (!c)
2,556✔
1590
                return 0;
2,556✔
1591

1592
        r = serialize_strv(f, "exec-context-environment", c->environment);
2,556✔
1593
        if (r < 0)
2,556✔
1594
                return r;
1595

1596
        r = serialize_strv(f, "exec-context-environment-files", c->environment_files);
2,556✔
1597
        if (r < 0)
2,556✔
1598
                return r;
1599

1600
        r = serialize_strv(f, "exec-context-pass-environment", c->pass_environment);
2,556✔
1601
        if (r < 0)
2,556✔
1602
                return r;
1603

1604
        r = serialize_strv(f, "exec-context-unset-environment", c->unset_environment);
2,556✔
1605
        if (r < 0)
2,556✔
1606
                return r;
1607

1608
        r = serialize_item_escaped(f, "exec-context-working-directory", c->working_directory);
2,556✔
1609
        if (r < 0)
2,556✔
1610
                return r;
1611

1612
        r = serialize_bool_elide(f, "exec-context-working-directory-missing-ok", c->working_directory_missing_ok);
2,556✔
1613
        if (r < 0)
2,556✔
1614
                return r;
1615

1616
        r = serialize_bool_elide(f, "exec-context-working-directory-home", c->working_directory_home);
2,556✔
1617
        if (r < 0)
2,556✔
1618
                return r;
1619

1620
        r = serialize_item_escaped(f, "exec-context-root-directory", c->root_directory);
2,556✔
1621
        if (r < 0)
2,556✔
1622
                return r;
1623

1624
        r = serialize_item_escaped(f, "exec-context-root-image", c->root_image);
2,556✔
1625
        if (r < 0)
2,556✔
1626
                return r;
1627

1628
        if (c->root_image_options) {
2,556✔
1629
                _cleanup_free_ char *options = NULL;
×
1630

1631
                LIST_FOREACH(mount_options, o, c->root_image_options) {
×
1632
                        if (isempty(o->options))
×
1633
                                continue;
×
1634

1635
                        _cleanup_free_ char *escaped = NULL;
×
1636
                        escaped = shell_escape(o->options, ":");
×
1637
                        if (!escaped)
×
1638
                                return log_oom_debug();
×
1639

1640
                        if (!strextend(&options,
×
1641
                                        " ",
1642
                                        partition_designator_to_string(o->partition_designator),
1643
                                               ":",
1644
                                               escaped))
1645
                                        return log_oom_debug();
×
1646
                }
1647

1648
                r = serialize_item(f, "exec-context-root-image-options", options);
×
1649
                if (r < 0)
×
1650
                        return r;
1651
        }
1652

1653
        r = serialize_item(f, "exec-context-root-verity", c->root_verity);
2,556✔
1654
        if (r < 0)
2,556✔
1655
                return r;
1656

1657
        r = serialize_item(f, "exec-context-root-hash-path", c->root_hash_path);
2,556✔
1658
        if (r < 0)
2,556✔
1659
                return r;
1660

1661
        r = serialize_item(f, "exec-context-root-hash-sig-path", c->root_hash_sig_path);
2,556✔
1662
        if (r < 0)
2,556✔
1663
                return r;
1664

1665
        r = serialize_item_hexmem(f, "exec-context-root-hash", c->root_hash.iov_base, c->root_hash.iov_len);
2,556✔
1666
        if (r < 0)
2,556✔
1667
                return r;
1668

1669
        r = serialize_item_base64mem(f, "exec-context-root-hash-sig", c->root_hash_sig.iov_base, c->root_hash_sig.iov_len);
2,556✔
1670
        if (r < 0)
2,556✔
1671
                return r;
1672

1673
        r = serialize_bool_elide(f, "exec-context-root-ephemeral", c->root_ephemeral);
2,556✔
1674
        if (r < 0)
2,556✔
1675
                return r;
1676

1677
        r = serialize_item_format(f, "exec-context-umask", "%04o", c->umask);
2,556✔
1678
        if (r < 0)
2,556✔
1679
                return r;
1680

1681
        r = serialize_bool_elide(f, "exec-context-non-blocking", c->non_blocking);
2,556✔
1682
        if (r < 0)
2,556✔
1683
                return r;
1684

1685
        r = serialize_item_tristate(f, "exec-context-private-mounts", c->private_mounts);
2,556✔
1686
        if (r < 0)
31✔
1687
                return r;
1688

1689
        r = serialize_item_tristate(f, "exec-context-mount-api-vfs", c->mount_apivfs);
2,556✔
1690
        if (r < 0)
2✔
1691
                return r;
1692

1693
        r = serialize_item_tristate(f, "exec-context-bind-log-sockets", c->bind_log_sockets);
2,556✔
1694
        if (r < 0)
×
1695
                return r;
1696

1697
        r = serialize_item_tristate(f, "exec-context-memory-ksm", c->memory_ksm);
2,556✔
1698
        if (r < 0)
×
1699
                return r;
1700

1701
        r = serialize_item(f, "exec-context-private-tmp", private_tmp_to_string(c->private_tmp));
2,556✔
1702
        if (r < 0)
2,556✔
1703
                return r;
1704

1705
        /* This must be set in unit_patch_contexts() before executing a command. */
1706
        assert(c->private_var_tmp >= 0 && c->private_var_tmp < _PRIVATE_TMP_MAX);
2,556✔
1707
        r = serialize_item(f, "exec-context-private-var-tmp", private_tmp_to_string(c->private_var_tmp));
2,556✔
1708
        if (r < 0)
2,556✔
1709
                return r;
1710

1711
        r = serialize_bool_elide(f, "exec-context-private-devices", c->private_devices);
2,556✔
1712
        if (r < 0)
2,556✔
1713
                return r;
1714

1715
        r = serialize_bool_elide(f, "exec-context-protect-kernel-tunables", c->protect_kernel_tunables);
2,556✔
1716
        if (r < 0)
2,556✔
1717
                return r;
1718

1719
        r = serialize_bool_elide(f, "exec-context-protect-kernel-modules", c->protect_kernel_modules);
2,556✔
1720
        if (r < 0)
2,556✔
1721
                return r;
1722

1723
        r = serialize_bool_elide(f, "exec-context-protect-kernel-logs", c->protect_kernel_logs);
2,556✔
1724
        if (r < 0)
2,556✔
1725
                return r;
1726

1727
        r = serialize_bool_elide(f, "exec-context-protect-clock", c->protect_clock);
2,556✔
1728
        if (r < 0)
2,556✔
1729
                return r;
1730

1731
        r = serialize_item(f, "exec-context-protect-control-groups", protect_control_groups_to_string(c->protect_control_groups));
2,556✔
1732
        if (r < 0)
2,556✔
1733
                return r;
1734

1735
        r = serialize_bool_elide(f, "exec-context-private-network", c->private_network);
2,556✔
1736
        if (r < 0)
2,556✔
1737
                return r;
1738

1739
        r = serialize_item(f, "exec-context-private-users", private_users_to_string(c->private_users));
2,556✔
1740
        if (r < 0)
2,556✔
1741
                return r;
1742

1743
        r = serialize_bool_elide(f, "exec-context-private-ipc", c->private_ipc);
2,556✔
1744
        if (r < 0)
2,556✔
1745
                return r;
1746

1747
        r = serialize_item(f, "exec-context-private-pids", private_pids_to_string(c->private_pids));
2,556✔
1748
        if (r < 0)
2,556✔
1749
                return r;
1750

1751
        r = serialize_bool_elide(f, "exec-context-remove-ipc", c->remove_ipc);
2,556✔
1752
        if (r < 0)
2,556✔
1753
                return r;
1754

1755
        r = serialize_item(f, "exec-context-protect-home", protect_home_to_string(c->protect_home));
2,556✔
1756
        if (r < 0)
2,556✔
1757
                return r;
1758

1759
        r = serialize_item(f, "exec-context-protect-system", protect_system_to_string(c->protect_system));
2,556✔
1760
        if (r < 0)
2,556✔
1761
                return r;
1762

1763
        r = serialize_bool_elide(f, "exec-context-same-pgrp", c->same_pgrp);
2,556✔
1764
        if (r < 0)
2,556✔
1765
                return r;
1766

1767
        r = serialize_bool(f, "exec-context-ignore-sigpipe", c->ignore_sigpipe);
2,556✔
1768
        if (r < 0)
2,556✔
1769
                return r;
1770

1771
        r = serialize_bool_elide(f, "exec-context-memory-deny-write-execute", c->memory_deny_write_execute);
2,556✔
1772
        if (r < 0)
2,556✔
1773
                return r;
1774

1775
        r = serialize_bool_elide(f, "exec-context-restrict-realtime", c->restrict_realtime);
2,556✔
1776
        if (r < 0)
2,556✔
1777
                return r;
1778

1779
        r = serialize_bool_elide(f, "exec-context-restrict-suid-sgid", c->restrict_suid_sgid);
2,556✔
1780
        if (r < 0)
2,556✔
1781
                return r;
1782

1783
        r = serialize_item(f, "exec-context-keyring-mode", exec_keyring_mode_to_string(c->keyring_mode));
2,556✔
1784
        if (r < 0)
2,556✔
1785
                return r;
1786

1787
        r = serialize_item(f, "exec-context-protect-hostname", protect_hostname_to_string(c->protect_hostname));
2,556✔
1788
        if (r < 0)
2,556✔
1789
                return r;
1790

1791
        r = serialize_item(f, "exec-context-private-hostname", c->private_hostname);
2,556✔
1792
        if (r < 0)
2,556✔
1793
                return r;
1794

1795
        r = serialize_item(f, "exec-context-protect-proc", protect_proc_to_string(c->protect_proc));
2,556✔
1796
        if (r < 0)
2,556✔
1797
                return r;
1798

1799
        r = serialize_item(f, "exec-context-proc-subset", proc_subset_to_string(c->proc_subset));
2,556✔
1800
        if (r < 0)
2,556✔
1801
                return r;
1802

1803
        r = serialize_item(f, "exec-context-private-bpf", private_bpf_to_string(c->private_bpf));
2,556✔
1804
        if (r < 0)
2,556✔
1805
                return r;
1806

1807
        if (c->bpf_delegate_commands != 0) {
2,556✔
1808
                r = serialize_item_format(f, "exec-context-bpf-delegate-commands", "0x%"PRIx64, c->bpf_delegate_commands);
×
1809
                if (r < 0)
×
1810
                        return r;
1811
        }
1812

1813
        if (c->bpf_delegate_maps != 0) {
2,556✔
1814
                r = serialize_item_format(f, "exec-context-bpf-delegate-maps", "0x%"PRIx64, c->bpf_delegate_maps);
×
1815
                if (r < 0)
×
1816
                        return r;
1817
        }
1818

1819
        if (c->bpf_delegate_programs != 0) {
2,556✔
1820
                r = serialize_item_format(f, "exec-context-bpf-delegate-programs", "0x%"PRIx64, c->bpf_delegate_programs);
×
1821
                if (r < 0)
×
1822
                        return r;
1823
        }
1824

1825
        if (c->bpf_delegate_attachments != 0) {
2,556✔
1826
                r = serialize_item_format(f, "exec-context-bpf-delegate-attachments", "0x%"PRIx64, c->bpf_delegate_attachments);
×
1827
                if (r < 0)
×
1828
                        return r;
1829
        }
1830

1831
        r = serialize_item(f, "exec-context-runtime-directory-preserve-mode", exec_preserve_mode_to_string(c->runtime_directory_preserve_mode));
2,556✔
1832
        if (r < 0)
2,556✔
1833
                return r;
1834

1835
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
15,336✔
1836
                _cleanup_free_ char *key = NULL, *value = NULL;
12,780✔
1837

1838
                key = strjoin("exec-context-directories-", exec_directory_type_to_string(dt));
12,780✔
1839
                if (!key)
12,780✔
1840
                        return log_oom_debug();
×
1841

1842
                if (asprintf(&value, "%04o", c->directories[dt].mode) < 0)
12,780✔
1843
                        return log_oom_debug();
×
1844

1845
                FOREACH_ARRAY(i, c->directories[dt].items, c->directories[dt].n_items) {
13,211✔
1846
                        _cleanup_free_ char *path_escaped = NULL;
431✔
1847

1848
                        path_escaped = shell_escape(i->path, ":" WHITESPACE);
431✔
1849
                        if (!path_escaped)
431✔
1850
                                return log_oom_debug();
×
1851

1852
                        if (!strextend(&value, " ", path_escaped))
431✔
1853
                                return log_oom_debug();
×
1854

1855
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE))))
857✔
1856
                                return log_oom_debug();
×
1857

1858
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_READ_ONLY))))
860✔
1859
                                return log_oom_debug();
×
1860

1861
                        STRV_FOREACH(d, i->symlinks) {
437✔
1862
                                _cleanup_free_ char *link_escaped = NULL;
6✔
1863

1864
                                link_escaped = shell_escape(*d, ":" WHITESPACE);
6✔
1865
                                if (!link_escaped)
6✔
1866
                                        return log_oom_debug();
×
1867

1868
                                if (!strextend(&value, ":", link_escaped))
6✔
1869
                                        return log_oom_debug();
×
1870
                        }
1871
                }
1872

1873
                r = serialize_item(f, key, value);
12,780✔
1874
                if (r < 0)
12,780✔
1875
                        return r;
1876

1877
                if (c->directories[dt].exec_quota.quota_enforce) {
12,780✔
1878
                        _cleanup_free_ char *key_quota = NULL;
×
1879
                        key_quota = strjoin("exec-context-quota-directories-", exec_directory_type_to_string(dt));
×
1880
                        if (!key_quota)
×
1881
                                return log_oom_debug();
×
1882

1883
                        r = serialize_item_format(f, key_quota, "%" PRIu64 " %" PRIu32, c->directories[dt].exec_quota.quota_absolute,
×
1884
                                                                                        c->directories[dt].exec_quota.quota_scale);
×
1885
                        if (r < 0)
×
1886
                                return r;
1887

1888
                } else if (c->directories[dt].exec_quota.quota_accounting) {
12,780✔
1889
                        _cleanup_free_ char *key_quota = NULL;
×
1890
                        key_quota = strjoin("exec-context-quota-accounting-directories-", exec_directory_type_to_string(dt));
×
1891
                        if (!key_quota)
×
1892
                                return log_oom_debug();
×
1893

1894
                        r = serialize_bool(f, key_quota, c->directories[dt].exec_quota.quota_accounting);
×
1895
                        if (r < 0)
×
1896
                                return r;
1897
                }
1898
        }
1899

1900
        r = serialize_usec(f, "exec-context-timeout-clean-usec", c->timeout_clean_usec);
2,556✔
1901
        if (r < 0)
2,556✔
1902
                return r;
1903

1904
        if (c->nice_set) {
2,556✔
1905
                r = serialize_item_format(f, "exec-context-nice", "%i", c->nice);
3✔
1906
                if (r < 0)
3✔
1907
                        return r;
1908
        }
1909

1910
        if (c->oom_score_adjust_set) {
2,556✔
1911
                r = serialize_item_format(f, "exec-context-oom-score-adjust", "%i", c->oom_score_adjust);
604✔
1912
                if (r < 0)
604✔
1913
                        return r;
1914
        }
1915

1916
        if (c->coredump_filter_set) {
2,556✔
1917
                r = serialize_item_format(f, "exec-context-coredump-filter", "%"PRIx64, c->coredump_filter);
×
1918
                if (r < 0)
×
1919
                        return r;
1920
        }
1921

1922
        for (unsigned i = 0; i < RLIM_NLIMITS; i++) {
43,452✔
1923
                _cleanup_free_ char *key = NULL, *limit = NULL;
5,106✔
1924

1925
                if (!c->rlimit[i])
40,896✔
1926
                        continue;
35,790✔
1927

1928
                key = strjoin("exec-context-limit-", rlimit_to_string(i));
5,106✔
1929
                if (!key)
5,106✔
1930
                        return log_oom_debug();
×
1931

1932
                r = rlimit_format(c->rlimit[i], &limit);
5,106✔
1933
                if (r < 0)
5,106✔
1934
                        return r;
1935

1936
                r = serialize_item(f, key, limit);
5,106✔
1937
                if (r < 0)
5,106✔
1938
                        return r;
1939
        }
1940

1941
        if (c->ioprio_is_set) {
2,556✔
1942
                r = serialize_item_format(f, "exec-context-ioprio", "%d", c->ioprio);
5✔
1943
                if (r < 0)
5✔
1944
                        return r;
1945
        }
1946

1947
        if (c->cpu_sched_set) {
2,556✔
1948
                _cleanup_free_ char *policy_str = NULL;
×
1949

1950
                r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
×
1951
                if (r < 0)
×
1952
                        return r;
1953

1954
                r = serialize_item(f, "exec-context-cpu-scheduling-policy", policy_str);
×
1955
                if (r < 0)
×
1956
                        return r;
1957

1958
                r = serialize_item_format(f, "exec-context-cpu-scheduling-priority", "%i", c->cpu_sched_priority);
×
1959
                if (r < 0)
×
1960
                        return r;
1961

1962
                r = serialize_bool_elide(f, "exec-context-cpu-scheduling-reset-on-fork", c->cpu_sched_reset_on_fork);
×
1963
                if (r < 0)
×
1964
                        return r;
1965
        }
1966

1967
        if (c->cpu_set.set) {
2,556✔
1968
                _cleanup_free_ char *affinity = NULL;
×
1969

1970
                affinity = cpu_set_to_range_string(&c->cpu_set);
×
1971
                if (!affinity)
×
1972
                        return log_oom_debug();
×
1973

1974
                r = serialize_item(f, "exec-context-cpu-affinity", affinity);
×
1975
                if (r < 0)
×
1976
                        return r;
1977
        }
1978

1979
        if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) {
2,556✔
1980
                _cleanup_free_ char *nodes = NULL;
×
1981

1982
                nodes = cpu_set_to_range_string(&c->numa_policy.nodes);
×
1983
                if (!nodes)
×
1984
                        return log_oom_debug();
×
1985

1986
                if (nodes) {
×
1987
                        r = serialize_item(f, "exec-context-numa-mask", nodes);
×
1988
                        if (r < 0)
×
1989
                                return r;
1990
                }
1991

1992
                r = serialize_item_format(f, "exec-context-numa-policy", "%d", c->numa_policy.type);
×
1993
                if (r < 0)
×
1994
                        return r;
1995
        }
1996

1997
        r = serialize_bool_elide(f, "exec-context-cpu-affinity-from-numa", c->cpu_affinity_from_numa);
2,556✔
1998
        if (r < 0)
2,556✔
1999
                return r;
2000

2001
        if (c->timer_slack_nsec != NSEC_INFINITY) {
2,556✔
2002
                r = serialize_item_format(f, "exec-context-timer-slack-nsec", NSEC_FMT, c->timer_slack_nsec);
×
2003
                if (r < 0)
×
2004
                        return r;
2005
        }
2006

2007
        r = serialize_item(f, "exec-context-std-input", exec_input_to_string(c->std_input));
2,556✔
2008
        if (r < 0)
2,556✔
2009
                return r;
2010

2011
        r = serialize_item(f, "exec-context-std-output", exec_output_to_string(c->std_output));
2,556✔
2012
        if (r < 0)
2,556✔
2013
                return r;
2014

2015
        r = serialize_item(f, "exec-context-std-error", exec_output_to_string(c->std_error));
2,556✔
2016
        if (r < 0)
2,556✔
2017
                return r;
2018

2019
        r = serialize_bool_elide(f, "exec-context-stdio-as-fds", c->stdio_as_fds);
2,556✔
2020
        if (r < 0)
2,556✔
2021
                return r;
2022

2023
        r = serialize_bool_elide(f, "exec-context-root-directory-as-fd", c->root_directory_as_fd);
2,556✔
2024
        if (r < 0)
2,556✔
2025
                return r;
2026

2027
        switch (c->std_input) {
2,556✔
2028
        case EXEC_INPUT_NAMED_FD:
×
2029
                r = serialize_item(f, "exec-context-std-input-fd-name", c->stdio_fdname[STDIN_FILENO]);
×
2030
                if (r < 0)
×
2031
                        return r;
2032
                break;
2033

2034
        case EXEC_INPUT_FILE:
×
2035
                r = serialize_item(f, "exec-context-std-input-file", c->stdio_file[STDIN_FILENO]);
×
2036
                if (r < 0)
×
2037
                        return r;
2038
                break;
2039

2040
        default:
2,556✔
2041
                ;
2,556✔
2042
        }
2043

2044
        r = serialize_std_out_err(c, f, STDOUT_FILENO);
2,556✔
2045
        if (r < 0)
2,556✔
2046
                return r;
2047

2048
        r = serialize_std_out_err(c, f, STDERR_FILENO);
2,556✔
2049
        if (r < 0)
2,556✔
2050
                return r;
2051

2052
        r = serialize_item_base64mem(f, "exec-context-stdin-data", c->stdin_data, c->stdin_data_size);
2,556✔
2053
        if (r < 0)
2,556✔
2054
                return r;
2055

2056
        r = serialize_item(f, "exec-context-tty-path", c->tty_path);
2,556✔
2057
        if (r < 0)
2,556✔
2058
                return r;
2059

2060
        r = serialize_bool_elide(f, "exec-context-tty-reset", c->tty_reset);
2,556✔
2061
        if (r < 0)
2,556✔
2062
                return r;
2063

2064
        r = serialize_bool_elide(f, "exec-context-tty-vhangup", c->tty_vhangup);
2,556✔
2065
        if (r < 0)
2,556✔
2066
                return r;
2067

2068
        r = serialize_bool_elide(f, "exec-context-tty-vt-disallocate", c->tty_vt_disallocate);
2,556✔
2069
        if (r < 0)
2,556✔
2070
                return r;
2071

2072
        r = serialize_item_format(f, "exec-context-tty-rows", "%u", c->tty_rows);
2,556✔
2073
        if (r < 0)
2,556✔
2074
                return r;
2075

2076
        r = serialize_item_format(f, "exec-context-tty-columns", "%u", c->tty_cols);
2,556✔
2077
        if (r < 0)
2,556✔
2078
                return r;
2079

2080
        r = serialize_item_format(f, "exec-context-syslog-priority", "%i", c->syslog_priority);
2,556✔
2081
        if (r < 0)
2,556✔
2082
                return r;
2083

2084
        r = serialize_bool(f, "exec-context-syslog-level-prefix", c->syslog_level_prefix);
2,556✔
2085
        if (r < 0)
2,556✔
2086
                return r;
2087

2088
        r = serialize_item(f, "exec-context-syslog-identifier", c->syslog_identifier);
2,556✔
2089
        if (r < 0)
2,556✔
2090
                return r;
2091

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

2098
        if (c->log_ratelimit.interval > 0) {
2,556✔
2099
                r = serialize_usec(f, "exec-context-log-ratelimit-interval-usec", c->log_ratelimit.interval);
×
2100
                if (r < 0)
×
2101
                        return r;
2102
        }
2103

2104
        if (c->log_ratelimit.burst > 0) {
2,556✔
2105
                r = serialize_item_format(f, "exec-context-log-ratelimit-burst", "%u", c->log_ratelimit.burst);
×
2106
                if (r < 0)
×
2107
                        return r;
2108
        }
2109

2110
        r = serialize_string_set(f, "exec-context-log-filter-allowed-patterns", c->log_filter_allowed_patterns);
2,556✔
2111
        if (r < 0)
2,556✔
2112
                return r;
2113

2114
        r = serialize_string_set(f, "exec-context-log-filter-denied-patterns", c->log_filter_denied_patterns);
2,556✔
2115
        if (r < 0)
2,556✔
2116
                return r;
2117

2118
        FOREACH_ARRAY(field, c->log_extra_fields, c->n_log_extra_fields) {
2,797✔
2119
                r = serialize_item(f, "exec-context-log-extra-fields", field->iov_base);
241✔
2120
                if (r < 0)
241✔
2121
                        return r;
2122
        }
2123

2124
        r = serialize_item(f, "exec-context-log-namespace", c->log_namespace);
2,556✔
2125
        if (r < 0)
2,556✔
2126
                return r;
2127

2128
        if (c->secure_bits != 0) {
2,556✔
2129
                r = serialize_item_format(f, "exec-context-secure-bits", "%d", c->secure_bits);
×
2130
                if (r < 0)
×
2131
                        return r;
2132
        }
2133

2134
        if (c->capability_bounding_set != CAP_MASK_UNSET) {
2,556✔
2135
                r = serialize_item_format(f, "exec-context-capability-bounding-set", "%" PRIu64, c->capability_bounding_set);
2,556✔
2136
                if (r < 0)
2,556✔
2137
                        return r;
2138
        }
2139

2140
        if (c->capability_ambient_set != 0) {
2,556✔
2141
                r = serialize_item_format(f, "exec-context-capability-ambient-set", "%" PRIu64, c->capability_ambient_set);
72✔
2142
                if (r < 0)
72✔
2143
                        return r;
2144
        }
2145

2146
        if (c->user) {
2,556✔
2147
                r = serialize_item(f, "exec-context-user", c->user);
202✔
2148
                if (r < 0)
202✔
2149
                        return r;
2150
        }
2151

2152
        r = serialize_item(f, "exec-context-group", c->group);
2,556✔
2153
        if (r < 0)
2,556✔
2154
                return r;
2155

2156
        r = serialize_bool_elide(f, "exec-context-dynamic-user", c->dynamic_user);
2,556✔
2157
        if (r < 0)
2,556✔
2158
                return r;
2159

2160
        r = serialize_strv(f, "exec-context-supplementary-groups", c->supplementary_groups);
2,556✔
2161
        if (r < 0)
2,556✔
2162
                return r;
2163

2164
        r = serialize_item_tristate(f, "exec-context-set-login-environment", c->set_login_environment);
2,556✔
2165
        if (r < 0)
×
2166
                return r;
2167

2168
        r = serialize_item(f, "exec-context-pam-name", c->pam_name);
2,556✔
2169
        if (r < 0)
2,556✔
2170
                return r;
2171

2172
        r = serialize_strv(f, "exec-context-read-write-paths", c->read_write_paths);
2,556✔
2173
        if (r < 0)
2,556✔
2174
                return r;
2175

2176
        r = serialize_strv(f, "exec-context-read-only-paths", c->read_only_paths);
2,556✔
2177
        if (r < 0)
2,556✔
2178
                return r;
2179

2180
        r = serialize_strv(f, "exec-context-inaccessible-paths", c->inaccessible_paths);
2,556✔
2181
        if (r < 0)
2,556✔
2182
                return r;
2183

2184
        r = serialize_strv(f, "exec-context-exec-paths", c->exec_paths);
2,556✔
2185
        if (r < 0)
2,556✔
2186
                return r;
2187

2188
        r = serialize_strv(f, "exec-context-no-exec-paths", c->no_exec_paths);
2,556✔
2189
        if (r < 0)
2,556✔
2190
                return r;
2191

2192
        r = serialize_strv(f, "exec-context-exec-search-path", c->exec_search_path);
2,556✔
2193
        if (r < 0)
2,556✔
2194
                return r;
2195

2196
        r = serialize_item_format(f, "exec-context-mount-propagation-flag", "%lu", c->mount_propagation_flag);
2,556✔
2197
        if (r < 0)
2,556✔
2198
                return r;
2199

2200
        FOREACH_ARRAY(mount, c->bind_mounts, c->n_bind_mounts) {
2,571✔
2201
                _cleanup_free_ char *src_escaped = NULL, *dst_escaped = NULL;
15✔
2202

2203
                src_escaped = shell_escape(mount->source, ":" WHITESPACE);
15✔
2204
                if (!src_escaped)
15✔
2205
                        return log_oom_debug();
×
2206

2207
                dst_escaped = shell_escape(mount->destination, ":" WHITESPACE);
15✔
2208
                if (!dst_escaped)
15✔
2209
                        return log_oom_debug();
×
2210

2211
                r = serialize_item_format(f,
15✔
2212
                                          mount->read_only ? "exec-context-bind-read-only-path" : "exec-context-bind-path",
15✔
2213
                                          "%s%s:%s:%s",
2214
                                          mount->ignore_enoent ? "-" : "",
15✔
2215
                                          src_escaped,
2216
                                          dst_escaped,
2217
                                          mount->recursive ? "rbind" : "norbind");
15✔
2218
                if (r < 0)
15✔
2219
                        return r;
2220
        }
2221

2222
        FOREACH_ARRAY(tmpfs, c->temporary_filesystems, c->n_temporary_filesystems) {
2,560✔
2223
                _cleanup_free_ char *escaped = NULL;
4✔
2224

2225
                if (!isempty(tmpfs->options)) {
4✔
2226
                        escaped = shell_escape(tmpfs->options, ":");
×
2227
                        if (!escaped)
×
2228
                                return log_oom_debug();
×
2229
                }
2230

2231
                r = serialize_item_format(f, "exec-context-temporary-filesystems", "%s%s%s",
×
2232
                                          tmpfs->path,
2233
                                          isempty(escaped) ? "" : ":",
4✔
2234
                                          strempty(escaped));
2235
                if (r < 0)
4✔
2236
                        return r;
2237
        }
2238

2239
        r = serialize_item(f, "exec-context-utmp-id", c->utmp_id);
2,556✔
2240
        if (r < 0)
2,556✔
2241
                return r;
2242

2243
        r = serialize_item(f, "exec-context-utmp-mode", exec_utmp_mode_to_string(c->utmp_mode));
2,556✔
2244
        if (r < 0)
2,556✔
2245
                return r;
2246

2247
        r = serialize_bool_elide(f, "exec-context-no-new-privileges", c->no_new_privileges);
2,556✔
2248
        if (r < 0)
2,556✔
2249
                return r;
2250

2251
        if (c->selinux_context) {
2,556✔
2252
                r = serialize_item_format(f, "exec-context-selinux-context",
×
2253
                                          "%s%s",
2254
                                          c->selinux_context_ignore ? "-" : "",
×
2255
                                          c->selinux_context);
2256
                if (r < 0)
×
2257
                        return r;
2258
        }
2259

2260
        if (c->apparmor_profile) {
2,556✔
2261
                r = serialize_item_format(f, "exec-context-apparmor-profile",
×
2262
                                          "%s%s",
2263
                                          c->apparmor_profile_ignore ? "-" : "",
×
2264
                                          c->apparmor_profile);
2265
                if (r < 0)
×
2266
                        return r;
2267
        }
2268

2269
        if (c->smack_process_label) {
2,556✔
2270
                r = serialize_item_format(f, "exec-context-smack-process-label",
×
2271
                                          "%s%s",
2272
                                          c->smack_process_label_ignore ? "-" : "",
×
2273
                                          c->smack_process_label);
2274
                if (r < 0)
×
2275
                        return r;
2276
        }
2277

2278
        if (c->personality != PERSONALITY_INVALID) {
2,556✔
2279
                r = serialize_item(f, "exec-context-personality", personality_to_string(c->personality));
×
2280
                if (r < 0)
×
2281
                        return r;
2282
        }
2283

2284
        r = serialize_bool_elide(f, "exec-context-lock-personality", c->lock_personality);
2,556✔
2285
        if (r < 0)
2,556✔
2286
                return r;
2287

2288
#if HAVE_SECCOMP
2289
        if (!hashmap_isempty(c->syscall_filter)) {
2,556✔
2290
                void *errno_num, *id;
246✔
2291
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_filter) {
94,493✔
2292
                        r = serialize_item_format(f, "exec-context-syscall-filter", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
94,247✔
2293
                        if (r < 0)
94,247✔
2294
                                return r;
×
2295
                }
2296
        }
2297

2298
        if (!set_isempty(c->syscall_archs)) {
2,556✔
2299
                void *id;
242✔
2300
                SET_FOREACH(id, c->syscall_archs) {
484✔
2301
                        r = serialize_item_format(f, "exec-context-syscall-archs", "%u", PTR_TO_UINT(id) - 1);
242✔
2302
                        if (r < 0)
242✔
2303
                                return r;
×
2304
                }
2305
        }
2306

2307
        if (c->syscall_errno > 0) {
2,556✔
2308
                r = serialize_item_format(f, "exec-context-syscall-errno", "%d", c->syscall_errno);
2,556✔
2309
                if (r < 0)
2,556✔
2310
                        return r;
2311
        }
2312

2313
        r = serialize_bool_elide(f, "exec-context-syscall-allow-list", c->syscall_allow_list);
2,556✔
2314
        if (r < 0)
2,556✔
2315
                return r;
2316

2317
        if (!hashmap_isempty(c->syscall_log)) {
2,556✔
2318
                void *errno_num, *id;
×
2319
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_log) {
×
2320
                        r = serialize_item_format(f, "exec-context-syscall-log", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
×
2321
                        if (r < 0)
×
2322
                                return r;
×
2323
                }
2324
        }
2325

2326
        r = serialize_bool_elide(f, "exec-context-syscall-log-allow-list", c->syscall_log_allow_list);
2,556✔
2327
        if (r < 0)
2,556✔
2328
                return r;
2329
#endif
2330

2331
        if (c->restrict_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,556✔
2332
                r = serialize_item_format(f, "exec-context-restrict-namespaces", "%lu", c->restrict_namespaces);
187✔
2333
                if (r < 0)
187✔
2334
                        return r;
2335
        }
2336

2337
        if (c->delegate_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,556✔
2338
                r = serialize_item_format(f, "exec-context-delegate-namespaces", "%lu", c->delegate_namespaces);
9✔
2339
                if (r < 0)
9✔
2340
                        return r;
2341
        }
2342

2343
#if HAVE_LIBBPF
2344
        if (exec_context_restrict_filesystems_set(c)) {
2,556✔
2345
                char *fs;
×
2346
                SET_FOREACH(fs, c->restrict_filesystems) {
×
2347
                        r = serialize_item(f, "exec-context-restrict-filesystems", fs);
×
2348
                        if (r < 0)
×
2349
                                return r;
×
2350
                }
2351
        }
2352

2353
        r = serialize_bool_elide(f, "exec-context-restrict-filesystems-allow-list", c->restrict_filesystems_allow_list);
2,556✔
2354
        if (r < 0)
2,556✔
2355
                return r;
2356
#endif
2357

2358
        if (!set_isempty(c->address_families)) {
2,556✔
2359
                void *afp;
242✔
2360

2361
                SET_FOREACH(afp, c->address_families) {
1,181✔
2362
                        int af = PTR_TO_INT(afp);
939✔
2363

2364
                        if (af <= 0 || af >= af_max())
939✔
2365
                                continue;
×
2366

2367
                        r = serialize_item_format(f, "exec-context-address-families", "%d", af);
939✔
2368
                        if (r < 0)
939✔
2369
                                return r;
×
2370
                }
2371
        }
2372

2373
        r = serialize_bool_elide(f, "exec-context-address-families-allow-list", c->address_families_allow_list);
2,556✔
2374
        if (r < 0)
2,556✔
2375
                return r;
2376

2377
        r = serialize_item(f, "exec-context-user-namespace-path", c->user_namespace_path);
2,556✔
2378
        if (r < 0)
2,556✔
2379
                return r;
2380

2381
        r = serialize_item(f, "exec-context-network-namespace-path", c->network_namespace_path);
2,556✔
2382
        if (r < 0)
2,556✔
2383
                return r;
2384

2385
        r = serialize_item(f, "exec-context-ipc-namespace-path", c->ipc_namespace_path);
2,556✔
2386
        if (r < 0)
2,556✔
2387
                return r;
2388

2389
        FOREACH_ARRAY(mount, c->mount_images, c->n_mount_images) {
2,556✔
2390
                _cleanup_free_ char *s = NULL, *source_escaped = NULL, *dest_escaped = NULL;
×
2391

2392
                source_escaped = shell_escape(mount->source, WHITESPACE);
×
2393
                if (!source_escaped)
×
2394
                        return log_oom_debug();
×
2395

2396
                dest_escaped = shell_escape(mount->destination, WHITESPACE);
×
2397
                if (!dest_escaped)
×
2398
                        return log_oom_debug();
×
2399

2400
                s = strjoin(mount->ignore_enoent ? "-" : "",
×
2401
                            source_escaped,
2402
                            " ",
2403
                            dest_escaped);
2404
                if (!s)
×
2405
                        return log_oom_debug();
×
2406

2407
                LIST_FOREACH(mount_options, o, mount->mount_options) {
×
2408
                        _cleanup_free_ char *escaped = NULL;
×
2409

2410
                        if (isempty(o->options))
×
2411
                                continue;
×
2412

2413
                        escaped = shell_escape(o->options, ":");
×
2414
                        if (!escaped)
×
2415
                                return log_oom_debug();
×
2416

2417
                        if (!strextend(&s,
×
2418
                                       " ",
2419
                                       partition_designator_to_string(o->partition_designator),
2420
                                       ":",
2421
                                       escaped))
2422
                                return log_oom_debug();
×
2423
                }
2424

2425
                r = serialize_item(f, "exec-context-mount-image", s);
×
2426
                if (r < 0)
×
2427
                        return r;
2428
        }
2429

2430
        FOREACH_ARRAY(mount, c->extension_images, c->n_extension_images) {
2,561✔
2431
                _cleanup_free_ char *s = NULL, *source_escaped = NULL;
5✔
2432

2433
                source_escaped = shell_escape(mount->source, ":" WHITESPACE);
5✔
2434
                if (!source_escaped)
5✔
2435
                        return log_oom_debug();
×
2436

2437
                s = strjoin(mount->ignore_enoent ? "-" : "",
10✔
2438
                            source_escaped);
2439
                if (!s)
5✔
2440
                        return log_oom_debug();
×
2441

2442
                LIST_FOREACH(mount_options, o, mount->mount_options) {
5✔
2443
                        _cleanup_free_ char *escaped = NULL;
×
2444

2445
                        if (isempty(o->options))
×
2446
                                continue;
×
2447

2448
                        escaped = shell_escape(o->options, ":");
×
2449
                        if (!escaped)
×
2450
                                return log_oom_debug();
×
2451

2452
                        if (!strextend(&s,
×
2453
                                       " ",
2454
                                       partition_designator_to_string(o->partition_designator),
2455
                                       ":",
2456
                                       escaped))
2457
                                return log_oom_debug();
×
2458
                }
2459

2460
                r = serialize_item(f, "exec-context-extension-image", s);
5✔
2461
                if (r < 0)
5✔
2462
                        return r;
2463
        }
2464

2465
        r = serialize_strv(f, "exec-context-extension-directories", c->extension_directories);
2,556✔
2466
        if (r < 0)
2,556✔
2467
                return r;
2468

2469
        ExecSetCredential *sc;
2,556✔
2470
        HASHMAP_FOREACH(sc, c->set_credentials) {
2,562✔
2471
                _cleanup_free_ char *data = NULL;
6✔
2472

2473
                if (base64mem(sc->data, sc->size, &data) < 0)
6✔
2474
                        return log_oom_debug();
×
2475

2476
                r = serialize_item_format(f, "exec-context-set-credentials", "%s %s %s", sc->id, data, yes_no(sc->encrypted));
12✔
2477
                if (r < 0)
6✔
2478
                        return r;
2479
        }
2480

2481
        ExecLoadCredential *lc;
2,556✔
2482
        HASHMAP_FOREACH(lc, c->load_credentials) {
2,567✔
2483
                r = serialize_item_format(f, "exec-context-load-credentials", "%s %s %s", lc->id, lc->path, yes_no(lc->encrypted));
21✔
2484
                if (r < 0)
11✔
2485
                        return r;
×
2486
        }
2487

2488
        ExecImportCredential *ic;
2,556✔
2489
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
3,582✔
2490
                r = serialize_item_format(f, "exec-context-import-credentials", "%s%s%s",
2,000✔
2491
                                          ic->glob,
2492
                                          ic->rename ? " " : "",
2493
                                          strempty(ic->rename));
1,026✔
2494
                if (r < 0)
1,026✔
2495
                        return r;
×
2496
        }
2497

2498
        r = serialize_image_policy(f, "exec-context-root-image-policy", c->root_image_policy);
2,556✔
2499
        if (r < 0)
2,556✔
2500
                return r;
2501

2502
        r = serialize_image_policy(f, "exec-context-mount-image-policy", c->mount_image_policy);
2,556✔
2503
        if (r < 0)
2,556✔
2504
                return r;
2505

2506
        r = serialize_image_policy(f, "exec-context-extension-image-policy", c->extension_image_policy);
2,556✔
2507
        if (r < 0)
2,556✔
2508
                return r;
2509

2510
        fputc('\n', f); /* End marker */
2,556✔
2511

2512
        return 0;
2513
}
2514

2515
static int exec_context_deserialize(ExecContext *c, FILE *f) {
10,226✔
2516
        int r;
10,226✔
2517

2518
        assert(f);
10,226✔
2519

2520
        if (!c)
10,226✔
2521
                return 0;
2522

2523
        for (;;) {
976,109✔
2524
                _cleanup_free_ char *l = NULL;
965,883✔
2525
                const char *val;
976,109✔
2526

2527
                r = deserialize_read_line(f, &l);
976,109✔
2528
                if (r < 0)
976,109✔
2529
                        return r;
2530
                if (r == 0) /* eof or end marker */
976,109✔
2531
                        break;
2532

2533
                if ((val = startswith(l, "exec-context-environment="))) {
965,883✔
2534
                        r = deserialize_strv(val, &c->environment);
3,519✔
2535
                        if (r < 0)
3,519✔
2536
                                return r;
2537
                } else if ((val = startswith(l, "exec-context-environment-files="))) {
962,364✔
2538
                        r = deserialize_strv(val, &c->environment_files);
344✔
2539
                        if (r < 0)
344✔
2540
                                return r;
2541
                } else if ((val = startswith(l, "exec-context-pass-environment="))) {
962,020✔
2542
                        r = deserialize_strv(val, &c->pass_environment);
320✔
2543
                        if (r < 0)
320✔
2544
                                return r;
2545
                } else if ((val = startswith(l, "exec-context-unset-environment="))) {
961,700✔
2546
                        r = deserialize_strv(val, &c->unset_environment);
988✔
2547
                        if (r < 0)
988✔
2548
                                return r;
2549
                } else if ((val = startswith(l, "exec-context-working-directory="))) {
960,712✔
2550
                        ssize_t k;
755✔
2551
                        char *p;
755✔
2552

2553
                        k = cunescape(val, 0, &p);
755✔
2554
                        if (k < 0)
755✔
2555
                                return k;
×
2556
                        free_and_replace(c->working_directory, p);
755✔
2557
                } else if ((val = startswith(l, "exec-context-root-directory="))) {
959,957✔
2558
                        ssize_t k;
7✔
2559
                        char *p;
7✔
2560

2561
                        k = cunescape(val, 0, &p);
7✔
2562
                        if (k < 0)
7✔
2563
                                return k;
×
2564
                        free_and_replace(c->root_directory, p);
7✔
2565
                } else if ((val = startswith(l, "exec-context-root-image="))) {
959,950✔
2566
                        ssize_t k;
9✔
2567
                        char *p;
9✔
2568

2569
                        k = cunescape(val, 0, &p);
9✔
2570
                        if (k < 0)
9✔
2571
                                return k;
×
2572
                        free_and_replace(c->root_image, p);
9✔
2573
                } else if ((val = startswith(l, "exec-context-root-image-options="))) {
959,941✔
2574
                        for (;;) {
×
2575
                                _cleanup_free_ char *word = NULL, *mount_options = NULL, *partition = NULL;
×
2576
                                PartitionDesignator partition_designator;
×
2577
                                MountOptions *o = NULL;
×
2578
                                const char *p;
×
2579

2580
                                r = extract_first_word(&val, &word, NULL, 0);
×
2581
                                if (r < 0)
×
2582
                                        return r;
2583
                                if (r == 0)
×
2584
                                        break;
2585

2586
                                p = word;
×
2587
                                r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options);
×
2588
                                if (r < 0)
×
2589
                                        return r;
2590
                                if (r == 0)
×
2591
                                        continue;
×
2592

2593
                                partition_designator = partition_designator_from_string(partition);
×
2594
                                if (partition_designator < 0)
×
2595
                                        return -EINVAL;
2596

2597
                                o = new(MountOptions, 1);
×
2598
                                if (!o)
×
2599
                                        return log_oom_debug();
×
2600
                                *o = (MountOptions) {
×
2601
                                        .partition_designator = partition_designator,
2602
                                        .options = TAKE_PTR(mount_options),
×
2603
                                };
2604
                                LIST_APPEND(mount_options, c->root_image_options, o);
×
2605
                        }
2606
                } else if ((val = startswith(l, "exec-context-root-verity="))) {
959,941✔
2607
                        r = free_and_strdup(&c->root_verity, val);
×
2608
                        if (r < 0)
×
2609
                                return r;
2610
                } else if ((val = startswith(l, "exec-context-root-hash-path="))) {
959,941✔
2611
                        r = free_and_strdup(&c->root_hash_path, val);
×
2612
                        if (r < 0)
×
2613
                                return r;
2614
                } else if ((val = startswith(l, "exec-context-root-hash-sig-path="))) {
959,941✔
2615
                        r = free_and_strdup(&c->root_hash_sig_path, val);
×
2616
                        if (r < 0)
×
2617
                                return r;
2618
                } else if ((val = startswith(l, "exec-context-root-hash="))) {
959,941✔
2619
                        iovec_done(&c->root_hash);
4✔
2620
                        r = unhexmem(val, &c->root_hash.iov_base, &c->root_hash.iov_len);
4✔
2621
                        if (r < 0)
4✔
2622
                                return r;
2623
                } else if ((val = startswith(l, "exec-context-root-hash-sig="))) {
959,937✔
2624
                        iovec_done(&c->root_hash_sig);
×
2625
                        r = unbase64mem(val, &c->root_hash_sig.iov_base, &c->root_hash_sig.iov_len);
×
2626
                        if (r < 0)
×
2627
                                return r;
2628
                } else if ((val = startswith(l, "exec-context-root-ephemeral="))) {
959,937✔
2629
                        r = parse_boolean(val);
×
2630
                        if (r < 0)
×
2631
                                return r;
2632
                        c->root_ephemeral = r;
×
2633
                } else if ((val = startswith(l, "exec-context-umask="))) {
959,937✔
2634
                        r = parse_mode(val, &c->umask);
10,226✔
2635
                        if (r < 0)
10,226✔
2636
                                return r;
2637
                } else if ((val = startswith(l, "exec-context-private-non-blocking="))) {
949,711✔
2638
                        r = parse_boolean(val);
×
2639
                        if (r < 0)
×
2640
                                return r;
2641
                        c->non_blocking = r;
×
2642
                } else if ((val = startswith(l, "exec-context-private-mounts="))) {
949,711✔
2643
                        r = safe_atoi(val, &c->private_mounts);
144✔
2644
                        if (r < 0)
144✔
2645
                                return r;
2646
                } else if ((val = startswith(l, "exec-context-mount-api-vfs="))) {
949,567✔
2647
                        r = safe_atoi(val, &c->mount_apivfs);
29✔
2648
                        if (r < 0)
29✔
2649
                                return r;
2650
                } else if ((val = startswith(l, "exec-context-bind-log-sockets="))) {
949,538✔
2651
                        r = safe_atoi(val, &c->bind_log_sockets);
2✔
2652
                        if (r < 0)
2✔
2653
                                return r;
2654
                } else if ((val = startswith(l, "exec-context-memory-ksm="))) {
949,536✔
2655
                        r = safe_atoi(val, &c->memory_ksm);
×
2656
                        if (r < 0)
×
2657
                                return r;
2658
                } else if ((val = startswith(l, "exec-context-private-tmp="))) {
949,536✔
2659
                        c->private_tmp = private_tmp_from_string(val);
10,226✔
2660
                        if (c->private_tmp < 0)
10,226✔
2661
                                return c->private_tmp;
2662
                } else if ((val = startswith(l, "exec-context-private-var-tmp="))) {
939,310✔
2663
                        c->private_var_tmp = private_tmp_from_string(val);
10,226✔
2664
                        if (c->private_var_tmp < 0)
10,226✔
2665
                                return c->private_var_tmp;
2666
                } else if ((val = startswith(l, "exec-context-private-devices="))) {
929,084✔
2667
                        r = parse_boolean(val);
508✔
2668
                        if (r < 0)
508✔
2669
                                return r;
2670
                        c->private_devices = r;
508✔
2671
                } else if ((val = startswith(l, "exec-context-protect-kernel-tunables="))) {
928,576✔
2672
                        r = parse_boolean(val);
315✔
2673
                        if (r < 0)
315✔
2674
                                return r;
2675
                        c->protect_kernel_tunables = r;
315✔
2676
                } else if ((val = startswith(l, "exec-context-protect-kernel-modules="))) {
928,261✔
2677
                        r = parse_boolean(val);
1,119✔
2678
                        if (r < 0)
1,119✔
2679
                                return r;
2680
                        c->protect_kernel_modules = r;
1,119✔
2681
                } else if ((val = startswith(l, "exec-context-protect-kernel-logs="))) {
927,142✔
2682
                        r = parse_boolean(val);
1,119✔
2683
                        if (r < 0)
1,119✔
2684
                                return r;
2685
                        c->protect_kernel_logs = r;
1,119✔
2686
                } else if ((val = startswith(l, "exec-context-protect-clock="))) {
926,023✔
2687
                        r = parse_boolean(val);
909✔
2688
                        if (r < 0)
909✔
2689
                                return r;
2690
                        c->protect_clock = r;
909✔
2691
                } else if ((val = startswith(l, "exec-context-protect-control-groups="))) {
925,114✔
2692
                        r = protect_control_groups_from_string(val);
10,226✔
2693
                        if (r < 0)
10,226✔
2694
                                return r;
2695
                        c->protect_control_groups = r;
10,226✔
2696
                } else if ((val = startswith(l, "exec-context-private-network="))) {
914,888✔
2697
                        r = parse_boolean(val);
70✔
2698
                        if (r < 0)
70✔
2699
                                return r;
2700
                        c->private_network = r;
70✔
2701
                } else if ((val = startswith(l, "exec-context-private-users="))) {
914,818✔
2702
                        c->private_users = private_users_from_string(val);
10,226✔
2703
                        if (c->private_users < 0)
10,226✔
2704
                                return -EINVAL;
2705
                } else if ((val = startswith(l, "exec-context-private-ipc="))) {
904,592✔
2706
                        r = parse_boolean(val);
6✔
2707
                        if (r < 0)
6✔
2708
                                return r;
2709
                        c->private_ipc = r;
6✔
2710
                } else if ((val = startswith(l, "exec-context-private-pids="))) {
904,586✔
2711
                        c->private_pids = private_pids_from_string(val);
10,226✔
2712
                        if (c->private_pids < 0)
10,226✔
2713
                                return -EINVAL;
2714
                } else if ((val = startswith(l, "exec-context-remove-ipc="))) {
894,360✔
2715
                        r = parse_boolean(val);
55✔
2716
                        if (r < 0)
55✔
2717
                                return r;
2718
                        c->remove_ipc = r;
55✔
2719
                } else if ((val = startswith(l, "exec-context-protect-home="))) {
894,305✔
2720
                        c->protect_home = protect_home_from_string(val);
10,226✔
2721
                        if (c->protect_home < 0)
10,226✔
2722
                                return -EINVAL;
2723
                } else if ((val = startswith(l, "exec-context-protect-system="))) {
884,079✔
2724
                        c->protect_system = protect_system_from_string(val);
10,226✔
2725
                        if (c->protect_system < 0)
10,226✔
2726
                                return -EINVAL;
2727
                } else if ((val = startswith(l, "exec-context-same-pgrp="))) {
873,853✔
2728
                        r = parse_boolean(val);
886✔
2729
                        if (r < 0)
886✔
2730
                                return r;
2731
                        c->same_pgrp = r;
886✔
2732
                } else if ((val = startswith(l, "exec-context-non-blocking="))) {
872,967✔
2733
                        r = parse_boolean(val);
×
2734
                        if (r < 0)
×
2735
                                return r;
2736
                        c->non_blocking = r;
×
2737
                } else if ((val = startswith(l, "exec-context-ignore-sigpipe="))) {
872,967✔
2738
                        r = parse_boolean(val);
10,226✔
2739
                        if (r < 0)
10,226✔
2740
                                return r;
2741
                        c->ignore_sigpipe = r;
10,226✔
2742
                } else if ((val = startswith(l, "exec-context-memory-deny-write-execute="))) {
862,741✔
2743
                        r = parse_boolean(val);
1,491✔
2744
                        if (r < 0)
1,491✔
2745
                                return r;
2746
                        c->memory_deny_write_execute = r;
1,491✔
2747
                } else if ((val = startswith(l, "exec-context-restrict-realtime="))) {
861,250✔
2748
                        r = parse_boolean(val);
1,493✔
2749
                        if (r < 0)
1,493✔
2750
                                return r;
2751
                        c->restrict_realtime = r;
1,493✔
2752
                } else if ((val = startswith(l, "exec-context-restrict-suid-sgid="))) {
859,757✔
2753
                        r = parse_boolean(val);
1,395✔
2754
                        if (r < 0)
1,395✔
2755
                                return r;
2756
                        c->restrict_suid_sgid = r;
1,395✔
2757
                } else if ((val = startswith(l, "exec-context-keyring-mode="))) {
858,362✔
2758
                        c->keyring_mode = exec_keyring_mode_from_string(val);
10,226✔
2759
                        if (c->keyring_mode < 0)
10,226✔
2760
                                return -EINVAL;
2761
                } else if ((val = startswith(l, "exec-context-protect-hostname="))) {
848,136✔
2762
                        c->protect_hostname = protect_hostname_from_string(val);
10,226✔
2763
                        if (c->protect_hostname < 0)
10,226✔
2764
                                return -EINVAL;
2765
                } else if ((val = startswith(l, "exec-context-private-hostname="))) {
837,910✔
2766
                        r = free_and_strdup(&c->private_hostname, val);
5✔
2767
                        if (r < 0)
5✔
2768
                                return r;
2769
                } else if ((val = startswith(l, "exec-context-protect-proc="))) {
837,905✔
2770
                        c->protect_proc = protect_proc_from_string(val);
10,226✔
2771
                        if (c->protect_proc < 0)
10,226✔
2772
                                return -EINVAL;
2773
                } else if ((val = startswith(l, "exec-context-proc-subset="))) {
827,679✔
2774
                        c->proc_subset = proc_subset_from_string(val);
10,226✔
2775
                        if (c->proc_subset < 0)
10,226✔
2776
                                return -EINVAL;
2777
                } else if ((val = startswith(l, "exec-context-private-bpf="))) {
817,453✔
2778
                        c->private_bpf = private_bpf_from_string(val);
10,226✔
2779
                        if (c->private_bpf < 0)
10,226✔
2780
                                return -EINVAL;
2781
                } else if ((val = startswith(l, "exec-context-bpf-delegate-commands="))) {
807,227✔
2782
                        r = safe_atoux64(val, &c->bpf_delegate_commands);
2✔
2783
                        if (r < 0)
2✔
2784
                                return r;
2785
                } else if ((val = startswith(l, "exec-context-bpf-delegate-maps="))) {
807,225✔
2786
                        r = safe_atoux64(val, &c->bpf_delegate_maps);
1✔
2787
                        if (r < 0)
1✔
2788
                                return r;
2789
                } else if ((val = startswith(l, "exec-context-bpf-delegate-programs="))) {
807,224✔
2790
                        r = safe_atoux64(val, &c->bpf_delegate_programs);
1✔
2791
                        if (r < 0)
1✔
2792
                                return r;
2793
                } else if ((val = startswith(l, "exec-context-bpf-delegate-attachments="))) {
807,223✔
2794
                        r = safe_atoux64(val, &c->bpf_delegate_attachments);
1✔
2795
                        if (r < 0)
1✔
2796
                                return r;
2797
                } else if ((val = startswith(l, "exec-context-runtime-directory-preserve-mode="))) {
807,222✔
2798
                        c->runtime_directory_preserve_mode = exec_preserve_mode_from_string(val);
10,226✔
2799
                        if (c->runtime_directory_preserve_mode < 0)
10,226✔
2800
                                return -EINVAL;
2801
                } else if ((val = startswith(l, "exec-context-directories-"))) {
796,996✔
2802
                        _cleanup_free_ char *type = NULL, *mode = NULL;
×
2803
                        ExecDirectoryType dt;
51,130✔
2804

2805
                        r = extract_many_words(&val, "= ", 0, &type, &mode);
51,130✔
2806
                        if (r < 0)
51,130✔
2807
                                return r;
2808
                        if (r == 0 || !mode)
51,130✔
2809
                                return -EINVAL;
2810

2811
                        dt = exec_directory_type_from_string(type);
51,130✔
2812
                        if (dt < 0)
51,130✔
2813
                                return dt;
2814

2815
                        r = parse_mode(mode, &c->directories[dt].mode);
51,130✔
2816
                        if (r < 0)
51,130✔
2817
                                return r;
2818

2819
                        for (;;) {
54,091✔
2820
                                _cleanup_free_ char *tuple = NULL, *path = NULL, *only_create = NULL, *read_only = NULL;
53,984✔
2821
                                ExecDirectoryFlags exec_directory_flags = 0;
54,091✔
2822
                                const char *p;
54,091✔
2823

2824
                                /* Use EXTRACT_UNESCAPE_RELAX here, as we unescape the colons in subsequent calls */
2825
                                r = extract_first_word(&val, &tuple, WHITESPACE, EXTRACT_UNESCAPE_SEPARATORS|EXTRACT_UNESCAPE_RELAX);
54,091✔
2826
                                if (r < 0)
54,091✔
2827
                                        return r;
2828
                                if (r == 0)
54,091✔
2829
                                        break;
2830

2831
                                p = tuple;
2,961✔
2832
                                r = extract_many_words(&p, ":", EXTRACT_UNESCAPE_SEPARATORS, &path, &only_create, &read_only);
2,961✔
2833
                                if (r < 0)
2,961✔
2834
                                        return r;
2835
                                if (r < 2)
2,961✔
2836
                                        continue;
×
2837

2838
                                r = parse_boolean(only_create);
2,961✔
2839
                                if (r < 0)
2,961✔
2840
                                        return r;
2841
                                if (r > 0)
2,961✔
2842
                                        exec_directory_flags |= EXEC_DIRECTORY_ONLY_CREATE;
5✔
2843

2844
                                r = parse_boolean(read_only);
2,961✔
2845
                                if (r < 0)
2,961✔
2846
                                        return r;
2847
                                if (r > 0)
2,961✔
2848
                                        exec_directory_flags |= EXEC_DIRECTORY_READ_ONLY;
50✔
2849

2850
                                r = exec_directory_add(&c->directories[dt], path, /* symlink= */ NULL, exec_directory_flags);
2,961✔
2851
                                if (r < 0)
2,961✔
2852
                                        return r;
2853

2854
                                if (isempty(p))
2,961✔
2855
                                        continue;
2,854✔
2856

2857
                                for (;;) {
385✔
2858
                                        _cleanup_free_ char *link = NULL;
246✔
2859

2860
                                        r = extract_first_word(&p, &link, ":", EXTRACT_UNESCAPE_SEPARATORS);
246✔
2861
                                        if (r < 0)
246✔
2862
                                                return r;
2863
                                        if (r == 0)
246✔
2864
                                                break;
2865

2866
                                        r = strv_consume(&c->directories[dt].items[c->directories[dt].n_items - 1].symlinks, TAKE_PTR(link));
139✔
2867
                                        if (r < 0)
139✔
2868
                                                return r;
2869
                                }
2870
                        }
2871
                } else if ((val = startswith(l, "exec-context-quota-accounting-directories-"))) {
745,866✔
2872
                        _cleanup_free_ char *type = NULL, *quota_accounting = NULL;
×
2873
                        ExecDirectoryType dt;
×
2874

2875
                        r = split_pair(val, "=", &type, &quota_accounting);
×
2876
                        if (r < 0)
×
2877
                                return r;
2878

2879
                        dt = exec_directory_type_from_string(type);
×
2880
                        if (dt < 0)
×
2881
                                return dt;
2882

2883
                        r = parse_boolean(quota_accounting);
×
2884
                        if (r < 0)
×
2885
                                return r;
2886

2887
                        c->directories[dt].exec_quota.quota_accounting = r;
×
2888
                } else if ((val = startswith(l, "exec-context-quota-directories-"))) {
745,866✔
2889
                        _cleanup_free_ char *type = NULL, *quota_info = NULL, *quota_absolute = NULL, *quota_scale = NULL;
×
2890
                        ExecDirectoryType dt;
×
2891

2892
                        r = split_pair(val, "=", &type, &quota_info);
×
2893
                        if (r < 0)
×
2894
                                return r;
2895

2896
                        r = split_pair(quota_info, " ", &quota_absolute, &quota_scale);
×
2897
                        if (r < 0)
×
2898
                                return r;
2899

2900
                        dt = exec_directory_type_from_string(type);
×
2901
                        if (dt < 0)
×
2902
                                return dt;
2903

2904
                        r = safe_atou64(quota_absolute, &c->directories[dt].exec_quota.quota_absolute);
×
2905
                        if (r < 0)
×
2906
                               return r;
2907

2908
                        r = safe_atou32(quota_scale, &c->directories[dt].exec_quota.quota_scale);
×
2909
                        if (r < 0)
×
2910
                               return r;
2911

2912
                        c->directories[dt].exec_quota.quota_enforce = true;
×
2913
                } else if ((val = startswith(l, "exec-context-timeout-clean-usec="))) {
745,866✔
2914
                        r = deserialize_usec(val, &c->timeout_clean_usec);
×
2915
                        if (r < 0)
×
2916
                                return r;
2917
                } else if ((val = startswith(l, "exec-context-nice="))) {
745,866✔
2918
                        r = safe_atoi(val, &c->nice);
19✔
2919
                        if (r < 0)
19✔
2920
                                return r;
2921
                        c->nice_set = true;
19✔
2922
                } else if ((val = startswith(l, "exec-context-working-directory-missing-ok="))) {
745,847✔
2923
                        r = parse_boolean(val);
694✔
2924
                        if (r < 0)
694✔
2925
                                return r;
2926
                        c->working_directory_missing_ok = r;
694✔
2927
                } else if ((val = startswith(l, "exec-context-working-directory-home="))) {
745,153✔
2928
                        r = parse_boolean(val);
174✔
2929
                        if (r < 0)
174✔
2930
                                return r;
2931
                        c->working_directory_home = r;
174✔
2932
                } else if ((val = startswith(l, "exec-context-oom-score-adjust="))) {
744,979✔
2933
                        r = safe_atoi(val, &c->oom_score_adjust);
1,096✔
2934
                        if (r < 0)
1,096✔
2935
                                return r;
2936
                        c->oom_score_adjust_set = true;
1,096✔
2937
                } else if ((val = startswith(l, "exec-context-coredump-filter="))) {
743,883✔
2938
                        r = safe_atoux64(val, &c->coredump_filter);
2✔
2939
                        if (r < 0)
2✔
2940
                                return r;
2941
                        c->coredump_filter_set = true;
2✔
2942
                } else if ((val = startswith(l, "exec-context-limit-"))) {
743,881✔
2943
                        _cleanup_free_ struct rlimit *rlimit = NULL;
×
2944
                        _cleanup_free_ char *limit = NULL;
20,447✔
2945
                        int type;
20,447✔
2946

2947
                        r = extract_first_word(&val, &limit, "=", 0);
20,447✔
2948
                        if (r < 0)
20,447✔
2949
                                return r;
2950
                        if (r == 0 || !val)
20,447✔
2951
                                return -EINVAL;
2952

2953
                        type = rlimit_from_string(limit);
20,447✔
2954
                        if (type < 0)
20,447✔
2955
                                return -EINVAL;
2956

2957
                        if (!c->rlimit[type]) {
20,447✔
2958
                                rlimit = new0(struct rlimit, 1);
20,447✔
2959
                                if (!rlimit)
20,447✔
2960
                                        return log_oom_debug();
×
2961

2962
                                r = rlimit_parse(type, val, rlimit);
20,447✔
2963
                                if (r < 0)
20,447✔
2964
                                        return r;
2965

2966
                                c->rlimit[type] = TAKE_PTR(rlimit);
20,447✔
2967
                        } else {
2968
                                r = rlimit_parse(type, val, c->rlimit[type]);
×
2969
                                if (r < 0)
×
2970
                                        return r;
2971
                        }
2972
                } else if ((val = startswith(l, "exec-context-ioprio="))) {
723,434✔
2973
                        r = safe_atoi(val, &c->ioprio);
11✔
2974
                        if (r < 0)
11✔
2975
                                return r;
2976
                        c->ioprio_is_set = true;
11✔
2977
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-policy="))) {
723,423✔
2978
                        c->cpu_sched_policy = sched_policy_from_string(val);
×
2979
                        if (c->cpu_sched_policy < 0)
×
2980
                                return -EINVAL;
2981
                        c->cpu_sched_set = true;
×
2982
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-priority="))) {
723,423✔
2983
                        r = safe_atoi(val, &c->cpu_sched_priority);
×
2984
                        if (r < 0)
×
2985
                                return r;
2986
                        c->cpu_sched_set = true;
×
2987
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-reset-on-fork="))) {
723,423✔
2988
                        r = parse_boolean(val);
×
2989
                        if (r < 0)
×
2990
                                return r;
2991
                        c->cpu_sched_reset_on_fork = r;
×
2992
                        c->cpu_sched_set = true;
×
2993
                } else if ((val = startswith(l, "exec-context-cpu-affinity="))) {
723,423✔
2994
                        if (c->cpu_set.set)
×
2995
                                return -EINVAL; /* duplicated */
2996

2997
                        r = parse_cpu_set(val, &c->cpu_set);
×
2998
                        if (r < 0)
×
2999
                                return r;
3000
                } else if ((val = startswith(l, "exec-context-numa-mask="))) {
723,423✔
3001
                        if (c->numa_policy.nodes.set)
19✔
3002
                                return -EINVAL; /* duplicated */
3003

3004
                        r = parse_cpu_set(val, &c->numa_policy.nodes);
19✔
3005
                        if (r < 0)
19✔
3006
                                return r;
3007
                } else if ((val = startswith(l, "exec-context-numa-policy="))) {
723,404✔
3008
                        r = safe_atoi(val, &c->numa_policy.type);
19✔
3009
                        if (r < 0)
19✔
3010
                                return r;
3011
                } else if ((val = startswith(l, "exec-context-cpu-affinity-from-numa="))) {
723,385✔
3012
                        r = parse_boolean(val);
2✔
3013
                        if (r < 0)
2✔
3014
                                return r;
3015
                        c->cpu_affinity_from_numa = r;
2✔
3016
                } else if ((val = startswith(l, "exec-context-timer-slack-nsec="))) {
723,383✔
3017
                        r = deserialize_usec(val, (usec_t *)&c->timer_slack_nsec);
×
3018
                        if (r < 0)
×
3019
                                return r;
3020
                } else if ((val = startswith(l, "exec-context-std-input="))) {
723,383✔
3021
                        c->std_input = exec_input_from_string(val);
10,226✔
3022
                        if (c->std_input < 0)
10,226✔
3023
                                return c->std_input;
3024
                } else if ((val = startswith(l, "exec-context-std-output="))) {
713,157✔
3025
                        c->std_output = exec_output_from_string(val);
10,226✔
3026
                        if (c->std_output < 0)
10,226✔
3027
                                return c->std_output;
3028
                } else if ((val = startswith(l, "exec-context-std-error="))) {
702,931✔
3029
                        c->std_error = exec_output_from_string(val);
10,226✔
3030
                        if (c->std_error < 0)
10,226✔
3031
                                return c->std_error;
3032
                } else if ((val = startswith(l, "exec-context-stdio-as-fds="))) {
692,705✔
3033
                        r = parse_boolean(val);
536✔
3034
                        if (r < 0)
536✔
3035
                                return r;
3036
                        c->stdio_as_fds = r;
536✔
3037
                } else if ((val = startswith(l, "exec-context-root-directory-as-fd="))) {
692,169✔
3038
                        r = parse_boolean(val);
×
3039
                        if (r < 0)
×
3040
                                return r;
3041
                        c->root_directory_as_fd = r;
×
3042
                } else if ((val = startswith(l, "exec-context-std-input-fd-name="))) {
692,169✔
3043
                        r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], val);
×
3044
                        if (r < 0)
×
3045
                                return r;
3046
                } else if ((val = startswith(l, "exec-context-std-output-fd-name="))) {
692,169✔
3047
                        r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], val);
×
3048
                        if (r < 0)
×
3049
                                return r;
3050
                } else if ((val = startswith(l, "exec-context-std-error-fd-name="))) {
692,169✔
3051
                        r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], val);
×
3052
                        if (r < 0)
×
3053
                                return r;
3054
                } else if ((val = startswith(l, "exec-context-std-input-file="))) {
692,169✔
3055
                        r = free_and_strdup(&c->stdio_file[STDIN_FILENO], val);
×
3056
                        if (r < 0)
×
3057
                                return r;
3058
                } else if ((val = startswith(l, "exec-context-std-output-file="))) {
692,169✔
3059
                        r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], val);
50✔
3060
                        if (r < 0)
50✔
3061
                                return r;
3062
                } else if ((val = startswith(l, "exec-context-std-output-file-append="))) {
692,119✔
3063
                        r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], val);
1✔
3064
                        if (r < 0)
1✔
3065
                                return r;
3066
                } else if ((val = startswith(l, "exec-context-std-output-file-truncate="))) {
692,118✔
3067
                        r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], val);
2✔
3068
                        if (r < 0)
2✔
3069
                                return r;
3070
                } else if ((val = startswith(l, "exec-context-std-error-file="))) {
692,116✔
3071
                        r = free_and_strdup(&c->stdio_file[STDERR_FILENO], val);
47✔
3072
                        if (r < 0)
47✔
3073
                                return r;
3074
                } else if ((val = startswith(l, "exec-context-std-error-file-append="))) {
692,069✔
3075
                        r = free_and_strdup(&c->stdio_file[STDERR_FILENO], val);
1✔
3076
                        if (r < 0)
1✔
3077
                                return r;
3078
                } else if ((val = startswith(l, "exec-context-std-error-file-truncate="))) {
692,068✔
3079
                        r = free_and_strdup(&c->stdio_file[STDERR_FILENO], val);
1✔
3080
                        if (r < 0)
1✔
3081
                                return r;
3082
                } else if ((val = startswith(l, "exec-context-stdin-data="))) {
692,067✔
3083
                        if (c->stdin_data)
1✔
3084
                                return -EINVAL; /* duplicated */
3085

3086
                        r = unbase64mem(val, &c->stdin_data, &c->stdin_data_size);
1✔
3087
                        if (r < 0)
1✔
3088
                                return r;
3089
                } else if ((val = startswith(l, "exec-context-tty-path="))) {
692,066✔
3090
                        r = free_and_strdup(&c->tty_path, val);
105✔
3091
                        if (r < 0)
105✔
3092
                                return r;
3093
                } else if ((val = startswith(l, "exec-context-tty-reset="))) {
691,961✔
3094
                        r = parse_boolean(val);
195✔
3095
                        if (r < 0)
195✔
3096
                                return r;
3097
                        c->tty_reset = r;
195✔
3098
                } else if ((val = startswith(l, "exec-context-tty-vhangup="))) {
691,766✔
3099
                        r = parse_boolean(val);
84✔
3100
                        if (r < 0)
84✔
3101
                                return r;
3102
                        c->tty_vhangup = r;
84✔
3103
                } else if ((val = startswith(l, "exec-context-tty-vt-disallocate="))) {
691,682✔
3104
                        r = parse_boolean(val);
46✔
3105
                        if (r < 0)
46✔
3106
                                return r;
3107
                        c->tty_vt_disallocate = r;
46✔
3108
                } else if ((val = startswith(l, "exec-context-tty-rows="))) {
691,636✔
3109
                        r = safe_atou(val, &c->tty_rows);
10,226✔
3110
                        if (r < 0)
10,226✔
3111
                                return r;
3112
                } else if ((val = startswith(l, "exec-context-tty-columns="))) {
681,410✔
3113
                        r = safe_atou(val, &c->tty_cols);
10,226✔
3114
                        if (r < 0)
10,226✔
3115
                                return r;
3116
                } else if ((val = startswith(l, "exec-context-syslog-priority="))) {
671,184✔
3117
                        r = safe_atoi(val, &c->syslog_priority);
10,226✔
3118
                        if (r < 0)
10,226✔
3119
                                return r;
3120
                } else if ((val = startswith(l, "exec-context-syslog-level-prefix="))) {
660,958✔
3121
                        r = parse_boolean(val);
10,226✔
3122
                        if (r < 0)
10,226✔
3123
                                return r;
3124
                        c->syslog_level_prefix = r;
10,226✔
3125
                } else if ((val = startswith(l, "exec-context-syslog-identifier="))) {
650,732✔
3126
                        r = free_and_strdup(&c->syslog_identifier, val);
×
3127
                        if (r < 0)
×
3128
                                return r;
3129
                } else if ((val = startswith(l, "exec-context-log-level-max="))) {
650,732✔
3130
                        /* See comment in serialization. */
3131
                        r = safe_atoi(val, &c->log_level_max);
10,226✔
3132
                        if (r < 0)
10,226✔
3133
                                return r;
3134
                } else if ((val = startswith(l, "exec-context-log-ratelimit-interval-usec="))) {
640,506✔
3135
                        r = deserialize_usec(val, &c->log_ratelimit.interval);
×
3136
                        if (r < 0)
×
3137
                                return r;
3138
                } else if ((val = startswith(l, "exec-context-log-ratelimit-burst="))) {
640,506✔
3139
                        r = safe_atou(val, &c->log_ratelimit.burst);
×
3140
                        if (r < 0)
×
3141
                                return r;
3142
                } else if ((val = startswith(l, "exec-context-log-filter-allowed-patterns="))) {
640,506✔
3143
                        r = set_put_strdup(&c->log_filter_allowed_patterns, val);
20✔
3144
                        if (r < 0)
20✔
3145
                                return r;
3146
                } else if ((val = startswith(l, "exec-context-log-filter-denied-patterns="))) {
640,486✔
3147
                        r = set_put_strdup(&c->log_filter_denied_patterns, val);
13✔
3148
                        if (r < 0)
13✔
3149
                                return r;
3150
                } else if ((val = startswith(l, "exec-context-log-extra-fields="))) {
640,473✔
3151
                        if (!GREEDY_REALLOC(c->log_extra_fields, c->n_log_extra_fields + 1))
691✔
3152
                                return log_oom_debug();
×
3153

3154
                        c->log_extra_fields[c->n_log_extra_fields++].iov_base = strdup(val);
691✔
3155
                        if (!c->log_extra_fields[c->n_log_extra_fields-1].iov_base)
691✔
3156
                                return log_oom_debug();
×
3157
                } else if ((val = startswith(l, "exec-context-log-namespace="))) {
639,782✔
3158
                        r = free_and_strdup(&c->log_namespace, val);
2✔
3159
                        if (r < 0)
2✔
3160
                                return r;
3161
                } else if ((val = startswith(l, "exec-context-secure-bits="))) {
639,780✔
3162
                        r = safe_atoi(val, &c->secure_bits);
×
3163
                        if (r < 0)
×
3164
                                return r;
3165
                } else if ((val = startswith(l, "exec-context-capability-bounding-set="))) {
639,780✔
3166
                        r = safe_atou64(val, &c->capability_bounding_set);
10,226✔
3167
                        if (r < 0)
10,226✔
3168
                                return r;
3169
                } else if ((val = startswith(l, "exec-context-capability-ambient-set="))) {
629,554✔
3170
                        r = safe_atou64(val, &c->capability_ambient_set);
659✔
3171
                        if (r < 0)
659✔
3172
                                return r;
3173
                } else if ((val = startswith(l, "exec-context-user="))) {
628,895✔
3174
                        r = free_and_strdup(&c->user, val);
2,075✔
3175
                        if (r < 0)
2,075✔
3176
                                return r;
3177
                } else if ((val = startswith(l, "exec-context-group="))) {
626,820✔
3178
                        r = free_and_strdup(&c->group, val);
60✔
3179
                        if (r < 0)
60✔
3180
                                return r;
3181
                } else if ((val = startswith(l, "exec-context-dynamic-user="))) {
626,760✔
3182
                        r = parse_boolean(val);
47✔
3183
                        if (r < 0)
47✔
3184
                                return r;
3185
                        c->dynamic_user = r;
47✔
3186
                } else if ((val = startswith(l, "exec-context-supplementary-groups="))) {
626,713✔
3187
                        r = deserialize_strv(val, &c->supplementary_groups);
12✔
3188
                        if (r < 0)
12✔
3189
                                return r;
3190
                } else if ((val = startswith(l, "exec-context-set-login-environment="))) {
626,701✔
3191
                        r = safe_atoi(val, &c->set_login_environment);
×
3192
                        if (r < 0)
×
3193
                                return r;
3194
                } else if ((val = startswith(l, "exec-context-pam-name="))) {
626,701✔
3195
                        r = free_and_strdup(&c->pam_name, val);
503✔
3196
                        if (r < 0)
503✔
3197
                                return r;
3198
                } else if ((val = startswith(l, "exec-context-read-write-paths="))) {
626,198✔
3199
                        r = deserialize_strv(val, &c->read_write_paths);
825✔
3200
                        if (r < 0)
825✔
3201
                                return r;
3202
                } else if ((val = startswith(l, "exec-context-read-only-paths="))) {
625,373✔
3203
                        r = deserialize_strv(val, &c->read_only_paths);
2✔
3204
                        if (r < 0)
2✔
3205
                                return r;
3206
                } else if ((val = startswith(l, "exec-context-inaccessible-paths="))) {
625,371✔
3207
                        r = deserialize_strv(val, &c->inaccessible_paths);
5✔
3208
                        if (r < 0)
5✔
3209
                                return r;
3210
                } else if ((val = startswith(l, "exec-context-exec-paths="))) {
625,366✔
3211
                        r = deserialize_strv(val, &c->exec_paths);
1✔
3212
                        if (r < 0)
1✔
3213
                                return r;
3214
                } else if ((val = startswith(l, "exec-context-no-exec-paths="))) {
625,365✔
3215
                        r = deserialize_strv(val, &c->no_exec_paths);
1✔
3216
                        if (r < 0)
1✔
3217
                                return r;
3218
                } else if ((val = startswith(l, "exec-context-exec-search-path="))) {
625,364✔
3219
                        r = deserialize_strv(val, &c->exec_search_path);
×
3220
                        if (r < 0)
×
3221
                                return r;
3222
                } else if ((val = startswith(l, "exec-context-mount-propagation-flag="))) {
625,364✔
3223
                        r = safe_atolu(val, &c->mount_propagation_flag);
10,226✔
3224
                        if (r < 0)
10,226✔
3225
                                return r;
3226
                } else if ((val = startswith(l, "exec-context-bind-read-only-path="))) {
615,138✔
3227
                        _cleanup_free_ char *source = NULL, *destination = NULL;
7✔
3228
                        bool rbind = true, ignore_enoent = false;
7✔
3229
                        char *s = NULL, *d = NULL;
7✔
3230

3231
                        r = extract_first_word(&val,
7✔
3232
                                               &source,
3233
                                               ":" WHITESPACE,
3234
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3235
                        if (r < 0)
7✔
3236
                                return r;
3237
                        if (r == 0)
7✔
3238
                                return -EINVAL;
3239

3240
                        s = source;
7✔
3241
                        if (s[0] == '-') {
7✔
3242
                                ignore_enoent = true;
1✔
3243
                                s++;
1✔
3244
                        }
3245

3246
                        if (val && val[-1] == ':') {
7✔
3247
                                r = extract_first_word(&val,
7✔
3248
                                                       &destination,
3249
                                                       ":" WHITESPACE,
3250
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3251
                                if (r < 0)
7✔
3252
                                        return r;
3253
                                if (r == 0)
7✔
3254
                                        continue;
×
3255

3256
                                d = destination;
7✔
3257

3258
                                if (val && val[-1] == ':') {
7✔
3259
                                        _cleanup_free_ char *options = NULL;
7✔
3260

3261
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
7✔
3262
                                        if (r < 0)
7✔
3263
                                                return -r;
×
3264

3265
                                        if (isempty(options) || streq(options, "rbind"))
15✔
3266
                                                rbind = true;
3267
                                        else if (streq(options, "norbind"))
1✔
3268
                                                rbind = false;
3269
                                        else
3270
                                                continue;
×
3271
                                }
3272
                        } else
3273
                                d = s;
3274

3275
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
14✔
3276
                                        &(BindMount) {
7✔
3277
                                                .source = s,
3278
                                                .destination = d,
3279
                                                .read_only = true,
3280
                                                .recursive = rbind,
3281
                                                .ignore_enoent = ignore_enoent,
3282
                                        });
3283
                        if (r < 0)
7✔
3284
                                return log_oom_debug();
×
3285
                } else if ((val = startswith(l, "exec-context-bind-path="))) {
615,131✔
3286
                        _cleanup_free_ char *source = NULL, *destination = NULL;
20✔
3287
                        bool rbind = true, ignore_enoent = false;
20✔
3288
                        char *s = NULL, *d = NULL;
20✔
3289

3290
                        r = extract_first_word(&val,
20✔
3291
                                               &source,
3292
                                               ":" WHITESPACE,
3293
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3294
                        if (r < 0)
20✔
3295
                                return r;
3296
                        if (r == 0)
20✔
3297
                                return -EINVAL;
3298

3299
                        s = source;
20✔
3300
                        if (s[0] == '-') {
20✔
3301
                                ignore_enoent = true;
1✔
3302
                                s++;
1✔
3303
                        }
3304

3305
                        if (val && val[-1] == ':') {
20✔
3306
                                r = extract_first_word(&val,
20✔
3307
                                                       &destination,
3308
                                                       ":" WHITESPACE,
3309
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3310
                                if (r < 0)
20✔
3311
                                        return r;
3312
                                if (r == 0)
20✔
3313
                                        continue;
×
3314

3315
                                d = destination;
20✔
3316

3317
                                if (val && val[-1] == ':') {
20✔
3318
                                        _cleanup_free_ char *options = NULL;
20✔
3319

3320
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
20✔
3321
                                        if (r < 0)
20✔
3322
                                                return -r;
×
3323

3324
                                        if (isempty(options) || streq(options, "rbind"))
43✔
3325
                                                rbind = true;
3326
                                        else if (streq(options, "norbind"))
3✔
3327
                                                rbind = false;
3328
                                        else
3329
                                                continue;
×
3330
                                }
3331
                        } else
3332
                                d = s;
3333

3334
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
40✔
3335
                                        &(BindMount) {
20✔
3336
                                                .source = s,
3337
                                                .destination = d,
3338
                                                .read_only = false,
3339
                                                .recursive = rbind,
3340
                                                .ignore_enoent = ignore_enoent,
3341
                                        });
3342
                        if (r < 0)
20✔
3343
                                return log_oom_debug();
×
3344
                } else if ((val = startswith(l, "exec-context-temporary-filesystems="))) {
615,111✔
3345
                        _cleanup_free_ char *path = NULL, *options = NULL;
61✔
3346

3347
                        r = extract_many_words(&val, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &path, &options);
61✔
3348
                        if (r < 0)
61✔
3349
                                return r;
3350
                        if (r < 1)
61✔
3351
                                continue;
×
3352

3353
                        r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
61✔
3354
                        if (r < 0)
61✔
3355
                                return log_oom_debug();
×
3356
                } else if ((val = startswith(l, "exec-context-utmp-id="))) {
615,050✔
3357
                        r = free_and_strdup(&c->utmp_id, val);
91✔
3358
                        if (r < 0)
91✔
3359
                                return r;
3360
                } else if ((val = startswith(l, "exec-context-utmp-mode="))) {
614,959✔
3361
                        c->utmp_mode = exec_utmp_mode_from_string(val);
10,226✔
3362
                        if (c->utmp_mode < 0)
10,226✔
3363
                                return c->utmp_mode;
3364
                } else if ((val = startswith(l, "exec-context-no-new-privileges="))) {
604,733✔
3365
                        r = parse_boolean(val);
1,417✔
3366
                        if (r < 0)
1,417✔
3367
                                return r;
3368
                        c->no_new_privileges = r;
1,417✔
3369
                } else if ((val = startswith(l, "exec-context-selinux-context="))) {
603,316✔
3370
                        if (val[0] == '-') {
×
3371
                                c->selinux_context_ignore = true;
×
3372
                                val++;
×
3373
                        } else
3374
                                c->selinux_context_ignore = false;
×
3375

3376
                        r = free_and_strdup(&c->selinux_context, val);
×
3377
                        if (r < 0)
×
3378
                                return r;
3379
                } else if ((val = startswith(l, "exec-context-apparmor-profile="))) {
603,316✔
3380
                        if (val[0] == '-') {
×
3381
                                c->apparmor_profile_ignore = true;
×
3382
                                val++;
×
3383
                        } else
3384
                                c->apparmor_profile_ignore = false;
×
3385

3386
                        r = free_and_strdup(&c->apparmor_profile, val);
×
3387
                        if (r < 0)
×
3388
                                return r;
3389
                } else if ((val = startswith(l, "exec-context-smack-process-label="))) {
603,316✔
3390
                        if (val[0] == '-') {
×
3391
                                c->smack_process_label_ignore = true;
×
3392
                                val++;
×
3393
                        } else
3394
                                c->smack_process_label_ignore = false;
×
3395

3396
                        r = free_and_strdup(&c->smack_process_label, val);
×
3397
                        if (r < 0)
×
3398
                                return r;
3399
                } else if ((val = startswith(l, "exec-context-personality="))) {
603,316✔
3400
                        c->personality = personality_from_string(val);
×
3401
                        if (c->personality == PERSONALITY_INVALID)
×
3402
                                return -EINVAL;
3403
                } else if ((val = startswith(l, "exec-context-lock-personality="))) {
603,316✔
3404
                        r = parse_boolean(val);
1,496✔
3405
                        if (r < 0)
1,496✔
3406
                                return r;
3407
                        c->lock_personality = r;
1,496✔
3408
#if HAVE_SECCOMP
3409
                } else if ((val = startswith(l, "exec-context-syscall-filter="))) {
601,820✔
3410
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
575,678✔
3411
                        int id, errno_num;
575,678✔
3412

3413
                        r = extract_many_words(&val, NULL, 0, &s_id, &s_errno_num);
575,678✔
3414
                        if (r < 0)
575,678✔
3415
                                return r;
3416
                        if (r != 2)
575,678✔
3417
                                continue;
×
3418

3419
                        r = safe_atoi(s_id, &id);
575,678✔
3420
                        if (r < 0)
575,678✔
3421
                                return r;
3422

3423
                        r = safe_atoi(s_errno_num, &errno_num);
575,678✔
3424
                        if (r < 0)
575,678✔
3425
                                return r;
3426

3427
                        r = hashmap_ensure_put(&c->syscall_filter, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
575,678✔
3428
                        if (r < 0)
575,678✔
3429
                                return r;
3430
                } else if ((val = startswith(l, "exec-context-syscall-archs="))) {
26,142✔
3431
                        unsigned id;
1,497✔
3432

3433
                        r = safe_atou(val, &id);
1,497✔
3434
                        if (r < 0)
1,497✔
3435
                                return r;
×
3436

3437
                        r = set_ensure_put(&c->syscall_archs, NULL, UINT_TO_PTR(id + 1));
1,497✔
3438
                        if (r < 0)
1,497✔
3439
                                return r;
3440
                } else if ((val = startswith(l, "exec-context-syscall-errno="))) {
24,645✔
3441
                        r = safe_atoi(val, &c->syscall_errno);
10,226✔
3442
                        if (r < 0)
10,226✔
3443
                                return r;
3444
                } else if ((val = startswith(l, "exec-context-syscall-allow-list="))) {
14,419✔
3445
                        r = parse_boolean(val);
1,473✔
3446
                        if (r < 0)
1,473✔
3447
                                return r;
3448
                        c->syscall_allow_list = r;
1,473✔
3449
                } else if ((val = startswith(l, "exec-context-syscall-log="))) {
12,946✔
3450
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
×
3451
                        int id, errno_num;
×
3452

3453
                        r = extract_many_words(&val, " ", 0, &s_id, &s_errno_num);
×
3454
                        if (r < 0)
×
3455
                                return r;
3456
                        if (r != 2)
×
3457
                                continue;
×
3458

3459
                        r = safe_atoi(s_id, &id);
×
3460
                        if (r < 0)
×
3461
                                return r;
3462

3463
                        r = safe_atoi(s_errno_num, &errno_num);
×
3464
                        if (r < 0)
×
3465
                                return r;
3466

3467
                        r = hashmap_ensure_put(&c->syscall_log, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
×
3468
                        if (r < 0)
×
3469
                                return r;
3470
                } else if ((val = startswith(l, "exec-context-syscall-log-allow-list="))) {
12,946✔
3471
                        r = parse_boolean(val);
×
3472
                        if (r < 0)
×
3473
                                return r;
3474
                        c->syscall_log_allow_list = r;
×
3475
#endif
3476
                } else if ((val = startswith(l, "exec-context-restrict-namespaces="))) {
12,946✔
3477
                        r = safe_atolu(val, &c->restrict_namespaces);
1,234✔
3478
                        if (r < 0)
1,234✔
3479
                                return r;
3480
                } else if ((val = startswith(l, "exec-context-delegate-namespaces="))) {
11,712✔
3481
                        r = safe_atolu(val, &c->delegate_namespaces);
21✔
3482
                        if (r < 0)
21✔
3483
                                return r;
3484
                } else if ((val = startswith(l, "exec-context-restrict-filesystems="))) {
11,691✔
3485
                        r = set_put_strdup(&c->restrict_filesystems, val);
×
3486
                        if (r < 0)
×
3487
                                return r;
3488
                } else if ((val = startswith(l, "exec-context-restrict-filesystems-allow-list="))) {
11,691✔
3489
                        r = parse_boolean(val);
×
3490
                        if (r < 0)
×
3491
                                return r;
3492
                        c->restrict_filesystems_allow_list = r;
×
3493
                } else if ((val = startswith(l, "exec-context-address-families="))) {
11,691✔
3494
                        int af;
5,877✔
3495

3496
                        r = safe_atoi(val, &af);
5,877✔
3497
                        if (r < 0)
5,877✔
3498
                                return r;
×
3499

3500
                        r = set_ensure_put(&c->address_families, NULL, INT_TO_PTR(af));
5,877✔
3501
                        if (r < 0)
5,877✔
3502
                                return r;
3503
                } else if ((val = startswith(l, "exec-context-address-families-allow-list="))) {
5,814✔
3504
                        r = parse_boolean(val);
1,491✔
3505
                        if (r < 0)
1,491✔
3506
                                return r;
3507
                        c->address_families_allow_list = r;
1,491✔
3508
                } else if ((val = startswith(l, "exec-context-network-namespace-path="))) {
4,323✔
3509
                        r = free_and_strdup(&c->network_namespace_path, val);
1✔
3510
                        if (r < 0)
1✔
3511
                                return r;
3512
                } else if ((val = startswith(l, "exec-context-user-namespace-path="))) {
4,322✔
3513
                        r = free_and_strdup(&c->user_namespace_path, val);
3✔
3514
                        if (r < 0)
3✔
3515
                                return r;
3516
                } else if ((val = startswith(l, "exec-context-ipc-namespace-path="))) {
4,319✔
3517
                        r = free_and_strdup(&c->ipc_namespace_path, val);
×
3518
                        if (r < 0)
×
3519
                                return r;
3520
                } else if ((val = startswith(l, "exec-context-mount-image="))) {
4,319✔
3521
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3522
                        _cleanup_free_ char *source = NULL, *destination = NULL;
60✔
3523
                        bool permissive = false;
60✔
3524
                        char *s;
60✔
3525

3526
                        r = extract_many_words(&val,
60✔
3527
                                               NULL,
3528
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3529
                                               &source,
3530
                                               &destination);
3531
                        if (r < 0)
60✔
3532
                                return r;
3533
                        if (r == 0)
60✔
3534
                                return -EINVAL;
3535

3536
                        s = source;
60✔
3537
                        if (s[0] == '-') {
60✔
3538
                                permissive = true;
×
3539
                                s++;
×
3540
                        }
3541

3542
                        if (isempty(destination))
60✔
3543
                                continue;
×
3544

3545
                        for (;;) {
65✔
3546
                                _cleanup_free_ char *tuple = NULL, *partition = NULL, *opts = NULL;
5✔
3547
                                PartitionDesignator partition_designator;
65✔
3548
                                MountOptions *o = NULL;
65✔
3549
                                const char *p;
65✔
3550

3551
                                r = extract_first_word(&val, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
65✔
3552
                                if (r < 0)
65✔
3553
                                        return r;
3554
                                if (r == 0)
65✔
3555
                                        break;
3556

3557
                                p = tuple;
5✔
3558
                                r = extract_many_words(&p,
5✔
3559
                                                       ":",
3560
                                                       EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3561
                                                       &partition,
3562
                                                       &opts);
3563
                                if (r < 0)
5✔
3564
                                        return r;
3565
                                if (r == 0)
5✔
3566
                                        continue;
×
3567
                                if (r == 1) {
5✔
3568
                                        o = new(MountOptions, 1);
×
3569
                                        if (!o)
×
3570
                                                return log_oom_debug();
×
3571
                                        *o = (MountOptions) {
×
3572
                                                .partition_designator = PARTITION_ROOT,
3573
                                                .options = TAKE_PTR(partition),
×
3574
                                        };
3575
                                        LIST_APPEND(mount_options, options, o);
×
3576

3577
                                        continue;
×
3578
                                }
3579

3580
                                partition_designator = partition_designator_from_string(partition);
5✔
3581
                                if (partition_designator < 0)
5✔
3582
                                        continue;
×
3583

3584
                                o = new(MountOptions, 1);
5✔
3585
                                if (!o)
5✔
3586
                                        return log_oom_debug();
×
3587
                                *o = (MountOptions) {
5✔
3588
                                        .partition_designator = partition_designator,
3589
                                        .options = TAKE_PTR(opts),
5✔
3590
                                };
3591
                                LIST_APPEND(mount_options, options, o);
5✔
3592
                        }
3593

3594
                        r = mount_image_add(&c->mount_images, &c->n_mount_images,
120✔
3595
                                        &(MountImage) {
60✔
3596
                                                .source = s,
3597
                                                .destination = destination,
3598
                                                .mount_options = options,
3599
                                                .ignore_enoent = permissive,
3600
                                                .type = MOUNT_IMAGE_DISCRETE,
3601
                                        });
3602
                        if (r < 0)
60✔
3603
                                return log_oom_debug();
×
3604
                } else if ((val = startswith(l, "exec-context-extension-image="))) {
4,259✔
3605
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3606
                        _cleanup_free_ char *source = NULL;
13✔
3607
                        bool permissive = false;
13✔
3608
                        char *s;
13✔
3609

3610
                        r = extract_first_word(&val,
13✔
3611
                                               &source,
3612
                                               NULL,
3613
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS);
3614
                        if (r < 0)
13✔
3615
                                return r;
3616
                        if (r == 0)
13✔
3617
                                return -EINVAL;
3618

3619
                        s = source;
13✔
3620
                        if (s[0] == '-') {
13✔
3621
                                permissive = true;
3✔
3622
                                s++;
3✔
3623
                        }
3624

3625
                        for (;;) {
13✔
3626
                                _cleanup_free_ char *tuple = NULL, *partition = NULL, *opts = NULL;
×
3627
                                PartitionDesignator partition_designator;
13✔
3628
                                MountOptions *o = NULL;
13✔
3629
                                const char *p;
13✔
3630

3631
                                r = extract_first_word(&val, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
13✔
3632
                                if (r < 0)
13✔
3633
                                        return r;
3634
                                if (r == 0)
13✔
3635
                                        break;
3636

3637
                                p = tuple;
×
3638
                                r = extract_many_words(&p,
×
3639
                                                       ":",
3640
                                                       EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3641
                                                       &partition,
3642
                                                       &opts);
3643
                                if (r < 0)
×
3644
                                        return r;
3645
                                if (r == 0)
×
3646
                                        continue;
×
3647
                                if (r == 1) {
×
3648
                                        o = new(MountOptions, 1);
×
3649
                                        if (!o)
×
3650
                                                return log_oom_debug();
×
3651
                                        *o = (MountOptions) {
×
3652
                                                .partition_designator = PARTITION_ROOT,
3653
                                                .options = TAKE_PTR(partition),
×
3654
                                        };
3655
                                        LIST_APPEND(mount_options, options, o);
×
3656

3657
                                        continue;
×
3658
                                }
3659

3660
                                partition_designator = partition_designator_from_string(partition);
×
3661
                                if (partition_designator < 0)
×
3662
                                        continue;
×
3663

3664
                                o = new(MountOptions, 1);
×
3665
                                if (!o)
×
3666
                                        return log_oom_debug();
×
3667
                                *o = (MountOptions) {
×
3668
                                        .partition_designator = partition_designator,
3669
                                        .options = TAKE_PTR(opts),
×
3670
                                };
3671
                                LIST_APPEND(mount_options, options, o);
×
3672
                        }
3673

3674
                        r = mount_image_add(&c->extension_images, &c->n_extension_images,
26✔
3675
                                        &(MountImage) {
13✔
3676
                                                .source = s,
3677
                                                .mount_options = options,
3678
                                                .ignore_enoent = permissive,
3679
                                                .type = MOUNT_IMAGE_EXTENSION,
3680
                                        });
3681
                        if (r < 0)
13✔
3682
                                return log_oom_debug();
×
3683
                } else if ((val = startswith(l, "exec-context-extension-directories="))) {
4,246✔
3684
                        r = deserialize_strv(val, &c->extension_directories);
8✔
3685
                        if (r < 0)
8✔
3686
                                return r;
3687
                } else if ((val = startswith(l, "exec-context-set-credentials="))) {
4,238✔
3688
                        _cleanup_free_ char *id = NULL, *data = NULL, *encrypted = NULL;
×
3689

3690
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &data, &encrypted);
93✔
3691
                        if (r < 0)
93✔
3692
                                return r;
3693
                        if (r != 3)
93✔
3694
                                return -EINVAL;
3695

3696
                        r = parse_boolean(encrypted);
93✔
3697
                        if (r < 0)
93✔
3698
                                return r;
3699
                        bool e = r;
93✔
3700

3701
                        _cleanup_free_ void *d = NULL;
93✔
3702
                        size_t size;
93✔
3703

3704
                        r = unbase64mem_full(data, SIZE_MAX, /* secure = */ true, &d, &size);
93✔
3705
                        if (r < 0)
93✔
3706
                                return r;
3707

3708
                        r = exec_context_put_set_credential(c, id, TAKE_PTR(d), size, e);
93✔
3709
                        if (r < 0)
93✔
3710
                                return r;
3711
                } else if ((val = startswith(l, "exec-context-load-credentials="))) {
4,145✔
3712
                        _cleanup_free_ char *id = NULL, *path = NULL, *encrypted = NULL;
34✔
3713

3714
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &path, &encrypted);
34✔
3715
                        if (r < 0)
34✔
3716
                                return r;
3717
                        if (r != 3)
34✔
3718
                                return -EINVAL;
3719

3720
                        r = parse_boolean(encrypted);
34✔
3721
                        if (r < 0)
34✔
3722
                                return r;
3723

3724
                        r = exec_context_put_load_credential(c, id, path, r > 0);
34✔
3725
                        if (r < 0)
34✔
3726
                                return r;
3727
                } else if ((val = startswith(l, "exec-context-import-credentials="))) {
4,111✔
3728
                        _cleanup_free_ char *glob = NULL, *rename = NULL;
4,105✔
3729

3730
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &glob, &rename);
4,105✔
3731
                        if (r < 0)
4,105✔
3732
                                return r;
3733
                        if (r == 0)
4,105✔
3734
                                return -EINVAL;
3735

3736
                        r = exec_context_put_import_credential(c, glob, rename);
4,105✔
3737
                        if (r < 0)
4,105✔
3738
                                return r;
3739
                } else if ((val = startswith(l, "exec-context-root-image-policy="))) {
6✔
3740
                        if (c->root_image_policy)
4✔
3741
                                return -EINVAL; /* duplicated */
3742

3743
                        r = image_policy_from_string(val, /* graceful= */ true, &c->root_image_policy);
4✔
3744
                        if (r < 0)
4✔
3745
                                return r;
3746
                } else if ((val = startswith(l, "exec-context-mount-image-policy="))) {
2✔
3747
                        if (c->mount_image_policy)
×
3748
                                return -EINVAL; /* duplicated */
3749

NEW
3750
                        r = image_policy_from_string(val, /* graceful= */ true, &c->mount_image_policy);
×
3751
                        if (r < 0)
×
3752
                                return r;
3753
                } else if ((val = startswith(l, "exec-context-extension-image-policy="))) {
2✔
3754
                        if (c->extension_image_policy)
2✔
3755
                                return -EINVAL; /* duplicated */
3756

3757
                        r = image_policy_from_string(val, /* graceful= */ true, &c->extension_image_policy);
2✔
3758
                        if (r < 0)
2✔
3759
                                return r;
3760
                } else
3761
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3762
        }
3763

3764
        return 0;
10,226✔
3765
}
3766

3767
static int exec_command_serialize(const ExecCommand *c, FILE *f) {
2,556✔
3768
        int r;
2,556✔
3769

3770
        assert(c);
2,556✔
3771
        assert(f);
2,556✔
3772

3773
        r = serialize_item(f, "exec-command-path", c->path);
2,556✔
3774
        if (r < 0)
2,556✔
3775
                return r;
3776

3777
        r = serialize_strv(f, "exec-command-argv", c->argv);
2,556✔
3778
        if (r < 0)
2,556✔
3779
                return r;
3780

3781
        r = serialize_item_format(f, "exec-command-flags", "%d", (int) c->flags);
2,556✔
3782
        if (r < 0)
2,556✔
3783
                return r;
3784

3785
        fputc('\n', f); /* End marker */
2,556✔
3786

3787
        return 0;
2,556✔
3788
}
3789

3790
static int exec_command_deserialize(ExecCommand *c, FILE *f) {
10,226✔
3791
        int r;
10,226✔
3792

3793
        assert(c);
10,226✔
3794
        assert(f);
10,226✔
3795

3796
        for (;;) {
110,828✔
3797
                _cleanup_free_ char *l = NULL;
50,301✔
3798
                const char *val;
60,527✔
3799

3800
                r = deserialize_read_line(f, &l);
60,527✔
3801
                if (r < 0)
60,527✔
3802
                        return r;
3803
                if (r == 0) /* eof or end marker */
60,527✔
3804
                        break;
3805

3806
                if ((val = startswith(l, "exec-command-path="))) {
50,301✔
3807
                        r = free_and_strdup(&c->path, val);
10,226✔
3808
                        if (r < 0)
10,226✔
3809
                                return r;
3810
                } else if ((val = startswith(l, "exec-command-argv="))) {
40,075✔
3811
                        r = deserialize_strv(val, &c->argv);
29,849✔
3812
                        if (r < 0)
29,849✔
3813
                                return r;
3814
                } else if ((val = startswith(l, "exec-command-flags="))) {
10,226✔
3815
                        r = safe_atoi(val, &c->flags);
10,226✔
3816
                        if (r < 0)
10,226✔
3817
                                return r;
3818
                } else
3819
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3820

3821
        }
3822

3823
        return 0;
10,226✔
3824
}
3825

3826
int exec_serialize_invocation(
2,556✔
3827
                FILE *f,
3828
                FDSet *fds,
3829
                const ExecContext *ctx,
3830
                const ExecCommand *cmd,
3831
                const ExecParameters *p,
3832
                const ExecRuntime *rt,
3833
                const CGroupContext *cg) {
3834

3835
        int r;
2,556✔
3836

3837
        assert(f);
2,556✔
3838
        assert(fds);
2,556✔
3839

3840
        r = exec_context_serialize(ctx, f);
2,556✔
3841
        if (r < 0)
2,556✔
3842
                return log_debug_errno(r, "Failed to serialize context: %m");
×
3843

3844
        r = exec_command_serialize(cmd, f);
2,556✔
3845
        if (r < 0)
2,556✔
3846
                return log_debug_errno(r, "Failed to serialize command: %m");
×
3847

3848
        r = exec_parameters_serialize(p, ctx, f, fds);
2,556✔
3849
        if (r < 0)
2,556✔
3850
                return log_debug_errno(r, "Failed to serialize parameters: %m");
×
3851

3852
        r = exec_runtime_serialize(rt, f, fds);
2,556✔
3853
        if (r < 0)
2,556✔
3854
                return log_debug_errno(r, "Failed to serialize runtime: %m");
×
3855

3856
        r = exec_cgroup_context_serialize(cg, f);
2,556✔
3857
        if (r < 0)
2,556✔
3858
                return log_debug_errno(r, "Failed to serialize cgroup context: %m");
×
3859

3860
        return 0;
3861
}
3862

3863
int exec_deserialize_invocation(
10,226✔
3864
                FILE *f,
3865
                FDSet *fds,
3866
                ExecContext *ctx,
3867
                ExecCommand *cmd,
3868
                ExecParameters *p,
3869
                ExecRuntime *rt,
3870
                CGroupContext *cg) {
3871

3872
        int r;
10,226✔
3873

3874
        assert(f);
10,226✔
3875
        assert(fds);
10,226✔
3876

3877
        r = exec_context_deserialize(ctx, f);
10,226✔
3878
        if (r < 0)
10,226✔
3879
                return log_debug_errno(r, "Failed to deserialize context: %m");
×
3880

3881
        r = exec_command_deserialize(cmd, f);
10,226✔
3882
        if (r < 0)
10,226✔
3883
                return log_debug_errno(r, "Failed to deserialize command: %m");
×
3884

3885
        r = exec_parameters_deserialize(p, f, fds);
10,226✔
3886
        if (r < 0)
10,226✔
3887
                return log_debug_errno(r, "Failed to deserialize parameters: %m");
×
3888

3889
        r = exec_runtime_deserialize(rt, f, fds);
10,226✔
3890
        if (r < 0)
10,226✔
3891
                return log_debug_errno(r, "Failed to deserialize runtime: %m");
×
3892

3893
        r = exec_cgroup_context_deserialize(cg, f);
10,226✔
3894
        if (r < 0)
10,226✔
3895
                return log_debug_errno(r, "Failed to deserialize cgroup context: %m");
×
3896

3897
        return 0;
3898
}
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