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

systemd / systemd / 23518499972

24 Mar 2026 09:45PM UTC coverage: 72.567% (-0.01%) from 72.581%
23518499972

push

github

web-flow
resolved: add "static RRs" concept (#41213)

split out of #40980

301 of 337 new or added lines in 9 files covered. (89.32%)

3451 existing lines in 67 files now uncovered.

316989 of 436822 relevant lines covered (72.57%)

1153112.24 hits per line

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

74.75
/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
#include "unit.h"
34

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

43
        assert(f);
2,517✔
44

45
        if (!c)
2,517✔
46
                return 0;
47

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

148
        if (c->startup_memory_low > 0) {
2,517✔
149
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-low", "%" PRIu64, c->startup_memory_low);
×
150
                if (r < 0)
×
151
                        return r;
152
        }
153

154
        if (c->memory_high != CGROUP_LIMIT_MAX) {
2,517✔
155
                r = serialize_item_format(f, "exec-cgroup-context-memory-high", "%" PRIu64, c->memory_high);
2✔
156
                if (r < 0)
2✔
157
                        return r;
158
        }
159

160
        if (c->startup_memory_high != CGROUP_LIMIT_MAX) {
2,517✔
161
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-high", "%" PRIu64, c->startup_memory_high);
×
162
                if (r < 0)
×
163
                        return r;
164
        }
165

166
        if (c->memory_max != CGROUP_LIMIT_MAX) {
2,517✔
167
                r = serialize_item_format(f, "exec-cgroup-context-memory-max", "%" PRIu64, c->memory_max);
1✔
168
                if (r < 0)
1✔
169
                        return r;
170
        }
171

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

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

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

190
        if (c->memory_zswap_max != CGROUP_LIMIT_MAX) {
2,517✔
191
                r = serialize_item_format(f, "exec-cgroup-context-memory-zswap-max", "%" PRIu64, c->memory_zswap_max);
×
192
                if (r < 0)
×
193
                        return r;
194
        }
195

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

202
        r = serialize_bool(f, "exec-cgroup-context-memory-zswap-writeback", c->memory_zswap_writeback);
2,517✔
203
        if (r < 0)
2,517✔
204
                return r;
205

206
        if (c->tasks_max.value != UINT64_MAX) {
2,517✔
207
                r = serialize_item_format(f, "exec-cgroup-context-tasks-max-value", "%" PRIu64, c->tasks_max.value);
2,464✔
208
                if (r < 0)
2,464✔
209
                        return r;
210
        }
211

212
        if (c->tasks_max.scale > 0) {
2,517✔
213
                r = serialize_item_format(f, "exec-cgroup-context-tasks-max-scale", "%" PRIu64, c->tasks_max.scale);
2,456✔
214
                if (r < 0)
2,456✔
215
                        return r;
216
        }
217

218
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-low-set", c->startup_memory_low_set);
2,517✔
219
        if (r < 0)
2,517✔
220
                return r;
221

222
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-high-set", c->startup_memory_high_set);
2,517✔
223
        if (r < 0)
2,517✔
224
                return r;
225

226
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-max-set", c->startup_memory_max_set);
2,517✔
227
        if (r < 0)
2,517✔
228
                return r;
229

230
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-swap-max-set", c->startup_memory_swap_max_set);
2,517✔
231
        if (r < 0)
2,517✔
232
                return r;
233

234
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-zswap-max-set", c->startup_memory_zswap_max_set);
2,517✔
235
        if (r < 0)
2,517✔
236
                return r;
237

238
        r = serialize_item(f, "exec-cgroup-context-device-policy", cgroup_device_policy_to_string(c->device_policy));
2,517✔
239
        if (r < 0)
2,517✔
240
                return r;
241

242
        r = cg_mask_to_string(c->disable_controllers, &disable_controllers_str);
2,517✔
243
        if (r < 0)
2,517✔
244
                return r;
245

246
        r = serialize_item(f, "exec-cgroup-context-disable-controllers", disable_controllers_str);
2,517✔
247
        if (r < 0)
2,517✔
248
                return r;
249

250
        r = cg_mask_to_string(c->delegate_controllers, &delegate_controllers_str);
2,517✔
251
        if (r < 0)
2,517✔
252
                return r;
253

254
        r = serialize_item(f, "exec-cgroup-context-delegate-controllers", delegate_controllers_str);
2,517✔
255
        if (r < 0)
2,517✔
256
                return r;
257

258
        r = serialize_bool_elide(f, "exec-cgroup-context-delegate", c->delegate);
2,517✔
259
        if (r < 0)
2,517✔
260
                return r;
261

262
        r = serialize_item(f, "exec-cgroup-context-managed-oom-swap", managed_oom_mode_to_string(c->moom_swap));
2,517✔
263
        if (r < 0)
2,517✔
264
                return r;
265

266
        r = serialize_item(f, "exec-cgroup-context-managed-oom-memory-pressure", managed_oom_mode_to_string(c->moom_mem_pressure));
2,517✔
267
        if (r < 0)
2,517✔
268
                return r;
269

270
        r = serialize_item_format(f, "exec-cgroup-context-managed-oom-memory-pressure-limit", "%" PRIu32, c->moom_mem_pressure_limit);
2,517✔
271
        if (r < 0)
2,517✔
272
                return r;
273

274
        r = serialize_usec(f, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec", c->moom_mem_pressure_duration_usec);
2,517✔
275
        if (r < 0)
2,517✔
276
                return r;
277

278
        r = serialize_item(f, "exec-cgroup-context-managed-oom-preference", managed_oom_preference_to_string(c->moom_preference));
2,517✔
279
        if (r < 0)
2,517✔
280
                return r;
281

282
        r = serialize_item(f, "exec-cgroup-context-memory-pressure-watch", cgroup_pressure_watch_to_string(c->memory_pressure_watch));
2,517✔
283
        if (r < 0)
2,517✔
284
                return r;
285

286
        r = serialize_item(f, "exec-cgroup-context-delegate-subgroup", c->delegate_subgroup);
2,517✔
287
        if (r < 0)
2,517✔
288
                return r;
289

290
        if (c->memory_pressure_threshold_usec != USEC_INFINITY) {
2,517✔
291
                r = serialize_usec(f, "exec-cgroup-context-memory-pressure-threshold-usec", c->memory_pressure_threshold_usec);
2,517✔
292
                if (r < 0)
2,517✔
293
                        return r;
294
        }
295

296
        LIST_FOREACH(device_allow, a, c->device_allow) {
3,200✔
297
                r = serialize_item_format(f, "exec-cgroup-context-device-allow", "%s %s",
683✔
298
                                          a->path,
299
                                          cgroup_device_permissions_to_string(a->permissions));
300
                if (r < 0)
683✔
301
                        return r;
302
        }
303

304
        LIST_FOREACH(device_weights, iw, c->io_device_weights) {
2,517✔
305
                r = serialize_item_format(f, "exec-cgroup-context-io-device-weight", "%s %" PRIu64,
×
306
                                          iw->path,
307
                                          iw->weight);
308
                if (r < 0)
×
309
                        return r;
310
        }
311

312
        LIST_FOREACH(device_latencies, l, c->io_device_latencies) {
2,517✔
313
                r = serialize_item_format(f, "exec-cgroup-context-io-device-latency-target-usec", "%s " USEC_FMT,
×
314
                                          l->path,
315
                                          l->target_usec);
316
                if (r < 0)
×
317
                        return r;
318
        }
319

320
        LIST_FOREACH(device_limits, il, c->io_device_limits)
2,517✔
321
                for (CGroupIOLimitType type = 0; type < _CGROUP_IO_LIMIT_TYPE_MAX; type++) {
×
322
                        _cleanup_free_ char *key = NULL;
×
323

324
                        if (il->limits[type] == cgroup_io_limit_defaults[type])
×
325
                                continue;
×
326

327
                        key = strjoin("exec-cgroup-context-io-device-limit-", cgroup_io_limit_type_to_string(type));
×
328
                        if (!key)
×
329
                                return -ENOMEM;
330

331
                        r = serialize_item_format(f, key, "%s %" PRIu64, il->path, il->limits[type]);
×
332
                        if (r < 0)
×
333
                                return r;
334
                }
335

336
        SET_FOREACH(iaai, c->ip_address_allow) {
2,517✔
337
                r = serialize_item(f,
×
338
                                   "exec-cgroup-context-ip-address-allow",
339
                                   IN_ADDR_PREFIX_TO_STRING(iaai->family, &iaai->address, iaai->prefixlen));
×
340
                if (r < 0)
×
341
                        return r;
×
342
        }
343
        SET_FOREACH(iaai, c->ip_address_deny) {
2,789✔
344
                r = serialize_item(f,
272✔
345
                                   "exec-cgroup-context-ip-address-deny",
346
                                   IN_ADDR_PREFIX_TO_STRING(iaai->family, &iaai->address, iaai->prefixlen));
272✔
347
                if (r < 0)
272✔
348
                        return r;
×
349
        }
350

351
        r = serialize_bool_elide(f, "exec-cgroup-context-ip-address-allow-reduced", c->ip_address_allow_reduced);
2,517✔
352
        if (r < 0)
2,517✔
353
                return r;
354

355
        r = serialize_bool_elide(f, "exec-cgroup-context-ip-address-deny-reduced", c->ip_address_deny_reduced);
2,517✔
356
        if (r < 0)
2,517✔
357
                return r;
358

359
        r = serialize_strv(f, "exec-cgroup-context-ip-ingress-filter-path", c->ip_filters_ingress);
2,517✔
360
        if (r < 0)
2,517✔
361
                return r;
362

363
        r = serialize_strv(f, "exec-cgroup-context-ip-egress-filter-path", c->ip_filters_egress);
2,517✔
364
        if (r < 0)
2,517✔
365
                return r;
366

367
        LIST_FOREACH(programs, p, c->bpf_foreign_programs) {
2,517✔
368
                r = serialize_item_format(f, "exec-cgroup-context-bpf-program", "%" PRIu32 " %s",
×
369
                                          p->attach_type,
370
                                          p->bpffs_path);
371
                if (r < 0)
×
372
                        return r;
373
        }
374

375
        LIST_FOREACH(socket_bind_items, bi, c->socket_bind_allow) {
2,517✔
376
                fprintf(f, "exec-cgroup-context-socket-bind-allow=");
×
377
                cgroup_context_dump_socket_bind_item(bi, f);
×
378
                fputc('\n', f);
×
379
        }
380

381
        LIST_FOREACH(socket_bind_items, bi, c->socket_bind_deny) {
2,517✔
382
                fprintf(f, "exec-cgroup-context-socket-bind-deny=");
×
383
                cgroup_context_dump_socket_bind_item(bi, f);
×
384
                fputc('\n', f);
×
385
        }
386

387
        SET_FOREACH(iface, c->restrict_network_interfaces) {
2,517✔
388
                r = serialize_item(f, "exec-cgroup-context-restrict-network-interfaces", iface);
×
389
                if (r < 0)
×
390
                        return r;
×
391
        }
392

393
        r = serialize_bool_elide(
5,034✔
394
                        f,
395
                        "exec-cgroup-context-restrict-network-interfaces-is-allow-list",
396
                        c->restrict_network_interfaces_is_allow_list);
2,517✔
397
        if (r < 0)
2,517✔
398
                return r;
399

400
        r = serialize_item(f, "exec-cgroup-context-bind-iface", c->bind_network_interface);
2,517✔
401
        if (r < 0)
2,517✔
402
                return r;
403

404
        fputc('\n', f); /* End marker */
2,517✔
405

406
        return 0;
407
}
408

409
static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
10,254✔
410
        int r;
10,254✔
411

412
        assert(f);
10,254✔
413

414
        if (!c)
10,254✔
415
                return 0;
416

417
        for (;;) {
382,252✔
418
                _cleanup_free_ char *l = NULL;
185,999✔
419
                const char *val;
196,253✔
420

421
                r = deserialize_read_line(f, &l);
196,253✔
422
                if (r < 0)
196,253✔
423
                        return r;
424
                if (r == 0) /* eof or end marker */
196,253✔
425
                        break;
426

427
                if ((val = startswith(l, "exec-cgroup-context-io-accounting="))) {
185,999✔
428
                        r = parse_boolean(val);
2✔
429
                        if (r < 0)
2✔
430
                                return r;
431
                        c->io_accounting = r;
2✔
432
                } else if ((val = startswith(l, "exec-cgroup-context-memory-accounting="))) {
185,997✔
433
                        r = parse_boolean(val);
9,931✔
434
                        if (r < 0)
9,931✔
435
                                return r;
436
                        c->memory_accounting = r;
9,931✔
437
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-accounting="))) {
176,066✔
438
                        r = parse_boolean(val);
10,254✔
439
                        if (r < 0)
10,254✔
440
                                return r;
441
                        c->tasks_accounting = r;
10,254✔
442
                } else if ((val = startswith(l, "exec-cgroup-context-ip-accounting="))) {
165,812✔
443
                        r = parse_boolean(val);
×
444
                        if (r < 0)
×
445
                                return r;
446
                        c->ip_accounting = r;
×
447
                } else if ((val = startswith(l, "exec-cgroup-context-memory-oom-group="))) {
165,812✔
448
                        r = parse_boolean(val);
2✔
449
                        if (r < 0)
2✔
450
                                return r;
451
                        c->memory_oom_group = r;
2✔
452
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-weight="))) {
165,810✔
453
                        r = safe_atou64(val, &c->cpu_weight);
1✔
454
                        if (r < 0)
1✔
455
                                return r;
456
                } else if ((val = startswith(l, "exec-cgroup-context-startup-cpu-weight="))) {
165,809✔
457
                        r = safe_atou64(val, &c->startup_cpu_weight);
×
458
                        if (r < 0)
×
459
                                return r;
460
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-quota-per-sec-usec="))) {
165,809✔
461
                        r = deserialize_usec(val, &c->cpu_quota_per_sec_usec);
×
462
                        if (r < 0)
×
463
                                return r;
464
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-quota-period-usec="))) {
165,809✔
465
                        r = deserialize_usec(val, &c->cpu_quota_period_usec);
×
466
                        if (r < 0)
×
467
                                return r;
468
                } else if ((val = startswith(l, "exec-cgroup-context-allowed-cpus="))) {
165,809✔
469
                        if (c->cpuset_cpus.set)
10,254✔
470
                                return -EINVAL; /* duplicated */
471

472
                        r = parse_cpu_set(val, &c->cpuset_cpus);
10,254✔
473
                        if (r < 0)
10,254✔
474
                                return r;
475
                } else if ((val = startswith(l, "exec-cgroup-context-startup-allowed-cpus="))) {
155,555✔
476
                        if (c->startup_cpuset_cpus.set)
10,254✔
477
                                return -EINVAL; /* duplicated */
478

479
                        r = parse_cpu_set(val, &c->startup_cpuset_cpus);
10,254✔
480
                        if (r < 0)
10,254✔
481
                                return r;
482
                } else if ((val = startswith(l, "exec-cgroup-context-allowed-memory-nodes="))) {
145,301✔
483
                        if (c->cpuset_mems.set)
10,254✔
484
                                return -EINVAL; /* duplicated */
485

486
                        r = parse_cpu_set(val, &c->cpuset_mems);
10,254✔
487
                        if (r < 0)
10,254✔
488
                                return r;
489
                } else if ((val = startswith(l, "exec-cgroup-context-startup-allowed-memory-nodes="))) {
135,047✔
490
                        if (c->startup_cpuset_mems.set)
10,254✔
491
                                return -EINVAL; /* duplicated */
492

493
                        r = parse_cpu_set(val, &c->startup_cpuset_mems);
10,254✔
494
                        if (r < 0)
10,254✔
495
                                return r;
496
                } else if ((val = startswith(l, "exec-cgroup-context-io-weight="))) {
124,793✔
497
                        r = safe_atou64(val, &c->io_weight);
×
498
                        if (r < 0)
×
499
                                return r;
500
                } else if ((val = startswith(l, "exec-cgroup-context-startup-io-weight="))) {
124,793✔
501
                        r = safe_atou64(val, &c->startup_io_weight);
×
502
                        if (r < 0)
×
503
                                return r;
504
                } else if ((val = startswith(l, "exec-cgroup-context-memory-min="))) {
124,793✔
505
                        r = safe_atou64(val, &c->memory_min);
1✔
506
                        if (r < 0)
1✔
507
                                return r;
508
                } else if ((val = startswith(l, "exec-cgroup-context-memory-low="))) {
124,792✔
509
                        r = safe_atou64(val, &c->memory_low);
1✔
510
                        if (r < 0)
1✔
511
                                return r;
512
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low="))) {
124,791✔
513
                        r = safe_atou64(val, &c->startup_memory_low);
×
514
                        if (r < 0)
×
515
                                return r;
516
                } else if ((val = startswith(l, "exec-cgroup-context-memory-high="))) {
124,791✔
517
                        r = safe_atou64(val, &c->memory_high);
13✔
518
                        if (r < 0)
13✔
519
                                return r;
520
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high="))) {
124,778✔
521
                        r = safe_atou64(val, &c->startup_memory_high);
×
522
                        if (r < 0)
×
523
                                return r;
524
                } else if ((val = startswith(l, "exec-cgroup-context-memory-max="))) {
124,778✔
525
                        r = safe_atou64(val, &c->memory_max);
11✔
526
                        if (r < 0)
11✔
527
                                return r;
528
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max="))) {
124,767✔
529
                        r = safe_atou64(val, &c->startup_memory_max);
×
530
                        if (r < 0)
×
531
                                return r;
532
                } else if ((val = startswith(l, "exec-cgroup-context-memory-swap-max="))) {
124,767✔
533
                        r = safe_atou64(val, &c->memory_swap_max);
10✔
534
                        if (r < 0)
10✔
535
                                return r;
536
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max="))) {
124,757✔
537
                        r = safe_atou64(val, &c->startup_memory_swap_max);
×
538
                        if (r < 0)
×
539
                                return r;
540
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-max="))) {
124,757✔
541
                        r = safe_atou64(val, &c->memory_zswap_max);
1✔
542
                        if (r < 0)
1✔
543
                                return r;
544
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max="))) {
124,756✔
545
                        r = safe_atou64(val, &c->startup_memory_zswap_max);
×
546
                        if (r < 0)
×
547
                                return r;
548
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-writeback="))) {
124,756✔
549
                        r = parse_boolean(val);
10,254✔
550
                        if (r < 0)
10,254✔
551
                                return r;
552
                        c->memory_zswap_writeback = r;
10,254✔
553
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-value="))) {
114,502✔
554
                        r = safe_atou64(val, &c->tasks_max.value);
9,952✔
555
                        if (r < 0)
9,952✔
556
                                return r;
557
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-scale="))) {
104,550✔
558
                        r = safe_atou64(val, &c->tasks_max.scale);
9,911✔
559
                        if (r < 0)
9,911✔
560
                                return r;
561
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low-set="))) {
94,639✔
562
                        r = parse_boolean(val);
×
563
                        if (r < 0)
×
564
                                return r;
565
                        c->startup_memory_low_set = r;
×
566
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high-set="))) {
94,639✔
567
                        r = parse_boolean(val);
×
568
                        if (r < 0)
×
569
                                return r;
570
                        c->startup_memory_high_set = r;
×
571
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max-set="))) {
94,639✔
572
                        r = parse_boolean(val);
×
573
                        if (r < 0)
×
574
                                return r;
575
                        c->startup_memory_max_set = r;
×
576
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max-set="))) {
94,639✔
577
                        r = parse_boolean(val);
×
578
                        if (r < 0)
×
579
                                return r;
580
                        c->startup_memory_swap_max_set = r;
×
581
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max-set="))) {
94,639✔
582
                        r = parse_boolean(val);
×
583
                        if (r < 0)
×
584
                                return r;
585
                        c->startup_memory_zswap_max_set = r;
×
586
                } else if ((val = startswith(l, "exec-cgroup-context-device-policy="))) {
94,639✔
587
                        c->device_policy = cgroup_device_policy_from_string(val);
10,254✔
588
                        if (c->device_policy < 0)
10,254✔
589
                                return -EINVAL;
590
                } else if ((val = startswith(l, "exec-cgroup-context-disable-controllers="))) {
84,385✔
591
                        r = cg_mask_from_string(val, &c->disable_controllers);
×
592
                        if (r < 0)
×
593
                                return r;
594
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-controllers="))) {
84,385✔
595
                        r = cg_mask_from_string(val, &c->delegate_controllers);
588✔
596
                        if (r < 0)
588✔
597
                                return r;
598
                } else if ((val = startswith(l, "exec-cgroup-context-delegate="))) {
83,797✔
599
                        r = parse_boolean(val);
704✔
600
                        if (r < 0)
704✔
601
                                return r;
602
                        c->delegate = r;
704✔
603
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-swap="))) {
83,093✔
604
                        c->moom_swap = managed_oom_mode_from_string(val);
10,254✔
605
                        if (c->moom_swap < 0)
10,254✔
606
                                return -EINVAL;
607
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure="))) {
72,839✔
608
                        c->moom_mem_pressure = managed_oom_mode_from_string(val);
10,254✔
609
                        if (c->moom_mem_pressure < 0)
10,254✔
610
                                return -EINVAL;
611
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-limit="))) {
62,585✔
612
                        r = safe_atou32(val, &c->moom_mem_pressure_limit);
10,254✔
613
                        if (r < 0)
10,254✔
614
                                return r;
615
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-preference="))) {
52,331✔
616
                        c->moom_preference = managed_oom_preference_from_string(val);
10,254✔
617
                        if (c->moom_preference < 0)
10,254✔
618
                                return -EINVAL;
619
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec="))) {
42,077✔
620
                        r = deserialize_usec(val, &c->moom_mem_pressure_duration_usec);
1✔
621
                        if (r < 0)
1✔
622
                                return r;
623
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-watch="))) {
42,076✔
624
                        c->memory_pressure_watch = cgroup_pressure_watch_from_string(val);
10,254✔
625
                        if (c->memory_pressure_watch < 0)
10,254✔
626
                                return -EINVAL;
627
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-subgroup="))) {
31,822✔
628
                        r = free_and_strdup(&c->delegate_subgroup, val);
352✔
629
                        if (r < 0)
352✔
630
                                return r;
631
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-threshold-usec="))) {
31,470✔
632
                        r = deserialize_usec(val, &c->memory_pressure_threshold_usec);
10,254✔
633
                        if (r < 0)
10,254✔
634
                                return r;
635
                } else if ((val = startswith(l, "exec-cgroup-context-device-allow="))) {
21,216✔
636
                        _cleanup_free_ char *path = NULL, *rwm = NULL;
3,346✔
637
                        CGroupDevicePermissions p;
3,346✔
638

639
                        r = extract_many_words(&val, " ", 0, &path, &rwm);
3,346✔
640
                        if (r < 0)
3,346✔
641
                                return r;
642
                        if (r == 0)
3,346✔
643
                                return -EINVAL;
644

645
                        p = isempty(rwm) ? 0 : cgroup_device_permissions_from_string(rwm);
6,692✔
646
                        if (p < 0)
3,346✔
647
                                return p;
648

649
                        r = cgroup_context_add_or_update_device_allow(c, path, p);
3,346✔
650
                        if (r < 0)
3,346✔
651
                                return r;
652
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-weight="))) {
17,870✔
653
                        _cleanup_free_ char *path = NULL, *weight = NULL;
×
654
                        CGroupIODeviceWeight *a = NULL;
×
655

656
                        r = extract_many_words(&val, " ", 0, &path, &weight);
×
657
                        if (r < 0)
×
658
                                return r;
659
                        if (r != 2)
×
660
                                return -EINVAL;
661

662
                        LIST_FOREACH(device_weights, b, c->io_device_weights)
×
663
                                if (path_equal(b->path, path)) {
×
664
                                        a = b;
665
                                        break;
666
                                }
667

668
                        if (!a) {
×
669
                                a = new0(CGroupIODeviceWeight, 1);
×
670
                                if (!a)
×
671
                                        return log_oom_debug();
×
672

673
                                a->path = TAKE_PTR(path);
×
674

675
                                LIST_PREPEND(device_weights, c->io_device_weights, a);
×
676
                        }
677

678
                        r = safe_atou64(weight, &a->weight);
×
679
                        if (r < 0)
×
680
                                return r;
681
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-latency-target-usec="))) {
17,870✔
682
                        _cleanup_free_ char *path = NULL, *target = NULL;
×
683
                        CGroupIODeviceLatency *a = NULL;
×
684

685
                        r = extract_many_words(&val, " ", 0, &path, &target);
×
686
                        if (r < 0)
×
687
                                return r;
688
                        if (r != 2)
×
689
                                return -EINVAL;
690

691
                        LIST_FOREACH(device_latencies, b, c->io_device_latencies)
×
692
                                if (path_equal(b->path, path)) {
×
693
                                        a = b;
694
                                        break;
695
                                }
696

697
                        if (!a) {
×
698
                                a = new0(CGroupIODeviceLatency, 1);
×
699
                                if (!a)
×
700
                                        return log_oom_debug();
×
701

702
                                a->path = TAKE_PTR(path);
×
703

704
                                LIST_PREPEND(device_latencies, c->io_device_latencies, a);
×
705
                        }
706

707
                        r = deserialize_usec(target, &a->target_usec);
×
708
                        if (r < 0)
×
709
                                return r;
710
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-limit-"))) {
17,870✔
711
                        _cleanup_free_ char *type = NULL, *path = NULL, *limits = NULL;
×
712
                        CGroupIODeviceLimit *limit = NULL;
×
713
                        CGroupIOLimitType t;
×
714

715
                        r = extract_many_words(&val, "= ", 0, &type, &path, &limits);
×
716
                        if (r < 0)
×
717
                                return r;
718
                        if (r != 3)
×
719
                                return -EINVAL;
720

721
                        t = cgroup_io_limit_type_from_string(type);
×
722
                        if (t < 0)
×
723
                                return t;
724

725
                        LIST_FOREACH(device_limits, i, c->io_device_limits)
×
726
                                if (path_equal(path, i->path)) {
×
727
                                        limit = i;
728
                                        break;
729
                                }
730

731
                        if (!limit) {
×
732
                                limit = new0(CGroupIODeviceLimit, 1);
×
733
                                if (!limit)
×
734
                                        return log_oom_debug();
×
735

736
                                limit->path = TAKE_PTR(path);
×
737
                                for (CGroupIOLimitType i = 0; i < _CGROUP_IO_LIMIT_TYPE_MAX; i++)
×
738
                                        limit->limits[i] = cgroup_io_limit_defaults[i];
×
739

740
                                LIST_PREPEND(device_limits, c->io_device_limits, limit);
×
741
                        }
742

743
                        r = safe_atou64(limits, &limit->limits[t]);
×
744
                        if (r < 0)
×
745
                                return r;
746
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow="))) {
17,870✔
747
                        struct in_addr_prefix a;
×
748

749
                        r = in_addr_prefix_from_string_auto(val, &a.family, &a.address, &a.prefixlen);
×
750
                        if (r < 0)
×
751
                                return r;
×
752

753
                        r = in_addr_prefix_add(&c->ip_address_allow, &a);
×
754
                        if (r < 0)
×
755
                                return r;
756
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny="))) {
17,870✔
757
                        struct in_addr_prefix a;
1,372✔
758

759
                        r = in_addr_prefix_from_string_auto(val, &a.family, &a.address, &a.prefixlen);
1,372✔
760
                        if (r < 0)
1,372✔
761
                                return r;
×
762

763
                        r = in_addr_prefix_add(&c->ip_address_deny, &a);
1,372✔
764
                        if (r < 0)
1,372✔
765
                                return r;
766
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow-reduced="))) {
16,498✔
767
                        r = parse_boolean(val);
8,237✔
768
                        if (r < 0)
8,237✔
769
                                return r;
770
                        c->ip_address_allow_reduced = r;
8,237✔
771
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny-reduced="))) {
8,261✔
772
                        r = parse_boolean(val);
8,237✔
773
                        if (r < 0)
8,237✔
774
                                return r;
775
                        c->ip_address_deny_reduced = r;
8,237✔
776
                } else if ((val = startswith(l, "exec-cgroup-context-ip-ingress-filter-path="))) {
24✔
777
                        r = deserialize_strv(val, &c->ip_filters_ingress);
×
778
                        if (r < 0)
×
779
                                return r;
780
                } else if ((val = startswith(l, "exec-cgroup-context-ip-egress-filter-path="))) {
24✔
781
                        r = deserialize_strv(val, &c->ip_filters_egress);
×
782
                        if (r < 0)
×
783
                                return r;
784
                } else if ((val = startswith(l, "exec-cgroup-context-bpf-program="))) {
24✔
785
                        _cleanup_free_ char *type = NULL, *path = NULL;
×
786
                        uint32_t t;
×
787

788
                        r = extract_many_words(&val, " ", 0, &type, &path);
×
789
                        if (r < 0)
×
790
                                return r;
791
                        if (r != 2)
×
792
                                return -EINVAL;
793

794
                        r = safe_atou32(type, &t);
×
795
                        if (r < 0)
×
796
                                return r;
797

798
                        r = cgroup_context_add_bpf_foreign_program(c, t, path);
×
799
                        if (r < 0)
×
800
                                return r;
801
                } else if ((val = startswith(l, "exec-cgroup-context-socket-bind-allow="))) {
24✔
802
                        CGroupSocketBindItem *item;
×
803
                        uint16_t nr_ports, port_min;
×
804
                        int af, ip_protocol;
×
805

806
                        r = parse_socket_bind_item(val, &af, &ip_protocol, &nr_ports, &port_min);
×
807
                        if (r < 0)
×
808
                                return r;
×
809

810
                        item = new(CGroupSocketBindItem, 1);
×
811
                        if (!item)
×
812
                                return log_oom_debug();
×
813
                        *item = (CGroupSocketBindItem) {
×
814
                                .address_family = af,
815
                                .ip_protocol = ip_protocol,
816
                                .nr_ports = nr_ports,
817
                                .port_min = port_min,
818
                        };
819

820
                        LIST_PREPEND(socket_bind_items, c->socket_bind_allow, item);
×
821
                } else if ((val = startswith(l, "exec-cgroup-context-socket-bind-deny="))) {
24✔
822
                        CGroupSocketBindItem *item;
×
823
                        uint16_t nr_ports, port_min;
×
824
                        int af, ip_protocol;
×
825

826
                        r = parse_socket_bind_item(val, &af, &ip_protocol, &nr_ports, &port_min);
×
827
                        if (r < 0)
×
828
                                return r;
×
829

830
                        item = new(CGroupSocketBindItem, 1);
×
831
                        if (!item)
×
832
                                return log_oom_debug();
×
833
                        *item = (CGroupSocketBindItem) {
×
834
                                .address_family = af,
835
                                .ip_protocol = ip_protocol,
836
                                .nr_ports = nr_ports,
837
                                .port_min = port_min,
838
                        };
839

840
                        LIST_PREPEND(socket_bind_items, c->socket_bind_deny, item);
×
841
                } else if ((val = startswith(l, "exec-cgroup-context-restrict-network-interfaces="))) {
24✔
842
                        r = set_put_strdup(&c->restrict_network_interfaces, val);
15✔
843
                        if (r < 0)
15✔
844
                                return r;
845
                } else if ((val = startswith(l, "exec-cgroup-context-restrict-network-interfaces-is-allow-list="))) {
9✔
846
                        r = parse_boolean(val);
9✔
847
                        if (r < 0)
9✔
848
                                return r;
849
                        c->restrict_network_interfaces_is_allow_list = r;
9✔
850
                } else if ((val = startswith(l, "exec-cgroup-context-bind-iface="))) {
×
851
                        r = free_and_strdup(&c->bind_network_interface, val);
×
852
                        if (r < 0)
×
853
                                return r;
854
                } else
855
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
856
        }
857

858
        return 0;
10,254✔
859
}
860

