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

systemd / systemd / 19948074208

04 Dec 2025 11:10AM UTC coverage: 72.917% (+0.008%) from 72.909%
19948074208

push

github

bluca
include: update kernel headers from v6.18

310215 of 425437 relevant lines covered (72.92%)

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

42
        assert(f);
2,416✔
43

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

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

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

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

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

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

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

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

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

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

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

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

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

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

123
        if (c->io_weight != CGROUP_WEIGHT_INVALID) {
2,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
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,416✔
214
        if (r < 0)
2,416✔
215
                return r;
216

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

398
        LIST_FOREACH(programs, p, c->bpf_foreign_programs) {
2,416✔
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,416✔
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,416✔
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,416✔
419
                r = serialize_item(f, "exec-cgroup-context-restrict-network-interfaces", iface);
×
420
                if (r < 0)
×
421
                        return r;
×
422
        }
423

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

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

433
        return 0;
434
}
435

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

439
        assert(f);
9,916✔
440

441
        if (!c)
9,916✔
442
                return 0;
443

444
        for (;;) {
370,032✔
445
                _cleanup_free_ char *l = NULL;
180,058✔
446
                const char *val;
189,974✔
447

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

454
                if ((val = startswith(l, "exec-cgroup-context-io-accounting="))) {
180,058✔
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="))) {
180,056✔
460
                        r = parse_boolean(val);
9,594✔
461
                        if (r < 0)
9,594✔
462
                                return r;
463
                        c->memory_accounting = r;
9,594✔
464
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-accounting="))) {
170,462✔
465
                        r = parse_boolean(val);
9,916✔
466
                        if (r < 0)
9,916✔
467
                                return r;
468
                        c->tasks_accounting = r;
9,916✔
469
                } else if ((val = startswith(l, "exec-cgroup-context-ip-accounting="))) {
160,546✔
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="))) {
160,546✔
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="))) {
160,544✔
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="))) {
160,543✔
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="))) {
160,543✔
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="))) {
160,543✔
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="))) {
160,543✔
496
                        if (c->cpuset_cpus.set)
9,916✔
497
                                return -EINVAL; /* duplicated */
498

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

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

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

520
                        r = parse_cpu_set(val, &c->startup_cpuset_mems);
9,916✔
521
                        if (r < 0)
9,916✔
522
                                return r;
523
                } else if ((val = startswith(l, "exec-cgroup-context-io-weight="))) {
120,879✔
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="))) {
120,879✔
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="))) {
120,879✔
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="))) {
120,879✔
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="))) {
120,879✔
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="))) {
120,878✔
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="))) {
120,877✔
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="))) {
120,877✔
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="))) {
120,867✔
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="))) {
120,867✔
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="))) {
120,865✔
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="))) {
120,865✔
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="))) {
120,864✔
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="))) {
120,864✔
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="))) {
120,863✔
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="))) {
120,863✔
584
                        r = parse_boolean(val);
9,916✔
585
                        if (r < 0)
9,916✔
586
                                return r;
587
                        c->memory_zswap_writeback = r;
9,916✔
588
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-value="))) {
110,947✔
589
                        r = safe_atou64(val, &c->tasks_max.value);
9,620✔
590
                        if (r < 0)
9,620✔
591
                                return r;
592
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-scale="))) {
101,327✔
593
                        r = safe_atou64(val, &c->tasks_max.scale);
9,573✔
594
                        if (r < 0)
9,573✔
595
                                return r;
596
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-min-set="))) {
91,754✔
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="))) {
91,754✔
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="))) {
91,754✔
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="))) {
91,754✔
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="))) {
91,753✔
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="))) {
91,752✔
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="))) {
91,752✔
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="))) {
91,752✔
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="))) {
91,752✔
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="))) {
91,752✔
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="))) {
91,752✔
647
                        c->device_policy = cgroup_device_policy_from_string(val);
9,916✔
648
                        if (c->device_policy < 0)
9,916✔
649
                                return -EINVAL;
650
                } else if ((val = startswith(l, "exec-cgroup-context-disable-controllers="))) {
81,836✔
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="))) {
81,836✔
655
                        r = cg_mask_from_string(val, &c->delegate_controllers);
585✔
656
                        if (r < 0)
585✔
657
                                return r;
658
                } else if ((val = startswith(l, "exec-cgroup-context-delegate="))) {
81,251✔
659
                        r = parse_boolean(val);
698✔
660
                        if (r < 0)
698✔
661
                                return r;
662
                        c->delegate = r;
698✔
663
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-swap="))) {
80,553✔
664
                        c->moom_swap = managed_oom_mode_from_string(val);
9,916✔
665
                        if (c->moom_swap < 0)
9,916✔
666
                                return -EINVAL;
667
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure="))) {
70,637✔
668
                        c->moom_mem_pressure = managed_oom_mode_from_string(val);
9,916✔
669
                        if (c->moom_mem_pressure < 0)
9,916✔
670
                                return -EINVAL;
671
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-limit="))) {
60,721✔
672
                        r = safe_atou32(val, &c->moom_mem_pressure_limit);
9,916✔
673
                        if (r < 0)
9,916✔
674
                                return r;
675
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-preference="))) {
50,805✔
676
                        c->moom_preference = managed_oom_preference_from_string(val);
9,916✔
677
                        if (c->moom_preference < 0)
9,916✔
678
                                return -EINVAL;
679
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec="))) {
40,889✔
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="))) {
40,888✔
684
                        c->memory_pressure_watch = cgroup_pressure_watch_from_string(val);
9,916✔
685
                        if (c->memory_pressure_watch < 0)
9,916✔
686
                                return -EINVAL;
687
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-subgroup="))) {
30,972✔
688
                        r = free_and_strdup(&c->delegate_subgroup, val);
352✔
689
                        if (r < 0)
352✔
690
                                return r;
691
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-threshold-usec="))) {
30,620✔
692
                        r = deserialize_usec(val, &c->memory_pressure_threshold_usec);
9,916✔
693
                        if (r < 0)
9,916✔
694
                                return r;
695
                } else if ((val = startswith(l, "exec-cgroup-context-device-allow="))) {
20,704✔
696
                        _cleanup_free_ char *path = NULL, *rwm = NULL;
3,358✔
697
                        CGroupDevicePermissions p;
3,358✔
698

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

988
        return 0;
77✔
989
}
990

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

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

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

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

1010
                if ((val = startswith(l, "exec-runtime-id="))) {
1,236✔
1011
                        r = free_and_strdup(&rt->shared->id, val);
370✔
1012
                        if (r < 0)
370✔
1013
                                return r;
1014
                } else if ((val = startswith(l, "exec-runtime-tmp-dir="))) {
866✔
1015
                        r = free_and_strdup(&rt->shared->tmp_dir, val);
346✔
1016
                        if (r < 0)
346✔
1017
                                return r;
1018
                } else if ((val = startswith(l, "exec-runtime-var-tmp-dir="))) {
520✔
1019
                        r = free_and_strdup(&rt->shared->var_tmp_dir, val);
346✔
1020
                        if (r < 0)
346✔
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;
9,916✔
1069
}
1070

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1256
        return 0;
2,416✔
1257
}
1258

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