861
static int exec_runtime_serialize(const ExecRuntime *rt, FILE *f, FDSet *fds) {
2,517✔
862
        int r;
2,517✔
863

864
        assert(f);
2,517✔
865
        assert(fds);
2,517✔
866

867
        if (!rt) {
2,517✔
868
                fputc('\n', f); /* End marker */
2,427✔
869
                return 0;
2,427✔
870
        }
871

872
        if (rt->shared) {
90✔
873
                r = serialize_item(f, "exec-runtime-id", rt->shared->id);
75✔
874
                if (r < 0)
75✔
875
                        return r;
876

877
                r = serialize_item(f, "exec-runtime-tmp-dir", rt->shared->tmp_dir);
75✔
878
                if (r < 0)
75✔
879
                        return r;
880

881
                r = serialize_item(f, "exec-runtime-var-tmp-dir", rt->shared->var_tmp_dir);
75✔
882
                if (r < 0)
75✔
883
                        return r;
884

885
                if (rt->shared->userns_storage_socket[0] >= 0 && rt->shared->userns_storage_socket[1] >= 0) {
75✔
886
                        r = serialize_fd_many(f, fds, "exec-runtime-userns-storage-socket", rt->shared->userns_storage_socket, 2);
×
887
                        if (r < 0)
×
888
                                return r;
889
                }
890

891
                if (rt->shared->netns_storage_socket[0] >= 0 && rt->shared->netns_storage_socket[1] >= 0) {
75✔
892
                        r = serialize_fd_many(f, fds, "exec-runtime-netns-storage-socket", rt->shared->netns_storage_socket, 2);
8✔
893
                        if (r < 0)
8✔
894
                                return r;
895
                }
896

897
                if (rt->shared->ipcns_storage_socket[0] >= 0 && rt->shared->ipcns_storage_socket[1] >= 0) {
75✔
898
                        r = serialize_fd_many(f, fds, "exec-runtime-ipcns-storage-socket", rt->shared->ipcns_storage_socket, 2);
2✔
899
                        if (r < 0)
2✔
900
                                return r;
901
                }
902
        }
903

904
        if (rt->dynamic_creds) {
90✔
905
                r = dynamic_user_serialize_one(rt->dynamic_creds->user, "exec-runtime-dynamic-creds-user", f, fds);
15✔
906
                if (r < 0)
15✔
907
                        return r;
908
        }
909

910
        if (rt->dynamic_creds && rt->dynamic_creds->group && rt->dynamic_creds->group == rt->dynamic_creds->user) {
90✔
911
                r = serialize_bool(f, "exec-runtime-dynamic-creds-group-copy", true);
14✔
912
                if (r < 0)
14✔
913
                        return r;
914
        } else if (rt->dynamic_creds) {
76✔
915
                r = dynamic_user_serialize_one(rt->dynamic_creds->group, "exec-runtime-dynamic-creds-group", f, fds);
1✔
916
                if (r < 0)
1✔
917
                        return r;
918
        }
919

920
        r = serialize_item(f, "exec-runtime-ephemeral-copy", rt->ephemeral_copy);
90✔
921
        if (r < 0)
90✔
922
                return r;
923

924
        if (rt->ephemeral_storage_socket[0] >= 0 && rt->ephemeral_storage_socket[1] >= 0) {
90✔
925
                r = serialize_fd_many(f, fds, "exec-runtime-ephemeral-storage-socket", rt->ephemeral_storage_socket, 2);
×
926
                if (r < 0)
×
927
                        return r;
928
        }
929

930
        fputc('\n', f); /* End marker */
90✔
931

932
        return 0;
90✔
933
}
934

935
static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) {
10,254✔
936
        int r;
10,254✔
937

938
        assert(rt);
10,254✔
939
        assert(rt->shared);
10,254✔
940
        assert(rt->dynamic_creds);
10,254✔
941
        assert(f);
10,254✔
942
        assert(fds);
10,254✔
943

944
        for (;;) {
11,367✔
945
                _cleanup_free_ char *l = NULL;
1,113✔
946
                const char *val;
11,367✔
947

948
                r = deserialize_read_line(f, &l);
11,367✔
949
                if (r < 0)
11,367✔
950
                        return r;
951
                if (r == 0) /* eof or end marker */
11,367✔
952
                        break;
953

954
                if ((val = startswith(l, "exec-runtime-id="))) {
1,113✔
955
                        r = free_and_strdup(&rt->shared->id, val);
375✔
956
                        if (r < 0)
375✔
957
                                return r;
958
                } else if ((val = startswith(l, "exec-runtime-tmp-dir="))) {
738✔
959
                        r = free_and_strdup(&rt->shared->tmp_dir, val);
211✔
960
                        if (r < 0)
211✔
961
                                return r;
962
                } else if ((val = startswith(l, "exec-runtime-var-tmp-dir="))) {
527✔
963
                        r = free_and_strdup(&rt->shared->var_tmp_dir, val);
351✔
964
                        if (r < 0)
351✔
965
                                return r;
966
                } else if ((val = startswith(l, "exec-runtime-userns-storage-socket="))) {
176✔
967

968
                        r = deserialize_fd_many(fds, val, 2, rt->shared->userns_storage_socket);
3✔
969
                        if (r < 0)
3✔
970
                                continue;
×
971

972
                } else if ((val = startswith(l, "exec-runtime-netns-storage-socket="))) {
173✔
973

974
                        r = deserialize_fd_many(fds, val, 2, rt->shared->netns_storage_socket);
73✔
975
                        if (r < 0)
73✔
976
                                continue;
×
977

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

980
                        r = deserialize_fd_many(fds, val, 2, rt->shared->ipcns_storage_socket);
6✔
981
                        if (r < 0)
6✔
982
                                continue;
×
983

984
                } else if ((val = startswith(l, "exec-runtime-dynamic-creds-user=")))
94✔
985
                        dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->user);
47✔
986
                else if ((val = startswith(l, "exec-runtime-dynamic-creds-group=")))
47✔
987
                        dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->group);
×
988
                else if ((val = startswith(l, "exec-runtime-dynamic-creds-group-copy="))) {
47✔
989
                        r = parse_boolean(val);
47✔
990
                        if (r < 0)
47✔
991
                                return r;
992
                        if (!r)
47✔
993
                                continue; /* Nothing to do */
×
994

995
                        if (!rt->dynamic_creds->user)
47✔
996
                                return -EINVAL;
997

998
                        rt->dynamic_creds->group = dynamic_user_ref(rt->dynamic_creds->user);
47✔
999
                } else if ((val = startswith(l, "exec-runtime-ephemeral-copy="))) {
×
1000
                        r = free_and_strdup(&rt->ephemeral_copy, val);
×
1001
                        if (r < 0)
×
1002
                                return r;
1003
                } else if ((val = startswith(l, "exec-runtime-ephemeral-storage-socket="))) {
×
1004

1005
                        r = deserialize_fd_many(fds, val, 2, rt->ephemeral_storage_socket);
×
1006
                        if (r < 0)
×
1007
                                continue;
×
1008
                } else
1009
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
1010
        }
1011

1012
        return 0;
10,254✔
1013
}
1014

1015
static bool exec_parameters_is_idle_pipe_set(const ExecParameters *p) {
2,517✔
1016
        assert(p);
2,517✔
1017

1018
        return p->idle_pipe &&
2,546✔
1019
                p->idle_pipe[0] >= 0 &&
29✔
1020
                p->idle_pipe[1] >= 0 &&
27✔
1021
                p->idle_pipe[2] >= 0 &&
2,544✔
1022
                p->idle_pipe[3] >= 0;
27✔
1023
}
1024

1025
static int exec_parameters_serialize(const ExecParameters *p, const ExecContext *c, FILE *f, FDSet *fds) {
2,517✔
1026
        int r;
2,517✔
1027

1028
        assert(f);
2,517✔
1029
        assert(fds);
2,517✔
1030

1031
        if (!p)
2,517✔
1032
                return 0;
1033

1034
        r = serialize_item(f, "exec-parameters-runtime-scope", runtime_scope_to_string(p->runtime_scope));
2,517✔
1035
        if (r < 0)
2,517✔
1036
                return r;
1037

1038
        r = serialize_strv(f, "exec-parameters-environment", p->environment);
2,517✔
1039
        if (r < 0)
2,517✔
1040
                return r;
1041

1042
        if (p->fds) {
2,517✔
1043
                if (p->n_socket_fds > 0) {
551✔
1044
                        r = serialize_item_format(f, "exec-parameters-n-socket-fds", "%zu", p->n_socket_fds);
550✔
1045
                        if (r < 0)
550✔
1046
                                return r;
1047
                }
1048

1049
                if (p->n_stashed_fds > 0) {
551✔
1050
                        r = serialize_item_format(f, "exec-parameters-n-stashed-fds", "%zu", p->n_stashed_fds);
4✔
1051
                        if (r < 0)
4✔
1052
                                return r;
1053
                }
1054

1055
                r = serialize_fd_many(f, fds, "exec-parameters-fds", p->fds, p->n_socket_fds + p->n_stashed_fds);
551✔
1056
                if (r < 0)
551✔
1057
                        return r;
1058

1059
                r = serialize_strv(f, "exec-parameters-fd-names", p->fd_names);
551✔
1060
                if (r < 0)
551✔
1061
                        return r;
1062
        }
1063

1064
        if (p->flags != 0) {
2,517✔
1065
                r = serialize_item_format(f, "exec-parameters-flags", "%u", (unsigned) p->flags);
2,517✔
1066
                if (r < 0)
2,517✔
1067
                        return r;
1068
        }
1069

1070
        r = serialize_bool_elide(f, "exec-parameters-selinux-context-net", p->selinux_context_net);
2,517✔
1071
        if (r < 0)
2,517✔
1072
                return r;
1073

1074
        r = serialize_item(f, "exec-parameters-cgroup-path", p->cgroup_path);
2,517✔
1075
        if (r < 0)
2,517✔
1076
                return r;
1077

1078
        r = serialize_item_format(f, "exec-parameters-cgroup-id", "%" PRIu64, p->cgroup_id);
2,517✔
1079
        if (r < 0)
2,517✔
1080
                return r;
1081

1082
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
15,102✔
1083
                _cleanup_free_ char *key = NULL;
12,585✔
1084

1085
                key = strjoin("exec-parameters-prefix-directories-", exec_directory_type_to_string(dt));
12,585✔
1086
                if (!key)
12,585✔
1087
                        return log_oom_debug();
×
1088

1089
                /* Always serialize, even an empty prefix, as this is a fixed array and we always expect
1090
                 * to have all elements (unless fuzzing is happening, hence the NULL check). */
1091
                r = serialize_item(f, key, strempty(p->prefix ? p->prefix[dt] : NULL));
12,585✔
1092
                if (r < 0)
12,585✔
1093
                        return r;
1094
        }