1262
        assert(p);
9,916✔
1263
        assert(f);
9,916✔
1264
        assert(fds);
9,916✔
1265

1266
        unsigned nr_open = MAX(read_nr_open(), NR_OPEN_MINIMUM);
9,916✔
1267

1268
        for (;;) {
211,697✔
1269
                _cleanup_free_ char *l = NULL;
201,781✔
1270
                const char *val;
211,697✔
1271

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

1278
                if ((val = startswith(l, "exec-parameters-runtime-scope="))) {
201,781✔
1279
                        p->runtime_scope = runtime_scope_from_string(val);
9,916✔
1280
                        if (p->runtime_scope < 0)
9,916✔
1281
                                return p->runtime_scope;
1282
                } else if ((val = startswith(l, "exec-parameters-environment="))) {
191,865✔
1283
                        r = deserialize_strv(val, &p->environment);
42,211✔
1284
                        if (r < 0)
42,211✔
1285
                                return r;
1286
                } else if ((val = startswith(l, "exec-parameters-n-socket-fds="))) {
149,654✔
1287
                        if (p->fds)
1,722✔
1288
                                return -EINVAL; /* Already received */
1289

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

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

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

1304
                        if (p->n_stashed_fds > nr_open)
108✔
1305
                                return -EINVAL; /* too many, someone is playing games with us */
1306
                } else if ((val = startswith(l, "exec-parameters-fds="))) {
147,824✔
1307
                        if (p->n_socket_fds + p->n_stashed_fds == 0)
1,727✔
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,727✔
1313
                                return -EINVAL; /* too many, someone is playing games with us */
1314

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

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

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

1330
                } else if ((val = startswith(l, "exec-parameters-fd-names="))) {
146,097✔
1331
                        r = deserialize_strv(val, &p->fd_names);
3,637✔
1332
                        if (r < 0)
3,637✔
1333
                                return r;
1334
                } else if ((val = startswith(l, "exec-parameters-flags="))) {
142,460✔
1335
                        unsigned flags;
9,916✔
1336

1337
                        r = safe_atou(val, &flags);
9,916✔
1338
                        if (r < 0)
9,916✔
1339
                                return r;
×
1340
                        p->flags = flags;
9,916✔
1341
                } else if ((val = startswith(l, "exec-parameters-selinux-context-net="))) {
132,544✔
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="))) {
132,544✔
1348
                        r = free_and_strdup(&p->cgroup_path, val);
9,916✔
1349
                        if (r < 0)
9,916✔
1350
                                return r;
1351
                } else if ((val = startswith(l, "exec-parameters-cgroup-id="))) {
122,628✔
1352
                        r = safe_atou64(val, &p->cgroup_id);
9,916✔
1353
                        if (r < 0)
9,916✔
1354
                                return r;
1355
                } else if ((val = startswith(l, "exec-parameters-prefix-directories-"))) {
112,712✔
1356
                        _cleanup_free_ char *type = NULL, *prefix = NULL;
49,580✔
1357
                        ExecDirectoryType dt;
49,580✔
1358

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

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

1369
                        if (!p->prefix) {
49,580✔
1370
                                p->prefix = new0(char*, _EXEC_DIRECTORY_TYPE_MAX+1);
9,916✔
1371
                                if (!p->prefix)
9,916✔
1372
                                        return log_oom_debug();
×
1373
                        }
1374

1375
                        if (isempty(prefix))
49,580✔
1376
                                p->prefix[dt] = mfree(p->prefix[dt]);
×
1377
                        else
1378
                                free_and_replace(p->prefix[dt], prefix);
49,580✔
1379
                } else if ((val = startswith(l, "exec-parameters-received-credentials-directory="))) {
63,132✔
1380
                        r = free_and_strdup(&p->received_credentials_directory, val);
9,234✔
1381
                        if (r < 0)
9,234✔
1382
                                return r;
1383
                } else if ((val = startswith(l, "exec-parameters-received-encrypted-credentials-directory="))) {
53,898✔
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="))) {
53,898✔
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="))) {
53,898✔
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="))) {
53,898✔
1398
                        r = deserialize_usec(val, &p->watchdog_usec);
1,471✔
1399
                        if (r < 0)
1,471✔
1400
                                return r;
1401
                } else if ((val = startswith(l, "exec-parameters-idle-pipe="))) {
52,427✔
1402
                        if (p->idle_pipe)
83✔
1403
                                return -EINVAL; /* duplicated */
1404

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

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

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

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

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

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

1424
                } else if ((val = startswith(l, "exec-parameters-stdout-fd="))) {
51,807✔
1425
                        int fd;
537✔
1426

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

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

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

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

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

1442
                } else if ((val = startswith(l, "exec-parameters-root-directory-fd="))) {
50,733✔
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="))) {
50,733✔
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="))) {
50,311✔
1460
                        int fd;
9,916✔
1461

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

1466
                        close_and_replace(p->handoff_timestamp_fd, fd);
9,916✔
1467
                } else if ((val = startswith(l, "exec-parameters-pidref-transport-fd="))) {
40,395✔
1468
                        int fd;
8,771✔
1469

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

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

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

1482
                        close_and_replace(p->bpf_restrict_fs_map_fd, fd);
×
1483
                } else if ((val = startswith(l, "exec-parameters-notify-socket="))) {
31,624✔
1484
                        r = free_and_strdup(&p->notify_socket, val);
1,867✔
1485
                        if (r < 0)
1,867✔
1486
                                return r;
1487
                } else if ((val = startswith(l, "exec-parameters-open-file="))) {
29,757✔
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="))) {
29,752✔
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="))) {
29,752✔
1500
                        int fd;
9,916✔
1501

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

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

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

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

1539
        return 0;
1540
}
1541

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

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

1550
        type = fileno == STDOUT_FILENO ? "output" : "error";
4,832✔
1551

1552
        switch (fileno == STDOUT_FILENO ? c->std_output : c->std_error) {
4,832✔
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,416✔
1585
        int r;
2,416✔
1586

1587
        assert(f);
2,416✔
1588

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

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

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

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

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

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

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

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

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

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

1628
        if (c->root_image_options) {
2,416✔
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,416✔
1654
        if (r < 0)
2,416✔
1655
                return r;
1656

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

1661
        r = serialize_item(f, "exec-context-root-hash-sig-path", c->root_hash_sig_path);
2,416✔
1662
        if (r < 0)
2,416✔
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,416✔
1666
        if (r < 0)
2,416✔
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,416✔
1670
        if (r < 0)
2,416✔
1671
                return r;
1672

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

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

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

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

1689
        r = serialize_item_tristate(f, "exec-context-mount-api-vfs", c->mount_apivfs);
2,416✔
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,416✔
1694
        if (r < 0)
×
1695
                return r;
1696

1697
        r = serialize_item_tristate(f, "exec-context-memory-ksm", c->memory_ksm);
2,416✔
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,416✔
1702
        if (r < 0)
2,416✔
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,416✔
1707
        r = serialize_item(f, "exec-context-private-var-tmp", private_tmp_to_string(c->private_var_tmp));
2,416✔
1708
        if (r < 0)
2,416✔
1709
                return r;
1710

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1807
        if (c->bpf_delegate_commands != 0) {
2,416✔
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,416✔
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,416✔
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,416✔
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,416✔
1832
        if (r < 0)
2,416✔
1833
                return r;
1834

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

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

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

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

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

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

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

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

1861
                        STRV_FOREACH(d, i->symlinks) {
431✔
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,080✔
1874
                if (r < 0)
12,080✔
1875
                        return r;
1876

1877
                if (c->directories[dt].exec_quota.quota_enforce) {
12,080✔
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,080✔
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,416✔
1901
        if (r < 0)
2,416✔
1902
                return r;
1903

1904
        if (c->nice_set) {
2,416✔
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,416✔
1911
                r = serialize_item_format(f, "exec-context-oom-score-adjust", "%i", c->oom_score_adjust);
591✔
1912
                if (r < 0)
591✔
1913
                        return r;
1914
        }
1915

1916
        if (c->coredump_filter_set) {
2,416✔
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++) {
41,072✔
1923
                _cleanup_free_ char *key = NULL, *limit = NULL;
4,826✔
1924

1925
                if (!c->rlimit[i])
38,656✔
1926
                        continue;
33,830✔
1927

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

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

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

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

1947
        if (c->cpu_sched_set) {
2,416✔
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,416✔
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,416✔
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,416✔
1998
        if (r < 0)
2,416✔
1999
                return r;
2000

2001
        if (c->timer_slack_nsec != NSEC_INFINITY) {
2,416✔
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,416✔
2008
        if (r < 0)
2,416✔
2009
                return r;
2010

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

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

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

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

2027
        switch (c->std_input) {
2,416✔
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,416✔
2041
                ;
2,416✔
2042
        }
2043

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

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

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

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

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

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

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

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

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

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

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

2088
        r = serialize_item(f, "exec-context-syslog-identifier", c->syslog_identifier);
2,416✔
2089
        if (r < 0)
2,416✔
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,416✔
2095
        if (r < 0)
2,416✔
2096
                return r;
2097

2098
        if (c->log_ratelimit.interval > 0) {
2,416✔
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,416✔
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,416✔
2111
        if (r < 0)
2,416✔
2112
                return r;
2113

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

2118
        FOREACH_ARRAY(field, c->log_extra_fields, c->n_log_extra_fields) {
2,657✔
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,416✔
2125
        if (r < 0)
2,416✔
2126
                return r;
2127

2128
        if (c->secure_bits != 0) {
2,416✔
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,416✔
2135
                r = serialize_item_format(f, "exec-context-capability-bounding-set", "%" PRIu64, c->capability_bounding_set);
2,416✔
2136
                if (r < 0)
2,416✔
2137
                        return r;
2138
        }
2139

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2200
        FOREACH_ARRAY(mount, c->bind_mounts, c->n_bind_mounts) {
2,431✔
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,420✔
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,416✔
2240
        if (r < 0)
2,416✔
2241
                return r;
2242

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

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

2251
        if (c->selinux_context) {
2,416✔
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,416✔
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,416✔
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,416✔
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,416✔
2285
        if (r < 0)
2,416✔
2286
                return r;
2287

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

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

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

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

2317
        if (!hashmap_isempty(c->syscall_log)) {
2,416✔
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,416✔
2327
        if (r < 0)
2,416✔
2328
                return r;
2329
#endif
2330

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

2337
        if (c->delegate_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,416✔
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,416✔
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,416✔
2354
        if (r < 0)
2,416✔
2355
                return r;
2356
#endif
2357

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

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

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

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

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

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

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

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

2389
        FOREACH_ARRAY(mount, c->mount_images, c->n_mount_images) {
2,416✔
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,421✔
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,416✔
2466
        if (r < 0)
2,416✔
2467
                return r;
2468

2469
        ExecSetCredential *sc;
2,416✔
2470
        HASHMAP_FOREACH(sc, c->set_credentials) {
2,422✔
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,416✔
2482
        HASHMAP_FOREACH(lc, c->load_credentials) {
2,427✔
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,416✔
2489
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
3,363✔
2490
                r = serialize_item_format(f, "exec-context-import-credentials", "%s%s%s",
1,844✔
2491
                                          ic->glob,
2492
                                          ic->rename ? " " : "",
2493
                                          strempty(ic->rename));
947✔
2494
                if (r < 0)
947✔
2495
                        return r;
×
2496
        }
2497

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

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

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

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

2512
        return 0;
2513
}
2514

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

2518
        assert(f);
9,916✔
2519

2520
        if (!c)
9,916✔
2521
                return 0;
2522

2523
        for (;;) {
947,835✔
2524
                _cleanup_free_ char *l = NULL;
937,919✔
2525
                const char *val;
947,835✔
2526

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

2533
                if ((val = startswith(l, "exec-context-environment="))) {
937,919✔
2534
                        r = deserialize_strv(val, &c->environment);
3,137✔
2535
                        if (r < 0)
3,137✔
2536
                                return r;
2537
                } else if ((val = startswith(l, "exec-context-environment-files="))) {
934,782✔
2538
                        r = deserialize_strv(val, &c->environment_files);
343✔
2539
                        if (r < 0)
343✔
2540
                                return r;
2541
                } else if ((val = startswith(l, "exec-context-pass-environment="))) {
934,439✔
2542
                        r = deserialize_strv(val, &c->pass_environment);
312✔
2543
                        if (r < 0)
312✔
2544
                                return r;
2545
                } else if ((val = startswith(l, "exec-context-unset-environment="))) {
934,127✔
2546
                        r = deserialize_strv(val, &c->unset_environment);
958✔
2547
                        if (r < 0)
958✔
2548
                                return r;
2549
                } else if ((val = startswith(l, "exec-context-working-directory="))) {
933,169✔
2550
                        ssize_t k;
748✔
2551
                        char *p;
748✔
2552

2553
                        k = cunescape(val, 0, &p);
748✔
2554
                        if (k < 0)
748✔
2555
                                return k;
×
2556
                        free_and_replace(c->working_directory, p);
748✔
2557
                } else if ((val = startswith(l, "exec-context-root-directory="))) {
932,421✔
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="))) {
932,414✔
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="))) {
932,405✔
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="))) {
932,405✔
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="))) {
932,405✔
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="))) {
932,405✔
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="))) {
932,405✔
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="))) {
932,401✔
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="))) {
932,401✔
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="))) {
932,401✔
2634
                        r = parse_mode(val, &c->umask);
9,916✔
2635
                        if (r < 0)
9,916✔
2636
                                return r;
2637
                } else if ((val = startswith(l, "exec-context-private-non-blocking="))) {
922,485✔
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="))) {
922,485✔
2643
                        r = safe_atoi(val, &c->private_mounts);
136✔
2644
                        if (r < 0)
136✔
2645
                                return r;
2646
                } else if ((val = startswith(l, "exec-context-mount-api-vfs="))) {
922,349✔
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="))) {
922,320✔
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="))) {
922,318✔
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="))) {
922,318✔
2659
                        c->private_tmp = private_tmp_from_string(val);
9,916✔
2660
                        if (c->private_tmp < 0)
9,916✔
2661
                                return c->private_tmp;
2662
                } else if ((val = startswith(l, "exec-context-private-var-tmp="))) {
912,402✔
2663
                        c->private_var_tmp = private_tmp_from_string(val);
9,916✔
2664
                        if (c->private_var_tmp < 0)
9,916✔
2665
                                return c->private_var_tmp;
2666
                } else if ((val = startswith(l, "exec-context-private-devices="))) {
902,486✔
2667
                        r = parse_boolean(val);
487✔
2668
                        if (r < 0)
487✔
2669
                                return r;
2670
                        c->private_devices = r;
487✔
2671
                } else if ((val = startswith(l, "exec-context-protect-kernel-tunables="))) {
901,999✔
2672
                        r = parse_boolean(val);
305✔
2673
                        if (r < 0)
305✔
2674
                                return r;
2675
                        c->protect_kernel_tunables = r;
305✔
2676
                } else if ((val = startswith(l, "exec-context-protect-kernel-modules="))) {
901,694✔
2677
                        r = parse_boolean(val);
1,093✔
2678
                        if (r < 0)
1,093✔
2679
                                return r;
2680
                        c->protect_kernel_modules = r;
1,093✔
2681
                } else if ((val = startswith(l, "exec-context-protect-kernel-logs="))) {
900,601✔
2682
                        r = parse_boolean(val);
1,093✔
2683
                        if (r < 0)
1,093✔
2684
                                return r;
2685
                        c->protect_kernel_logs = r;
1,093✔
2686
                } else if ((val = startswith(l, "exec-context-protect-clock="))) {
899,508✔
2687
                        r = parse_boolean(val);
891✔
2688
                        if (r < 0)
891✔
2689
                                return r;
2690
                        c->protect_clock = r;
891✔
2691
                } else if ((val = startswith(l, "exec-context-protect-control-groups="))) {
898,617✔
2692
                        r = protect_control_groups_from_string(val);
9,916✔
2693
                        if (r < 0)
9,916✔
2694
                                return r;
2695
                        c->protect_control_groups = r;
9,916✔
2696
                } else if ((val = startswith(l, "exec-context-private-network="))) {
888,701✔
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="))) {
888,631✔
2702
                        c->private_users = private_users_from_string(val);
9,916✔
2703
                        if (c->private_users < 0)
9,916✔
2704
                                return -EINVAL;
2705
                } else if ((val = startswith(l, "exec-context-private-ipc="))) {
878,715✔
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="))) {
878,709✔
2711
                        c->private_pids = private_pids_from_string(val);
9,916✔
2712
                        if (c->private_pids < 0)
9,916✔
2713
                                return -EINVAL;
2714
                } else if ((val = startswith(l, "exec-context-remove-ipc="))) {
868,793✔
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="))) {
868,738✔
2720
                        c->protect_home = protect_home_from_string(val);
9,916✔
2721
                        if (c->protect_home < 0)
9,916✔
2722
                                return -EINVAL;
2723
                } else if ((val = startswith(l, "exec-context-protect-system="))) {
858,822✔
2724
                        c->protect_system = protect_system_from_string(val);
9,916✔
2725
                        if (c->protect_system < 0)
9,916✔
2726
                                return -EINVAL;
2727
                } else if ((val = startswith(l, "exec-context-same-pgrp="))) {
848,906✔
2728
                        r = parse_boolean(val);
826✔
2729
                        if (r < 0)
826✔
2730
                                return r;
2731
                        c->same_pgrp = r;
826✔
2732
                } else if ((val = startswith(l, "exec-context-non-blocking="))) {
848,080✔
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="))) {
848,080✔
2738
                        r = parse_boolean(val);
9,916✔
2739
                        if (r < 0)
9,916✔
2740
                                return r;
2741
                        c->ignore_sigpipe = r;
9,916✔
2742
                } else if ((val = startswith(l, "exec-context-memory-deny-write-execute="))) {
838,164✔
2743
                        r = parse_boolean(val);
1,450✔
2744
                        if (r < 0)
1,450✔
2745
                                return r;
2746
                        c->memory_deny_write_execute = r;
1,450✔
2747
                } else if ((val = startswith(l, "exec-context-restrict-realtime="))) {
836,714✔
2748
                        r = parse_boolean(val);
1,452✔
2749
                        if (r < 0)
1,452✔
2750
                                return r;
2751
                        c->restrict_realtime = r;
1,452✔
2752
                } else if ((val = startswith(l, "exec-context-restrict-suid-sgid="))) {
835,262✔
2753
                        r = parse_boolean(val);
1,355✔
2754
                        if (r < 0)
1,355✔
2755
                                return r;
2756
                        c->restrict_suid_sgid = r;
1,355✔
2757
                } else if ((val = startswith(l, "exec-context-keyring-mode="))) {
833,907✔
2758
                        c->keyring_mode = exec_keyring_mode_from_string(val);
9,916✔
2759
                        if (c->keyring_mode < 0)
9,916✔
2760
                                return -EINVAL;
2761
                } else if ((val = startswith(l, "exec-context-protect-hostname="))) {
823,991✔
2762
                        c->protect_hostname = protect_hostname_from_string(val);
9,916✔
2763
                        if (c->protect_hostname < 0)
9,916✔
2764
                                return -EINVAL;
2765
                } else if ((val = startswith(l, "exec-context-private-hostname="))) {
814,075✔
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="))) {
814,070✔
2770
                        c->protect_proc = protect_proc_from_string(val);
9,916✔
2771
                        if (c->protect_proc < 0)
9,916✔
2772
                                return -EINVAL;
2773
                } else if ((val = startswith(l, "exec-context-proc-subset="))) {
804,154✔
2774
                        c->proc_subset = proc_subset_from_string(val);
9,916✔
2775
                        if (c->proc_subset < 0)
9,916✔
2776
                                return -EINVAL;
2777
                } else if ((val = startswith(l, "exec-context-private-bpf="))) {
794,238✔
2778
                        c->private_bpf = private_bpf_from_string(val);
9,916✔
2779
                        if (c->private_bpf < 0)
9,916✔
2780
                                return -EINVAL;
2781
                } else if ((val = startswith(l, "exec-context-bpf-delegate-commands="))) {
784,322✔
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="))) {
784,320✔
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="))) {
784,319✔
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="))) {
784,318✔
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="))) {
784,317✔
2798
                        c->runtime_directory_preserve_mode = exec_preserve_mode_from_string(val);
9,916✔
2799
                        if (c->runtime_directory_preserve_mode < 0)
9,916✔
2800
                                return -EINVAL;
2801
                } else if ((val = startswith(l, "exec-context-directories-"))) {
774,401✔
2802
                        _cleanup_free_ char *type = NULL, *mode = NULL;
×
2803
                        ExecDirectoryType dt;
49,580✔
2804

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

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

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

2819
                        for (;;) {
52,508✔
2820
                                _cleanup_free_ char *tuple = NULL, *path = NULL, *only_create = NULL, *read_only = NULL;
52,401✔
2821
                                ExecDirectoryFlags exec_directory_flags = 0;
52,508✔
2822
                                const char *p;
52,508✔
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);
52,508✔
2826
                                if (r < 0)
52,508✔
2827
                                        return r;
2828
                                if (r == 0)
52,508✔
2829
                                        break;
2830

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

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

2844
                                r = parse_boolean(read_only);
2,928✔
2845
                                if (r < 0)
2,928✔
2846
                                        return r;
2847
                                if (r > 0)
2,928✔
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,928✔
2851
                                if (r < 0)
2,928✔
2852
                                        return r;
2853

2854
                                if (isempty(p))
2,928✔
2855
                                        continue;
2,821✔
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-"))) {
724,821✔
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-"))) {
724,821✔
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="))) {
724,821✔
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="))) {
724,821✔
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="))) {
724,802✔
2923
                        r = parse_boolean(val);
687✔
2924
                        if (r < 0)
687✔
2925
                                return r;
2926
                        c->working_directory_missing_ok = r;
687✔
2927
                } else if ((val = startswith(l, "exec-context-working-directory-home="))) {
724,115✔
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="))) {
723,941✔
2933
                        r = safe_atoi(val, &c->oom_score_adjust);
1,070✔
2934
                        if (r < 0)
1,070✔
2935
                                return r;
2936
                        c->oom_score_adjust_set = true;
1,070✔
2937
                } else if ((val = startswith(l, "exec-context-coredump-filter="))) {
722,871✔
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-"))) {
722,869✔
2943
                        _cleanup_free_ struct rlimit *rlimit = NULL;
×
2944
                        _cleanup_free_ char *limit = NULL;
19,827✔
2945
                        int type;
19,827✔
2946

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

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

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

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

2966
                                c->rlimit[type] = TAKE_PTR(rlimit);
19,827✔
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="))) {
703,042✔
2973
                        r = safe_atoi(val, &c->ioprio);
10✔
2974
                        if (r < 0)
10✔
2975
                                return r;
2976
                        c->ioprio_is_set = true;
10✔
2977
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-policy="))) {
703,032✔
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="))) {
703,032✔
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="))) {
703,032✔
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="))) {
703,032✔
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="))) {
703,032✔
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="))) {
703,013✔
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="))) {
702,994✔
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="))) {
702,992✔
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="))) {
702,992✔
3021
                        c->std_input = exec_input_from_string(val);
9,916✔
3022
                        if (c->std_input < 0)
9,916✔
3023
                                return c->std_input;
3024
                } else if ((val = startswith(l, "exec-context-std-output="))) {
693,076✔
3025
                        c->std_output = exec_output_from_string(val);
9,916✔
3026
                        if (c->std_output < 0)
9,916✔
3027
                                return c->std_output;
3028
                } else if ((val = startswith(l, "exec-context-std-error="))) {
683,160✔
3029
                        c->std_error = exec_output_from_string(val);
9,916✔
3030
                        if (c->std_error < 0)
9,916✔
3031
                                return c->std_error;
3032
                } else if ((val = startswith(l, "exec-context-stdio-as-fds="))) {
673,244✔
3033
                        r = parse_boolean(val);
537✔
3034
                        if (r < 0)
537✔
3035
                                return r;
3036
                        c->stdio_as_fds = r;
537✔
3037
                } else if ((val = startswith(l, "exec-context-root-directory-as-fd="))) {
672,707✔
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="))) {
672,707✔
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="))) {
672,707✔
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="))) {
672,707✔
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="))) {
672,707✔
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="))) {
672,707✔
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="))) {
672,657✔
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="))) {
672,656✔
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="))) {
672,654✔
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="))) {
672,607✔
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="))) {
672,606✔
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="))) {
672,605✔
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="))) {
672,604✔
3090
                        r = free_and_strdup(&c->tty_path, val);
102✔
3091
                        if (r < 0)
102✔
3092
                                return r;
3093
                } else if ((val = startswith(l, "exec-context-tty-reset="))) {
672,502✔
3094
                        r = parse_boolean(val);
189✔
3095
                        if (r < 0)
189✔
3096
                                return r;
3097
                        c->tty_reset = r;
189✔
3098
                } else if ((val = startswith(l, "exec-context-tty-vhangup="))) {
672,313✔
3099
                        r = parse_boolean(val);
81✔
3100
                        if (r < 0)
81✔
3101
                                return r;
3102
                        c->tty_vhangup = r;
81✔
3103
                } else if ((val = startswith(l, "exec-context-tty-vt-disallocate="))) {
672,232✔
3104
                        r = parse_boolean(val);
45✔
3105
                        if (r < 0)
45✔
3106
                                return r;
3107
                        c->tty_vt_disallocate = r;
45✔
3108
                } else if ((val = startswith(l, "exec-context-tty-rows="))) {
672,187✔
3109
                        r = safe_atou(val, &c->tty_rows);
9,916✔
3110
                        if (r < 0)
9,916✔
3111
                                return r;
3112
                } else if ((val = startswith(l, "exec-context-tty-columns="))) {
662,271✔
3113
                        r = safe_atou(val, &c->tty_cols);
9,916✔
3114
                        if (r < 0)
9,916✔
3115
                                return r;
3116
                } else if ((val = startswith(l, "exec-context-syslog-priority="))) {
652,355✔
3117
                        r = safe_atoi(val, &c->syslog_priority);
9,916✔
3118
                        if (r < 0)
9,916✔
3119
                                return r;
3120
                } else if ((val = startswith(l, "exec-context-syslog-level-prefix="))) {
642,439✔
3121
                        r = parse_boolean(val);
9,916✔
3122
                        if (r < 0)
9,916✔
3123
                                return r;
3124
                        c->syslog_level_prefix = r;
9,916✔
3125
                } else if ((val = startswith(l, "exec-context-syslog-identifier="))) {
632,523✔
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="))) {
632,523✔
3130
                        /* See comment in serialization. */
3131
                        r = safe_atoi(val, &c->log_level_max);
9,916✔
3132
                        if (r < 0)
9,916✔
3133
                                return r;
3134
                } else if ((val = startswith(l, "exec-context-log-ratelimit-interval-usec="))) {
622,607✔
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="))) {
622,607✔
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="))) {
622,607✔
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="))) {
622,587✔
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="))) {
622,574✔
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="))) {
621,883✔
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="))) {
621,881✔
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="))) {
621,881✔
3166
                        r = safe_atou64(val, &c->capability_bounding_set);
9,916✔
3167
                        if (r < 0)
9,916✔
3168
                                return r;
3169
                } else if ((val = startswith(l, "exec-context-capability-ambient-set="))) {
611,965✔
3170
                        r = safe_atou64(val, &c->capability_ambient_set);
647✔
3171
                        if (r < 0)
647✔
3172
                                return r;
3173
                } else if ((val = startswith(l, "exec-context-user="))) {
611,318✔
3174
                        r = free_and_strdup(&c->user, val);
2,056✔
3175
                        if (r < 0)
2,056✔
3176
                                return r;
3177
                } else if ((val = startswith(l, "exec-context-group="))) {
609,262✔
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="))) {
609,202✔
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="))) {
609,155✔
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="))) {
609,143✔
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="))) {
609,143✔
3195
                        r = free_and_strdup(&c->pam_name, val);
502✔
3196
                        if (r < 0)
502✔
3197
                                return r;
3198
                } else if ((val = startswith(l, "exec-context-read-write-paths="))) {
608,641✔
3199
                        r = deserialize_strv(val, &c->read_write_paths);
804✔
3200
                        if (r < 0)
804✔
3201
                                return r;
3202
                } else if ((val = startswith(l, "exec-context-read-only-paths="))) {
607,837✔
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="))) {
607,835✔
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="))) {
607,830✔
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="))) {
607,829✔
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="))) {
607,828✔
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="))) {
607,828✔
3223
                        r = safe_atolu(val, &c->mount_propagation_flag);
9,916✔
3224
                        if (r < 0)
9,916✔
3225
                                return r;
3226
                } else if ((val = startswith(l, "exec-context-bind-read-only-path="))) {
597,912✔
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="))) {
597,905✔
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="))) {
597,885✔
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="))) {
597,824✔
3357
                        r = free_and_strdup(&c->utmp_id, val);
88✔
3358
                        if (r < 0)
88✔
3359
                                return r;
3360
                } else if ((val = startswith(l, "exec-context-utmp-mode="))) {
597,736✔
3361
                        c->utmp_mode = exec_utmp_mode_from_string(val);
9,916✔
3362
                        if (c->utmp_mode < 0)
9,916✔
3363
                                return c->utmp_mode;
3364
                } else if ((val = startswith(l, "exec-context-no-new-privileges="))) {
587,820✔
3365
                        r = parse_boolean(val);
1,384✔
3366
                        if (r < 0)
1,384✔
3367
                                return r;
3368
                        c->no_new_privileges = r;
1,384✔
3369
                } else if ((val = startswith(l, "exec-context-selinux-context="))) {
586,436✔
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="))) {
586,436✔
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="))) {
586,436✔
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="))) {
586,436✔
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="))) {
586,436✔
3404
                        r = parse_boolean(val);
1,455✔
3405
                        if (r < 0)
1,455✔
3406
                                return r;
3407
                        c->lock_personality = r;
1,455✔
3408
#if HAVE_SECCOMP
3409
                } else if ((val = startswith(l, "exec-context-syscall-filter="))) {
584,981✔
3410
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
559,636✔
3411
                        int id, errno_num;
559,636✔
3412

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

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

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

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

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

3437
                        r = set_ensure_put(&c->syscall_archs, NULL, UINT_TO_PTR(id + 1));
1,458✔
3438
                        if (r < 0)
1,458✔
3439
                                return r;
3440
                } else if ((val = startswith(l, "exec-context-syscall-errno="))) {
23,887✔
3441
                        r = safe_atoi(val, &c->syscall_errno);
9,916✔
3442
                        if (r < 0)
9,916✔
3443
                                return r;
3444
                } else if ((val = startswith(l, "exec-context-syscall-allow-list="))) {
13,971✔
3445
                        r = parse_boolean(val);
1,432✔
3446
                        if (r < 0)
1,432✔
3447
                                return r;
3448
                        c->syscall_allow_list = r;
1,432✔
3449
                } else if ((val = startswith(l, "exec-context-syscall-log="))) {
12,539✔
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,539✔
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,539✔
3477
                        r = safe_atolu(val, &c->restrict_namespaces);
1,207✔
3478
                        if (r < 0)
1,207✔
3479
                                return r;
3480
                } else if ((val = startswith(l, "exec-context-delegate-namespaces="))) {
11,332✔
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,311✔
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,311✔
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,311✔
3494
                        int af;
5,721✔
3495

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

3500
                        r = set_ensure_put(&c->address_families, NULL, INT_TO_PTR(af));
5,721✔
3501
                        if (r < 0)
5,721✔
3502
                                return r;
3503
                } else if ((val = startswith(l, "exec-context-address-families-allow-list="))) {
5,590✔
3504
                        r = parse_boolean(val);
1,450✔
3505
                        if (r < 0)
1,450✔
3506
                                return r;
3507
                        c->address_families_allow_list = r;
1,450✔
3508
                } else if ((val = startswith(l, "exec-context-network-namespace-path="))) {
4,140✔
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,139✔
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,136✔
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,136✔
3521
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3522
                        _cleanup_free_ char *source = NULL, *destination = NULL;
43✔
3523
                        bool permissive = false;
43✔
3524
                        char *s;
43✔
3525

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

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

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

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

3551
                                r = extract_first_word(&val, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
48✔
3552
                                if (r < 0)
48✔
3553
                                        return r;
3554
                                if (r == 0)
48✔
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,
86✔
3595
                                        &(MountImage) {
43✔
3596
                                                .source = s,
3597
                                                .destination = destination,
3598
                                                .mount_options = options,
3599
                                                .ignore_enoent = permissive,
3600
                                                .type = MOUNT_IMAGE_DISCRETE,
3601
                                        });
3602
                        if (r < 0)
43✔
3603
                                return log_oom_debug();
×
3604
                } else if ((val = startswith(l, "exec-context-extension-image="))) {
4,093✔
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,080✔
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,072✔
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="))) {
3,979✔
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="))) {
3,945✔
3728
                        _cleanup_free_ char *glob = NULL, *rename = NULL;
3,939✔
3729

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

3736
                        r = exec_context_put_import_credential(c, glob, rename);
3,939✔
3737
                        if (r < 0)
3,939✔
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, &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

3750
                        r = image_policy_from_string(val, &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, &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;
9,916✔
3765
}
3766

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

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

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

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

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

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

3787
        return 0;
2,416✔
3788
}
3789

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

3793
        assert(c);
9,916✔
3794
        assert(f);
9,916✔
3795

3796
        for (;;) {
107,388✔
3797
                _cleanup_free_ char *l = NULL;
48,736✔
3798
                const char *val;
58,652✔
3799

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

3806
                if ((val = startswith(l, "exec-command-path="))) {
48,736✔
3807
                        r = free_and_strdup(&c->path, val);
9,916✔
3808
                        if (r < 0)
9,916✔
3809
                                return r;
3810
                } else if ((val = startswith(l, "exec-command-argv="))) {
38,820✔
3811
                        r = deserialize_strv(val, &c->argv);
28,904✔
3812
                        if (r < 0)
28,904✔
3813
                                return r;
3814
                } else if ((val = startswith(l, "exec-command-flags="))) {
9,916✔
3815
                        r = safe_atoi(val, &c->flags);
9,916✔
3816
                        if (r < 0)
9,916✔
3817
                                return r;
3818
                } else
3819
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3820

3821
        }
3822

3823
        return 0;
9,916✔
3824
}
3825

3826
int exec_serialize_invocation(
2,416✔
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,416✔
3836

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

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

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

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

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

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

3860
        return 0;
3861
}
3862

3863
int exec_deserialize_invocation(
9,916✔
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;
9,916✔
3873

3874
        assert(f);
9,916✔
3875
        assert(fds);
9,916✔
3876

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

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

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

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

3893
        r = exec_cgroup_context_deserialize(cg, f);
9,916✔
3894
        if (r < 0)
9,916✔
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