1095

1096
        r = serialize_item(f, "exec-parameters-received-credentials-directory", p->received_credentials_directory);
2,517✔
1097
        if (r < 0)
2,517✔
1098
                return r;
1099

1100
        r = serialize_item(f, "exec-parameters-received-encrypted-credentials-directory", p->received_encrypted_credentials_directory);
2,517✔
1101
        if (r < 0)
2,517✔
1102
                return r;
1103

1104
        r = serialize_item(f, "exec-parameters-confirm-spawn", p->confirm_spawn);
2,517✔
1105
        if (r < 0)
2,517✔
1106
                return r;
1107

1108
        r = serialize_bool_elide(f, "exec-parameters-shall-confirm-spawn", p->shall_confirm_spawn);
2,517✔
1109
        if (r < 0)
2,517✔
1110
                return r;
1111

1112
        if (p->watchdog_usec > 0) {
2,517✔
1113
                r = serialize_usec(f, "exec-parameters-watchdog-usec", p->watchdog_usec);
233✔
1114
                if (r < 0)
233✔
1115
                        return r;
1116
        }
1117

1118
        if (exec_parameters_is_idle_pipe_set(p)) {
2,517✔
1119
                r = serialize_fd_many(f, fds, "exec-parameters-idle-pipe", p->idle_pipe, 4);
27✔
1120
                if (r < 0)
27✔
1121
                        return r;
1122
        }
1123

1124
        r = serialize_fd(f, fds, "exec-parameters-stdin-fd", p->stdin_fd);
2,517✔
1125
        if (r < 0)
2,517✔
1126
                return r;
1127

1128
        r = serialize_fd(f, fds, "exec-parameters-stdout-fd", p->stdout_fd);
2,517✔
1129
        if (r < 0)
2,517✔
1130
                return r;
1131

1132
        r = serialize_fd(f, fds, "exec-parameters-stderr-fd", p->stderr_fd);
2,517✔
1133
        if (r < 0)
2,517✔
1134
                return r;
1135

1136
        r = serialize_fd(f, fds, "exec-parameters-root-directory-fd", p->root_directory_fd);
2,517✔
1137
        if (r < 0)
2,517✔
1138
                return r;
1139

1140
        r = serialize_fd(f, fds, "exec-parameters-exec-fd", p->exec_fd);
2,517✔
1141
        if (r < 0)
2,517✔
1142
                return r;
1143

1144
        r = serialize_fd(f, fds, "exec-parameters-handoff-timestamp-fd", p->handoff_timestamp_fd);
2,517✔
1145
        if (r < 0)
2,517✔
1146
                return r;
1147

1148
        r = serialize_fd(f, fds, "exec-parameters-pidref-transport-fd", p->pidref_transport_fd);
2,517✔
1149
        if (r < 0)
2,517✔
1150
                return r;
1151

1152
        if (c && exec_context_restrict_filesystems_set(c)) {
2,517✔
1153
                r = serialize_fd(f, fds, "exec-parameters-bpf-outer-map-fd", p->bpf_restrict_fs_map_fd);
×
1154
                if (r < 0)
×
1155
                        return r;
1156
        }
1157

1158
        r = serialize_item(f, "exec-parameters-notify-socket", p->notify_socket);
2,517✔
1159
        if (r < 0)
2,517✔
1160
                return r;
1161

1162
        LIST_FOREACH(open_files, file, p->open_files) {
2,517✔
1163
                _cleanup_free_ char *ofs = NULL;
×
1164

1165
                r = open_file_to_string(file, &ofs);
×
1166
                if (r < 0)
×
1167
                        return r;
1168

1169
                r = serialize_item(f, "exec-parameters-open-file", ofs);
×
1170
                if (r < 0)
×
1171
                        return r;
1172
        }
1173

1174
        r = serialize_item(f, "exec-parameters-fallback-smack-process-label", p->fallback_smack_process_label);
2,517✔
1175
        if (r < 0)
2,517✔
1176
                return r;
1177

1178
        r = serialize_fd(f, fds, "exec-parameters-user-lookup-fd", p->user_lookup_fd);
2,517✔
1179
        if (r < 0)
2,517✔
1180
                return r;
1181

1182
        r = serialize_strv(f, "exec-parameters-files-env", p->files_env);
2,517✔
1183
        if (r < 0)
2,517✔
1184
                return r;
1185

1186
        r = serialize_item(f, "exec-parameters-unit-id", p->unit_id);
2,517✔
1187
        if (r < 0)
2,517✔
1188
                return r;
1189

1190
        r = serialize_item(f, "exec-parameters-invocation-id-string", p->invocation_id_string);
2,517✔
1191
        if (r < 0)
2,517✔
1192
                return r;
1193

1194
        r = serialize_bool_elide(f, "exec-parameters-debug-invocation", p->debug_invocation);
2,517✔
1195
        if (r < 0)
2,517✔
1196
                return r;
1197

1198
        fputc('\n', f); /* End marker */
2,517✔
1199

1200
        return 0;
2,517✔
1201
}
1202

1203
static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
10,254✔
1204
        int r;
10,254✔
1205

1206
        assert(p);
10,254✔
1207
        assert(f);
10,254✔
1208
        assert(fds);
10,254✔
1209

1210
        unsigned nr_open = MAX(read_nr_open(), NR_OPEN_MINIMUM);
10,254✔
1211

1212
        for (;;) {
219,215✔
1213
                _cleanup_free_ char *l = NULL;
208,961✔
1214
                const char *val;
219,215✔
1215

1216
                r = deserialize_read_line(f, &l);
219,215✔
1217
                if (r < 0)
219,215✔
1218
                        return r;
1219
                if (r == 0) /* eof or end marker */
219,215✔
1220
                        break;
1221

1222
                if ((val = startswith(l, "exec-parameters-runtime-scope="))) {
208,961✔
1223
                        p->runtime_scope = runtime_scope_from_string(val);
10,254✔
1224
                        if (p->runtime_scope < 0)
10,254✔
1225
                                return p->runtime_scope;
1226
                } else if ((val = startswith(l, "exec-parameters-environment="))) {
198,707✔
1227
                        r = deserialize_strv(val, &p->environment);
43,607✔
1228
                        if (r < 0)
43,607✔
1229
                                return r;
1230
                } else if ((val = startswith(l, "exec-parameters-n-socket-fds="))) {
155,100✔
1231
                        if (p->fds)
1,757✔
1232
                                return -EINVAL; /* Already received */
1233

1234
                        r = safe_atozu(val, &p->n_socket_fds);
1,757✔
1235
                        if (r < 0)
1,757✔
1236
                                return r;
1237

1238
                        if (p->n_socket_fds > nr_open)
1,757✔
1239
                                return -EINVAL; /* too many, someone is playing games with us */
1240
                } else if ((val = startswith(l, "exec-parameters-n-stashed-fds="))) {
153,343✔
1241
                        if (p->fds)
110✔
1242
                                return -EINVAL; /* Already received */
1243

1244
                        r = safe_atozu(val, &p->n_stashed_fds);
110✔
1245
                        if (r < 0)
110✔
1246
                                return r;
1247

1248
                        if (p->n_stashed_fds > nr_open)
110✔
1249
                                return -EINVAL; /* too many, someone is playing games with us */
1250
                } else if ((val = startswith(l, "exec-parameters-fds="))) {
153,233✔
1251
                        if (p->n_socket_fds + p->n_stashed_fds == 0)
1,762✔
1252
                                return log_warning_errno(
×
1253
                                                SYNTHETIC_ERRNO(EINVAL),
1254
                                                "Got exec-parameters-fds= without "
1255
                                                "prior exec-parameters-n-socket-fds= or exec-parameters-n-stashed-fds=");
1256
                        if (p->n_socket_fds + p->n_stashed_fds > nr_open)
1,762✔
1257
                                return -EINVAL; /* too many, someone is playing games with us */
1258

1259
                        if (p->fds)
1,762✔
1260
                                return -EINVAL; /* duplicated */
1261

1262
                        p->fds = new(int, p->n_socket_fds + p->n_stashed_fds);
1,762✔
1263
                        if (!p->fds)
1,762✔
1264
                                return log_oom_debug();
×
1265

1266
                        /* Ensure we don't leave any FD uninitialized on error, it makes the fuzzer sad */
1267
                        FOREACH_ARRAY(i, p->fds, p->n_socket_fds + p->n_stashed_fds)
5,902✔
1268
                                *i = -EBADF;
4,140✔
1269

1270
                        r = deserialize_fd_many(fds, val, p->n_socket_fds + p->n_stashed_fds, p->fds);
1,762✔
1271
                        if (r < 0)
1,762✔
1272
                                continue;
×
1273

1274
                } else if ((val = startswith(l, "exec-parameters-fd-names="))) {
151,471✔
1275
                        r = deserialize_strv(val, &p->fd_names);
4,140✔
1276
                        if (r < 0)
4,140✔
1277
                                return r;
1278
                } else if ((val = startswith(l, "exec-parameters-flags="))) {
147,331✔
1279
                        unsigned flags;
10,254✔
1280

1281
                        r = safe_atou(val, &flags);
10,254✔
1282
                        if (r < 0)
10,254✔
1283
                                return r;
×
1284
                        p->flags = flags;
10,254✔
1285
                } else if ((val = startswith(l, "exec-parameters-selinux-context-net="))) {
137,077✔
1286
                        r = parse_boolean(val);
×
1287
                        if (r < 0)
×
1288
                                return r;
1289

1290
                        p->selinux_context_net = r;
×
1291
                } else if ((val = startswith(l, "exec-parameters-cgroup-path="))) {
137,077✔
1292
                        r = free_and_strdup(&p->cgroup_path, val);
10,254✔
1293
                        if (r < 0)
10,254✔
1294
                                return r;
1295
                } else if ((val = startswith(l, "exec-parameters-cgroup-id="))) {
126,823✔
1296
                        r = safe_atou64(val, &p->cgroup_id);
10,254✔
1297
                        if (r < 0)
10,254✔
1298
                                return r;
1299
                } else if ((val = startswith(l, "exec-parameters-prefix-directories-"))) {
116,569✔
1300
                        _cleanup_free_ char *type = NULL, *prefix = NULL;
51,270✔
1301
                        ExecDirectoryType dt;
51,270✔
1302

1303
                        r = extract_many_words(&val, "= ", 0, &type, &prefix);
51,270✔
1304
                        if (r < 0)
51,270✔
1305
                                return r;
1306
                        if (r == 0)
51,270✔
1307
                                return -EINVAL;
1308

1309
                        dt = exec_directory_type_from_string(type);
51,270✔
1310
                        if (dt < 0)
51,270✔
1311
                                return -EINVAL;
1312

1313
                        if (!p->prefix) {
51,270✔
1314
                                p->prefix = new0(char*, _EXEC_DIRECTORY_TYPE_MAX+1);
10,254✔
1315
                                if (!p->prefix)
10,254✔
1316
                                        return log_oom_debug();
×
1317
                        }
1318

1319
                        if (isempty(prefix))
51,270✔
1320
                                p->prefix[dt] = mfree(p->prefix[dt]);
×
1321
                        else
1322
                                free_and_replace(p->prefix[dt], prefix);
51,270✔
1323
                } else if ((val = startswith(l, "exec-parameters-received-credentials-directory="))) {
65,299✔
1324
                        r = free_and_strdup(&p->received_credentials_directory, val);
9,545✔
1325
                        if (r < 0)
9,545✔
1326
                                return r;
1327
                } else if ((val = startswith(l, "exec-parameters-received-encrypted-credentials-directory="))) {
55,754✔
1328
                        r = free_and_strdup(&p->received_encrypted_credentials_directory, val);
×
1329
                        if (r < 0)
×
1330
                                return r;
1331
                } else if ((val = startswith(l, "exec-parameters-confirm-spawn="))) {
55,754✔
1332
                        r = free_and_strdup(&p->confirm_spawn, val);
×
1333
                        if (r < 0)
×
1334
                                return r;
1335
                } else if ((val = startswith(l, "exec-parameters-shall-confirm-spawn="))) {
55,754✔
1336
                        r = parse_boolean(val);
×
1337
                        if (r < 0)
×
1338
                                return r;
1339

1340
                        p->shall_confirm_spawn = r;
×
1341
                } else if ((val = startswith(l, "exec-parameters-watchdog-usec="))) {
55,754✔
1342
                        r = deserialize_usec(val, &p->watchdog_usec);
1,487✔
1343
                        if (r < 0)
1,487✔
1344
                                return r;
1345
                } else if ((val = startswith(l, "exec-parameters-idle-pipe="))) {
54,267✔
1346
                        if (p->idle_pipe)
87✔
1347
                                return -EINVAL; /* duplicated */
1348

1349
                        p->idle_pipe = new(int, 4);
87✔
1350
                        if (!p->idle_pipe)
87✔
1351
                                return log_oom_debug();
×
1352

1353
                        p->idle_pipe[0] = p->idle_pipe[1] = p->idle_pipe[2] = p->idle_pipe[3] = -EBADF;
87✔
1354

1355
                        r = deserialize_fd_many(fds, val, 4, p->idle_pipe);
87✔
1356
                        if (r < 0)
87✔
1357
                                continue;
×
1358

1359
                } else if ((val = startswith(l, "exec-parameters-stdin-fd="))) {
54,180✔
1360
                        int fd;
590✔
1361

1362
                        fd = deserialize_fd(fds, val);
590✔
1363
                        if (fd < 0)
590✔
1364
                                continue;
×
1365

1366
                        close_and_replace(p->stdin_fd, fd);
590✔
1367

1368
                } else if ((val = startswith(l, "exec-parameters-stdout-fd="))) {
53,590✔
1369
                        int fd;
590✔
1370

1371
                        fd = deserialize_fd(fds, val);
590✔
1372
                        if (fd < 0)
590✔
1373
                                continue;
×
1374

1375
                        close_and_replace(p->stdout_fd, fd);
590✔
1376

1377
                } else if ((val = startswith(l, "exec-parameters-stderr-fd="))) {
53,000✔
1378
                        int fd;
590✔
1379

1380
                        fd = deserialize_fd(fds, val);
590✔
1381
                        if (fd < 0)
590✔
1382
                                continue;
×
1383

1384
                        close_and_replace(p->stderr_fd, fd);
590✔
1385

1386
                } else if ((val = startswith(l, "exec-parameters-root-directory-fd="))) {
52,410✔
1387
                        int fd;
2✔
1388

1389
                        fd = deserialize_fd(fds, val);
2✔
1390
                        if (fd < 0)
2✔
1391
                                continue;
×
1392

1393
                        close_and_replace(p->root_directory_fd, fd);
2✔
1394

1395
                } else if ((val = startswith(l, "exec-parameters-exec-fd="))) {
52,408✔
1396
                        int fd;
459✔
1397

1398
                        fd = deserialize_fd(fds, val);
459✔
1399
                        if (fd < 0)
459✔
1400
                                continue;
×
1401

1402
                        close_and_replace(p->exec_fd, fd);
459✔
1403
                } else if ((val = startswith(l, "exec-parameters-handoff-timestamp-fd="))) {
51,949✔
1404
                        int fd;
10,254✔
1405

1406
                        fd = deserialize_fd(fds, val);
10,254✔
1407
                        if (fd < 0)
10,254✔
1408
                                continue;
×
1409

1410
                        close_and_replace(p->handoff_timestamp_fd, fd);
10,254✔
1411
                } else if ((val = startswith(l, "exec-parameters-pidref-transport-fd="))) {
41,695✔
1412
                        int fd;
9,028✔
1413

1414
                        fd = deserialize_fd(fds, val);
9,028✔
1415
                        if (fd < 0)
9,028✔
1416
                                continue;
×
1417

1418
                        close_and_replace(p->pidref_transport_fd, fd);
9,028✔
1419
                } else if ((val = startswith(l, "exec-parameters-bpf-outer-map-fd="))) {
32,667✔
1420
                        int fd;
×
1421

1422
                        fd = deserialize_fd(fds, val);
×
1423
                        if (fd < 0)
×
1424
                                continue;
×
1425

1426
                        close_and_replace(p->bpf_restrict_fs_map_fd, fd);
×
1427
                } else if ((val = startswith(l, "exec-parameters-notify-socket="))) {
32,667✔
1428
                        r = free_and_strdup(&p->notify_socket, val);
1,896✔
1429
                        if (r < 0)
1,896✔
1430
                                return r;
1431
                } else if ((val = startswith(l, "exec-parameters-open-file="))) {
30,771✔
1432
                        OpenFile *of;
5✔
1433

1434
                        r = open_file_parse(val, &of);
5✔
1435
                        if (r < 0)
5✔
1436
                                return r;
×
1437

1438
                        LIST_APPEND(open_files, p->open_files, of);
5✔
1439
                } else if ((val = startswith(l, "exec-parameters-fallback-smack-process-label="))) {
30,766✔
1440
                        r = free_and_strdup(&p->fallback_smack_process_label, val);
×
1441
                        if (r < 0)
×
1442
                                return r;
1443
                } else if ((val = startswith(l, "exec-parameters-user-lookup-fd="))) {
30,766✔
1444
                        int fd;
10,254✔
1445

1446
                        fd = deserialize_fd(fds, val);
10,254✔
1447
                        if (fd < 0)
10,254✔
1448
                                continue;
×
1449

1450
                        close_and_replace(p->user_lookup_fd, fd);
10,254✔
1451
                } else if ((val = startswith(l, "exec-parameters-files-env="))) {
20,512✔
1452
                        r = deserialize_strv(val, &p->files_env);
2✔
1453
                        if (r < 0)
2✔
1454
                                return r;
1455
                } else if ((val = startswith(l, "exec-parameters-unit-id="))) {
20,510✔
1456
                        r = free_and_strdup(&p->unit_id, val);
10,254✔
1457
                        if (r < 0)
10,254✔
1458
                                return r;
1459
                } else if ((val = startswith(l, "exec-parameters-invocation-id-string="))) {
10,256✔
1460
                        if (strlen(val) > SD_ID128_STRING_MAX - 1)
10,254✔
1461
                                return -EINVAL;
1462

1463
                        r = sd_id128_from_string(val, &p->invocation_id);
10,254✔
1464
                        if (r < 0)
10,254✔
1465
                                return r;
1466

1467
                        sd_id128_to_string(p->invocation_id, p->invocation_id_string);
10,254✔
1468
                } else if ((val = startswith(l, "exec-parameters-debug-invocation="))) {
2✔
1469
                        r = parse_boolean(val);
2✔
1470
                        if (r < 0)
2✔
1471
                                return r;
1472

1473
                        p->debug_invocation = r;
2✔
1474
                } else
1475
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
1476
        }
1477

1478
        /* Bail out if we got exec-parameters-n-{socket/stashed}-fds= but no corresponding
1479
         * exec-parameters-fds= */
1480
        if (p->n_socket_fds + p->n_stashed_fds > 0 && !p->fds)
10,254✔
1481
                return -EINVAL;
×
1482

1483
        return 0;
1484
}
1485

1486
static int serialize_mount_options(const MountOptions *mount_options, char **s) {
24✔
1487
        assert(s);
24✔
1488

1489
        if (!mount_options)
24✔
1490
                return 0;
1491

1492
        for (PartitionDesignator i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
84✔
1493
                _cleanup_free_ char *escaped = NULL;
7✔
1494

1495
                if (isempty(mount_options->options[i]))
78✔
1496
                        continue;
71✔
1497

1498
                escaped = shell_escape(mount_options->options[i], ":");
7✔
1499
                if (!escaped)
7✔
1500
                        return log_oom_debug();
×
1501

1502
                if (!strextend(s,
7✔
1503
                               " ",
1504
                               partition_designator_to_string(i),
1505
                               ":",
1506
                               escaped))
1507
                        return log_oom_debug();
×
1508
        }
1509

1510
        return 0;
1511
}
1512

1513
static int deserialize_mount_options(const char *s, MountOptions **ret_mount_options) {
78✔
1514
        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
78✔
1515
        int r;
78✔
1516

1517
        assert(ret_mount_options);
78✔
1518

1519
        for (;;) {
86✔
1520
                _cleanup_free_ char *word = NULL, *mount_options = NULL, *partition = NULL;
8✔
1521
                PartitionDesignator partition_designator;
86✔
1522
                const char *p;
86✔
1523

1524
                r = extract_first_word(&s, &word, NULL, 0);
86✔
1525
                if (r < 0)
86✔
1526
                        return r;
1527
                if (r == 0)
86✔
1528
                        break;
1529

1530
                p = word;
8✔
1531
                r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options);
8✔
1532
                if (r < 0)
8✔
1533
                        return r;
1534
                if (r == 0)
8✔
1535
                        continue;
×
1536
                if (r != 2) {
8✔
1537
                        log_warning("Failed to parse mount options entry '%s', ignoring.", word);
×
1538
                        continue;
×
1539
                }
1540

1541
                partition_designator = partition_designator_from_string(partition);
8✔
1542
                if (partition_designator < 0) {
8✔
1543
                        log_warning_errno(partition_designator, "Unknown partition designator '%s' in exec-context-root-image-options= entry, ignoring.", partition);
×
1544
                        continue;
×
1545
                }
1546

1547
                r = mount_options_set_and_consume(&options, partition_designator, TAKE_PTR(mount_options));
8✔
1548
                if (r < 0)
8✔
1549
                        return r;
1550
        }
1551

1552
        *ret_mount_options = TAKE_PTR(options);
78✔
1553

1554
        return 0;
78✔
1555
}
1556

1557
static int exec_context_serialize(const ExecContext *c, FILE *f) {
2,517✔
1558
        int r;
2,517✔
1559

1560
        assert(f);
2,517✔
1561

1562
        if (!c)
2,517✔
1563
                return 0;
2,517✔
1564

1565
        r = serialize_strv(f, "exec-context-environment", c->environment);
2,517✔
1566
        if (r < 0)
2,517✔
1567
                return r;
1568

1569
        r = serialize_strv(f, "exec-context-environment-files", c->environment_files);
2,517✔
1570
        if (r < 0)
2,517✔
1571
                return r;
1572

1573
        r = serialize_strv(f, "exec-context-pass-environment", c->pass_environment);
2,517✔
1574
        if (r < 0)
2,517✔
1575
                return r;
1576

1577
        r = serialize_strv(f, "exec-context-unset-environment", c->unset_environment);
2,517✔
1578
        if (r < 0)
2,517✔
1579
                return r;
1580

1581
        r = serialize_item_escaped(f, "exec-context-working-directory", c->working_directory);
2,517✔
1582
        if (r < 0)
2,517✔
1583
                return r;
1584

1585
        r = serialize_bool_elide(f, "exec-context-working-directory-missing-ok", c->working_directory_missing_ok);
2,517✔
1586
        if (r < 0)
2,517✔
1587
                return r;
1588

1589
        r = serialize_bool_elide(f, "exec-context-working-directory-home", c->working_directory_home);
2,517✔
1590
        if (r < 0)
2,517✔
1591
                return r;
1592

1593
        r = serialize_item_escaped(f, "exec-context-root-directory", c->root_directory);
2,517✔
1594
        if (r < 0)
2,517✔
1595
                return r;
1596

1597
        r = serialize_item_escaped(f, "exec-context-root-image", c->root_image);
2,517✔
1598
        if (r < 0)
2,517✔
1599
                return r;
1600

1601
        if (c->root_image_options) {
2,517✔
1602
                _cleanup_free_ char *options = NULL;
2✔
1603

1604
                r = serialize_mount_options(c->root_image_options, &options);
2✔
1605
                if (r < 0)
2✔
1606
                        return r;
1607

1608
                r = serialize_item(f, "exec-context-root-image-options", options);
2✔
1609
                if (r < 0)
2✔
1610
                        return r;
1611
        }
1612

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

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

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

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

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

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

1637
        r = serialize_item_escaped(f, "exec-context-root-mstack", c->root_mstack);
2,517✔
1638
        if (r < 0)
2,517✔
1639
                return r;
1640

1641
        r = serialize_item_format(f, "exec-context-umask", "%04o", c->umask);
2,517✔
1642
        if (r < 0)
2,517✔
1643
                return r;
1644

1645
        r = serialize_bool_elide(f, "exec-context-non-blocking", c->non_blocking);
2,517✔
1646
        if (r < 0)
2,517✔
1647
                return r;
1648

1649
        r = serialize_item_tristate(f, "exec-context-private-mounts", c->private_mounts);
2,517✔
1650
        if (r < 0)
28✔
1651
                return r;
1652

1653
        r = serialize_item_tristate(f, "exec-context-mount-api-vfs", c->mount_apivfs);
2,517✔
1654
        if (r < 0)
30✔
1655
                return r;
1656

1657
        r = serialize_item_tristate(f, "exec-context-bind-log-sockets", c->bind_log_sockets);
2,517✔
1658
        if (r < 0)
28✔
1659
                return r;
1660

1661
        r = serialize_item_tristate(f, "exec-context-memory-ksm", c->memory_ksm);
2,517✔
1662
        if (r < 0)
×
1663
                return r;
1664

1665
        r = serialize_item(f, "exec-context-memory-thp", memory_thp_to_string(c->memory_thp));
2,517✔
1666
        if (r < 0)
2,517✔
1667
                return r;
1668

1669
        r = serialize_item(f, "exec-context-private-tmp", private_tmp_to_string(c->private_tmp));
2,517✔
1670
        if (r < 0)
2,517✔
1671
                return r;
1672

1673
        /* This must be set in unit_patch_contexts() before executing a command. */
1674
        assert(c->private_var_tmp >= 0 && c->private_var_tmp < _PRIVATE_TMP_MAX);
2,517✔
1675
        r = serialize_item(f, "exec-context-private-var-tmp", private_tmp_to_string(c->private_var_tmp));
2,517✔
1676
        if (r < 0)
2,517✔
1677
                return r;
1678

1679
        r = serialize_bool_elide(f, "exec-context-private-devices", c->private_devices);
2,517✔
1680
        if (r < 0)
2,517✔
1681
                return r;
1682

1683
        r = serialize_bool_elide(f, "exec-context-protect-kernel-tunables", c->protect_kernel_tunables);
2,517✔
1684
        if (r < 0)
2,517✔
1685
                return r;
1686

1687
        r = serialize_bool_elide(f, "exec-context-protect-kernel-modules", c->protect_kernel_modules);
2,517✔
1688
        if (r < 0)
2,517✔
1689
                return r;
1690

1691
        r = serialize_bool_elide(f, "exec-context-protect-kernel-logs", c->protect_kernel_logs);
2,517✔
1692
        if (r < 0)
2,517✔
1693
                return r;
1694

1695
        r = serialize_bool_elide(f, "exec-context-protect-clock", c->protect_clock);
2,517✔
1696
        if (r < 0)
2,517✔
1697
                return r;
1698

1699
        r = serialize_item(f, "exec-context-protect-control-groups", protect_control_groups_to_string(c->protect_control_groups));
2,517✔
1700
        if (r < 0)
2,517✔
1701
                return r;
1702

1703
        r = serialize_bool_elide(f, "exec-context-private-network", c->private_network);
2,517✔
1704
        if (r < 0)
2,517✔
1705
                return r;
1706

1707
        r = serialize_item(f, "exec-context-private-users", private_users_to_string(c->private_users));
2,517✔
1708
        if (r < 0)
2,517✔
1709
                return r;
1710

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

1715
        r = serialize_item(f, "exec-context-private-pids", private_pids_to_string(c->private_pids));
2,517✔
1716
        if (r < 0)
2,517✔
1717
                return r;
1718

1719
        r = serialize_bool_elide(f, "exec-context-remove-ipc", c->remove_ipc);
2,517✔
1720
        if (r < 0)
2,517✔
1721
                return r;
1722

1723
        r = serialize_item(f, "exec-context-protect-home", protect_home_to_string(c->protect_home));
2,517✔
1724
        if (r < 0)
2,517✔
1725
                return r;
1726

1727
        r = serialize_item(f, "exec-context-protect-system", protect_system_to_string(c->protect_system));
2,517✔
1728
        if (r < 0)
2,517✔
1729
                return r;
1730

1731
        r = serialize_bool_elide(f, "exec-context-same-pgrp", c->same_pgrp);
2,517✔
1732
        if (r < 0)
2,517✔
1733
                return r;
1734

1735
        r = serialize_bool(f, "exec-context-ignore-sigpipe", c->ignore_sigpipe);
2,517✔
1736
        if (r < 0)
2,517✔
1737
                return r;
1738

1739
        r = serialize_bool_elide(f, "exec-context-memory-deny-write-execute", c->memory_deny_write_execute);
2,517✔
1740
        if (r < 0)
2,517✔
1741
                return r;
1742

1743
        r = serialize_bool_elide(f, "exec-context-restrict-realtime", c->restrict_realtime);
2,517✔
1744
        if (r < 0)
2,517✔
1745
                return r;
1746

1747
        r = serialize_bool_elide(f, "exec-context-restrict-suid-sgid", c->restrict_suid_sgid);
2,517✔
1748
        if (r < 0)
2,517✔
1749
                return r;
1750

1751
        r = serialize_item(f, "exec-context-keyring-mode", exec_keyring_mode_to_string(c->keyring_mode));
2,517✔
1752
        if (r < 0)
2,517✔
1753
                return r;
1754

1755
        r = serialize_item(f, "exec-context-protect-hostname", protect_hostname_to_string(c->protect_hostname));
2,517✔
1756
        if (r < 0)
2,517✔
1757
                return r;
1758

1759
        r = serialize_item(f, "exec-context-private-hostname", c->private_hostname);
2,517✔
1760
        if (r < 0)
2,517✔
1761
                return r;
1762

1763
        r = serialize_item(f, "exec-context-protect-proc", protect_proc_to_string(c->protect_proc));
2,517✔
1764
        if (r < 0)
2,517✔
1765
                return r;
1766

1767
        r = serialize_item(f, "exec-context-proc-subset", proc_subset_to_string(c->proc_subset));
2,517✔
1768
        if (r < 0)
2,517✔
1769
                return r;
1770

1771
        r = serialize_item(f, "exec-context-private-bpf", private_bpf_to_string(c->private_bpf));
2,517✔
1772
        if (r < 0)
2,517✔
1773
                return r;
1774

1775
        if (c->bpf_delegate_commands != 0) {
2,517✔
1776
                r = serialize_item_format(f, "exec-context-bpf-delegate-commands", "0x%"PRIx64, c->bpf_delegate_commands);
×
1777
                if (r < 0)
×
1778
                        return r;
1779
        }
1780

1781
        if (c->bpf_delegate_maps != 0) {
2,517✔
1782
                r = serialize_item_format(f, "exec-context-bpf-delegate-maps", "0x%"PRIx64, c->bpf_delegate_maps);
×
1783
                if (r < 0)
×
1784
                        return r;
1785
        }
1786

1787
        if (c->bpf_delegate_programs != 0) {
2,517✔
1788
                r = serialize_item_format(f, "exec-context-bpf-delegate-programs", "0x%"PRIx64, c->bpf_delegate_programs);
×
1789
                if (r < 0)
×
1790
                        return r;
1791
        }
1792

1793
        if (c->bpf_delegate_attachments != 0) {
2,517✔
1794
                r = serialize_item_format(f, "exec-context-bpf-delegate-attachments", "0x%"PRIx64, c->bpf_delegate_attachments);
×
1795
                if (r < 0)
×
1796
                        return r;
1797
        }
1798

1799
        r = serialize_item(f, "exec-context-runtime-directory-preserve-mode", exec_preserve_mode_to_string(c->runtime_directory_preserve_mode));
2,517✔
1800
        if (r < 0)
2,517✔
1801
                return r;
1802

1803
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
15,102✔
1804
                _cleanup_free_ char *key = NULL, *value = NULL;
12,585✔
1805

1806
                key = strjoin("exec-context-directories-", exec_directory_type_to_string(dt));
12,585✔
1807
                if (!key)
12,585✔
1808
                        return log_oom_debug();
×
1809

1810
                if (asprintf(&value, "%04o", c->directories[dt].mode) < 0)
12,585✔
1811
                        return log_oom_debug();
×
1812

1813
                FOREACH_ARRAY(i, c->directories[dt].items, c->directories[dt].n_items) {
13,034✔
1814
                        _cleanup_free_ char *path_escaped = NULL;
449✔
1815

1816
                        path_escaped = shell_escape(i->path, ":" WHITESPACE);
449✔
1817
                        if (!path_escaped)
449✔
1818
                                return log_oom_debug();
×
1819

1820
                        if (!strextend(&value, " ", path_escaped))
449✔
1821
                                return log_oom_debug();
×
1822

1823
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE))))
893✔
1824
                                return log_oom_debug();
×
1825

1826
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_READ_ONLY))))
896✔
1827
                                return log_oom_debug();
×
1828

1829
                        STRV_FOREACH(d, i->symlinks) {
455✔
1830
                                _cleanup_free_ char *link_escaped = NULL;
6✔
1831

1832
                                link_escaped = shell_escape(*d, ":" WHITESPACE);
6✔
1833
                                if (!link_escaped)
6✔
1834
                                        return log_oom_debug();
×
1835

1836
                                if (!strextend(&value, ":", link_escaped))
6✔
1837
                                        return log_oom_debug();
×
1838
                        }
1839
                }
1840

1841
                r = serialize_item(f, key, value);
12,585✔
1842
                if (r < 0)
12,585✔
1843
                        return r;
1844

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

1851
                        r = serialize_item_format(f, key_quota, "%" PRIu64 " %" PRIu32, c->directories[dt].exec_quota.quota_absolute,
×
1852
                                                                                        c->directories[dt].exec_quota.quota_scale);
×
1853
                        if (r < 0)
×
1854
                                return r;
1855

1856
                } else if (c->directories[dt].exec_quota.quota_accounting) {
12,585✔
1857
                        _cleanup_free_ char *key_quota = NULL;
×
1858
                        key_quota = strjoin("exec-context-quota-accounting-directories-", exec_directory_type_to_string(dt));
×
1859
                        if (!key_quota)
×
1860
                                return log_oom_debug();
×
1861

1862
                        r = serialize_bool(f, key_quota, c->directories[dt].exec_quota.quota_accounting);
×
1863
                        if (r < 0)
×
1864
                                return r;
1865
                }
1866
        }
1867

1868
        r = serialize_usec(f, "exec-context-timeout-clean-usec", c->timeout_clean_usec);
2,517✔
1869
        if (r < 0)
2,517✔
1870
                return r;
1871

1872
        if (c->nice_set) {
2,517✔
1873
                r = serialize_item_format(f, "exec-context-nice", "%i", c->nice);
3✔
1874
                if (r < 0)
3✔
1875
                        return r;
1876
        }
1877

1878
        if (c->oom_score_adjust_set) {
2,517✔
1879
                r = serialize_item_format(f, "exec-context-oom-score-adjust", "%i", c->oom_score_adjust);
639✔
1880
                if (r < 0)
639✔
1881
                        return r;
1882
        }
1883

1884
        if (c->coredump_filter_set) {
2,517✔
1885
                r = serialize_item_format(f, "exec-context-coredump-filter", "%"PRIx64, c->coredump_filter);
×
1886
                if (r < 0)
×
1887
                        return r;
1888
        }
1889

1890
        for (unsigned i = 0; i < RLIM_NLIMITS; i++) {
42,789✔
1891
                _cleanup_free_ char *key = NULL, *limit = NULL;
5,028✔
1892

1893
                if (!c->rlimit[i])
40,272✔
1894
                        continue;
35,244✔
1895

1896
                key = strjoin("exec-context-limit-", rlimit_to_string(i));
5,028✔
1897
                if (!key)
5,028✔
1898
                        return log_oom_debug();
×
1899

1900
                r = rlimit_format(c->rlimit[i], &limit);
5,028✔
1901
                if (r < 0)
5,028✔
1902
                        return r;
1903

1904
                r = serialize_item(f, key, limit);
5,028✔
1905
                if (r < 0)
5,028✔
1906
                        return r;
1907
        }
1908

1909
        if (c->ioprio_is_set) {
2,517✔
1910
                r = serialize_item_format(f, "exec-context-ioprio", "%d", c->ioprio);
7✔
1911
                if (r < 0)
7✔
1912
                        return r;
1913
        }
1914

1915
        if (c->cpu_sched_set) {
2,517✔
1916
                _cleanup_free_ char *policy_str = NULL;
×
1917

1918
                r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
×
1919
                if (r < 0)
×
1920
                        return r;
1921

1922
                r = serialize_item(f, "exec-context-cpu-scheduling-policy", policy_str);
×
1923
                if (r < 0)
×
1924
                        return r;
1925

1926
                r = serialize_item_format(f, "exec-context-cpu-scheduling-priority", "%i", c->cpu_sched_priority);
×
1927
                if (r < 0)
×
1928
                        return r;
1929

1930
                r = serialize_bool_elide(f, "exec-context-cpu-scheduling-reset-on-fork", c->cpu_sched_reset_on_fork);
×
1931
                if (r < 0)
×
1932
                        return r;
1933
        }
1934

1935
        if (c->cpu_set.set) {
2,517✔
1936
                _cleanup_free_ char *affinity = NULL;
×
1937

1938
                affinity = cpu_set_to_range_string(&c->cpu_set);
×
1939
                if (!affinity)
×
1940
                        return log_oom_debug();
×
1941

1942
                r = serialize_item(f, "exec-context-cpu-affinity", affinity);
×
1943
                if (r < 0)
×
1944
                        return r;
1945
        }
1946

1947
        if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) {
2,517✔
1948
                _cleanup_free_ char *nodes = NULL;
×
1949

1950
                nodes = cpu_set_to_range_string(&c->numa_policy.nodes);
×
1951
                if (!nodes)
×
1952
                        return log_oom_debug();
×
1953

1954
                if (nodes) {
×
1955
                        r = serialize_item(f, "exec-context-numa-mask", nodes);
×
1956
                        if (r < 0)
×
1957
                                return r;
1958
                }
1959

1960
                r = serialize_item_format(f, "exec-context-numa-policy", "%d", c->numa_policy.type);
×
1961
                if (r < 0)
×
1962
                        return r;
1963
        }
1964

1965
        r = serialize_bool_elide(f, "exec-context-cpu-affinity-from-numa", c->cpu_affinity_from_numa);
2,517✔
1966
        if (r < 0)
2,517✔
1967
                return r;
1968

1969
        if (c->timer_slack_nsec != NSEC_INFINITY) {
2,517✔
1970
                r = serialize_item_format(f, "exec-context-timer-slack-nsec", NSEC_FMT, c->timer_slack_nsec);
×
1971
                if (r < 0)
×
1972
                        return r;
1973
        }
1974

1975
        r = serialize_bool_elide(f, "exec-context-root-directory-as-fd", c->root_directory_as_fd);
2,517✔
1976
        if (r < 0)
2,517✔
1977
                return r;
1978

1979
        r = serialize_item(f, "exec-context-std-input", exec_input_to_string(c->std_input));
2,517✔
1980
        if (r < 0)
2,517✔
1981
                return r;
1982

1983
        r = serialize_item(f, "exec-context-std-output", exec_output_to_string(c->std_output));
2,517✔
1984
        if (r < 0)
2,517✔
1985
                return r;
1986

1987
        r = serialize_item(f, "exec-context-std-error", exec_output_to_string(c->std_error));
2,517✔
1988
        if (r < 0)
2,517✔
1989
                return r;
1990

1991
        r = serialize_bool_elide(f, "exec-context-stdio-as-fds", c->stdio_as_fds);
2,517✔
1992
        if (r < 0)
2,517✔
1993
                return r;
1994

1995
        switch (c->std_input) {
2,517✔
1996

1997
        case EXEC_INPUT_NAMED_FD:
×
1998
                r = serialize_item(f, "exec-context-std-input-fd-name", c->stdio_fdname[STDIN_FILENO]);
×
1999
                break;
2000

2001
        case EXEC_INPUT_FILE:
×
2002
                r = serialize_item_escaped(f, "exec-context-std-input-file", c->stdio_file[STDIN_FILENO]);
×
2003
                break;
2004

2005
        case EXEC_INPUT_DATA:
×
2006
                r = serialize_item_base64mem(f, "exec-context-std-input-data", c->stdin_data, c->stdin_data_size);
×
2007
                break;
2008

2009
        default:
2010
                r = 0;
2011
        }
2012
        if (r < 0)
×
2013
                return r;
2014

2015
        switch (c->std_output) {
2,517✔
2016

2017
        case EXEC_OUTPUT_NAMED_FD:
×
2018
                r = serialize_item(f, "exec-context-std-output-fd-name", c->stdio_fdname[STDOUT_FILENO]);
×
2019
                break;
2020

2021
        case EXEC_OUTPUT_FILE:
2✔
2022
        case EXEC_OUTPUT_FILE_APPEND:
2023
        case EXEC_OUTPUT_FILE_TRUNCATE:
2024
                r = serialize_item_escaped(f, "exec-context-std-output-file", c->stdio_file[STDOUT_FILENO]);
2✔
2025
                break;
2026

2027
        default:
2028
                r = 0;
2029
        }
2030
        if (r < 0)
2✔
2031
                return r;
2032

2033

2034
        switch (c->std_error) {
2,517✔
2035

2036
        case EXEC_OUTPUT_NAMED_FD:
×
2037
                r = serialize_item(f, "exec-context-std-error-fd-name", c->stdio_fdname[STDERR_FILENO]);
×
2038
                break;
2039

2040
        case EXEC_OUTPUT_FILE:
×
2041
        case EXEC_OUTPUT_FILE_APPEND:
2042
        case EXEC_OUTPUT_FILE_TRUNCATE:
2043
                r = serialize_item_escaped(f, "exec-context-std-error-file", c->stdio_file[STDERR_FILENO]);
×
2044
                break;
2045

2046
        default:
2047
                r = 0;
2048
        }
2049
        if (r < 0)
×
2050
                return r;
2051

2052
        r = serialize_item(f, "exec-context-tty-path", c->tty_path);
2,517✔
2053
        if (r < 0)
2,517✔
2054
                return r;
2055

2056
        r = serialize_bool_elide(f, "exec-context-tty-reset", c->tty_reset);
2,517✔
2057
        if (r < 0)
2,517✔
2058
                return r;
2059

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

2064
        r = serialize_bool_elide(f, "exec-context-tty-vt-disallocate", c->tty_vt_disallocate);
2,517✔
2065
        if (r < 0)
2,517✔
2066
                return r;
2067

2068
        r = serialize_item_format(f, "exec-context-tty-rows", "%u", c->tty_rows);
2,517✔
2069
        if (r < 0)
2,517✔
2070
                return r;
2071

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

2076
        r = serialize_item_format(f, "exec-context-syslog-priority", "%i", c->syslog_priority);
2,517✔
2077
        if (r < 0)
2,517✔
2078
                return r;
2079

2080
        r = serialize_bool(f, "exec-context-syslog-level-prefix", c->syslog_level_prefix);
2,517✔
2081
        if (r < 0)
2,517✔
2082
                return r;
2083

2084
        r = serialize_item(f, "exec-context-syslog-identifier", c->syslog_identifier);
2,517✔
2085
        if (r < 0)
2,517✔
2086
                return r;
2087

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

2094
        if (c->log_ratelimit.interval > 0) {
2,517✔
2095
                r = serialize_usec(f, "exec-context-log-ratelimit-interval-usec", c->log_ratelimit.interval);
×
2096
                if (r < 0)
×
2097
                        return r;
2098
        }
2099

2100
        if (c->log_ratelimit.burst > 0) {
2,517✔
2101
                r = serialize_item_format(f, "exec-context-log-ratelimit-burst", "%u", c->log_ratelimit.burst);
×
2102
                if (r < 0)
×
2103
                        return r;
2104
        }
2105

2106
        r = serialize_string_set(f, "exec-context-log-filter-allowed-patterns", c->log_filter_allowed_patterns);
2,517✔
2107
        if (r < 0)
2,517✔
2108
                return r;
2109

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

2114
        FOREACH_ARRAY(field, c->log_extra_fields, c->n_log_extra_fields) {
2,858✔
2115
                r = serialize_item(f, "exec-context-log-extra-fields", field->iov_base);
341✔
2116
                if (r < 0)
341✔
2117
                        return r;
2118
        }
2119

2120
        r = serialize_item(f, "exec-context-log-namespace", c->log_namespace);
2,517✔
2121
        if (r < 0)
2,517✔
2122
                return r;
2123

2124
        if (c->secure_bits != 0) {
2,517✔
2125
                r = serialize_item_format(f, "exec-context-secure-bits", "%d", c->secure_bits);
×
2126
                if (r < 0)
×
2127
                        return r;
2128
        }
2129

2130
        if (c->capability_bounding_set != CAP_MASK_UNSET) {
2,517✔
2131
                r = serialize_item_format(f, "exec-context-capability-bounding-set", "%" PRIu64, c->capability_bounding_set);
2,517✔
2132
                if (r < 0)
2,517✔
2133
                        return r;
2134
        }
2135

2136
        if (c->capability_ambient_set != 0) {
2,517✔
2137
                r = serialize_item_format(f, "exec-context-capability-ambient-set", "%" PRIu64, c->capability_ambient_set);
69✔
2138
                if (r < 0)
69✔
2139
                        return r;
2140
        }
2141

2142
        if (c->user) {
2,517✔
2143
                r = serialize_item(f, "exec-context-user", c->user);
215✔
2144
                if (r < 0)
215✔
2145
                        return r;
2146
        }
2147

2148
        r = serialize_item(f, "exec-context-group", c->group);
2,517✔
2149
        if (r < 0)
2,517✔
2150
                return r;
2151

2152
        r = serialize_bool_elide(f, "exec-context-dynamic-user", c->dynamic_user);
2,517✔
2153
        if (r < 0)
2,517✔
2154
                return r;
2155

2156
        r = serialize_strv(f, "exec-context-supplementary-groups", c->supplementary_groups);
2,517✔
2157
        if (r < 0)
2,517✔
2158
                return r;
2159

2160
        r = serialize_item_tristate(f, "exec-context-set-login-environment", c->set_login_environment);
2,517✔
2161
        if (r < 0)
×
2162
                return r;
2163

2164
        r = serialize_item(f, "exec-context-pam-name", c->pam_name);
2,517✔
2165
        if (r < 0)
2,517✔
2166
                return r;
2167

2168
        r = serialize_strv(f, "exec-context-read-write-paths", c->read_write_paths);
2,517✔
2169
        if (r < 0)
2,517✔
2170
                return r;
2171

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

2176
        r = serialize_strv(f, "exec-context-inaccessible-paths", c->inaccessible_paths);
2,517✔
2177
        if (r < 0)
2,517✔
2178
                return r;
2179

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

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

2188
        r = serialize_strv(f, "exec-context-exec-search-path", c->exec_search_path);
2,517✔
2189
        if (r < 0)
2,517✔
2190
                return r;
2191

2192
        r = serialize_item_format(f, "exec-context-mount-propagation-flag", "%lu", c->mount_propagation_flag);
2,517✔
2193
        if (r < 0)
2,517✔
2194
                return r;
2195

2196
        FOREACH_ARRAY(mount, c->bind_mounts, c->n_bind_mounts) {
2,616✔
2197
                _cleanup_free_ char *src_escaped = NULL, *dst_escaped = NULL;
99✔
2198

2199
                src_escaped = shell_escape(mount->source, ":" WHITESPACE);
99✔
2200
                if (!src_escaped)
99✔
2201
                        return log_oom_debug();
×
2202

2203
                dst_escaped = shell_escape(mount->destination, ":" WHITESPACE);
99✔
2204
                if (!dst_escaped)
99✔
2205
                        return log_oom_debug();
×
2206

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

2218
        FOREACH_ARRAY(tmpfs, c->temporary_filesystems, c->n_temporary_filesystems) {
2,538✔
2219
                _cleanup_free_ char *escaped = NULL;
21✔
2220

2221
                if (!isempty(tmpfs->options)) {
21✔
2222
                        escaped = shell_escape(tmpfs->options, ":");
×
2223
                        if (!escaped)
×
2224
                                return log_oom_debug();
×
2225
                }
2226

2227
                r = serialize_item_format(f, "exec-context-temporary-filesystems", "%s%s%s",
×
2228
                                          tmpfs->path,
2229
                                          isempty(escaped) ? "" : ":",
21✔
2230
                                          strempty(escaped));
2231
                if (r < 0)
21✔
2232
                        return r;
2233
        }
2234

2235
        r = serialize_item(f, "exec-context-utmp-id", c->utmp_id);
2,517✔
2236
        if (r < 0)
2,517✔
2237
                return r;
2238

2239
        r = serialize_item(f, "exec-context-utmp-mode", exec_utmp_mode_to_string(c->utmp_mode));
2,517✔
2240
        if (r < 0)
2,517✔
2241
                return r;
2242

2243
        r = serialize_bool_elide(f, "exec-context-no-new-privileges", c->no_new_privileges);
2,517✔
2244
        if (r < 0)
2,517✔
2245
                return r;
2246

2247
        if (c->selinux_context) {
2,517✔
2248
                r = serialize_item_format(f, "exec-context-selinux-context",
×
2249
                                          "%s%s",
2250
                                          c->selinux_context_ignore ? "-" : "",
×
2251
                                          c->selinux_context);
2252
                if (r < 0)
×
2253
                        return r;
2254
        }
2255

2256
        if (c->apparmor_profile) {
2,517✔
2257
                r = serialize_item_format(f, "exec-context-apparmor-profile",
×
2258
                                          "%s%s",
2259
                                          c->apparmor_profile_ignore ? "-" : "",
×
2260
                                          c->apparmor_profile);
2261
                if (r < 0)
×
2262
                        return r;
2263
        }
2264

2265
        if (c->smack_process_label) {
2,517✔
2266
                r = serialize_item_format(f, "exec-context-smack-process-label",
×
2267
                                          "%s%s",
2268
                                          c->smack_process_label_ignore ? "-" : "",
×
2269
                                          c->smack_process_label);
2270
                if (r < 0)
×
2271
                        return r;
2272
        }
2273

2274
        if (c->personality != PERSONALITY_INVALID) {
2,517✔
2275
                r = serialize_item(f, "exec-context-personality", personality_to_string(c->personality));
×
2276
                if (r < 0)
×
2277
                        return r;
2278
        }
2279

2280
        r = serialize_bool_elide(f, "exec-context-lock-personality", c->lock_personality);
2,517✔
2281
        if (r < 0)
2,517✔
2282
                return r;
2283

2284
#if HAVE_SECCOMP
2285
        if (!hashmap_isempty(c->syscall_filter)) {
2,517✔
2286
                void *errno_num, *id;
260✔
2287
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_filter) {
100,418✔
2288
                        r = serialize_item_format(f, "exec-context-syscall-filter", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
100,158✔
2289
                        if (r < 0)
100,158✔
2290
                                return r;
×
2291
                }
2292
        }
2293

2294
        if (!set_isempty(c->syscall_archs)) {
2,517✔
2295
                void *id;
256✔
2296
                SET_FOREACH(id, c->syscall_archs) {
512✔
2297
                        r = serialize_item_format(f, "exec-context-syscall-archs", "%u", PTR_TO_UINT(id) - 1);
256✔
2298
                        if (r < 0)
256✔
2299
                                return r;
×
2300
                }
2301
        }
2302

2303
        if (c->syscall_errno > 0) {
2,517✔
2304
                r = serialize_item_format(f, "exec-context-syscall-errno", "%d", c->syscall_errno);
2,517✔
2305
                if (r < 0)
2,517✔
2306
                        return r;
2307
        }
2308

2309
        r = serialize_bool_elide(f, "exec-context-syscall-allow-list", c->syscall_allow_list);
2,517✔
2310
        if (r < 0)
2,517✔
2311
                return r;
2312

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

2322
        r = serialize_bool_elide(f, "exec-context-syscall-log-allow-list", c->syscall_log_allow_list);
2,517✔
2323
        if (r < 0)
2,517✔
2324
                return r;
2325
#endif
2326

2327
        if (c->restrict_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,517✔
2328
                r = serialize_item_format(f, "exec-context-restrict-namespaces", "%lu", c->restrict_namespaces);
206✔
2329
                if (r < 0)
206✔
2330
                        return r;
2331
        }
2332

2333
        if (c->delegate_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,517✔
2334
                r = serialize_item_format(f, "exec-context-delegate-namespaces", "%lu", c->delegate_namespaces);
37✔
2335
                if (r < 0)
37✔
2336
                        return r;
2337
        }
2338

2339
#if HAVE_LIBBPF
2340
        if (exec_context_restrict_filesystems_set(c)) {
2,517✔
2341
                char *fs;
×
2342
                SET_FOREACH(fs, c->restrict_filesystems) {
×
2343
                        r = serialize_item(f, "exec-context-restrict-filesystems", fs);
×
2344
                        if (r < 0)
×
2345
                                return r;
×
2346
                }
2347
        }
2348

2349
        r = serialize_bool_elide(f, "exec-context-restrict-filesystems-allow-list", c->restrict_filesystems_allow_list);
2,517✔
2350
        if (r < 0)
2,517✔
2351
                return r;
2352
#endif
2353

2354
        if (!set_isempty(c->address_families)) {
2,517✔
2355
                void *afp;
256✔
2356

2357
                SET_FOREACH(afp, c->address_families) {
1,254✔
2358
                        int af = PTR_TO_INT(afp);
998✔
2359

2360
                        if (af <= 0 || af >= af_max())
998✔
2361
                                continue;
×
2362

2363
                        r = serialize_item_format(f, "exec-context-address-families", "%d", af);
998✔
2364
                        if (r < 0)
998✔
2365
                                return r;
×
2366
                }
2367
        }
2368

2369
        r = serialize_bool_elide(f, "exec-context-address-families-allow-list", c->address_families_allow_list);
2,517✔
2370
        if (r < 0)
2,517✔
2371
                return r;
2372

2373
        r = serialize_item(f, "exec-context-user-namespace-path", c->user_namespace_path);
2,517✔
2374
        if (r < 0)
2,517✔
2375
                return r;
2376

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

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

2385
        FOREACH_ARRAY(mount, c->mount_images, c->n_mount_images) {
2,519✔
2386
                _cleanup_free_ char *s = NULL, *source_escaped = NULL, *dest_escaped = NULL;
2✔
2387

2388
                source_escaped = shell_escape(mount->source, WHITESPACE);
2✔
2389
                if (!source_escaped)
2✔
2390
                        return log_oom_debug();
×
2391

2392
                dest_escaped = shell_escape(mount->destination, WHITESPACE);
2✔
2393
                if (!dest_escaped)
2✔
2394
                        return log_oom_debug();
×
2395

2396
                s = strjoin(mount->ignore_enoent ? "-" : "",
4✔
2397
                            source_escaped,
2398
                            " ",
2399
                            dest_escaped);
2400
                if (!s)
2✔
2401
                        return log_oom_debug();
×
2402

2403
                r = serialize_mount_options(mount->mount_options, &s);
2✔
2404
                if (r < 0)
2✔
2405
                        return r;
2406

2407
                r = serialize_item(f, "exec-context-mount-image", s);
2✔
2408
                if (r < 0)
2✔
2409
                        return r;
2410
        }
2411

2412
        FOREACH_ARRAY(mount, c->extension_images, c->n_extension_images) {
2,537✔
2413
                _cleanup_free_ char *s = NULL, *source_escaped = NULL;
20✔
2414

2415
                source_escaped = shell_escape(mount->source, ":" WHITESPACE);
20✔
2416
                if (!source_escaped)
20✔
2417
                        return log_oom_debug();
×
2418

2419
                s = strjoin(mount->ignore_enoent ? "-" : "",
40✔
2420
                            source_escaped);
2421
                if (!s)
20✔
2422
                        return log_oom_debug();
×
2423

2424
                r = serialize_mount_options(mount->mount_options, &s);
20✔
2425
                if (r < 0)
20✔
2426
                        return r;
2427

2428
                r = serialize_item(f, "exec-context-extension-image", s);
20✔
2429
                if (r < 0)
20✔
2430
                        return r;
2431
        }
2432

2433
        r = serialize_strv(f, "exec-context-extension-directories", c->extension_directories);
2,517✔
2434
        if (r < 0)
2,517✔
2435
                return r;
2436

2437
        ExecSetCredential *sc;
2,517✔
2438
        HASHMAP_FOREACH(sc, c->set_credentials) {
2,523✔
2439
                _cleanup_free_ char *data = NULL;
6✔
2440

2441
                if (base64mem(sc->data, sc->size, &data) < 0)
6✔
2442
                        return log_oom_debug();
×
2443

2444
                r = serialize_item_format(f, "exec-context-set-credentials", "%s %s %s", sc->id, data, yes_no(sc->encrypted));
12✔
2445
                if (r < 0)
6✔
2446
                        return r;
2447
        }
2448

2449
        ExecLoadCredential *lc;
2,517✔
2450
        HASHMAP_FOREACH(lc, c->load_credentials) {
2,528✔
2451
                r = serialize_item_format(f, "exec-context-load-credentials", "%s %s %s", lc->id, lc->path, yes_no(lc->encrypted));
21✔
2452
                if (r < 0)
11✔
2453
                        return r;
×
2454
        }
2455

2456
        ExecImportCredential *ic;
2,517✔
2457
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
3,464✔
2458
                r = serialize_item_format(f, "exec-context-import-credentials", "%s%s%s",
1,844✔
2459
                                          ic->glob,
2460
                                          ic->rename ? " " : "",
2461
                                          strempty(ic->rename));
947✔
2462
                if (r < 0)
947✔
2463
                        return r;
×
2464
        }
2465

2466
        r = serialize_image_policy(f, "exec-context-root-image-policy", c->root_image_policy);
2,517✔
2467
        if (r < 0)
2,517✔
2468
                return r;
2469

2470
        r = serialize_image_policy(f, "exec-context-mount-image-policy", c->mount_image_policy);
2,517✔
2471
        if (r < 0)
2,517✔
2472
                return r;
2473

2474
        r = serialize_image_policy(f, "exec-context-extension-image-policy", c->extension_image_policy);
2,517✔
2475
        if (r < 0)
2,517✔
2476
                return r;
2477

2478
        fputc('\n', f); /* End marker */
2,517✔
2479

2480
        return 0;
2481
}
2482

2483
static int exec_context_deserialize(ExecContext *c, FILE *f) {
10,254✔
2484
        int r;
10,254✔
2485

2486
        assert(f);
10,254✔
2487

2488
        if (!c)
10,254✔
2489
                return 0;
2490

2491
        for (;;) {
985,302✔
2492
                _cleanup_free_ char *l = NULL;
975,048✔
2493
                const char *val;
985,302✔
2494

2495
                r = deserialize_read_line(f, &l);
985,302✔
2496
                if (r < 0)
985,302✔
2497
                        return r;
2498
                if (r == 0) /* eof or end marker */
985,302✔
2499
                        break;
2500

2501
                if ((val = startswith(l, "exec-context-environment="))) {
975,048✔
2502
                        r = deserialize_strv(val, &c->environment);
3,937✔
2503
                        if (r < 0)
3,937✔
2504
                                return r;
2505
                } else if ((val = startswith(l, "exec-context-environment-files="))) {
971,111✔
2506
                        r = deserialize_strv(val, &c->environment_files);
349✔
2507
                        if (r < 0)
349✔
2508
                                return r;
2509
                } else if ((val = startswith(l, "exec-context-pass-environment="))) {
970,762✔
2510
                        r = deserialize_strv(val, &c->pass_environment);
316✔
2511
                        if (r < 0)
316✔
2512
                                return r;
2513
                } else if ((val = startswith(l, "exec-context-unset-environment="))) {
970,446✔
2514
                        r = deserialize_strv(val, &c->unset_environment);
1,015✔
2515
                        if (r < 0)
1,015✔
2516
                                return r;
2517
                } else if ((val = startswith(l, "exec-context-working-directory="))) {
969,431✔
2518
                        ssize_t k;
775✔
2519
                        char *p;
775✔
2520

2521
                        k = cunescape(val, 0, &p);
775✔
2522
                        if (k < 0)
775✔
2523
                                return k;
×
2524
                        free_and_replace(c->working_directory, p);
775✔
2525
                } else if ((val = startswith(l, "exec-context-root-directory="))) {
968,656✔
2526
                        ssize_t k;
7✔
2527
                        char *p;
7✔
2528

2529
                        k = cunescape(val, 0, &p);
7✔
2530
                        if (k < 0)
7✔
2531
                                return k;
×
2532
                        free_and_replace(c->root_directory, p);
7✔
2533
                } else if ((val = startswith(l, "exec-context-root-image="))) {
968,649✔
2534
                        ssize_t k;
11✔
2535
                        char *p;
11✔
2536

2537
                        k = cunescape(val, 0, &p);
11✔
2538
                        if (k < 0)
11✔
2539
                                return k;
×
2540
                        free_and_replace(c->root_image, p);
11✔
2541
                } else if ((val = startswith(l, "exec-context-root-image-options="))) {
968,638✔
2542
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
2543

2544
                        r = deserialize_mount_options(val, &options);
1✔
2545
                        if (r < 0)
1✔
2546
                                return r;
×
2547

2548
                        free_and_replace_full(c->root_image_options, options, mount_options_free_all);
1✔
2549
                } else if ((val = startswith(l, "exec-context-root-verity="))) {
968,637✔
2550
                        r = free_and_strdup(&c->root_verity, val);
×
2551
                        if (r < 0)
×
2552
                                return r;
2553
                } else if ((val = startswith(l, "exec-context-root-hash-path="))) {
968,637✔
2554
                        r = free_and_strdup(&c->root_hash_path, val);
×
2555
                        if (r < 0)
×
2556
                                return r;
2557
                } else if ((val = startswith(l, "exec-context-root-hash-sig-path="))) {
968,637✔
2558
                        r = free_and_strdup(&c->root_hash_sig_path, val);
×
2559
                        if (r < 0)
×
2560
                                return r;
2561
                } else if ((val = startswith(l, "exec-context-root-hash="))) {
968,637✔
2562
                        iovec_done(&c->root_hash);
4✔
2563
                        r = unhexmem(val, &c->root_hash.iov_base, &c->root_hash.iov_len);
4✔
2564
                        if (r < 0)
4✔
2565
                                return r;
2566
                } else if ((val = startswith(l, "exec-context-root-hash-sig="))) {
968,633✔
2567
                        iovec_done(&c->root_hash_sig);
×
2568
                        r = unbase64mem(val, &c->root_hash_sig.iov_base, &c->root_hash_sig.iov_len);
×
2569
                        if (r < 0)
×
2570
                                return r;
2571
                } else if ((val = startswith(l, "exec-context-root-ephemeral="))) {
968,633✔
2572
                        r = parse_boolean(val);
×
2573
                        if (r < 0)
×
2574
                                return r;
2575
                        c->root_ephemeral = r;
×
2576
                } else if ((val = startswith(l, "exec-context-root-mstack="))) {
968,633✔
2577
                        ssize_t k;
4✔
2578
                        char *p;
4✔
2579

2580
                        k = cunescape(val, 0, &p);
4✔
2581
                        if (k < 0)
4✔
2582
                                return k;
×
2583
                        free_and_replace(c->root_mstack, p);
4✔
2584
                } else if ((val = startswith(l, "exec-context-umask="))) {
968,629✔
2585
                        r = parse_mode(val, &c->umask);
10,254✔
2586
                        if (r < 0)
10,254✔
2587
                                return r;
2588
                } else if ((val = startswith(l, "exec-context-private-non-blocking="))) {
958,375✔
2589
                        r = parse_boolean(val);
×
2590
                        if (r < 0)
×
2591
                                return r;
2592
                        c->non_blocking = r;
×
2593
                } else if ((val = startswith(l, "exec-context-private-mounts="))) {
958,375✔
2594
                        r = safe_atoi(val, &c->private_mounts);
139✔
2595
                        if (r < 0)
139✔
2596
                                return r;
2597
                } else if ((val = startswith(l, "exec-context-mount-api-vfs="))) {
958,236✔
2598
                        r = safe_atoi(val, &c->mount_apivfs);
29✔
2599
                        if (r < 0)
29✔
2600
                                return r;
2601
                } else if ((val = startswith(l, "exec-context-bind-log-sockets="))) {
958,207✔
2602
                        r = safe_atoi(val, &c->bind_log_sockets);
2✔
2603
                        if (r < 0)
2✔
2604
                                return r;
2605
                } else if ((val = startswith(l, "exec-context-memory-ksm="))) {
958,205✔
2606
                        r = safe_atoi(val, &c->memory_ksm);
×
2607
                        if (r < 0)
×
2608
                                return r;
2609
                } else if ((val = startswith(l, "exec-context-memory-thp="))) {
958,205✔
2610
                        c->memory_thp = memory_thp_from_string(val);
10,254✔
2611
                        if (c->memory_thp < 0)
10,254✔
2612
                                return c->memory_thp;
2613
                } else if ((val = startswith(l, "exec-context-private-tmp="))) {
947,951✔
2614
                        c->private_tmp = private_tmp_from_string(val);
10,254✔
2615
                        if (c->private_tmp < 0)
10,254✔
2616
                                return c->private_tmp;
2617
                } else if ((val = startswith(l, "exec-context-private-var-tmp="))) {
937,697✔
2618
                        c->private_var_tmp = private_tmp_from_string(val);
10,254✔
2619
                        if (c->private_var_tmp < 0)
10,254✔
2620
                                return c->private_var_tmp;
2621
                } else if ((val = startswith(l, "exec-context-private-devices="))) {
927,443✔
2622
                        r = parse_boolean(val);
494✔
2623
                        if (r < 0)
494✔
2624
                                return r;
2625
                        c->private_devices = r;
494✔
2626
                } else if ((val = startswith(l, "exec-context-protect-kernel-tunables="))) {
926,949✔
2627
                        r = parse_boolean(val);
312✔
2628
                        if (r < 0)
312✔
2629
                                return r;
2630
                        c->protect_kernel_tunables = r;
312✔
2631
                } else if ((val = startswith(l, "exec-context-protect-kernel-modules="))) {
926,637✔
2632
                        r = parse_boolean(val);
1,109✔
2633
                        if (r < 0)
1,109✔
2634
                                return r;
2635
                        c->protect_kernel_modules = r;
1,109✔
2636
                } else if ((val = startswith(l, "exec-context-protect-kernel-logs="))) {
925,528✔
2637
                        r = parse_boolean(val);
1,109✔
2638
                        if (r < 0)
1,109✔
2639
                                return r;
2640
                        c->protect_kernel_logs = r;
1,109✔
2641
                } else if ((val = startswith(l, "exec-context-protect-clock="))) {
924,419✔
2642
                        r = parse_boolean(val);
903✔
2643
                        if (r < 0)
903✔
2644
                                return r;
2645
                        c->protect_clock = r;
903✔
2646
                } else if ((val = startswith(l, "exec-context-protect-control-groups="))) {
923,516✔
2647
                        r = protect_control_groups_from_string(val);
10,254✔
2648
                        if (r < 0)
10,254✔
2649
                                return r;
2650
                        c->protect_control_groups = r;
10,254✔
2651
                } else if ((val = startswith(l, "exec-context-private-network="))) {
913,262✔
2652
                        r = parse_boolean(val);
72✔
2653
                        if (r < 0)
72✔
2654
                                return r;
2655
                        c->private_network = r;
72✔
2656
                } else if ((val = startswith(l, "exec-context-private-users="))) {
913,190✔
2657
                        c->private_users = private_users_from_string(val);
10,254✔
2658
                        if (c->private_users < 0)
10,254✔
2659
                                return -EINVAL;
2660
                } else if ((val = startswith(l, "exec-context-private-ipc="))) {
902,936✔
2661
                        r = parse_boolean(val);
6✔
2662
                        if (r < 0)
6✔
2663
                                return r;
2664
                        c->private_ipc = r;
6✔
2665
                } else if ((val = startswith(l, "exec-context-private-pids="))) {
902,930✔
2666
                        c->private_pids = private_pids_from_string(val);
10,254✔
2667
                        if (c->private_pids < 0)
10,254✔
2668
                                return -EINVAL;
2669
                } else if ((val = startswith(l, "exec-context-remove-ipc="))) {
892,676✔
2670
                        r = parse_boolean(val);
56✔
2671
                        if (r < 0)
56✔
2672
                                return r;
2673
                        c->remove_ipc = r;
56✔
2674
                } else if ((val = startswith(l, "exec-context-protect-home="))) {
892,620✔
2675
                        c->protect_home = protect_home_from_string(val);
10,254✔
2676
                        if (c->protect_home < 0)
10,254✔
2677
                                return -EINVAL;
2678
                } else if ((val = startswith(l, "exec-context-protect-system="))) {
882,366✔
2679
                        c->protect_system = protect_system_from_string(val);
10,254✔
2680
                        if (c->protect_system < 0)
10,254✔
2681
                                return -EINVAL;
2682
                } else if ((val = startswith(l, "exec-context-same-pgrp="))) {
872,112✔
2683
                        r = parse_boolean(val);
901✔
2684
                        if (r < 0)
901✔
2685
                                return r;
2686
                        c->same_pgrp = r;
901✔
2687
                } else if ((val = startswith(l, "exec-context-non-blocking="))) {
871,211✔
2688
                        r = parse_boolean(val);
×
2689
                        if (r < 0)
×
2690
                                return r;
2691
                        c->non_blocking = r;
×
2692
                } else if ((val = startswith(l, "exec-context-ignore-sigpipe="))) {
871,211✔
2693
                        r = parse_boolean(val);
10,254✔
2694
                        if (r < 0)
10,254✔
2695
                                return r;
2696
                        c->ignore_sigpipe = r;
10,254✔
2697
                } else if ((val = startswith(l, "exec-context-memory-deny-write-execute="))) {
860,957✔
2698
                        r = parse_boolean(val);
1,473✔
2699
                        if (r < 0)
1,473✔
2700
                                return r;
2701
                        c->memory_deny_write_execute = r;
1,473✔
2702
                } else if ((val = startswith(l, "exec-context-restrict-realtime="))) {
859,484✔
2703
                        r = parse_boolean(val);
1,475✔
2704
                        if (r < 0)
1,475✔
2705
                                return r;
2706
                        c->restrict_realtime = r;
1,475✔
2707
                } else if ((val = startswith(l, "exec-context-restrict-suid-sgid="))) {
858,009✔
2708
                        r = parse_boolean(val);
1,376✔
2709
                        if (r < 0)
1,376✔
2710
                                return r;
2711
                        c->restrict_suid_sgid = r;
1,376✔
2712
                } else if ((val = startswith(l, "exec-context-keyring-mode="))) {
856,633✔
2713
                        c->keyring_mode = exec_keyring_mode_from_string(val);
10,254✔
2714
                        if (c->keyring_mode < 0)
10,254✔
2715
                                return -EINVAL;
2716
                } else if ((val = startswith(l, "exec-context-protect-hostname="))) {
846,379✔
2717
                        c->protect_hostname = protect_hostname_from_string(val);
10,254✔
2718
                        if (c->protect_hostname < 0)
10,254✔
2719
                                return -EINVAL;
2720
                } else if ((val = startswith(l, "exec-context-private-hostname="))) {
836,125✔
2721
                        r = free_and_strdup(&c->private_hostname, val);
5✔
2722
                        if (r < 0)
5✔
2723
                                return r;
2724
                } else if ((val = startswith(l, "exec-context-protect-proc="))) {
836,120✔
2725
                        c->protect_proc = protect_proc_from_string(val);
10,254✔
2726
                        if (c->protect_proc < 0)
10,254✔
2727
                                return -EINVAL;
2728
                } else if ((val = startswith(l, "exec-context-proc-subset="))) {
825,866✔
2729
                        c->proc_subset = proc_subset_from_string(val);
10,254✔
2730
                        if (c->proc_subset < 0)
10,254✔
2731
                                return -EINVAL;
2732
                } else if ((val = startswith(l, "exec-context-private-bpf="))) {
815,612✔
2733
                        c->private_bpf = private_bpf_from_string(val);
10,254✔
2734
                        if (c->private_bpf < 0)
10,254✔
2735
                                return -EINVAL;
2736
                } else if ((val = startswith(l, "exec-context-bpf-delegate-commands="))) {
805,358✔
2737
                        r = safe_atoux64(val, &c->bpf_delegate_commands);
2✔
2738
                        if (r < 0)
2✔
2739
                                return r;
2740
                } else if ((val = startswith(l, "exec-context-bpf-delegate-maps="))) {
805,356✔
2741
                        r = safe_atoux64(val, &c->bpf_delegate_maps);
1✔
2742
                        if (r < 0)
1✔
2743
                                return r;
2744
                } else if ((val = startswith(l, "exec-context-bpf-delegate-programs="))) {
805,355✔
2745
                        r = safe_atoux64(val, &c->bpf_delegate_programs);
1✔
2746
                        if (r < 0)
1✔
2747
                                return r;
2748
                } else if ((val = startswith(l, "exec-context-bpf-delegate-attachments="))) {
805,354✔
2749
                        r = safe_atoux64(val, &c->bpf_delegate_attachments);
1✔
2750
                        if (r < 0)
1✔
2751
                                return r;
2752
                } else if ((val = startswith(l, "exec-context-runtime-directory-preserve-mode="))) {
805,353✔
2753
                        c->runtime_directory_preserve_mode = exec_preserve_mode_from_string(val);
10,254✔
2754
                        if (c->runtime_directory_preserve_mode < 0)
10,254✔
2755
                                return -EINVAL;
2756
                } else if ((val = startswith(l, "exec-context-directories-"))) {
795,099✔
2757
                        _cleanup_free_ char *type = NULL, *mode = NULL;
×
2758
                        ExecDirectoryType dt;
51,270✔
2759

2760
                        r = extract_many_words(&val, "= ", 0, &type, &mode);
51,270✔
2761
                        if (r < 0)
51,270✔
2762
                                return r;
2763
                        if (r == 0 || !mode)
51,270✔
2764
                                return -EINVAL;
2765

2766
                        dt = exec_directory_type_from_string(type);
51,270✔
2767
                        if (dt < 0)
51,270✔
2768
                                return dt;
2769

2770
                        r = parse_mode(mode, &c->directories[dt].mode);
51,270✔
2771
                        if (r < 0)
51,270✔
2772
                                return r;
2773

2774
                        for (;;) {
54,245✔
2775
                                _cleanup_free_ char *tuple = NULL, *path = NULL, *only_create = NULL, *read_only = NULL;
54,138✔
2776
                                ExecDirectoryFlags exec_directory_flags = 0;
54,245✔
2777
                                const char *p;
54,245✔
2778

2779
                                /* Use EXTRACT_UNESCAPE_RELAX here, as we unescape the colons in subsequent calls */
2780
                                r = extract_first_word(&val, &tuple, WHITESPACE, EXTRACT_UNESCAPE_SEPARATORS|EXTRACT_UNESCAPE_RELAX);
54,245✔
2781
                                if (r < 0)
54,245✔
2782
                                        return r;
2783
                                if (r == 0)
54,245✔
2784
                                        break;
2785

2786
                                p = tuple;
2,975✔
2787
                                r = extract_many_words(&p, ":", EXTRACT_UNESCAPE_SEPARATORS, &path, &only_create, &read_only);
2,975✔
2788
                                if (r < 0)
2,975✔
2789
                                        return r;
2790
                                if (r < 2)
2,975✔
2791
                                        continue;
×
2792

2793
                                r = parse_boolean(only_create);
2,975✔
2794
                                if (r < 0)
2,975✔
2795
                                        return r;
2796
                                if (r > 0)
2,975✔
2797
                                        exec_directory_flags |= EXEC_DIRECTORY_ONLY_CREATE;
5✔
2798

2799
                                r = parse_boolean(read_only);
2,975✔
2800
                                if (r < 0)
2,975✔
2801
                                        return r;
2802
                                if (r > 0)
2,975✔
2803
                                        exec_directory_flags |= EXEC_DIRECTORY_READ_ONLY;
50✔
2804

2805
                                r = exec_directory_add(&c->directories[dt], path, /* symlink= */ NULL, exec_directory_flags);
2,975✔
2806
                                if (r < 0)
2,975✔
2807
                                        return r;
2808

2809
                                if (isempty(p))
2,975✔
2810
                                        continue;
2,868✔
2811

2812
                                for (;;) {
385✔
2813
                                        _cleanup_free_ char *link = NULL;
246✔
2814

2815
                                        r = extract_first_word(&p, &link, ":", EXTRACT_UNESCAPE_SEPARATORS);
246✔
2816
                                        if (r < 0)
246✔
2817
                                                return r;
2818
                                        if (r == 0)
246✔
2819
                                                break;
2820

2821
                                        r = strv_consume(&c->directories[dt].items[c->directories[dt].n_items - 1].symlinks, TAKE_PTR(link));
139✔
2822
                                        if (r < 0)
139✔
2823
                                                return r;
2824
                                }
2825
                        }
2826
                } else if ((val = startswith(l, "exec-context-quota-accounting-directories-"))) {
743,829✔
2827
                        _cleanup_free_ char *type = NULL, *quota_accounting = NULL;
×
2828
                        ExecDirectoryType dt;
×
2829

2830
                        r = split_pair(val, "=", &type, &quota_accounting);
×
2831
                        if (r < 0)
×
2832
                                return r;
2833

2834
                        dt = exec_directory_type_from_string(type);
×
2835
                        if (dt < 0)
×
2836
                                return dt;
2837

2838
                        r = parse_boolean(quota_accounting);
×
2839
                        if (r < 0)
×
2840
                                return r;
2841

2842
                        c->directories[dt].exec_quota.quota_accounting = r;
×
2843
                } else if ((val = startswith(l, "exec-context-quota-directories-"))) {
743,829✔
2844
                        _cleanup_free_ char *type = NULL, *quota_info = NULL, *quota_absolute = NULL, *quota_scale = NULL;
×
2845
                        ExecDirectoryType dt;
×
2846

2847
                        r = split_pair(val, "=", &type, &quota_info);
×
2848
                        if (r < 0)
×
2849
                                return r;
2850

2851
                        r = split_pair(quota_info, " ", &quota_absolute, &quota_scale);
×
2852
                        if (r < 0)
×
2853
                                return r;
2854

2855
                        dt = exec_directory_type_from_string(type);
×
2856
                        if (dt < 0)
×
2857
                                return dt;
2858

2859
                        r = safe_atou64(quota_absolute, &c->directories[dt].exec_quota.quota_absolute);
×
2860
                        if (r < 0)
×
2861
                               return r;
2862

2863
                        r = safe_atou32(quota_scale, &c->directories[dt].exec_quota.quota_scale);
×
2864
                        if (r < 0)
×
2865
                               return r;
2866

2867
                        c->directories[dt].exec_quota.quota_enforce = true;
×
2868
                } else if ((val = startswith(l, "exec-context-timeout-clean-usec="))) {
743,829✔
2869
                        r = deserialize_usec(val, &c->timeout_clean_usec);
×
2870
                        if (r < 0)
×
2871
                                return r;
2872
                } else if ((val = startswith(l, "exec-context-nice="))) {
743,829✔
2873
                        r = safe_atoi(val, &c->nice);
19✔
2874
                        if (r < 0)
19✔
2875
                                return r;
2876
                        c->nice_set = true;
19✔
2877
                } else if ((val = startswith(l, "exec-context-working-directory-missing-ok="))) {
743,810✔
2878
                        r = parse_boolean(val);
714✔
2879
                        if (r < 0)
714✔
2880
                                return r;
2881
                        c->working_directory_missing_ok = r;
714✔
2882
                } else if ((val = startswith(l, "exec-context-working-directory-home="))) {
743,096✔
2883
                        r = parse_boolean(val);
209✔
2884
                        if (r < 0)
209✔
2885
                                return r;
2886
                        c->working_directory_home = r;
209✔
2887
                } else if ((val = startswith(l, "exec-context-oom-score-adjust="))) {
742,887✔
2888
                        r = safe_atoi(val, &c->oom_score_adjust);
1,097✔
2889
                        if (r < 0)
1,097✔
2890
                                return r;
2891
                        c->oom_score_adjust_set = true;
1,097✔
2892
                } else if ((val = startswith(l, "exec-context-coredump-filter="))) {
741,790✔
2893
                        r = safe_atoux64(val, &c->coredump_filter);
2✔
2894
                        if (r < 0)
2✔
2895
                                return r;
2896
                        c->coredump_filter_set = true;
2✔
2897
                } else if ((val = startswith(l, "exec-context-limit-"))) {
741,788✔
2898
                        _cleanup_free_ struct rlimit *rlimit = NULL;
×
2899
                        _cleanup_free_ char *limit = NULL;
20,503✔
2900
                        int type;
20,503✔
2901

2902
                        r = extract_first_word(&val, &limit, "=", 0);
20,503✔
2903
                        if (r < 0)
20,503✔
2904
                                return r;
2905
                        if (r == 0 || !val)
20,503✔
2906
                                return -EINVAL;
2907

2908
                        type = rlimit_from_string(limit);
20,503✔
2909
                        if (type < 0)
20,503✔
2910
                                return -EINVAL;
2911

2912
                        if (!c->rlimit[type]) {
20,503✔
2913
                                rlimit = new0(struct rlimit, 1);
20,503✔
2914
                                if (!rlimit)
20,503✔
2915
                                        return log_oom_debug();
×
2916

2917
                                r = rlimit_parse(type, val, rlimit);
20,503✔
2918
                                if (r < 0)
20,503✔
2919
                                        return r;
2920

2921
                                c->rlimit[type] = TAKE_PTR(rlimit);
20,503✔
2922
                        } else {
2923
                                r = rlimit_parse(type, val, c->rlimit[type]);
×
2924
                                if (r < 0)
×
2925
                                        return r;
2926
                        }
2927
                } else if ((val = startswith(l, "exec-context-ioprio="))) {
721,285✔
2928
                        r = safe_atoi(val, &c->ioprio);
13✔
2929
                        if (r < 0)
13✔
2930
                                return r;
2931
                        c->ioprio_is_set = true;
13✔
2932
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-policy="))) {
721,272✔
2933
                        c->cpu_sched_policy = sched_policy_from_string(val);
×
2934
                        if (c->cpu_sched_policy < 0)
×
2935
                                return -EINVAL;
2936
                        c->cpu_sched_set = true;
×
2937
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-priority="))) {
721,272✔
2938
                        r = safe_atoi(val, &c->cpu_sched_priority);
×
2939
                        if (r < 0)
×
2940
                                return r;
2941
                        c->cpu_sched_set = true;
×
2942
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-reset-on-fork="))) {
721,272✔
2943
                        r = parse_boolean(val);
×
2944
                        if (r < 0)
×
2945
                                return r;
2946
                        c->cpu_sched_reset_on_fork = r;
×
2947
                        c->cpu_sched_set = true;
×
2948
                } else if ((val = startswith(l, "exec-context-cpu-affinity="))) {
721,272✔
2949
                        if (c->cpu_set.set)
×
2950
                                return -EINVAL; /* duplicated */
2951

2952
                        r = parse_cpu_set(val, &c->cpu_set);
×
2953
                        if (r < 0)
×
2954
                                return r;
2955
                } else if ((val = startswith(l, "exec-context-numa-mask="))) {
721,272✔
2956
                        if (c->numa_policy.nodes.set)
19✔
2957
                                return -EINVAL; /* duplicated */
2958

2959
                        r = parse_cpu_set(val, &c->numa_policy.nodes);
19✔
2960
                        if (r < 0)
19✔
2961
                                return r;
2962
                } else if ((val = startswith(l, "exec-context-numa-policy="))) {
721,253✔
2963
                        r = safe_atoi(val, &c->numa_policy.type);
19✔
2964
                        if (r < 0)
19✔
2965
                                return r;
2966
                } else if ((val = startswith(l, "exec-context-cpu-affinity-from-numa="))) {
721,234✔
2967
                        r = parse_boolean(val);
2✔
2968
                        if (r < 0)
2✔
2969
                                return r;
2970
                        c->cpu_affinity_from_numa = r;
2✔
2971
                } else if ((val = startswith(l, "exec-context-timer-slack-nsec="))) {
721,232✔
2972
                        r = deserialize_usec(val, (usec_t *)&c->timer_slack_nsec);
×
2973
                        if (r < 0)
×
2974
                                return r;
2975
                } else if ((val = startswith(l, "exec-context-root-directory-as-fd="))) {
721,232✔
2976
                        r = parse_boolean(val);
2✔
2977
                        if (r < 0)
2✔
2978
                                return r;
2979
                        c->root_directory_as_fd = r;
2✔
2980
                } else if ((val = startswith(l, "exec-context-std-input="))) {
721,230✔
2981
                        c->std_input = exec_input_from_string(val);
10,254✔
2982
                        if (c->std_input < 0)
10,254✔
2983
                                return c->std_input;
2984
                } else if ((val = startswith(l, "exec-context-std-output="))) {
710,976✔
2985
                        c->std_output = exec_output_from_string(val);
10,254✔
2986
                        if (c->std_output < 0)
10,254✔
2987
                                return c->std_output;
2988
                } else if ((val = startswith(l, "exec-context-std-error="))) {
700,722✔
2989
                        c->std_error = exec_output_from_string(val);
10,254✔
2990
                        if (c->std_error < 0)
10,254✔
2991
                                return c->std_error;
2992
                } else if ((val = startswith(l, "exec-context-stdio-as-fds="))) {
690,468✔
2993
                        r = parse_boolean(val);
590✔
2994
                        if (r < 0)
590✔
2995
                                return r;
2996
                        c->stdio_as_fds = r;
590✔
2997
                } else if ((val = startswith(l, "exec-context-std-input-data="))) {
689,878✔
2998
                        if (c->stdin_data)
1✔
2999
                                return -EINVAL; /* duplicated */
3000

3001
                        r = unbase64mem(val, &c->stdin_data, &c->stdin_data_size);
1✔
3002
                        if (r < 0)
1✔
3003
                                return r;
3004
                } else if ((val = startswith(l, "exec-context-std-input-fd-name="))) {
689,877✔
3005
                        r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], val);
×
3006
                        if (r < 0)
×
3007
                                return r;
3008
                } else if ((val = startswith(l, "exec-context-std-output-fd-name="))) {
689,877✔
3009
                        r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], val);
×
3010
                        if (r < 0)
×
3011
                                return r;
3012
                } else if ((val = startswith(l, "exec-context-std-error-fd-name="))) {
689,877✔
3013
                        r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], val);
×
3014
                        if (r < 0)
×
3015
                                return r;
3016
                } else if ((val = startswith(l, "exec-context-std-input-file="))) {
689,877✔
3017
                        ssize_t k;
×
3018
                        char *p;
×
3019

3020
                        k = cunescape(val, 0, &p);
×
3021
                        if (k < 0)
×
3022
                                return k;
×
3023

3024
                        free_and_replace(c->stdio_file[STDIN_FILENO], p);
×
3025

3026
                } else if ((val = startswith(l, "exec-context-std-output-file="))) {
689,877✔
3027
                        ssize_t k;
54✔
3028
                        char *p;
54✔
3029

3030
                        k = cunescape(val, 0, &p);
54✔
3031
                        if (k < 0)
54✔
3032
                                return k;
×
3033

3034
                        free_and_replace(c->stdio_file[STDOUT_FILENO], p);
54✔
3035

3036
                } else if ((val = startswith(l, "exec-context-std-error-file="))) {
689,823✔
3037
                        ssize_t k;
50✔
3038
                        char *p;
50✔
3039

3040
                        k = cunescape(val, 0, &p);
50✔
3041
                        if (k < 0)
50✔
3042
                                return k;
×
3043

3044
                        free_and_replace(c->stdio_file[STDERR_FILENO], p);
50✔
3045

3046
                } else if ((val = startswith(l, "exec-context-tty-path="))) {
689,773✔
3047
                        r = free_and_strdup(&c->tty_path, val);
110✔
3048
                        if (r < 0)
110✔
3049
                                return r;
3050
                } else if ((val = startswith(l, "exec-context-tty-reset="))) {
689,663✔
3051
                        r = parse_boolean(val);
194✔
3052
                        if (r < 0)
194✔
3053
                                return r;
3054
                        c->tty_reset = r;
194✔
3055
                } else if ((val = startswith(l, "exec-context-tty-vhangup="))) {
689,469✔
3056
                        r = parse_boolean(val);
85✔
3057
                        if (r < 0)
85✔
3058
                                return r;
3059
                        c->tty_vhangup = r;
85✔
3060
                } else if ((val = startswith(l, "exec-context-tty-vt-disallocate="))) {
689,384✔
3061
                        r = parse_boolean(val);
49✔
3062
                        if (r < 0)
49✔
3063
                                return r;
3064
                        c->tty_vt_disallocate = r;
49✔
3065
                } else if ((val = startswith(l, "exec-context-tty-rows="))) {
689,335✔
3066
                        r = safe_atou(val, &c->tty_rows);
10,254✔
3067
                        if (r < 0)
10,254✔
3068
                                return r;
3069
                } else if ((val = startswith(l, "exec-context-tty-columns="))) {
679,081✔
3070
                        r = safe_atou(val, &c->tty_cols);
10,254✔
3071
                        if (r < 0)
10,254✔
3072
                                return r;
3073
                } else if ((val = startswith(l, "exec-context-syslog-priority="))) {
668,827✔
3074
                        r = safe_atoi(val, &c->syslog_priority);
10,254✔
3075
                        if (r < 0)
10,254✔
3076
                                return r;
3077
                } else if ((val = startswith(l, "exec-context-syslog-level-prefix="))) {
658,573✔
3078
                        r = parse_boolean(val);
10,254✔
3079
                        if (r < 0)
10,254✔
3080
                                return r;
3081
                        c->syslog_level_prefix = r;
10,254✔
3082
                } else if ((val = startswith(l, "exec-context-syslog-identifier="))) {
648,319✔
3083
                        r = free_and_strdup(&c->syslog_identifier, val);
×
3084
                        if (r < 0)
×
3085
                                return r;
3086
                } else if ((val = startswith(l, "exec-context-log-level-max="))) {
648,319✔
3087
                        /* See comment in serialization. */
3088
                        r = safe_atoi(val, &c->log_level_max);
10,254✔
3089
                        if (r < 0)
10,254✔
3090
                                return r;
3091
                } else if ((val = startswith(l, "exec-context-log-ratelimit-interval-usec="))) {
638,065✔
3092
                        r = deserialize_usec(val, &c->log_ratelimit.interval);
×
3093
                        if (r < 0)
×
3094
                                return r;
3095
                } else if ((val = startswith(l, "exec-context-log-ratelimit-burst="))) {
638,065✔
3096
                        r = safe_atou(val, &c->log_ratelimit.burst);
×
3097
                        if (r < 0)
×
3098
                                return r;
3099
                } else if ((val = startswith(l, "exec-context-log-filter-allowed-patterns="))) {
638,065✔
3100
                        r = set_put_strdup(&c->log_filter_allowed_patterns, val);
20✔
3101
                        if (r < 0)
20✔
3102
                                return r;
3103
                } else if ((val = startswith(l, "exec-context-log-filter-denied-patterns="))) {
638,045✔
3104
                        r = set_put_strdup(&c->log_filter_denied_patterns, val);
13✔
3105
                        if (r < 0)
13✔
3106
                                return r;
3107
                } else if ((val = startswith(l, "exec-context-log-extra-fields="))) {
638,032✔
3108
                        if (c->n_log_extra_fields >= LOG_EXTRA_FIELDS_MAX) {
2,810✔
3109
                                log_warning("Too many extra log fields, ignoring.");
×
3110
                                continue;
×
3111
                        }
3112

3113
                        if (!GREEDY_REALLOC(c->log_extra_fields, c->n_log_extra_fields + 1))
2,810✔
3114
                                return log_oom_debug();
×
3115

3116
                        char *field = strdup(val);
2,810✔
3117
                        if (!field)
2,810✔
3118
                                return log_oom_debug();
×
3119

3120
                        c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE_STRING(field);
2,810✔
3121
                } else if ((val = startswith(l, "exec-context-log-namespace="))) {
635,222✔
3122
                        r = free_and_strdup(&c->log_namespace, val);
2✔
3123
                        if (r < 0)
2✔
3124
                                return r;
3125
                } else if ((val = startswith(l, "exec-context-secure-bits="))) {
635,220✔
UNCOV
3126
                        r = safe_atoi(val, &c->secure_bits);
×
UNCOV
3127
                        if (r < 0)
×
3128
                                return r;
3129
                } else if ((val = startswith(l, "exec-context-capability-bounding-set="))) {
635,220✔
3130
                        r = safe_atou64(val, &c->capability_bounding_set);
10,254✔
3131
                        if (r < 0)
10,254✔
3132
                                return r;
3133
                } else if ((val = startswith(l, "exec-context-capability-ambient-set="))) {
624,966✔
3134
                        r = safe_atou64(val, &c->capability_ambient_set);
657✔
3135
                        if (r < 0)
657✔
3136
                                return r;
3137
                } else if ((val = startswith(l, "exec-context-user="))) {
624,309✔
3138
                        r = free_and_strdup(&c->user, val);
2,123✔
3139
                        if (r < 0)
2,123✔
3140
                                return r;
3141
                } else if ((val = startswith(l, "exec-context-group="))) {
622,186✔
3142
                        r = free_and_strdup(&c->group, val);
60✔
3143
                        if (r < 0)
60✔
3144
                                return r;
3145
                } else if ((val = startswith(l, "exec-context-dynamic-user="))) {
622,126✔
3146
                        r = parse_boolean(val);
47✔
3147
                        if (r < 0)
47✔
3148
                                return r;
3149
                        c->dynamic_user = r;
47✔
3150
                } else if ((val = startswith(l, "exec-context-supplementary-groups="))) {
622,079✔
3151
                        r = deserialize_strv(val, &c->supplementary_groups);
12✔
3152
                        if (r < 0)
12✔
3153
                                return r;
3154
                } else if ((val = startswith(l, "exec-context-set-login-environment="))) {
622,067✔
UNCOV
3155
                        r = safe_atoi(val, &c->set_login_environment);
×
UNCOV
3156
                        if (r < 0)
×
3157
                                return r;
3158
                } else if ((val = startswith(l, "exec-context-pam-name="))) {
622,067✔
3159
                        r = free_and_strdup(&c->pam_name, val);
546✔
3160
                        if (r < 0)
546✔
3161
                                return r;
3162
                } else if ((val = startswith(l, "exec-context-read-write-paths="))) {
621,521✔
3163
                        r = deserialize_strv(val, &c->read_write_paths);
844✔
3164
                        if (r < 0)
844✔
3165
                                return r;
3166
                } else if ((val = startswith(l, "exec-context-read-only-paths="))) {
620,677✔
3167
                        r = deserialize_strv(val, &c->read_only_paths);
2✔
3168
                        if (r < 0)
2✔
3169
                                return r;
3170
                } else if ((val = startswith(l, "exec-context-inaccessible-paths="))) {
620,675✔
3171
                        r = deserialize_strv(val, &c->inaccessible_paths);
5✔
3172
                        if (r < 0)
5✔
3173
                                return r;
3174
                } else if ((val = startswith(l, "exec-context-exec-paths="))) {
620,670✔
3175
                        r = deserialize_strv(val, &c->exec_paths);
1✔
3176
                        if (r < 0)
1✔
3177
                                return r;
3178
                } else if ((val = startswith(l, "exec-context-no-exec-paths="))) {
620,669✔
3179
                        r = deserialize_strv(val, &c->no_exec_paths);
1✔
3180
                        if (r < 0)
1✔
3181
                                return r;
3182
                } else if ((val = startswith(l, "exec-context-exec-search-path="))) {
620,668✔
UNCOV
3183
                        r = deserialize_strv(val, &c->exec_search_path);
×
UNCOV
3184
                        if (r < 0)
×
3185
                                return r;
3186
                } else if ((val = startswith(l, "exec-context-mount-propagation-flag="))) {
620,668✔
3187
                        r = safe_atolu(val, &c->mount_propagation_flag);
10,254✔
3188
                        if (r < 0)
10,254✔
3189
                                return r;
3190
                } else if ((val = startswith(l, "exec-context-bind-read-only-path="))) {
610,414✔
3191
                        _cleanup_free_ char *source = NULL, *destination = NULL;
7✔
3192
                        bool rbind = true, ignore_enoent = false;
7✔
3193
                        char *s = NULL, *d = NULL;
7✔
3194

3195
                        r = extract_first_word(&val,
7✔
3196
                                               &source,
3197
                                               ":" WHITESPACE,
3198
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3199
                        if (r < 0)
7✔
3200
                                return r;
3201
                        if (r == 0)
7✔
3202
                                return -EINVAL;
3203

3204
                        s = source;
7✔
3205
                        if (s[0] == '-') {
7✔
3206
                                ignore_enoent = true;
1✔
3207
                                s++;
1✔
3208
                        }
3209

3210
                        if (val && val[-1] == ':') {
7✔
3211
                                r = extract_first_word(&val,
7✔
3212
                                                       &destination,
3213
                                                       ":" WHITESPACE,
3214
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3215
                                if (r < 0)
7✔
3216
                                        return r;
3217
                                if (r == 0)
7✔
UNCOV
3218
                                        continue;
×
3219

3220
                                d = destination;
7✔
3221

3222
                                if (val && val[-1] == ':') {
7✔
3223
                                        _cleanup_free_ char *options = NULL;
7✔
3224

3225
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
7✔
3226
                                        if (r < 0)
7✔
UNCOV
3227
                                                return -r;
×
3228

3229
                                        if (isempty(options) || streq(options, "rbind"))
15✔
3230
                                                rbind = true;
3231
                                        else if (streq(options, "norbind"))
1✔
3232
                                                rbind = false;
3233
                                        else
UNCOV
3234
                                                continue;
×
3235
                                }
3236
                        } else
3237
                                d = s;
3238

3239
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
14✔
3240
                                        &(BindMount) {
7✔
3241
                                                .source = s,
3242
                                                .destination = d,
3243
                                                .read_only = true,
3244
                                                .recursive = rbind,
3245
                                                .ignore_enoent = ignore_enoent,
3246
                                        });
3247
                        if (r < 0)
7✔
UNCOV
3248
                                return log_oom_debug();
×
3249
                } else if ((val = startswith(l, "exec-context-bind-path="))) {
610,407✔
3250
                        _cleanup_free_ char *source = NULL, *destination = NULL;
20✔
3251
                        bool rbind = true, ignore_enoent = false;
20✔
3252
                        char *s = NULL, *d = NULL;
20✔
3253

3254
                        r = extract_first_word(&val,
20✔
3255
                                               &source,
3256
                                               ":" WHITESPACE,
3257
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3258
                        if (r < 0)
20✔
3259
                                return r;
3260
                        if (r == 0)
20✔
3261
                                return -EINVAL;
3262

3263
                        s = source;
20✔
3264
                        if (s[0] == '-') {
20✔
3265
                                ignore_enoent = true;
1✔
3266
                                s++;
1✔
3267
                        }
3268

3269
                        if (val && val[-1] == ':') {
20✔
3270
                                r = extract_first_word(&val,
20✔
3271
                                                       &destination,
3272
                                                       ":" WHITESPACE,
3273
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3274
                                if (r < 0)
20✔
3275
                                        return r;
3276
                                if (r == 0)
20✔
UNCOV
3277
                                        continue;
×
3278

3279
                                d = destination;
20✔
3280

3281
                                if (val && val[-1] == ':') {
20✔
3282
                                        _cleanup_free_ char *options = NULL;
20✔
3283

3284
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
20✔
3285
                                        if (r < 0)
20✔
UNCOV
3286
                                                return -r;
×
3287

3288
                                        if (isempty(options) || streq(options, "rbind"))
43✔
3289
                                                rbind = true;
3290
                                        else if (streq(options, "norbind"))
3✔
3291
                                                rbind = false;
3292
                                        else
UNCOV
3293
                                                continue;
×
3294
                                }
3295
                        } else
3296
                                d = s;
3297

3298
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
40✔
3299
                                        &(BindMount) {
20✔
3300
                                                .source = s,
3301
                                                .destination = d,
3302
                                                .read_only = false,
3303
                                                .recursive = rbind,
3304
                                                .ignore_enoent = ignore_enoent,
3305
                                        });
3306
                        if (r < 0)
20✔
UNCOV
3307
                                return log_oom_debug();
×
3308
                } else if ((val = startswith(l, "exec-context-temporary-filesystems="))) {
610,387✔
3309
                        _cleanup_free_ char *path = NULL, *options = NULL;
61✔
3310

3311
                        r = extract_many_words(&val, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &path, &options);
61✔
3312
                        if (r < 0)
61✔
3313
                                return r;
3314
                        if (r < 1)
61✔
UNCOV
3315
                                continue;
×
3316

3317
                        r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
61✔
3318
                        if (r < 0)
61✔
UNCOV
3319
                                return log_oom_debug();
×
3320
                } else if ((val = startswith(l, "exec-context-utmp-id="))) {
610,326✔
3321
                        r = free_and_strdup(&c->utmp_id, val);
92✔
3322
                        if (r < 0)
92✔
3323
                                return r;
3324
                } else if ((val = startswith(l, "exec-context-utmp-mode="))) {
610,234✔
3325
                        c->utmp_mode = exec_utmp_mode_from_string(val);
10,254✔
3326
                        if (c->utmp_mode < 0)
10,254✔
3327
                                return c->utmp_mode;
3328
                } else if ((val = startswith(l, "exec-context-no-new-privileges="))) {
599,980✔
3329
                        r = parse_boolean(val);
1,405✔
3330
                        if (r < 0)
1,405✔
3331
                                return r;
3332
                        c->no_new_privileges = r;
1,405✔
3333
                } else if ((val = startswith(l, "exec-context-selinux-context="))) {
598,575✔
3334
                        if (val[0] == '-') {
×
UNCOV
3335
                                c->selinux_context_ignore = true;
×
3336
                                val++;
×
3337
                        } else
3338
                                c->selinux_context_ignore = false;
×
3339

UNCOV
3340
                        r = free_and_strdup(&c->selinux_context, val);
×
UNCOV
3341
                        if (r < 0)
×
3342
                                return r;
3343
                } else if ((val = startswith(l, "exec-context-apparmor-profile="))) {
598,575✔
3344
                        if (val[0] == '-') {
×
UNCOV
3345
                                c->apparmor_profile_ignore = true;
×
3346
                                val++;
×
3347
                        } else
3348
                                c->apparmor_profile_ignore = false;
×
3349

UNCOV
3350
                        r = free_and_strdup(&c->apparmor_profile, val);
×
UNCOV
3351
                        if (r < 0)
×
3352
                                return r;
3353
                } else if ((val = startswith(l, "exec-context-smack-process-label="))) {
598,575✔
3354
                        if (val[0] == '-') {
×
UNCOV
3355
                                c->smack_process_label_ignore = true;
×
3356
                                val++;
×
3357
                        } else
3358
                                c->smack_process_label_ignore = false;
×
3359

UNCOV
3360
                        r = free_and_strdup(&c->smack_process_label, val);
×
UNCOV
3361
                        if (r < 0)
×
3362
                                return r;
3363
                } else if ((val = startswith(l, "exec-context-personality="))) {
598,575✔
UNCOV
3364
                        c->personality = personality_from_string(val);
×
UNCOV
3365
                        if (c->personality == PERSONALITY_INVALID)
×
3366
                                return -EINVAL;
3367
                } else if ((val = startswith(l, "exec-context-lock-personality="))) {
598,575✔
3368
                        r = parse_boolean(val);
1,478✔
3369
                        if (r < 0)
1,478✔
3370
                                return r;
3371
                        c->lock_personality = r;
1,478✔
3372
#if HAVE_SECCOMP
3373
                } else if ((val = startswith(l, "exec-context-syscall-filter="))) {
597,097✔
3374
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
571,160✔
3375
                        int id, errno_num;
571,160✔
3376

3377
                        r = extract_many_words(&val, NULL, 0, &s_id, &s_errno_num);
571,160✔
3378
                        if (r < 0)
571,160✔
3379
                                return r;
3380
                        if (r != 2)
571,160✔
UNCOV
3381
                                continue;
×
3382

3383
                        r = safe_atoi(s_id, &id);
571,160✔
3384
                        if (r < 0)
571,160✔
3385
                                return r;
3386

3387
                        r = safe_atoi(s_errno_num, &errno_num);
571,160✔
3388
                        if (r < 0)
571,160✔
3389
                                return r;
3390

3391
                        r = hashmap_ensure_put(&c->syscall_filter, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
571,160✔
3392
                        if (r < 0)
571,160✔
3393
                                return r;
3394
                } else if ((val = startswith(l, "exec-context-syscall-archs="))) {
25,937✔
3395
                        unsigned id;
1,478✔
3396

3397
                        r = safe_atou(val, &id);
1,478✔
3398
                        if (r < 0)
1,478✔
UNCOV
3399
                                return r;
×
3400

3401
                        r = set_ensure_put(&c->syscall_archs, NULL, UINT_TO_PTR(id + 1));
1,478✔
3402
                        if (r < 0)
1,478✔
3403
                                return r;
3404
                } else if ((val = startswith(l, "exec-context-syscall-errno="))) {
24,459✔
3405
                        r = safe_atoi(val, &c->syscall_errno);
10,254✔
3406
                        if (r < 0)
10,254✔
3407
                                return r;
3408
                } else if ((val = startswith(l, "exec-context-syscall-allow-list="))) {
14,205✔
3409
                        r = parse_boolean(val);
1,454✔
3410
                        if (r < 0)
1,454✔
3411
                                return r;
3412
                        c->syscall_allow_list = r;
1,454✔
3413
                } else if ((val = startswith(l, "exec-context-syscall-log="))) {
12,751✔
UNCOV
3414
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
×
3415
                        int id, errno_num;
×
3416

UNCOV
3417
                        r = extract_many_words(&val, " ", 0, &s_id, &s_errno_num);
×
3418
                        if (r < 0)
×
3419
                                return r;
UNCOV
3420
                        if (r != 2)
×
3421
                                continue;
×
3422

UNCOV
3423
                        r = safe_atoi(s_id, &id);
×
UNCOV
3424
                        if (r < 0)
×
3425
                                return r;
3426

UNCOV
3427
                        r = safe_atoi(s_errno_num, &errno_num);
×
UNCOV
3428
                        if (r < 0)
×
3429
                                return r;
3430

UNCOV
3431
                        r = hashmap_ensure_put(&c->syscall_log, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
×
UNCOV
3432
                        if (r < 0)
×
3433
                                return r;
3434
                } else if ((val = startswith(l, "exec-context-syscall-log-allow-list="))) {
12,751✔
UNCOV
3435
                        r = parse_boolean(val);
×
3436
                        if (r < 0)
×
3437
                                return r;
UNCOV
3438
                        c->syscall_log_allow_list = r;
×
3439
#endif
3440
                } else if ((val = startswith(l, "exec-context-restrict-namespaces="))) {
12,751✔
3441
                        r = safe_atolu(val, &c->restrict_namespaces);
1,224✔
3442
                        if (r < 0)
1,224✔
3443
                                return r;
3444
                } else if ((val = startswith(l, "exec-context-delegate-namespaces="))) {
11,527✔
3445
                        r = safe_atolu(val, &c->delegate_namespaces);
21✔
3446
                        if (r < 0)
21✔
3447
                                return r;
3448
                } else if ((val = startswith(l, "exec-context-restrict-filesystems="))) {
11,506✔
UNCOV
3449
                        r = set_put_strdup(&c->restrict_filesystems, val);
×
UNCOV
3450
                        if (r < 0)
×
3451
                                return r;
3452
                } else if ((val = startswith(l, "exec-context-restrict-filesystems-allow-list="))) {
11,506✔
UNCOV
3453
                        r = parse_boolean(val);
×
3454
                        if (r < 0)
×
3455
                                return r;
UNCOV
3456
                        c->restrict_filesystems_allow_list = r;
×
3457
                } else if ((val = startswith(l, "exec-context-address-families="))) {
11,506✔
3458
                        int af;
5,807✔
3459

3460
                        r = safe_atoi(val, &af);
5,807✔
3461
                        if (r < 0)
5,807✔
UNCOV
3462
                                return r;
×
3463

3464
                        r = set_ensure_put(&c->address_families, NULL, INT_TO_PTR(af));
5,807✔
3465
                        if (r < 0)
5,807✔
3466
                                return r;
3467
                } else if ((val = startswith(l, "exec-context-address-families-allow-list="))) {
5,699✔
3468
                        r = parse_boolean(val);
1,473✔
3469
                        if (r < 0)
1,473✔
3470
                                return r;
3471
                        c->address_families_allow_list = r;
1,473✔
3472
                } else if ((val = startswith(l, "exec-context-network-namespace-path="))) {
4,226✔
3473
                        r = free_and_strdup(&c->network_namespace_path, val);
1✔
3474
                        if (r < 0)
1✔
3475
                                return r;
3476
                } else if ((val = startswith(l, "exec-context-user-namespace-path="))) {
4,225✔
3477
                        r = free_and_strdup(&c->user_namespace_path, val);
3✔
3478
                        if (r < 0)
3✔
3479
                                return r;
3480
                } else if ((val = startswith(l, "exec-context-ipc-namespace-path="))) {
4,222✔
UNCOV
3481
                        r = free_and_strdup(&c->ipc_namespace_path, val);
×
UNCOV
3482
                        if (r < 0)
×
3483
                                return r;
3484
                } else if ((val = startswith(l, "exec-context-mount-image="))) {
4,222✔
UNCOV
3485
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3486
                        _cleanup_free_ char *source = NULL, *destination = NULL;
61✔
3487
                        bool permissive = false;
61✔
3488
                        char *s;
61✔
3489

3490
                        r = extract_many_words(&val,
61✔
3491
                                               NULL,
3492
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3493
                                               &source,
3494
                                               &destination);
3495
                        if (r < 0)
61✔
3496
                                return r;
3497
                        if (r == 0)
61✔
3498
                                return -EINVAL;
3499

3500
                        s = source;
61✔
3501
                        if (s[0] == '-') {
61✔
UNCOV
3502
                                permissive = true;
×
UNCOV
3503
                                s++;
×
3504
                        }
3505

3506
                        if (isempty(destination))
61✔
UNCOV
3507
                                continue;
×
3508

3509
                        r = deserialize_mount_options(val, &options);
61✔
3510
                        if (r < 0)
61✔
3511
                                return r;
3512

3513
                        r = mount_image_add(&c->mount_images, &c->n_mount_images,
122✔
3514
                                        &(MountImage) {
61✔
3515
                                                .source = s,
3516
                                                .destination = destination,
3517
                                                .mount_options = options,
3518
                                                .ignore_enoent = permissive,
3519
                                                .type = MOUNT_IMAGE_DISCRETE,
3520
                                        });
3521
                        if (r < 0)
61✔
3522
                                return log_oom_debug();
×
3523
                } else if ((val = startswith(l, "exec-context-extension-image="))) {
4,161✔
UNCOV
3524
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3525
                        _cleanup_free_ char *source = NULL;
16✔
3526
                        bool permissive = false;
16✔
3527
                        char *s;
16✔
3528

3529
                        r = extract_first_word(&val,
16✔
3530
                                               &source,
3531
                                               NULL,
3532
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS);
3533
                        if (r < 0)
16✔
3534
                                return r;
3535
                        if (r == 0)
16✔
3536
                                return -EINVAL;
3537

3538
                        s = source;
16✔
3539
                        if (s[0] == '-') {
16✔
3540
                                permissive = true;
3✔
3541
                                s++;
3✔
3542
                        }
3543

3544
                        r = deserialize_mount_options(val, &options);
16✔
3545
                        if (r < 0)
16✔
3546
                                return r;
3547

3548
                        r = mount_image_add(&c->extension_images, &c->n_extension_images,
32✔
3549
                                        &(MountImage) {
16✔
3550
                                                .source = s,
3551
                                                .mount_options = options,
3552
                                                .ignore_enoent = permissive,
3553
                                                .type = MOUNT_IMAGE_EXTENSION,
3554
                                        });
3555
                        if (r < 0)
16✔
UNCOV
3556
                                return log_oom_debug();
×
3557
                } else if ((val = startswith(l, "exec-context-extension-directories="))) {
4,145✔
3558
                        r = deserialize_strv(val, &c->extension_directories);
10✔
3559
                        if (r < 0)
10✔
3560
                                return r;
3561
                } else if ((val = startswith(l, "exec-context-set-credentials="))) {
4,135✔
UNCOV
3562
                        _cleanup_free_ char *id = NULL, *data = NULL, *encrypted = NULL;
×
3563

3564
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &data, &encrypted);
93✔
3565
                        if (r < 0)
93✔
3566
                                return r;
3567
                        if (r != 3)
93✔
3568
                                return -EINVAL;
3569

3570
                        r = parse_boolean(encrypted);
93✔
3571
                        if (r < 0)
93✔
3572
                                return r;
3573
                        bool e = r;
93✔
3574

3575
                        _cleanup_free_ void *d = NULL;
93✔
3576
                        size_t size;
93✔
3577

3578
                        r = unbase64mem_full(data, SIZE_MAX, /* secure= */ true, &d, &size);
93✔
3579
                        if (r < 0)
93✔
3580
                                return r;
3581

3582
                        r = exec_context_put_set_credential(c, id, TAKE_PTR(d), size, e);
93✔
3583
                        if (r < 0)
93✔
3584
                                return r;
3585
                } else if ((val = startswith(l, "exec-context-load-credentials="))) {
4,042✔
3586
                        _cleanup_free_ char *id = NULL, *path = NULL, *encrypted = NULL;
34✔
3587

3588
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &path, &encrypted);
34✔
3589
                        if (r < 0)
34✔
3590
                                return r;
3591
                        if (r != 3)
34✔
3592
                                return -EINVAL;
3593

3594
                        r = parse_boolean(encrypted);
34✔
3595
                        if (r < 0)
34✔
3596
                                return r;
3597

3598
                        r = exec_context_put_load_credential(c, id, path, r > 0);
34✔
3599
                        if (r < 0)
34✔
3600
                                return r;
3601
                } else if ((val = startswith(l, "exec-context-import-credentials="))) {
4,008✔
3602
                        _cleanup_free_ char *glob = NULL, *rename = NULL;
4,002✔
3603

3604
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &glob, &rename);
4,002✔
3605
                        if (r < 0)
4,002✔
3606
                                return r;
3607
                        if (r == 0)
4,002✔
3608
                                return -EINVAL;
3609

3610
                        r = exec_context_put_import_credential(c, glob, rename);
4,002✔
3611
                        if (r < 0)
4,002✔
3612
                                return r;
3613
                } else if ((val = startswith(l, "exec-context-root-image-policy="))) {
6✔
3614
                        if (c->root_image_policy)
4✔
3615
                                return -EINVAL; /* duplicated */
3616

3617
                        r = image_policy_from_string(val, /* graceful= */ false, &c->root_image_policy);
4✔
3618
                        if (r < 0)
4✔
3619
                                return r;
3620
                } else if ((val = startswith(l, "exec-context-mount-image-policy="))) {
2✔
UNCOV
3621
                        if (c->mount_image_policy)
×
3622
                                return -EINVAL; /* duplicated */
3623

UNCOV
3624
                        r = image_policy_from_string(val, /* graceful= */ false, &c->mount_image_policy);
×
UNCOV
3625
                        if (r < 0)
×
3626
                                return r;
3627
                } else if ((val = startswith(l, "exec-context-extension-image-policy="))) {
2✔
3628
                        if (c->extension_image_policy)
2✔
3629
                                return -EINVAL; /* duplicated */
3630

3631
                        r = image_policy_from_string(val, /* graceful= */ false, &c->extension_image_policy);
2✔
3632
                        if (r < 0)
2✔
3633
                                return r;
3634
                } else
UNCOV
3635
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3636
        }
3637

3638
        return 0;
10,254✔
3639
}
3640

3641
static int exec_command_serialize(const ExecCommand *c, FILE *f) {
2,517✔
3642
        int r;
2,517✔
3643

3644
        assert(c);
2,517✔
3645
        assert(f);
2,517✔
3646

3647
        r = serialize_item(f, "exec-command-path", c->path);
2,517✔
3648
        if (r < 0)
2,517✔
3649
                return r;
3650

3651
        r = serialize_strv(f, "exec-command-argv", c->argv);
2,517✔
3652
        if (r < 0)
2,517✔
3653
                return r;
3654

3655
        r = serialize_item_format(f, "exec-command-flags", "%d", (int) c->flags);
2,517✔
3656
        if (r < 0)
2,517✔
3657
                return r;
3658

3659
        fputc('\n', f); /* End marker */
2,517✔
3660

3661
        return 0;
2,517✔
3662
}
3663

3664
static int exec_command_deserialize(ExecCommand *c, FILE *f) {
10,254✔
3665
        int r;
10,254✔
3666

3667
        assert(c);
10,254✔
3668
        assert(f);
10,254✔
3669

3670
        for (;;) {
111,298✔
3671
                _cleanup_free_ char *l = NULL;
50,522✔
3672
                const char *val;
60,776✔
3673

3674
                r = deserialize_read_line(f, &l);
60,776✔
3675
                if (r < 0)
60,776✔
3676
                        return r;
3677
                if (r == 0) /* eof or end marker */
60,776✔
3678
                        break;
3679

3680
                if ((val = startswith(l, "exec-command-path="))) {
50,522✔
3681
                        r = free_and_strdup(&c->path, val);
10,254✔
3682
                        if (r < 0)
10,254✔
3683
                                return r;
3684
                } else if ((val = startswith(l, "exec-command-argv="))) {
40,268✔
3685
                        r = deserialize_strv(val, &c->argv);
30,014✔
3686
                        if (r < 0)
30,014✔
3687
                                return r;
3688
                } else if ((val = startswith(l, "exec-command-flags="))) {
10,254✔
3689
                        r = safe_atoi(val, &c->flags);
10,254✔
3690
                        if (r < 0)
10,254✔
3691
                                return r;
3692
                } else
UNCOV
3693
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3694

3695
        }
3696

3697
        return 0;
10,254✔
3698
}
3699

3700
int exec_serialize_invocation(
2,517✔
3701
                FILE *f,
3702
                FDSet *fds,
3703
                const ExecContext *ctx,
3704
                const ExecCommand *cmd,
3705
                const ExecParameters *p,
3706
                const ExecRuntime *rt,
3707
                const CGroupContext *cg) {
3708

3709
        int r;
2,517✔
3710

3711
        assert(f);
2,517✔
3712
        assert(fds);
2,517✔
3713

3714
        r = exec_context_serialize(ctx, f);
2,517✔
3715
        if (r < 0)
2,517✔
UNCOV
3716
                return log_debug_errno(r, "Failed to serialize context: %m");
×
3717

3718
        r = exec_command_serialize(cmd, f);
2,517✔
3719
        if (r < 0)
2,517✔
UNCOV
3720
                return log_debug_errno(r, "Failed to serialize command: %m");
×
3721

3722
        r = exec_parameters_serialize(p, ctx, f, fds);
2,517✔
3723
        if (r < 0)
2,517✔
UNCOV
3724
                return log_debug_errno(r, "Failed to serialize parameters: %m");
×
3725

3726
        r = exec_runtime_serialize(rt, f, fds);
2,517✔
3727
        if (r < 0)
2,517✔
UNCOV
3728
                return log_debug_errno(r, "Failed to serialize runtime: %m");
×
3729

3730
        r = exec_cgroup_context_serialize(cg, f);
2,517✔
3731
        if (r < 0)
2,517✔
UNCOV
3732
                return log_debug_errno(r, "Failed to serialize cgroup context: %m");
×
3733

3734
        return 0;
3735
}
3736

3737
int exec_deserialize_invocation(
10,254✔
3738
                FILE *f,
3739
                FDSet *fds,
3740
                ExecContext *ctx,
3741
                ExecCommand *cmd,
3742
                ExecParameters *p,
3743
                ExecRuntime *rt,
3744
                CGroupContext *cg) {
3745

3746
        int r;
10,254✔
3747

3748
        assert(f);
10,254✔
3749
        assert(fds);
10,254✔
3750

3751
        r = exec_context_deserialize(ctx, f);
10,254✔
3752
        if (r < 0)
10,254✔
UNCOV
3753
                return log_debug_errno(r, "Failed to deserialize context: %m");
×
3754

3755
        r = exec_command_deserialize(cmd, f);
10,254✔
3756
        if (r < 0)
10,254✔
UNCOV
3757
                return log_debug_errno(r, "Failed to deserialize command: %m");
×
3758

3759
        r = exec_parameters_deserialize(p, f, fds);
10,254✔
3760
        if (r < 0)
10,254✔
UNCOV
3761
                return log_debug_errno(r, "Failed to deserialize parameters: %m");
×
3762

3763
        r = exec_runtime_deserialize(rt, f, fds);
10,254✔
3764
        if (r < 0)
10,254✔
UNCOV
3765
                return log_debug_errno(r, "Failed to deserialize runtime: %m");
×
3766

3767
        r = exec_cgroup_context_deserialize(cg, f);
10,254✔
3768
        if (r < 0)
10,254✔
UNCOV
3769
                return log_debug_errno(r, "Failed to deserialize cgroup context: %m");
×
3770

3771
        return 0;
3772
}
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