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

systemd / systemd / 28760256242

04 Jul 2026 01:10PM UTC coverage: 72.813% (-0.09%) from 72.9%
28760256242

push

github

bluca
hwdb: Make Amlogic burn mode work out-of-box

342890 of 470919 relevant lines covered (72.81%)

1341914.37 hits per line

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

75.39
/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) {
4,971✔
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;
4,971✔
39
        char *iface;
4,971✔
40
        struct in_addr_prefix *iaai;
4,971✔
41
        int r;
4,971✔
42

43
        assert(f);
4,971✔
44

45
        if (!c)
4,971✔
46
                return 0;
47

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

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

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

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

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

68
        if (c->cpu_weight != CGROUP_WEIGHT_INVALID) {
4,971✔
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) {
4,971✔
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) {
4,971✔
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) {
4,971✔
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);
4,971✔
93
        if (!cpuset_cpus)
4,971✔
94
                return log_oom_debug();
×
95

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

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

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

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

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

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

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

124
        if (c->cpuset_partition >= 0) {
4,971✔
125
                r = serialize_item(f, "exec-cgroup-context-cpuset-partition", cpuset_partition_to_string(c->cpuset_partition));
×
126
                if (r < 0)
×
127
                        return r;
128
        }
129

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

136
        if (c->startup_io_weight != CGROUP_WEIGHT_INVALID) {
4,971✔
137
                r = serialize_item_format(f, "exec-cgroup-context-startup-io-weight", "%" PRIu64, c->startup_io_weight);
×
138
                if (r < 0)
×
139
                        return r;
140
        }
141

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

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

154
        if (c->startup_memory_low > 0) {
4,971✔
155
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-low", "%" PRIu64, c->startup_memory_low);
×
156
                if (r < 0)
×
157
                        return r;
158
        }
159

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

166
        if (c->startup_memory_high != CGROUP_LIMIT_MAX) {
4,971✔
167
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-high", "%" PRIu64, c->startup_memory_high);
×
168
                if (r < 0)
×
169
                        return r;
170
        }
171

172
        if (c->memory_max != CGROUP_LIMIT_MAX) {
4,971✔
173
                r = serialize_item_format(f, "exec-cgroup-context-memory-max", "%" PRIu64, c->memory_max);
1✔
174
                if (r < 0)
1✔
175
                        return r;
176
        }
177

178
        if (c->startup_memory_max != CGROUP_LIMIT_MAX) {
4,971✔
179
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-max", "%" PRIu64, c->startup_memory_max);
×
180
                if (r < 0)
×
181
                        return r;
182
        }
183

184
        if (c->memory_swap_max != CGROUP_LIMIT_MAX) {
4,971✔
185
                r = serialize_item_format(f, "exec-cgroup-context-memory-swap-max", "%" PRIu64, c->memory_swap_max);
1✔
186
                if (r < 0)
1✔
187
                        return r;
188
        }
189

190
        if (c->startup_memory_swap_max != CGROUP_LIMIT_MAX) {
4,971✔
191
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-swap-max", "%" PRIu64, c->startup_memory_swap_max);
×
192
                if (r < 0)
×
193
                        return r;
194
        }
195

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

202
        if (c->startup_memory_zswap_max != CGROUP_LIMIT_MAX) {
4,971✔
203
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-zswap-max", "%" PRIu64, c->startup_memory_zswap_max);
×
204
                if (r < 0)
×
205
                        return r;
206
        }
207

208
        r = serialize_bool(f, "exec-cgroup-context-memory-zswap-writeback", c->memory_zswap_writeback);
4,971✔
209
        if (r < 0)
4,971✔
210
                return r;
211

212
        if (c->tasks_max.value != UINT64_MAX) {
4,971✔
213
                r = serialize_item_format(f, "exec-cgroup-context-tasks-max-value", "%" PRIu64, c->tasks_max.value);
4,890✔
214
                if (r < 0)
4,890✔
215
                        return r;
216
        }
217

218
        if (c->tasks_max.scale > 0) {
4,971✔
219
                r = serialize_item_format(f, "exec-cgroup-context-tasks-max-scale", "%" PRIu64, c->tasks_max.scale);
4,873✔
220
                if (r < 0)
4,873✔
221
                        return r;
222
        }
223

224
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-low-set", c->startup_memory_low_set);
4,971✔
225
        if (r < 0)
4,971✔
226
                return r;
227

228
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-high-set", c->startup_memory_high_set);
4,971✔
229
        if (r < 0)
4,971✔
230
                return r;
231

232
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-max-set", c->startup_memory_max_set);
4,971✔
233
        if (r < 0)
4,971✔
234
                return r;
235

236
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-swap-max-set", c->startup_memory_swap_max_set);
4,971✔
237
        if (r < 0)
4,971✔
238
                return r;
239

240
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-zswap-max-set", c->startup_memory_zswap_max_set);
4,971✔
241
        if (r < 0)
4,971✔
242
                return r;
243

244
        r = serialize_item(f, "exec-cgroup-context-device-policy", cgroup_device_policy_to_string(c->device_policy));
4,971✔
245
        if (r < 0)
4,971✔
246
                return r;
247

248
        r = cg_mask_to_string(c->disable_controllers, &disable_controllers_str);
4,971✔
249
        if (r < 0)
4,971✔
250
                return r;
251

252
        r = serialize_item(f, "exec-cgroup-context-disable-controllers", disable_controllers_str);
4,971✔
253
        if (r < 0)
4,971✔
254
                return r;
255

256
        r = cg_mask_to_string(c->delegate_controllers, &delegate_controllers_str);
4,971✔
257
        if (r < 0)
4,971✔
258
                return r;
259

260
        r = serialize_item(f, "exec-cgroup-context-delegate-controllers", delegate_controllers_str);
4,971✔
261
        if (r < 0)
4,971✔
262
                return r;
263

264
        r = serialize_bool_elide(f, "exec-cgroup-context-delegate", c->delegate);
4,971✔
265
        if (r < 0)
4,971✔
266
                return r;
267

268
        r = serialize_item(f, "exec-cgroup-context-managed-oom-swap", managed_oom_mode_to_string(c->moom_swap));
4,971✔
269
        if (r < 0)
4,971✔
270
                return r;
271

272
        r = serialize_item(f, "exec-cgroup-context-managed-oom-memory-pressure", managed_oom_mode_to_string(c->moom_mem_pressure));
4,971✔
273
        if (r < 0)
4,971✔
274
                return r;
275

276
        r = serialize_item_format(f, "exec-cgroup-context-managed-oom-memory-pressure-limit", "%" PRIu32, c->moom_mem_pressure_limit);
4,971✔
277
        if (r < 0)
4,971✔
278
                return r;
279

280
        r = serialize_usec(f, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec", c->moom_mem_pressure_duration_usec);
4,971✔
281
        if (r < 0)
4,971✔
282
                return r;
283

284
        r = serialize_item(f, "exec-cgroup-context-managed-oom-preference", managed_oom_preference_to_string(c->moom_preference));
4,971✔
285
        if (r < 0)
4,971✔
286
                return r;
287

288
        r = serialize_strv(f, "exec-cgroup-context-managed-oom-rules", c->moom_rules);
4,971✔
289
        if (r < 0)
4,971✔
290
                return r;
291

292
        r = serialize_item(f, "exec-cgroup-context-memory-pressure-watch", cgroup_pressure_watch_to_string(c->pressure[PRESSURE_MEMORY].watch));
4,971✔
293
        if (r < 0)
4,971✔
294
                return r;
295

296
        r = serialize_item(f, "exec-cgroup-context-cpu-pressure-watch", cgroup_pressure_watch_to_string(c->pressure[PRESSURE_CPU].watch));
4,971✔
297
        if (r < 0)
4,971✔
298
                return r;
299

300
        r = serialize_item(f, "exec-cgroup-context-io-pressure-watch", cgroup_pressure_watch_to_string(c->pressure[PRESSURE_IO].watch));
4,971✔
301
        if (r < 0)
4,971✔
302
                return r;
303

304
        r = serialize_item(f, "exec-cgroup-context-delegate-subgroup", c->delegate_subgroup);
4,971✔
305
        if (r < 0)
4,971✔
306
                return r;
307

308
        if (c->pressure[PRESSURE_MEMORY].threshold_usec != USEC_INFINITY) {
4,971✔
309
                r = serialize_usec(f, "exec-cgroup-context-memory-pressure-threshold-usec", c->pressure[PRESSURE_MEMORY].threshold_usec);
4,971✔
310
                if (r < 0)
4,971✔
311
                        return r;
312
        }
313

314
        if (c->pressure[PRESSURE_CPU].threshold_usec != USEC_INFINITY) {
4,971✔
315
                r = serialize_usec(f, "exec-cgroup-context-cpu-pressure-threshold-usec", c->pressure[PRESSURE_CPU].threshold_usec);
4,971✔
316
                if (r < 0)
4,971✔
317
                        return r;
318
        }
319

320
        if (c->pressure[PRESSURE_IO].threshold_usec != USEC_INFINITY) {
4,971✔
321
                r = serialize_usec(f, "exec-cgroup-context-io-pressure-threshold-usec", c->pressure[PRESSURE_IO].threshold_usec);
4,971✔
322
                if (r < 0)
4,971✔
323
                        return r;
324
        }
325

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

430
        r = serialize_item(f, "exec-cgroup-context-bind-iface", c->bind_network_interface);
4,971✔
431
        if (r < 0)
4,971✔
432
                return r;
433

434
        fputc('\n', f); /* End marker */
4,971✔
435

436
        return 0;
437
}
438

439
static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
12,789✔
440
        int r;
12,789✔
441

442
        assert(f);
12,789✔
443

444
        if (!c)
12,789✔
445
                return 0;
446

447
        for (;;) {
576,677✔
448
                _cleanup_free_ char *l = NULL;
281,944✔
449
                const char *val;
294,733✔
450

451
                r = deserialize_read_line(f, &l);
294,733✔
452
                if (r < 0)
294,733✔
453
                        return r;
454
                if (r == 0) /* eof or end marker */
294,733✔
455
                        break;
456

457
                if ((val = startswith(l, "exec-cgroup-context-io-accounting="))) {
281,944✔
458
                        r = parse_boolean(val);
2✔
459
                        if (r < 0)
2✔
460
                                return r;
461
                        c->io_accounting = r;
2✔
462
                } else if ((val = startswith(l, "exec-cgroup-context-memory-accounting="))) {
281,942✔
463
                        r = parse_boolean(val);
12,434✔
464
                        if (r < 0)
12,434✔
465
                                return r;
466
                        c->memory_accounting = r;
12,434✔
467
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-accounting="))) {
269,508✔
468
                        r = parse_boolean(val);
12,789✔
469
                        if (r < 0)
12,789✔
470
                                return r;
471
                        c->tasks_accounting = r;
12,789✔
472
                } else if ((val = startswith(l, "exec-cgroup-context-ip-accounting="))) {
256,719✔
473
                        r = parse_boolean(val);
×
474
                        if (r < 0)
×
475
                                return r;
476
                        c->ip_accounting = r;
×
477
                } else if ((val = startswith(l, "exec-cgroup-context-memory-oom-group="))) {
256,719✔
478
                        r = parse_boolean(val);
2✔
479
                        if (r < 0)
2✔
480
                                return r;
481
                        c->memory_oom_group = r;
2✔
482
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-weight="))) {
256,717✔
483
                        r = safe_atou64(val, &c->cpu_weight);
1✔
484
                        if (r < 0)
1✔
485
                                return r;
486
                } else if ((val = startswith(l, "exec-cgroup-context-startup-cpu-weight="))) {
256,716✔
487
                        r = safe_atou64(val, &c->startup_cpu_weight);
×
488
                        if (r < 0)
×
489
                                return r;
490
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-quota-per-sec-usec="))) {
256,716✔
491
                        r = deserialize_usec(val, &c->cpu_quota_per_sec_usec);
×
492
                        if (r < 0)
×
493
                                return r;
494
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-quota-period-usec="))) {
256,716✔
495
                        r = deserialize_usec(val, &c->cpu_quota_period_usec);
×
496
                        if (r < 0)
×
497
                                return r;
498
                } else if ((val = startswith(l, "exec-cgroup-context-allowed-cpus="))) {
256,716✔
499
                        if (c->cpuset_cpus.set)
12,789✔
500
                                return -EINVAL; /* duplicated */
501

502
                        r = parse_cpu_set(val, &c->cpuset_cpus);
12,789✔
503
                        if (r < 0)
12,789✔
504
                                return r;
505
                } else if ((val = startswith(l, "exec-cgroup-context-startup-allowed-cpus="))) {
243,927✔
506
                        if (c->startup_cpuset_cpus.set)
12,789✔
507
                                return -EINVAL; /* duplicated */
508

509
                        r = parse_cpu_set(val, &c->startup_cpuset_cpus);
12,789✔
510
                        if (r < 0)
12,789✔
511
                                return r;
512
                } else if ((val = startswith(l, "exec-cgroup-context-allowed-memory-nodes="))) {
231,138✔
513
                        if (c->cpuset_mems.set)
12,789✔
514
                                return -EINVAL; /* duplicated */
515

516
                        r = parse_cpu_set(val, &c->cpuset_mems);
12,789✔
517
                        if (r < 0)
12,789✔
518
                                return r;
519
                } else if ((val = startswith(l, "exec-cgroup-context-startup-allowed-memory-nodes="))) {
218,349✔
520
                        if (c->startup_cpuset_mems.set)
12,789✔
521
                                return -EINVAL; /* duplicated */
522

523
                        r = parse_cpu_set(val, &c->startup_cpuset_mems);
12,789✔
524
                        if (r < 0)
12,789✔
525
                                return r;
526
                } else if ((val = startswith(l, "exec-cgroup-context-cpuset-partition="))) {
205,560✔
527
                        c->cpuset_partition = cpuset_partition_from_string(val);
×
528
                        if (c->cpuset_partition < 0)
×
529
                                return -EINVAL;
530
                } else if ((val = startswith(l, "exec-cgroup-context-io-weight="))) {
205,560✔
531
                        r = safe_atou64(val, &c->io_weight);
×
532
                        if (r < 0)
×
533
                                return r;
534
                } else if ((val = startswith(l, "exec-cgroup-context-startup-io-weight="))) {
205,560✔
535
                        r = safe_atou64(val, &c->startup_io_weight);
×
536
                        if (r < 0)
×
537
                                return r;
538
                } else if ((val = startswith(l, "exec-cgroup-context-memory-min="))) {
205,560✔
539
                        r = safe_atou64(val, &c->memory_min);
1✔
540
                        if (r < 0)
1✔
541
                                return r;
542
                } else if ((val = startswith(l, "exec-cgroup-context-memory-low="))) {
205,559✔
543
                        r = safe_atou64(val, &c->memory_low);
1✔
544
                        if (r < 0)
1✔
545
                                return r;
546
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low="))) {
205,558✔
547
                        r = safe_atou64(val, &c->startup_memory_low);
×
548
                        if (r < 0)
×
549
                                return r;
550
                } else if ((val = startswith(l, "exec-cgroup-context-memory-high="))) {
205,558✔
551
                        r = safe_atou64(val, &c->memory_high);
1✔
552
                        if (r < 0)
1✔
553
                                return r;
554
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high="))) {
205,557✔
555
                        r = safe_atou64(val, &c->startup_memory_high);
×
556
                        if (r < 0)
×
557
                                return r;
558
                } else if ((val = startswith(l, "exec-cgroup-context-memory-max="))) {
205,557✔
559
                        r = safe_atou64(val, &c->memory_max);
12✔
560
                        if (r < 0)
12✔
561
                                return r;
562
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max="))) {
205,545✔
563
                        r = safe_atou64(val, &c->startup_memory_max);
×
564
                        if (r < 0)
×
565
                                return r;
566
                } else if ((val = startswith(l, "exec-cgroup-context-memory-swap-max="))) {
205,545✔
567
                        r = safe_atou64(val, &c->memory_swap_max);
11✔
568
                        if (r < 0)
11✔
569
                                return r;
570
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max="))) {
205,534✔
571
                        r = safe_atou64(val, &c->startup_memory_swap_max);
×
572
                        if (r < 0)
×
573
                                return r;
574
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-max="))) {
205,534✔
575
                        r = safe_atou64(val, &c->memory_zswap_max);
1✔
576
                        if (r < 0)
1✔
577
                                return r;
578
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max="))) {
205,533✔
579
                        r = safe_atou64(val, &c->startup_memory_zswap_max);
×
580
                        if (r < 0)
×
581
                                return r;
582
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-writeback="))) {
205,533✔
583
                        r = parse_boolean(val);
12,789✔
584
                        if (r < 0)
12,789✔
585
                                return r;
586
                        c->memory_zswap_writeback = r;
12,789✔
587
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-value="))) {
192,744✔
588
                        r = safe_atou64(val, &c->tasks_max.value);
12,455✔
589
                        if (r < 0)
12,455✔
590
                                return r;
591
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-scale="))) {
180,289✔
592
                        r = safe_atou64(val, &c->tasks_max.scale);
12,402✔
593
                        if (r < 0)
12,402✔
594
                                return r;
595
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low-set="))) {
167,887✔
596
                        r = parse_boolean(val);
×
597
                        if (r < 0)
×
598
                                return r;
599
                        c->startup_memory_low_set = r;
×
600
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high-set="))) {
167,887✔
601
                        r = parse_boolean(val);
×
602
                        if (r < 0)
×
603
                                return r;
604
                        c->startup_memory_high_set = r;
×
605
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max-set="))) {
167,887✔
606
                        r = parse_boolean(val);
×
607
                        if (r < 0)
×
608
                                return r;
609
                        c->startup_memory_max_set = r;
×
610
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max-set="))) {
167,887✔
611
                        r = parse_boolean(val);
×
612
                        if (r < 0)
×
613
                                return r;
614
                        c->startup_memory_swap_max_set = r;
×
615
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max-set="))) {
167,887✔
616
                        r = parse_boolean(val);
×
617
                        if (r < 0)
×
618
                                return r;
619
                        c->startup_memory_zswap_max_set = r;
×
620
                } else if ((val = startswith(l, "exec-cgroup-context-device-policy="))) {
167,887✔
621
                        c->device_policy = cgroup_device_policy_from_string(val);
12,789✔
622
                        if (c->device_policy < 0)
12,789✔
623
                                return -EINVAL;
624
                } else if ((val = startswith(l, "exec-cgroup-context-disable-controllers="))) {
155,098✔
625
                        r = cg_mask_from_string(val, &c->disable_controllers);
×
626
                        if (r < 0)
×
627
                                return r;
628
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-controllers="))) {
155,098✔
629
                        r = cg_mask_from_string(val, &c->delegate_controllers);
646✔
630
                        if (r < 0)
646✔
631
                                return r;
632
                } else if ((val = startswith(l, "exec-cgroup-context-delegate="))) {
154,452✔
633
                        r = parse_boolean(val);
776✔
634
                        if (r < 0)
776✔
635
                                return r;
636
                        c->delegate = r;
776✔
637
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-swap="))) {
153,676✔
638
                        c->moom_swap = managed_oom_mode_from_string(val);
12,789✔
639
                        if (c->moom_swap < 0)
12,789✔
640
                                return -EINVAL;
641
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure="))) {
140,887✔
642
                        c->moom_mem_pressure = managed_oom_mode_from_string(val);
12,789✔
643
                        if (c->moom_mem_pressure < 0)
12,789✔
644
                                return -EINVAL;
645
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-limit="))) {
128,098✔
646
                        r = safe_atou32(val, &c->moom_mem_pressure_limit);
12,789✔
647
                        if (r < 0)
12,789✔
648
                                return r;
649
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-preference="))) {
115,309✔
650
                        c->moom_preference = managed_oom_preference_from_string(val);
12,789✔
651
                        if (c->moom_preference < 0)
12,789✔
652
                                return -EINVAL;
653
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec="))) {
102,520✔
654
                        r = deserialize_usec(val, &c->moom_mem_pressure_duration_usec);
×
655
                        if (r < 0)
×
656
                                return r;
657
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-rules="))) {
102,520✔
658
                        r = deserialize_strv(val, &c->moom_rules);
1✔
659
                        if (r < 0)
1✔
660
                                return r;
661
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-watch="))) {
102,519✔
662
                        c->pressure[PRESSURE_MEMORY].watch = cgroup_pressure_watch_from_string(val);
12,789✔
663
                        if (c->pressure[PRESSURE_MEMORY].watch < 0)
12,789✔
664
                                return -EINVAL;
665
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-pressure-watch="))) {
89,730✔
666
                        c->pressure[PRESSURE_CPU].watch = cgroup_pressure_watch_from_string(val);
12,789✔
667
                        if (c->pressure[PRESSURE_CPU].watch < 0)
12,789✔
668
                                return -EINVAL;
669
                } else if ((val = startswith(l, "exec-cgroup-context-io-pressure-watch="))) {
76,941✔
670
                        c->pressure[PRESSURE_IO].watch = cgroup_pressure_watch_from_string(val);
12,789✔
671
                        if (c->pressure[PRESSURE_IO].watch < 0)
12,789✔
672
                                return -EINVAL;
673
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-subgroup="))) {
64,152✔
674
                        r = free_and_strdup(&c->delegate_subgroup, val);
396✔
675
                        if (r < 0)
396✔
676
                                return r;
677
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-threshold-usec="))) {
63,756✔
678
                        r = deserialize_usec(val, &c->pressure[PRESSURE_MEMORY].threshold_usec);
12,789✔
679
                        if (r < 0)
12,789✔
680
                                return r;
681
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-pressure-threshold-usec="))) {
50,967✔
682
                        r = deserialize_usec(val, &c->pressure[PRESSURE_CPU].threshold_usec);
12,789✔
683
                        if (r < 0)
12,789✔
684
                                return r;
685
                } else if ((val = startswith(l, "exec-cgroup-context-io-pressure-threshold-usec="))) {
38,178✔
686
                        r = deserialize_usec(val, &c->pressure[PRESSURE_IO].threshold_usec);
12,789✔
687
                        if (r < 0)
12,789✔
688
                                return r;
689
                } else if ((val = startswith(l, "exec-cgroup-context-device-allow="))) {
25,389✔
690
                        _cleanup_free_ char *path = NULL, *rwm = NULL;
3,663✔
691
                        CGroupDevicePermissions p;
3,663✔
692

693
                        r = extract_many_words(&val, " ", 0, &path, &rwm);
3,663✔
694
                        if (r < 0)
3,663✔
695
                                return r;
696
                        if (r == 0)
3,663✔
697
                                return -EINVAL;
698

699
                        p = isempty(rwm) ? 0 : cgroup_device_permissions_from_string(rwm);
7,326✔
700
                        if (p < 0)
3,663✔
701
                                return p;
702

703
                        r = cgroup_context_add_or_update_device_allow(c, path, p);
3,663✔
704
                        if (r < 0)
3,663✔
705
                                return r;
706
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-weight="))) {
21,726✔
707
                        _cleanup_free_ char *path = NULL, *weight = NULL;
×
708
                        CGroupIODeviceWeight *a = NULL;
×
709

710
                        r = extract_many_words(&val, " ", 0, &path, &weight);
×
711
                        if (r < 0)
×
712
                                return r;
713
                        if (r != 2)
×
714
                                return -EINVAL;
715

716
                        LIST_FOREACH(device_weights, b, c->io_device_weights)
×
717
                                if (path_equal(b->path, path)) {
×
718
                                        a = b;
719
                                        break;
720
                                }
721

722
                        if (!a) {
×
723
                                a = new0(CGroupIODeviceWeight, 1);
×
724
                                if (!a)
×
725
                                        return log_oom_debug();
×
726

727
                                a->path = TAKE_PTR(path);
×
728

729
                                LIST_PREPEND(device_weights, c->io_device_weights, a);
×
730
                        }
731

732
                        r = safe_atou64(weight, &a->weight);
×
733
                        if (r < 0)
×
734
                                return r;
735
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-latency-target-usec="))) {
21,726✔
736
                        _cleanup_free_ char *path = NULL, *target = NULL;
×
737
                        CGroupIODeviceLatency *a = NULL;
×
738

739
                        r = extract_many_words(&val, " ", 0, &path, &target);
×
740
                        if (r < 0)
×
741
                                return r;
742
                        if (r != 2)
×
743
                                return -EINVAL;
744

745
                        LIST_FOREACH(device_latencies, b, c->io_device_latencies)
×
746
                                if (path_equal(b->path, path)) {
×
747
                                        a = b;
748
                                        break;
749
                                }
750

751
                        if (!a) {
×
752
                                a = new0(CGroupIODeviceLatency, 1);
×
753
                                if (!a)
×
754
                                        return log_oom_debug();
×
755

756
                                a->path = TAKE_PTR(path);
×
757

758
                                LIST_PREPEND(device_latencies, c->io_device_latencies, a);
×
759
                        }
760

761
                        r = deserialize_usec(target, &a->target_usec);
×
762
                        if (r < 0)
×
763
                                return r;
764
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-limit-"))) {
21,726✔
765
                        _cleanup_free_ char *type = NULL, *path = NULL, *limits = NULL;
×
766
                        CGroupIODeviceLimit *limit = NULL;
×
767
                        CGroupIOLimitType t;
×
768

769
                        r = extract_many_words(&val, "= ", 0, &type, &path, &limits);
×
770
                        if (r < 0)
×
771
                                return r;
772
                        if (r != 3)
×
773
                                return -EINVAL;
774

775
                        t = cgroup_io_limit_type_from_string(type);
×
776
                        if (t < 0)
×
777
                                return t;
778

779
                        LIST_FOREACH(device_limits, i, c->io_device_limits)
×
780
                                if (path_equal(path, i->path)) {
×
781
                                        limit = i;
782
                                        break;
783
                                }
784

785
                        if (!limit) {
×
786
                                limit = new0(CGroupIODeviceLimit, 1);
×
787
                                if (!limit)
×
788
                                        return log_oom_debug();
×
789

790
                                limit->path = TAKE_PTR(path);
×
791
                                for (CGroupIOLimitType i = 0; i < _CGROUP_IO_LIMIT_TYPE_MAX; i++)
×
792
                                        limit->limits[i] = cgroup_io_limit_defaults[i];
×
793

794
                                LIST_PREPEND(device_limits, c->io_device_limits, limit);
×
795
                        }
796

797
                        r = safe_atou64(limits, &limit->limits[t]);
×
798
                        if (r < 0)
×
799
                                return r;
800
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow="))) {
21,726✔
801
                        struct in_addr_prefix a;
×
802

803
                        r = in_addr_prefix_from_string_auto(val, &a.family, &a.address, &a.prefixlen);
×
804
                        if (r < 0)
×
805
                                return r;
×
806

807
                        r = in_addr_prefix_add(&c->ip_address_allow, &a);
×
808
                        if (r < 0)
×
809
                                return r;
810
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny="))) {
21,726✔
811
                        struct in_addr_prefix a;
1,546✔
812

813
                        r = in_addr_prefix_from_string_auto(val, &a.family, &a.address, &a.prefixlen);
1,546✔
814
                        if (r < 0)
1,546✔
815
                                return r;
×
816

817
                        r = in_addr_prefix_add(&c->ip_address_deny, &a);
1,546✔
818
                        if (r < 0)
1,546✔
819
                                return r;
820
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow-reduced="))) {
20,180✔
821
                        r = parse_boolean(val);
10,078✔
822
                        if (r < 0)
10,078✔
823
                                return r;
824
                        c->ip_address_allow_reduced = r;
10,078✔
825
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny-reduced="))) {
10,102✔
826
                        r = parse_boolean(val);
10,078✔
827
                        if (r < 0)
10,078✔
828
                                return r;
829
                        c->ip_address_deny_reduced = r;
10,078✔
830
                } else if ((val = startswith(l, "exec-cgroup-context-ip-ingress-filter-path="))) {
24✔
831
                        r = deserialize_strv(val, &c->ip_filters_ingress);
×
832
                        if (r < 0)
×
833
                                return r;
834
                } else if ((val = startswith(l, "exec-cgroup-context-ip-egress-filter-path="))) {
24✔
835
                        r = deserialize_strv(val, &c->ip_filters_egress);
×
836
                        if (r < 0)
×
837
                                return r;
838
                } else if ((val = startswith(l, "exec-cgroup-context-bpf-program="))) {
24✔
839
                        _cleanup_free_ char *type = NULL, *path = NULL;
×
840
                        uint32_t t;
×
841

842
                        r = extract_many_words(&val, " ", 0, &type, &path);
×
843
                        if (r < 0)
×
844
                                return r;
845
                        if (r != 2)
×
846
                                return -EINVAL;
847

848
                        r = safe_atou32(type, &t);
×
849
                        if (r < 0)
×
850
                                return r;
851

852
                        r = cgroup_context_add_bpf_foreign_program(c, t, path);
×
853
                        if (r < 0)
×
854
                                return r;
855
                } else if ((val = startswith(l, "exec-cgroup-context-socket-bind-allow="))) {
24✔
856
                        CGroupSocketBindItem *item;
×
857
                        uint16_t nr_ports, port_min;
×
858
                        int af, ip_protocol;
×
859

860
                        r = parse_socket_bind_item(val, &af, &ip_protocol, &nr_ports, &port_min);
×
861
                        if (r < 0)
×
862
                                return r;
×
863

864
                        item = new(CGroupSocketBindItem, 1);
×
865
                        if (!item)
×
866
                                return log_oom_debug();
×
867
                        *item = (CGroupSocketBindItem) {
×
868
                                .address_family = af,
869
                                .ip_protocol = ip_protocol,
870
                                .nr_ports = nr_ports,
871
                                .port_min = port_min,
872
                        };
873

874
                        LIST_PREPEND(socket_bind_items, c->socket_bind_allow, item);
×
875
                } else if ((val = startswith(l, "exec-cgroup-context-socket-bind-deny="))) {
24✔
876
                        CGroupSocketBindItem *item;
×
877
                        uint16_t nr_ports, port_min;
×
878
                        int af, ip_protocol;
×
879

880
                        r = parse_socket_bind_item(val, &af, &ip_protocol, &nr_ports, &port_min);
×
881
                        if (r < 0)
×
882
                                return r;
×
883

884
                        item = new(CGroupSocketBindItem, 1);
×
885
                        if (!item)
×
886
                                return log_oom_debug();
×
887
                        *item = (CGroupSocketBindItem) {
×
888
                                .address_family = af,
889
                                .ip_protocol = ip_protocol,
890
                                .nr_ports = nr_ports,
891
                                .port_min = port_min,
892
                        };
893

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

912
        return 0;
12,789✔
913
}
914

915
static int exec_runtime_serialize(const ExecRuntime *rt, FILE *f, FDSet *fds) {
4,971✔
916
        int r;
4,971✔
917

918
        assert(f);
4,971✔
919
        assert(fds);
4,971✔
920

921
        if (!rt) {
4,971✔
922
                fputc('\n', f); /* End marker */
4,719✔
923
                return 0;
4,719✔
924
        }
925

926
        if (rt->shared) {
252✔
927
                r = serialize_item(f, "exec-runtime-id", rt->shared->id);
232✔
928
                if (r < 0)
232✔
929
                        return r;
930

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

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

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

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

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

958
        if (rt->dynamic_creds) {
252✔
959
                r = dynamic_user_serialize_one(rt->dynamic_creds->user, "exec-runtime-dynamic-creds-user", f, fds);
105✔
960
                if (r < 0)
105✔
961
                        return r;
962
        }
963

964
        if (rt->dynamic_creds && rt->dynamic_creds->group && rt->dynamic_creds->group == rt->dynamic_creds->user) {
252✔
965
                r = serialize_bool(f, "exec-runtime-dynamic-creds-group-copy", true);
104✔
966
                if (r < 0)
104✔
967
                        return r;
968
        } else if (rt->dynamic_creds) {
148✔
969
                r = dynamic_user_serialize_one(rt->dynamic_creds->group, "exec-runtime-dynamic-creds-group", f, fds);
1✔
970
                if (r < 0)
1✔
971
                        return r;
972
        }
973

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

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

984
        fputc('\n', f); /* End marker */
252✔
985

986
        return 0;
252✔
987
}
988

989
static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) {
12,789✔
990
        int r;
12,789✔
991

992
        assert(rt);
12,789✔
993
        assert(rt->shared);
12,789✔
994
        assert(rt->dynamic_creds);
12,789✔
995
        assert(f);
12,789✔
996
        assert(fds);
12,789✔
997

998
        for (;;) {
14,073✔
999
                _cleanup_free_ char *l = NULL;
1,284✔
1000
                const char *val;
14,073✔
1001

1002
                r = deserialize_read_line(f, &l);
14,073✔
1003
                if (r < 0)
14,073✔
1004
                        return r;
1005
                if (r == 0) /* eof or end marker */
14,073✔
1006
                        break;
1007

1008
                if ((val = startswith(l, "exec-runtime-id="))) {
1,284✔
1009
                        r = free_and_strdup(&rt->shared->id, val);
441✔
1010
                        if (r < 0)
441✔
1011
                                return r;
1012
                } else if ((val = startswith(l, "exec-runtime-tmp-dir="))) {
843✔
1013
                        r = free_and_strdup(&rt->shared->tmp_dir, val);
225✔
1014
                        if (r < 0)
225✔
1015
                                return r;
1016
                } else if ((val = startswith(l, "exec-runtime-var-tmp-dir="))) {
618✔
1017
                        r = free_and_strdup(&rt->shared->var_tmp_dir, val);
380✔
1018
                        if (r < 0)
380✔
1019
                                return r;
1020
                } else if ((val = startswith(l, "exec-runtime-userns-storage-socket="))) {
238✔
1021

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

1026
                } else if ((val = startswith(l, "exec-runtime-netns-storage-socket="))) {
235✔
1027

1028
                        r = deserialize_fd_many(fds, val, 2, rt->shared->netns_storage_socket);
114✔
1029
                        if (r < 0)
114✔
1030
                                continue;
×
1031

1032
                } else if ((val = startswith(l, "exec-runtime-ipcns-storage-socket="))) {
121✔
1033

1034
                        r = deserialize_fd_many(fds, val, 2, rt->shared->ipcns_storage_socket);
23✔
1035
                        if (r < 0)
23✔
1036
                                continue;
×
1037

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

1049
                        if (!rt->dynamic_creds->user)
49✔
1050
                                return -EINVAL;
1051

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

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

1066
        return 0;
12,789✔
1067
}
1068

1069
static bool exec_parameters_is_idle_pipe_set(const ExecParameters *p) {
4,971✔
1070
        assert(p);
4,971✔
1071

1072
        return p->idle_pipe &&
5,006✔
1073
                p->idle_pipe[0] >= 0 &&
35✔
1074
                p->idle_pipe[1] >= 0 &&
33✔
1075
                p->idle_pipe[2] >= 0 &&
5,004✔
1076
                p->idle_pipe[3] >= 0;
33✔
1077
}
1078

1079
static int exec_parameters_serialize(const ExecParameters *p, const ExecContext *c, FILE *f, FDSet *fds) {
4,971✔
1080
        int r;
4,971✔
1081

1082
        assert(f);
4,971✔
1083
        assert(fds);
4,971✔
1084

1085
        if (!p)
4,971✔
1086
                return 0;
1087

1088
        r = serialize_item(f, "exec-parameters-runtime-scope", runtime_scope_to_string(p->runtime_scope));
4,971✔
1089
        if (r < 0)
4,971✔
1090
                return r;
1091

1092
        r = serialize_strv(f, "exec-parameters-environment", p->environment);
4,971✔
1093
        if (r < 0)
4,971✔
1094
                return r;
1095

1096
        if (p->fds) {
4,971✔
1097
                if (p->n_socket_fds > 0) {
861✔
1098
                        r = serialize_item_format(f, "exec-parameters-n-socket-fds", "%zu", p->n_socket_fds);
852✔
1099
                        if (r < 0)
852✔
1100
                                return r;
1101
                }
1102

1103
                if (p->n_stashed_fds > 0) {
861✔
1104
                        r = serialize_item_format(f, "exec-parameters-n-stashed-fds", "%zu", p->n_stashed_fds);
19✔
1105
                        if (r < 0)
19✔
1106
                                return r;
1107
                }
1108

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

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

1118
        if (p->flags != 0) {
4,971✔
1119
                r = serialize_item_format(f, "exec-parameters-flags", "%u", (unsigned) p->flags);
4,971✔
1120
                if (r < 0)
4,971✔
1121
                        return r;
1122
        }
1123

1124
        r = serialize_bool_elide(f, "exec-parameters-selinux-context-net", p->selinux_context_net);
4,971✔
1125
        if (r < 0)
4,971✔
1126
                return r;
1127

1128
        r = serialize_item(f, "exec-parameters-cgroup-path", p->cgroup_path);
4,971✔
1129
        if (r < 0)
4,971✔
1130
                return r;
1131

1132
        r = serialize_item_format(f, "exec-parameters-cgroup-id", "%" PRIu64, p->cgroup_id);
4,971✔
1133
        if (r < 0)
4,971✔
1134
                return r;
1135

1136
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
29,826✔
1137
                _cleanup_free_ char *key = NULL;
24,855✔
1138

1139
                key = strjoin("exec-parameters-prefix-directories-", exec_directory_type_to_string(dt));
24,855✔
1140
                if (!key)
24,855✔
1141
                        return log_oom_debug();
×
1142

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

1150
        r = serialize_item(f, "exec-parameters-received-credentials-directory", p->received_credentials_directory);
4,971✔
1151
        if (r < 0)
4,971✔
1152
                return r;
1153

1154
        r = serialize_item(f, "exec-parameters-received-encrypted-credentials-directory", p->received_encrypted_credentials_directory);
4,971✔
1155
        if (r < 0)
4,971✔
1156
                return r;
1157

1158
        r = serialize_item(f, "exec-parameters-confirm-spawn", p->confirm_spawn);
4,971✔
1159
        if (r < 0)
4,971✔
1160
                return r;
1161

1162
        r = serialize_bool_elide(f, "exec-parameters-shall-confirm-spawn", p->shall_confirm_spawn);
4,971✔
1163
        if (r < 0)
4,971✔
1164
                return r;
1165

1166
        if (p->watchdog_usec > 0) {
4,971✔
1167
                r = serialize_usec(f, "exec-parameters-watchdog-usec", p->watchdog_usec);
329✔
1168
                if (r < 0)
329✔
1169
                        return r;
1170
        }
1171

1172
        if (exec_parameters_is_idle_pipe_set(p)) {
4,971✔
1173
                r = serialize_fd_many(f, fds, "exec-parameters-idle-pipe", p->idle_pipe, 4);
33✔
1174
                if (r < 0)
33✔
1175
                        return r;
1176
        }
1177

1178
        r = serialize_fd(f, fds, "exec-parameters-stdin-fd", p->stdin_fd);
4,971✔
1179
        if (r < 0)
4,971✔
1180
                return r;
1181

1182
        r = serialize_fd(f, fds, "exec-parameters-stdout-fd", p->stdout_fd);
4,971✔
1183
        if (r < 0)
4,971✔
1184
                return r;
1185

1186
        r = serialize_fd(f, fds, "exec-parameters-stderr-fd", p->stderr_fd);
4,971✔
1187
        if (r < 0)
4,971✔
1188
                return r;
1189

1190
        r = serialize_fd(f, fds, "exec-parameters-root-directory-fd", p->root_directory_fd);
4,971✔
1191
        if (r < 0)
4,971✔
1192
                return r;
1193

1194
        r = serialize_fd(f, fds, "exec-parameters-exec-fd", p->exec_fd);
4,971✔
1195
        if (r < 0)
4,971✔
1196
                return r;
1197

1198
        r = serialize_fd(f, fds, "exec-parameters-handoff-timestamp-fd", p->handoff_timestamp_fd);
4,971✔
1199
        if (r < 0)
4,971✔
1200
                return r;
1201

1202
        r = serialize_fd(f, fds, "exec-parameters-pidref-transport-fd", p->pidref_transport_fd);
4,971✔
1203
        if (r < 0)
4,971✔
1204
                return r;
1205

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

1212
        r = serialize_item(f, "exec-parameters-notify-socket", p->notify_socket);
4,971✔
1213
        if (r < 0)
4,971✔
1214
                return r;
1215

1216
        LIST_FOREACH(open_files, file, p->open_files) {
4,971✔
1217
                _cleanup_free_ char *ofs = NULL;
×
1218

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

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

1228
        r = serialize_item(f, "exec-parameters-fallback-smack-process-label", p->fallback_smack_process_label);
4,971✔
1229
        if (r < 0)
4,971✔
1230
                return r;
1231

1232
        r = serialize_fd(f, fds, "exec-parameters-user-lookup-fd", p->user_lookup_fd);
4,971✔
1233
        if (r < 0)
4,971✔
1234
                return r;
1235

1236
        r = serialize_strv(f, "exec-parameters-files-env", p->files_env);
4,971✔
1237
        if (r < 0)
4,971✔
1238
                return r;
1239

1240
        r = serialize_item(f, "exec-parameters-unit-id", p->unit_id);
4,971✔
1241
        if (r < 0)
4,971✔
1242
                return r;
1243

1244
        r = serialize_item(f, "exec-parameters-invocation-id-string", p->invocation_id_string);
4,971✔
1245
        if (r < 0)
4,971✔
1246
                return r;
1247

1248
        r = serialize_bool_elide(f, "exec-parameters-debug-invocation", p->debug_invocation);
4,971✔
1249
        if (r < 0)
4,971✔
1250
                return r;
1251

1252
        fputc('\n', f); /* End marker */
4,971✔
1253

1254
        return 0;
4,971✔
1255
}
1256

1257
static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
12,789✔
1258
        int r;
12,789✔
1259

1260
        assert(p);
12,789✔
1261
        assert(f);
12,789✔
1262
        assert(fds);
12,789✔
1263

1264
        unsigned nr_open = MAX(read_nr_open(), NR_OPEN_MINIMUM);
12,789✔
1265

1266
        for (;;) {
273,890✔
1267
                _cleanup_free_ char *l = NULL;
261,101✔
1268
                const char *val;
273,890✔
1269

1270
                r = deserialize_read_line(f, &l);
273,890✔
1271
                if (r < 0)
273,890✔
1272
                        return r;
1273
                if (r == 0) /* eof or end marker */
273,890✔
1274
                        break;
1275

1276
                if ((val = startswith(l, "exec-parameters-runtime-scope="))) {
261,101✔
1277
                        p->runtime_scope = runtime_scope_from_string(val);
12,789✔
1278
                        if (p->runtime_scope < 0)
12,789✔
1279
                                return p->runtime_scope;
1280
                } else if ((val = startswith(l, "exec-parameters-environment="))) {
248,312✔
1281
                        r = deserialize_strv(val, &p->environment);
55,093✔
1282
                        if (r < 0)
55,093✔
1283
                                return r;
1284
                } else if ((val = startswith(l, "exec-parameters-n-socket-fds="))) {
193,219✔
1285
                        if (p->fds)
2,418✔
1286
                                return -EINVAL; /* Already received */
1287

1288
                        r = safe_atozu(val, &p->n_socket_fds);
2,418✔
1289
                        if (r < 0)
2,418✔
1290
                                return r;
1291

1292
                        if (p->n_socket_fds > nr_open)
2,418✔
1293
                                return -EINVAL; /* too many, someone is playing games with us */
1294
                } else if ((val = startswith(l, "exec-parameters-n-stashed-fds="))) {
190,801✔
1295
                        if (p->fds)
137✔
1296
                                return -EINVAL; /* Already received */
1297

1298
                        r = safe_atozu(val, &p->n_stashed_fds);
137✔
1299
                        if (r < 0)
137✔
1300
                                return r;
1301

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

1313
                        if (p->fds)
2,437✔
1314
                                return -EINVAL; /* duplicated */
1315

1316
                        p->fds = new(int, p->n_socket_fds + p->n_stashed_fds);
2,437✔
1317
                        if (!p->fds)
2,437✔
1318
                                return log_oom_debug();
×
1319

1320
                        /* Ensure we don't leave any FD uninitialized on error, it makes the fuzzer sad */
1321
                        FOREACH_ARRAY(i, p->fds, p->n_socket_fds + p->n_stashed_fds)
7,421✔
1322
                                *i = -EBADF;
4,984✔
1323

1324
                        r = deserialize_fd_many(fds, val, p->n_socket_fds + p->n_stashed_fds, p->fds);
2,437✔
1325
                        if (r < 0)
2,437✔
1326
                                continue;
×
1327

1328
                } else if ((val = startswith(l, "exec-parameters-fd-names="))) {
188,227✔
1329
                        r = deserialize_strv(val, &p->fd_names);
4,984✔
1330
                        if (r < 0)
4,984✔
1331
                                return r;
1332
                } else if ((val = startswith(l, "exec-parameters-flags="))) {
183,243✔
1333
                        unsigned flags;
12,789✔
1334

1335
                        r = safe_atou(val, &flags);
12,789✔
1336
                        if (r < 0)
12,789✔
1337
                                return r;
×
1338
                        p->flags = flags;
12,789✔
1339
                } else if ((val = startswith(l, "exec-parameters-selinux-context-net="))) {
170,454✔
1340
                        r = parse_boolean(val);
×
1341
                        if (r < 0)
×
1342
                                return r;
1343

1344
                        p->selinux_context_net = r;
×
1345
                } else if ((val = startswith(l, "exec-parameters-cgroup-path="))) {
170,454✔
1346
                        r = free_and_strdup(&p->cgroup_path, val);
12,789✔
1347
                        if (r < 0)
12,789✔
1348
                                return r;
1349
                } else if ((val = startswith(l, "exec-parameters-cgroup-id="))) {
157,665✔
1350
                        r = safe_atou64(val, &p->cgroup_id);
12,789✔
1351
                        if (r < 0)
12,789✔
1352
                                return r;
1353
                } else if ((val = startswith(l, "exec-parameters-prefix-directories-"))) {
144,876✔
1354
                        _cleanup_free_ char *type = NULL, *prefix = NULL;
63,945✔
1355
                        ExecDirectoryType dt;
63,945✔
1356

1357
                        r = extract_many_words(&val, "= ", 0, &type, &prefix);
63,945✔
1358
                        if (r < 0)
63,945✔
1359
                                return r;
1360
                        if (r == 0)
63,945✔
1361
                                return -EINVAL;
1362

1363
                        dt = exec_directory_type_from_string(type);
63,945✔
1364
                        if (dt < 0)
63,945✔
1365
                                return -EINVAL;
1366

1367
                        if (!p->prefix) {
63,945✔
1368
                                p->prefix = new0(char*, _EXEC_DIRECTORY_TYPE_MAX+1);
12,789✔
1369
                                if (!p->prefix)
12,789✔
1370
                                        return log_oom_debug();
×
1371
                        }
1372

1373
                        if (isempty(prefix))
63,945✔
1374
                                p->prefix[dt] = mfree(p->prefix[dt]);
×
1375
                        else
1376
                                free_and_replace(p->prefix[dt], prefix);
63,945✔
1377
                } else if ((val = startswith(l, "exec-parameters-received-credentials-directory="))) {
80,931✔
1378
                        r = free_and_strdup(&p->received_credentials_directory, val);
12,014✔
1379
                        if (r < 0)
12,014✔
1380
                                return r;
1381
                } else if ((val = startswith(l, "exec-parameters-received-encrypted-credentials-directory="))) {
68,917✔
1382
                        r = free_and_strdup(&p->received_encrypted_credentials_directory, val);
×
1383
                        if (r < 0)
×
1384
                                return r;
1385
                } else if ((val = startswith(l, "exec-parameters-confirm-spawn="))) {
68,917✔
1386
                        r = free_and_strdup(&p->confirm_spawn, val);
×
1387
                        if (r < 0)
×
1388
                                return r;
1389
                } else if ((val = startswith(l, "exec-parameters-shall-confirm-spawn="))) {
68,917✔
1390
                        r = parse_boolean(val);
×
1391
                        if (r < 0)
×
1392
                                return r;
1393

1394
                        p->shall_confirm_spawn = r;
×
1395
                } else if ((val = startswith(l, "exec-parameters-watchdog-usec="))) {
68,917✔
1396
                        r = deserialize_usec(val, &p->watchdog_usec);
1,610✔
1397
                        if (r < 0)
1,610✔
1398
                                return r;
1399
                } else if ((val = startswith(l, "exec-parameters-idle-pipe="))) {
67,307✔
1400
                        if (p->idle_pipe)
129✔
1401
                                return -EINVAL; /* duplicated */
1402

1403
                        p->idle_pipe = new(int, 4);
129✔
1404
                        if (!p->idle_pipe)
129✔
1405
                                return log_oom_debug();
×
1406

1407
                        p->idle_pipe[0] = p->idle_pipe[1] = p->idle_pipe[2] = p->idle_pipe[3] = -EBADF;
129✔
1408

1409
                        r = deserialize_fd_many(fds, val, 4, p->idle_pipe);
129✔
1410
                        if (r < 0)
129✔
1411
                                continue;
×
1412

1413
                } else if ((val = startswith(l, "exec-parameters-stdin-fd="))) {
67,178✔
1414
                        int fd;
618✔
1415

1416
                        fd = deserialize_fd(fds, val);
618✔
1417
                        if (fd < 0)
618✔
1418
                                continue;
×
1419

1420
                        close_and_replace(p->stdin_fd, fd);
618✔
1421

1422
                } else if ((val = startswith(l, "exec-parameters-stdout-fd="))) {
66,560✔
1423
                        int fd;
618✔
1424

1425
                        fd = deserialize_fd(fds, val);
618✔
1426
                        if (fd < 0)
618✔
1427
                                continue;
×
1428

1429
                        close_and_replace(p->stdout_fd, fd);
618✔
1430

1431
                } else if ((val = startswith(l, "exec-parameters-stderr-fd="))) {
65,942✔
1432
                        int fd;
618✔
1433

1434
                        fd = deserialize_fd(fds, val);
618✔
1435
                        if (fd < 0)
618✔
1436
                                continue;
×
1437

1438
                        close_and_replace(p->stderr_fd, fd);
618✔
1439

1440
                } else if ((val = startswith(l, "exec-parameters-root-directory-fd="))) {
65,324✔
1441
                        int fd;
2✔
1442

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

1447
                        close_and_replace(p->root_directory_fd, fd);
2✔
1448

1449
                } else if ((val = startswith(l, "exec-parameters-exec-fd="))) {
65,322✔
1450
                        int fd;
493✔
1451

1452
                        fd = deserialize_fd(fds, val);
493✔
1453
                        if (fd < 0)
493✔
1454
                                continue;
×
1455

1456
                        close_and_replace(p->exec_fd, fd);
493✔
1457
                } else if ((val = startswith(l, "exec-parameters-handoff-timestamp-fd="))) {
64,829✔
1458
                        int fd;
12,789✔
1459

1460
                        fd = deserialize_fd(fds, val);
12,789✔
1461
                        if (fd < 0)
12,789✔
1462
                                continue;
×
1463

1464
                        close_and_replace(p->handoff_timestamp_fd, fd);
12,789✔
1465
                } else if ((val = startswith(l, "exec-parameters-pidref-transport-fd="))) {
52,040✔
1466
                        int fd;
11,565✔
1467

1468
                        fd = deserialize_fd(fds, val);
11,565✔
1469
                        if (fd < 0)
11,565✔
1470
                                continue;
×
1471

1472
                        close_and_replace(p->pidref_transport_fd, fd);
11,565✔
1473
                } else if ((val = startswith(l, "exec-parameters-bpf-outer-map-fd="))) {
40,475✔
1474
                        int fd;
×
1475

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

1480
                        close_and_replace(p->bpf_restrict_fs_map_fd, fd);
×
1481
                } else if ((val = startswith(l, "exec-parameters-notify-socket="))) {
40,475✔
1482
                        r = free_and_strdup(&p->notify_socket, val);
2,099✔
1483
                        if (r < 0)
2,099✔
1484
                                return r;
1485
                } else if ((val = startswith(l, "exec-parameters-open-file="))) {
38,376✔
1486
                        OpenFile *of;
5✔
1487

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

1492
                        LIST_APPEND(open_files, p->open_files, of);
5✔
1493
                } else if ((val = startswith(l, "exec-parameters-fallback-smack-process-label="))) {
38,371✔
1494
                        r = free_and_strdup(&p->fallback_smack_process_label, val);
×
1495
                        if (r < 0)
×
1496
                                return r;
1497
                } else if ((val = startswith(l, "exec-parameters-user-lookup-fd="))) {
38,371✔
1498
                        int fd;
12,789✔
1499

1500
                        fd = deserialize_fd(fds, val);
12,789✔
1501
                        if (fd < 0)
12,789✔
1502
                                continue;
×
1503

1504
                        close_and_replace(p->user_lookup_fd, fd);
12,789✔
1505
                } else if ((val = startswith(l, "exec-parameters-files-env="))) {
25,582✔
1506
                        r = deserialize_strv(val, &p->files_env);
2✔
1507
                        if (r < 0)
2✔
1508
                                return r;
1509
                } else if ((val = startswith(l, "exec-parameters-unit-id="))) {
25,580✔
1510
                        r = free_and_strdup(&p->unit_id, val);
12,789✔
1511
                        if (r < 0)
12,789✔
1512
                                return r;
1513
                } else if ((val = startswith(l, "exec-parameters-invocation-id-string="))) {
12,791✔
1514
                        if (strlen(val) > SD_ID128_STRING_MAX - 1)
12,789✔
1515
                                return -EINVAL;
1516

1517
                        r = sd_id128_from_string(val, &p->invocation_id);
12,789✔
1518
                        if (r < 0)
12,789✔
1519
                                return r;
1520

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

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

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

1537
        return 0;
1538
}
1539

1540
static int serialize_mount_options(const MountOptions *mount_options, char **s) {
24✔
1541
        assert(s);
24✔
1542

1543
        if (!mount_options)
24✔
1544
                return 0;
1545

1546
        for (PartitionDesignator i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
84✔
1547
                _cleanup_free_ char *escaped = NULL;
7✔
1548

1549
                if (isempty(mount_options->options[i]))
78✔
1550
                        continue;
71✔
1551

1552
                escaped = shell_escape(mount_options->options[i], ":");
7✔
1553
                if (!escaped)
7✔
1554
                        return log_oom_debug();
×
1555

1556
                if (!strextend(s,
7✔
1557
                               " ",
1558
                               partition_designator_to_string(i),
1559
                               ":",
1560
                               escaped))
1561
                        return log_oom_debug();
×
1562
        }
1563

1564
        return 0;
1565
}
1566

1567
static int deserialize_mount_options(const char *s, MountOptions **ret_mount_options) {
77✔
1568
        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
77✔
1569
        int r;
77✔
1570

1571
        assert(ret_mount_options);
77✔
1572

1573
        for (;;) {
87✔
1574
                _cleanup_free_ char *word = NULL, *mount_options = NULL, *partition = NULL;
10✔
1575
                PartitionDesignator partition_designator;
87✔
1576
                const char *p;
87✔
1577

1578
                r = extract_first_word(&s, &word, NULL, 0);
87✔
1579
                if (r < 0)
87✔
1580
                        return r;
1581
                if (r == 0)
87✔
1582
                        break;
1583

1584
                p = word;
10✔
1585
                r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options);
10✔
1586
                if (r < 0)
10✔
1587
                        return r;
1588
                if (r == 0)
10✔
1589
                        continue;
×
1590
                if (r != 2) {
10✔
1591
                        log_warning("Failed to parse mount options entry '%s', ignoring.", word);
×
1592
                        continue;
×
1593
                }
1594

1595
                partition_designator = partition_designator_from_string(partition);
10✔
1596
                if (partition_designator < 0) {
10✔
1597
                        log_warning_errno(partition_designator, "Unknown partition designator '%s' in exec-context-root-image-options= entry, ignoring.", partition);
×
1598
                        continue;
×
1599
                }
1600

1601
                r = mount_options_set_and_consume(&options, partition_designator, TAKE_PTR(mount_options));
10✔
1602
                if (r < 0)
10✔
1603
                        return r;
1604
        }
1605

1606
        *ret_mount_options = TAKE_PTR(options);
77✔
1607

1608
        return 0;
77✔
1609
}
1610

1611
static int exec_context_serialize(const ExecContext *c, FILE *f) {
4,971✔
1612
        int r;
4,971✔
1613

1614
        assert(f);
4,971✔
1615

1616
        if (!c)
4,971✔
1617
                return 0;
4,971✔
1618

1619
        r = serialize_strv(f, "exec-context-environment", c->environment);
4,971✔
1620
        if (r < 0)
4,971✔
1621
                return r;
1622

1623
        r = serialize_strv(f, "exec-context-environment-files", c->environment_files);
4,971✔
1624
        if (r < 0)
4,971✔
1625
                return r;
1626

1627
        r = serialize_strv(f, "exec-context-pass-environment", c->pass_environment);
4,971✔
1628
        if (r < 0)
4,971✔
1629
                return r;
1630

1631
        r = serialize_strv(f, "exec-context-unset-environment", c->unset_environment);
4,971✔
1632
        if (r < 0)
4,971✔
1633
                return r;
1634

1635
        r = serialize_item_escaped(f, "exec-context-working-directory", c->working_directory);
4,971✔
1636
        if (r < 0)
4,971✔
1637
                return r;
1638

1639
        r = serialize_bool_elide(f, "exec-context-working-directory-missing-ok", c->working_directory_missing_ok);
4,971✔
1640
        if (r < 0)
4,971✔
1641
                return r;
1642

1643
        r = serialize_bool_elide(f, "exec-context-working-directory-home", c->working_directory_home);
4,971✔
1644
        if (r < 0)
4,971✔
1645
                return r;
1646

1647
        r = serialize_item_escaped(f, "exec-context-root-directory", c->root_directory);
4,971✔
1648
        if (r < 0)
4,971✔
1649
                return r;
1650

1651
        r = serialize_item_escaped(f, "exec-context-root-image", c->root_image);
4,971✔
1652
        if (r < 0)
4,971✔
1653
                return r;
1654

1655
        if (c->root_image_options) {
4,971✔
1656
                _cleanup_free_ char *options = NULL;
2✔
1657

1658
                r = serialize_mount_options(c->root_image_options, &options);
2✔
1659
                if (r < 0)
2✔
1660
                        return r;
1661

1662
                r = serialize_item(f, "exec-context-root-image-options", options);
2✔
1663
                if (r < 0)
2✔
1664
                        return r;
1665
        }
1666

1667
        r = serialize_item(f, "exec-context-root-verity", c->root_verity);
4,971✔
1668
        if (r < 0)
4,971✔
1669
                return r;
1670

1671
        r = serialize_item(f, "exec-context-root-hash-path", c->root_hash_path);
4,971✔
1672
        if (r < 0)
4,971✔
1673
                return r;
1674

1675
        r = serialize_item(f, "exec-context-root-hash-sig-path", c->root_hash_sig_path);
4,971✔
1676
        if (r < 0)
4,971✔
1677
                return r;
1678

1679
        r = serialize_item_hexmem(f, "exec-context-root-hash", c->root_hash.iov_base, c->root_hash.iov_len);
4,971✔
1680
        if (r < 0)
4,971✔
1681
                return r;
1682

1683
        r = serialize_item_base64mem(f, "exec-context-root-hash-sig", c->root_hash_sig.iov_base, c->root_hash_sig.iov_len);
4,971✔
1684
        if (r < 0)
4,971✔
1685
                return r;
1686

1687
        r = serialize_bool_elide(f, "exec-context-root-ephemeral", c->root_ephemeral);
4,971✔
1688
        if (r < 0)
4,971✔
1689
                return r;
1690

1691
        r = serialize_item_escaped(f, "exec-context-root-mstack", c->root_mstack);
4,971✔
1692
        if (r < 0)
4,971✔
1693
                return r;
1694

1695
        r = serialize_item_format(f, "exec-context-umask", "%04o", c->umask);
4,971✔
1696
        if (r < 0)
4,971✔
1697
                return r;
1698

1699
        r = serialize_bool_elide(f, "exec-context-non-blocking", c->non_blocking);
4,971✔
1700
        if (r < 0)
4,971✔
1701
                return r;
1702

1703
        r = serialize_item_tristate(f, "exec-context-private-mounts", c->private_mounts);
4,971✔
1704
        if (r < 0)
59✔
1705
                return r;
1706

1707
        r = serialize_item_tristate(f, "exec-context-mount-api-vfs", c->mount_apivfs);
4,971✔
1708
        if (r < 0)
30✔
1709
                return r;
1710

1711
        r = serialize_item_tristate(f, "exec-context-bind-log-sockets", c->bind_log_sockets);
4,971✔
1712
        if (r < 0)
28✔
1713
                return r;
1714

1715
        r = serialize_item_tristate(f, "exec-context-memory-ksm", c->memory_ksm);
4,971✔
1716
        if (r < 0)
×
1717
                return r;
1718

1719
        r = serialize_item(f, "exec-context-memory-thp", exec_memory_thp_to_string(c->memory_thp));
4,971✔
1720
        if (r < 0)
4,971✔
1721
                return r;
1722

1723
        r = serialize_item(f, "exec-context-private-tmp", private_tmp_to_string(c->private_tmp));
4,971✔
1724
        if (r < 0)
4,971✔
1725
                return r;
1726

1727
        /* This must be set in unit_patch_contexts() before executing a command. */
1728
        assert(c->private_var_tmp >= 0 && c->private_var_tmp < _PRIVATE_TMP_MAX);
4,971✔
1729
        r = serialize_item(f, "exec-context-private-var-tmp", private_tmp_to_string(c->private_var_tmp));
4,971✔
1730
        if (r < 0)
4,971✔
1731
                return r;
1732

1733
        r = serialize_bool_elide(f, "exec-context-private-devices", c->private_devices);
4,971✔
1734
        if (r < 0)
4,971✔
1735
                return r;
1736

1737
        r = serialize_bool_elide(f, "exec-context-protect-kernel-tunables", c->protect_kernel_tunables);
4,971✔
1738
        if (r < 0)
4,971✔
1739
                return r;
1740

1741
        r = serialize_bool_elide(f, "exec-context-protect-kernel-modules", c->protect_kernel_modules);
4,971✔
1742
        if (r < 0)
4,971✔
1743
                return r;
1744

1745
        r = serialize_bool_elide(f, "exec-context-protect-kernel-logs", c->protect_kernel_logs);
4,971✔
1746
        if (r < 0)
4,971✔
1747
                return r;
1748

1749
        r = serialize_bool_elide(f, "exec-context-protect-clock", c->protect_clock);
4,971✔
1750
        if (r < 0)
4,971✔
1751
                return r;
1752

1753
        r = serialize_item(f, "exec-context-protect-control-groups", protect_control_groups_to_string(c->protect_control_groups));
4,971✔
1754
        if (r < 0)
4,971✔
1755
                return r;
1756

1757
        r = serialize_bool_elide(f, "exec-context-private-network", c->private_network);
4,971✔
1758
        if (r < 0)
4,971✔
1759
                return r;
1760

1761
        r = serialize_item(f, "exec-context-private-users", private_users_to_string(c->private_users));
4,971✔
1762
        if (r < 0)
4,971✔
1763
                return r;
1764

1765
        r = serialize_bool_elide(f, "exec-context-private-ipc", c->private_ipc);
4,971✔
1766
        if (r < 0)
4,971✔
1767
                return r;
1768

1769
        r = serialize_item(f, "exec-context-private-pids", private_pids_to_string(c->private_pids));
4,971✔
1770
        if (r < 0)
4,971✔
1771
                return r;
1772

1773
        r = serialize_bool_elide(f, "exec-context-remove-ipc", c->remove_ipc);
4,971✔
1774
        if (r < 0)
4,971✔
1775
                return r;
1776

1777
        r = serialize_item(f, "exec-context-protect-home", protect_home_to_string(c->protect_home));
4,971✔
1778
        if (r < 0)
4,971✔
1779
                return r;
1780

1781
        r = serialize_item(f, "exec-context-protect-system", protect_system_to_string(c->protect_system));
4,971✔
1782
        if (r < 0)
4,971✔
1783
                return r;
1784

1785
        r = serialize_bool_elide(f, "exec-context-same-pgrp", c->same_pgrp);
4,971✔
1786
        if (r < 0)
4,971✔
1787
                return r;
1788

1789
        r = serialize_bool(f, "exec-context-ignore-sigpipe", c->ignore_sigpipe);
4,971✔
1790
        if (r < 0)
4,971✔
1791
                return r;
1792

1793
        r = serialize_bool_elide(f, "exec-context-memory-deny-write-execute", c->memory_deny_write_execute);
4,971✔
1794
        if (r < 0)
4,971✔
1795
                return r;
1796

1797
        r = serialize_bool_elide(f, "exec-context-restrict-realtime", c->restrict_realtime);
4,971✔
1798
        if (r < 0)
4,971✔
1799
                return r;
1800

1801
        r = serialize_bool_elide(f, "exec-context-restrict-suid-sgid", c->restrict_suid_sgid);
4,971✔
1802
        if (r < 0)
4,971✔
1803
                return r;
1804

1805
        r = serialize_item(f, "exec-context-keyring-mode", exec_keyring_mode_to_string(c->keyring_mode));
4,971✔
1806
        if (r < 0)
4,971✔
1807
                return r;
1808

1809
        r = serialize_item(f, "exec-context-protect-hostname", protect_hostname_to_string(c->protect_hostname));
4,971✔
1810
        if (r < 0)
4,971✔
1811
                return r;
1812

1813
        r = serialize_item(f, "exec-context-private-hostname", c->private_hostname);
4,971✔
1814
        if (r < 0)
4,971✔
1815
                return r;
1816

1817
        r = serialize_item(f, "exec-context-protect-proc", protect_proc_to_string(c->protect_proc));
4,971✔
1818
        if (r < 0)
4,971✔
1819
                return r;
1820

1821
        r = serialize_item(f, "exec-context-proc-subset", proc_subset_to_string(c->proc_subset));
4,971✔
1822
        if (r < 0)
4,971✔
1823
                return r;
1824

1825
        r = serialize_item(f, "exec-context-private-bpf", private_bpf_to_string(c->private_bpf));
4,971✔
1826
        if (r < 0)
4,971✔
1827
                return r;
1828

1829
        if (c->bpf_delegate_commands != 0) {
4,971✔
1830
                r = serialize_item_format(f, "exec-context-bpf-delegate-commands", "0x%"PRIx64, c->bpf_delegate_commands);
2✔
1831
                if (r < 0)
2✔
1832
                        return r;
1833
        }
1834

1835
        if (c->bpf_delegate_maps != 0) {
4,971✔
1836
                r = serialize_item_format(f, "exec-context-bpf-delegate-maps", "0x%"PRIx64, c->bpf_delegate_maps);
1✔
1837
                if (r < 0)
1✔
1838
                        return r;
1839
        }
1840

1841
        if (c->bpf_delegate_programs != 0) {
4,971✔
1842
                r = serialize_item_format(f, "exec-context-bpf-delegate-programs", "0x%"PRIx64, c->bpf_delegate_programs);
1✔
1843
                if (r < 0)
1✔
1844
                        return r;
1845
        }
1846

1847
        if (c->bpf_delegate_attachments != 0) {
4,971✔
1848
                r = serialize_item_format(f, "exec-context-bpf-delegate-attachments", "0x%"PRIx64, c->bpf_delegate_attachments);
1✔
1849
                if (r < 0)
1✔
1850
                        return r;
1851
        }
1852

1853
        r = serialize_item(f, "exec-context-runtime-directory-preserve-mode", exec_preserve_mode_to_string(c->runtime_directory_preserve_mode));
4,971✔
1854
        if (r < 0)
4,971✔
1855
                return r;
1856

1857
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
29,826✔
1858
                _cleanup_free_ char *key = NULL, *value = NULL;
24,855✔
1859

1860
                key = strjoin("exec-context-directories-", exec_directory_type_to_string(dt));
24,855✔
1861
                if (!key)
24,855✔
1862
                        return log_oom_debug();
×
1863

1864
                if (asprintf(&value, "%04o", c->directories[dt].mode) < 0)
24,855✔
1865
                        return log_oom_debug();
×
1866

1867
                FOREACH_ARRAY(i, c->directories[dt].items, c->directories[dt].n_items) {
25,457✔
1868
                        _cleanup_free_ char *path_escaped = NULL;
602✔
1869

1870
                        path_escaped = shell_escape(i->path, ":" WHITESPACE);
602✔
1871
                        if (!path_escaped)
602✔
1872
                                return log_oom_debug();
×
1873

1874
                        if (!strextend(&value, " ", path_escaped))
602✔
1875
                                return log_oom_debug();
×
1876

1877
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE))))
1,199✔
1878
                                return log_oom_debug();
×
1879

1880
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_READ_ONLY))))
1,202✔
1881
                                return log_oom_debug();
×
1882

1883
                        STRV_FOREACH(d, i->symlinks) {
608✔
1884
                                _cleanup_free_ char *link_escaped = NULL;
6✔
1885

1886
                                link_escaped = shell_escape(*d, ":" WHITESPACE);
6✔
1887
                                if (!link_escaped)
6✔
1888
                                        return log_oom_debug();
×
1889

1890
                                if (!strextend(&value, ":", link_escaped))
6✔
1891
                                        return log_oom_debug();
×
1892
                        }
1893
                }
1894

1895
                r = serialize_item(f, key, value);
24,855✔
1896
                if (r < 0)
24,855✔
1897
                        return r;
1898

1899
                if (c->directories[dt].exec_quota.quota_enforce) {
24,855✔
1900
                        _cleanup_free_ char *key_quota = NULL;
×
1901
                        key_quota = strjoin("exec-context-quota-directories-", exec_directory_type_to_string(dt));
×
1902
                        if (!key_quota)
×
1903
                                return log_oom_debug();
×
1904

1905
                        r = serialize_item_format(f, key_quota, "%" PRIu64 " %" PRIu32, c->directories[dt].exec_quota.quota_absolute,
×
1906
                                                                                        c->directories[dt].exec_quota.quota_scale);
×
1907
                        if (r < 0)
×
1908
                                return r;
1909

1910
                } else if (c->directories[dt].exec_quota.quota_accounting) {
24,855✔
1911
                        _cleanup_free_ char *key_quota = NULL;
×
1912
                        key_quota = strjoin("exec-context-quota-accounting-directories-", exec_directory_type_to_string(dt));
×
1913
                        if (!key_quota)
×
1914
                                return log_oom_debug();
×
1915

1916
                        r = serialize_bool(f, key_quota, c->directories[dt].exec_quota.quota_accounting);
×
1917
                        if (r < 0)
×
1918
                                return r;
1919
                }
1920
        }
1921

1922
        r = serialize_usec(f, "exec-context-timeout-clean-usec", c->timeout_clean_usec);
4,971✔
1923
        if (r < 0)
4,971✔
1924
                return r;
1925

1926
        if (c->nice_set) {
4,971✔
1927
                r = serialize_item_format(f, "exec-context-nice", "%i", c->nice);
4✔
1928
                if (r < 0)
4✔
1929
                        return r;
1930
        }
1931

1932
        if (c->oom_score_adjust_set) {
4,971✔
1933
                r = serialize_item_format(f, "exec-context-oom-score-adjust", "%i", c->oom_score_adjust);
755✔
1934
                if (r < 0)
755✔
1935
                        return r;
1936
        }
1937

1938
        if (c->coredump_filter_set) {
4,971✔
1939
                r = serialize_item_format(f, "exec-context-coredump-filter", "%"PRIx64, c->coredump_filter);
×
1940
                if (r < 0)
×
1941
                        return r;
1942
        }
1943

1944
        for (unsigned i = 0; i < RLIM_NLIMITS; i++) {
84,507✔
1945
                _cleanup_free_ char *key = NULL, *limit = NULL;
9,936✔
1946

1947
                if (!c->rlimit[i])
79,536✔
1948
                        continue;
69,600✔
1949

1950
                key = strjoin("exec-context-limit-", rlimit_to_string(i));
9,936✔
1951
                if (!key)
9,936✔
1952
                        return log_oom_debug();
×
1953

1954
                r = rlimit_format(c->rlimit[i], &limit);
9,936✔
1955
                if (r < 0)
9,936✔
1956
                        return r;
1957

1958
                r = serialize_item(f, key, limit);
9,936✔
1959
                if (r < 0)
9,936✔
1960
                        return r;
1961
        }
1962

1963
        if (c->ioprio_is_set) {
4,971✔
1964
                r = serialize_item_format(f, "exec-context-ioprio", "%d", c->ioprio);
10✔
1965
                if (r < 0)
10✔
1966
                        return r;
1967
        }
1968

1969
        if (c->cpu_sched_set) {
4,971✔
1970
                _cleanup_free_ char *policy_str = NULL;
×
1971

1972
                r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
×
1973
                if (r < 0)
×
1974
                        return r;
1975

1976
                r = serialize_item(f, "exec-context-cpu-scheduling-policy", policy_str);
×
1977
                if (r < 0)
×
1978
                        return r;
1979

1980
                r = serialize_item_format(f, "exec-context-cpu-scheduling-priority", "%i", c->cpu_sched_priority);
×
1981
                if (r < 0)
×
1982
                        return r;
1983

1984
                r = serialize_bool_elide(f, "exec-context-cpu-scheduling-reset-on-fork", c->cpu_sched_reset_on_fork);
×
1985
                if (r < 0)
×
1986
                        return r;
1987
        }
1988

1989
        if (c->cpu_set.set) {
4,971✔
1990
                _cleanup_free_ char *affinity = NULL;
×
1991

1992
                affinity = cpu_set_to_range_string(&c->cpu_set);
×
1993
                if (!affinity)
×
1994
                        return log_oom_debug();
×
1995

1996
                r = serialize_item(f, "exec-context-cpu-affinity", affinity);
×
1997
                if (r < 0)
×
1998
                        return r;
1999
        }
2000

2001
        if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) {
4,971✔
2002
                _cleanup_free_ char *nodes = NULL;
×
2003

2004
                nodes = cpu_set_to_range_string(&c->numa_policy.nodes);
×
2005
                if (!nodes)
×
2006
                        return log_oom_debug();
×
2007

2008
                if (nodes) {
×
2009
                        r = serialize_item(f, "exec-context-numa-mask", nodes);
×
2010
                        if (r < 0)
×
2011
                                return r;
2012
                }
2013

2014
                r = serialize_item_format(f, "exec-context-numa-policy", "%d", c->numa_policy.type);
×
2015
                if (r < 0)
×
2016
                        return r;
2017
        }
2018

2019
        r = serialize_bool_elide(f, "exec-context-cpu-affinity-from-numa", c->cpu_affinity_from_numa);
4,971✔
2020
        if (r < 0)
4,971✔
2021
                return r;
2022

2023
        if (c->timer_slack_nsec != NSEC_INFINITY) {
4,971✔
2024
                r = serialize_item_format(f, "exec-context-timer-slack-nsec", NSEC_FMT, c->timer_slack_nsec);
×
2025
                if (r < 0)
×
2026
                        return r;
2027
        }
2028

2029
        r = serialize_bool_elide(f, "exec-context-root-directory-as-fd", c->root_directory_as_fd);
4,971✔
2030
        if (r < 0)
4,971✔
2031
                return r;
2032

2033
        r = serialize_item(f, "exec-context-std-input", exec_input_to_string(c->std_input));
4,971✔
2034
        if (r < 0)
4,971✔
2035
                return r;
2036

2037
        r = serialize_item(f, "exec-context-std-output", exec_output_to_string(c->std_output));
4,971✔
2038
        if (r < 0)
4,971✔
2039
                return r;
2040

2041
        r = serialize_item(f, "exec-context-std-error", exec_output_to_string(c->std_error));
4,971✔
2042
        if (r < 0)
4,971✔
2043
                return r;
2044

2045
        r = serialize_bool_elide(f, "exec-context-stdio-as-fds", c->stdio_as_fds);
4,971✔
2046
        if (r < 0)
4,971✔
2047
                return r;
2048

2049
        switch (c->std_input) {
4,971✔
2050

2051
        case EXEC_INPUT_NAMED_FD:
×
2052
                r = serialize_item(f, "exec-context-std-input-fd-name", c->stdio_fdname[STDIN_FILENO]);
×
2053
                break;
2054

2055
        case EXEC_INPUT_FILE:
×
2056
                r = serialize_item_escaped(f, "exec-context-std-input-file", c->stdio_file[STDIN_FILENO]);
×
2057
                break;
2058

2059
        case EXEC_INPUT_DATA:
×
2060
                r = serialize_item_base64mem(f, "exec-context-std-input-data", c->stdin_data, c->stdin_data_size);
×
2061
                break;
2062

2063
        default:
2064
                r = 0;
2065
        }
2066
        if (r < 0)
×
2067
                return r;
2068

2069
        switch (c->std_output) {
4,971✔
2070

2071
        case EXEC_OUTPUT_NAMED_FD:
×
2072
                r = serialize_item(f, "exec-context-std-output-fd-name", c->stdio_fdname[STDOUT_FILENO]);
×
2073
                break;
2074

2075
        case EXEC_OUTPUT_FILE:
2✔
2076
        case EXEC_OUTPUT_FILE_APPEND:
2077
        case EXEC_OUTPUT_FILE_TRUNCATE:
2078
                r = serialize_item_escaped(f, "exec-context-std-output-file", c->stdio_file[STDOUT_FILENO]);
2✔
2079
                break;
2080

2081
        default:
2082
                r = 0;
2083
        }
2084
        if (r < 0)
2✔
2085
                return r;
2086

2087

2088
        switch (c->std_error) {
4,971✔
2089

2090
        case EXEC_OUTPUT_NAMED_FD:
×
2091
                r = serialize_item(f, "exec-context-std-error-fd-name", c->stdio_fdname[STDERR_FILENO]);
×
2092
                break;
2093

2094
        case EXEC_OUTPUT_FILE:
×
2095
        case EXEC_OUTPUT_FILE_APPEND:
2096
        case EXEC_OUTPUT_FILE_TRUNCATE:
2097
                r = serialize_item_escaped(f, "exec-context-std-error-file", c->stdio_file[STDERR_FILENO]);
×
2098
                break;
2099

2100
        default:
2101
                r = 0;
2102
        }
2103
        if (r < 0)
×
2104
                return r;
2105

2106
        r = serialize_item(f, "exec-context-tty-path", c->tty_path);
4,971✔
2107
        if (r < 0)
4,971✔
2108
                return r;
2109

2110
        r = serialize_bool_elide(f, "exec-context-tty-reset", c->tty_reset);
4,971✔
2111
        if (r < 0)
4,971✔
2112
                return r;
2113

2114
        r = serialize_bool_elide(f, "exec-context-tty-vhangup", c->tty_vhangup);
4,971✔
2115
        if (r < 0)
4,971✔
2116
                return r;
2117

2118
        r = serialize_bool_elide(f, "exec-context-tty-vt-disallocate", c->tty_vt_disallocate);
4,971✔
2119
        if (r < 0)
4,971✔
2120
                return r;
2121

2122
        r = serialize_item_format(f, "exec-context-tty-rows", "%u", c->tty_rows);
4,971✔
2123
        if (r < 0)
4,971✔
2124
                return r;
2125

2126
        r = serialize_item_format(f, "exec-context-tty-columns", "%u", c->tty_cols);
4,971✔
2127
        if (r < 0)
4,971✔
2128
                return r;
2129

2130
        r = serialize_item_format(f, "exec-context-syslog-priority", "%i", c->syslog_priority);
4,971✔
2131
        if (r < 0)
4,971✔
2132
                return r;
2133

2134
        r = serialize_bool(f, "exec-context-syslog-level-prefix", c->syslog_level_prefix);
4,971✔
2135
        if (r < 0)
4,971✔
2136
                return r;
2137

2138
        r = serialize_item(f, "exec-context-syslog-identifier", c->syslog_identifier);
4,971✔
2139
        if (r < 0)
4,971✔
2140
                return r;
2141

2142
        /* This is also passed to executor as an argument. So, the information should be redundant in general.
2143
         * But, let's keep this as is for consistency with other elements of ExecContext. See exec_spawn(). */
2144
        r = serialize_item_format(f, "exec-context-log-level-max", "%d", c->log_level_max);
4,971✔
2145
        if (r < 0)
4,971✔
2146
                return r;
2147

2148
        if (c->log_ratelimit.interval > 0) {
4,971✔
2149
                r = serialize_usec(f, "exec-context-log-ratelimit-interval-usec", c->log_ratelimit.interval);
×
2150
                if (r < 0)
×
2151
                        return r;
2152
        }
2153

2154
        if (c->log_ratelimit.burst > 0) {
4,971✔
2155
                r = serialize_item_format(f, "exec-context-log-ratelimit-burst", "%u", c->log_ratelimit.burst);
×
2156
                if (r < 0)
×
2157
                        return r;
2158
        }
2159

2160
        r = serialize_string_set(f, "exec-context-log-filter-allowed-patterns", c->log_filter_allowed_patterns);
4,971✔
2161
        if (r < 0)
4,971✔
2162
                return r;
2163

2164
        r = serialize_string_set(f, "exec-context-log-filter-denied-patterns", c->log_filter_denied_patterns);
4,971✔
2165
        if (r < 0)
4,971✔
2166
                return r;
2167

2168
        FOREACH_ARRAY(field, c->log_extra_fields, c->n_log_extra_fields) {
7,338✔
2169
                r = serialize_item(f, "exec-context-log-extra-fields", field->iov_base);
2,367✔
2170
                if (r < 0)
2,367✔
2171
                        return r;
2172
        }
2173

2174
        r = serialize_item(f, "exec-context-log-namespace", c->log_namespace);
4,971✔
2175
        if (r < 0)
4,971✔
2176
                return r;
2177

2178
        if (c->secure_bits != 0) {
4,971✔
2179
                r = serialize_item_format(f, "exec-context-secure-bits", "%d", c->secure_bits);
×
2180
                if (r < 0)
×
2181
                        return r;
2182
        }
2183

2184
        if (c->capability_bounding_set != CAP_MASK_UNSET) {
4,971✔
2185
                r = serialize_item_format(f, "exec-context-capability-bounding-set", "%" PRIu64, c->capability_bounding_set);
4,971✔
2186
                if (r < 0)
4,971✔
2187
                        return r;
2188
        }
2189

2190
        if (c->capability_ambient_set != 0) {
4,971✔
2191
                r = serialize_item_format(f, "exec-context-capability-ambient-set", "%" PRIu64, c->capability_ambient_set);
97✔
2192
                if (r < 0)
97✔
2193
                        return r;
2194
        }
2195

2196
        if (c->user) {
4,971✔
2197
                r = serialize_item(f, "exec-context-user", c->user);
418✔
2198
                if (r < 0)
418✔
2199
                        return r;
2200
        }
2201

2202
        r = serialize_item(f, "exec-context-group", c->group);
4,971✔
2203
        if (r < 0)
4,971✔
2204
                return r;
2205

2206
        r = serialize_bool_elide(f, "exec-context-dynamic-user", c->dynamic_user);
4,971✔
2207
        if (r < 0)
4,971✔
2208
                return r;
2209

2210
        r = serialize_strv(f, "exec-context-supplementary-groups", c->supplementary_groups);
4,971✔
2211
        if (r < 0)
4,971✔
2212
                return r;
2213

2214
        r = serialize_item_tristate(f, "exec-context-set-login-environment", c->set_login_environment);
4,971✔
2215
        if (r < 0)
×
2216
                return r;
2217

2218
        r = serialize_item(f, "exec-context-pam-name", c->pam_name);
4,971✔
2219
        if (r < 0)
4,971✔
2220
                return r;
2221

2222
        r = serialize_strv(f, "exec-context-read-write-paths", c->read_write_paths);
4,971✔
2223
        if (r < 0)
4,971✔
2224
                return r;
2225

2226
        r = serialize_strv(f, "exec-context-read-only-paths", c->read_only_paths);
4,971✔
2227
        if (r < 0)
4,971✔
2228
                return r;
2229

2230
        r = serialize_strv(f, "exec-context-inaccessible-paths", c->inaccessible_paths);
4,971✔
2231
        if (r < 0)
4,971✔
2232
                return r;
2233

2234
        r = serialize_strv(f, "exec-context-exec-paths", c->exec_paths);
4,971✔
2235
        if (r < 0)
4,971✔
2236
                return r;
2237

2238
        r = serialize_strv(f, "exec-context-no-exec-paths", c->no_exec_paths);
4,971✔
2239
        if (r < 0)
4,971✔
2240
                return r;
2241

2242
        r = serialize_strv(f, "exec-context-exec-search-path", c->exec_search_path);
4,971✔
2243
        if (r < 0)
4,971✔
2244
                return r;
2245

2246
        r = serialize_item_format(f, "exec-context-mount-propagation-flag", "%lu", c->mount_propagation_flag);
4,971✔
2247
        if (r < 0)
4,971✔
2248
                return r;
2249

2250
        FOREACH_ARRAY(mount, c->bind_mounts, c->n_bind_mounts) {
5,071✔
2251
                _cleanup_free_ char *src_escaped = NULL, *dst_escaped = NULL;
100✔
2252

2253
                src_escaped = shell_escape(mount->source, ":" WHITESPACE);
100✔
2254
                if (!src_escaped)
100✔
2255
                        return log_oom_debug();
×
2256

2257
                dst_escaped = shell_escape(mount->destination, ":" WHITESPACE);
100✔
2258
                if (!dst_escaped)
100✔
2259
                        return log_oom_debug();
×
2260

2261
                r = serialize_item_format(f,
100✔
2262
                                          mount->read_only ? "exec-context-bind-read-only-path" : "exec-context-bind-path",
100✔
2263
                                          "%s%s:%s:%s",
2264
                                          mount->ignore_enoent ? "-" : "",
100✔
2265
                                          src_escaped,
2266
                                          dst_escaped,
2267
                                          mount->recursive ? "rbind" : "norbind");
100✔
2268
                if (r < 0)
100✔
2269
                        return r;
2270
        }
2271

2272
        FOREACH_ARRAY(tmpfs, c->temporary_filesystems, c->n_temporary_filesystems) {
4,993✔
2273
                _cleanup_free_ char *escaped = NULL;
22✔
2274

2275
                if (!isempty(tmpfs->options)) {
22✔
2276
                        escaped = shell_escape(tmpfs->options, ":");
×
2277
                        if (!escaped)
×
2278
                                return log_oom_debug();
×
2279
                }
2280

2281
                r = serialize_item_format(f, "exec-context-temporary-filesystems", "%s%s%s",
×
2282
                                          tmpfs->path,
2283
                                          isempty(escaped) ? "" : ":",
22✔
2284
                                          strempty(escaped));
2285
                if (r < 0)
22✔
2286
                        return r;
2287
        }
2288

2289
        r = serialize_item(f, "exec-context-utmp-id", c->utmp_id);
4,971✔
2290
        if (r < 0)
4,971✔
2291
                return r;
2292

2293
        r = serialize_item(f, "exec-context-utmp-mode", exec_utmp_mode_to_string(c->utmp_mode));
4,971✔
2294
        if (r < 0)
4,971✔
2295
                return r;
2296

2297
        r = serialize_bool_elide(f, "exec-context-no-new-privileges", c->no_new_privileges);
4,971✔
2298
        if (r < 0)
4,971✔
2299
                return r;
2300

2301
        if (c->selinux_context) {
4,971✔
2302
                r = serialize_item_format(f, "exec-context-selinux-context",
×
2303
                                          "%s%s",
2304
                                          c->selinux_context_ignore ? "-" : "",
×
2305
                                          c->selinux_context);
2306
                if (r < 0)
×
2307
                        return r;
2308
        }
2309

2310
        if (c->apparmor_profile) {
4,971✔
2311
                r = serialize_item_format(f, "exec-context-apparmor-profile",
×
2312
                                          "%s%s",
2313
                                          c->apparmor_profile_ignore ? "-" : "",
×
2314
                                          c->apparmor_profile);
2315
                if (r < 0)
×
2316
                        return r;
2317
        }
2318

2319
        if (c->smack_process_label) {
4,971✔
2320
                r = serialize_item_format(f, "exec-context-smack-process-label",
×
2321
                                          "%s%s",
2322
                                          c->smack_process_label_ignore ? "-" : "",
×
2323
                                          c->smack_process_label);
2324
                if (r < 0)
×
2325
                        return r;
2326
        }
2327

2328
        if (c->personality != PERSONALITY_INVALID) {
4,971✔
2329
                r = serialize_item(f, "exec-context-personality", personality_to_string(c->personality));
×
2330
                if (r < 0)
×
2331
                        return r;
2332
        }
2333

2334
        r = serialize_bool_elide(f, "exec-context-lock-personality", c->lock_personality);
4,971✔
2335
        if (r < 0)
4,971✔
2336
                return r;
2337

2338
#if HAVE_SECCOMP
2339
        if (!hashmap_isempty(c->syscall_filter)) {
4,971✔
2340
                void *errno_num, *id;
488✔
2341
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_filter) {
189,496✔
2342
                        r = serialize_item_format(f, "exec-context-syscall-filter", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
189,008✔
2343
                        if (r < 0)
189,008✔
2344
                                return r;
×
2345
                }
2346
        }
2347

2348
        if (!set_isempty(c->syscall_archs)) {
4,971✔
2349
                void *id;
485✔
2350
                SET_FOREACH(id, c->syscall_archs) {
970✔
2351
                        r = serialize_item_format(f, "exec-context-syscall-archs", "%u", PTR_TO_UINT(id) - 1);
485✔
2352
                        if (r < 0)
485✔
2353
                                return r;
×
2354
                }
2355
        }
2356

2357
        if (c->syscall_errno > 0) {
4,971✔
2358
                r = serialize_item_format(f, "exec-context-syscall-errno", "%d", c->syscall_errno);
4,971✔
2359
                if (r < 0)
4,971✔
2360
                        return r;
2361
        }
2362

2363
        r = serialize_bool_elide(f, "exec-context-syscall-allow-list", c->syscall_allow_list);
4,971✔
2364
        if (r < 0)
4,971✔
2365
                return r;
2366

2367
        if (!hashmap_isempty(c->syscall_log)) {
4,971✔
2368
                void *errno_num, *id;
×
2369
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_log) {
×
2370
                        r = serialize_item_format(f, "exec-context-syscall-log", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
×
2371
                        if (r < 0)
×
2372
                                return r;
×
2373
                }
2374
        }
2375

2376
        r = serialize_bool_elide(f, "exec-context-syscall-log-allow-list", c->syscall_log_allow_list);
4,971✔
2377
        if (r < 0)
4,971✔
2378
                return r;
2379
#endif
2380

2381
        if (c->restrict_namespaces != NAMESPACE_FLAGS_INITIAL) {
4,971✔
2382
                r = serialize_item_format(f, "exec-context-restrict-namespaces", "%lu", c->restrict_namespaces);
409✔
2383
                if (r < 0)
409✔
2384
                        return r;
2385
        }
2386

2387
        if (c->delegate_namespaces != NAMESPACE_FLAGS_INITIAL) {
4,971✔
2388
                r = serialize_item_format(f, "exec-context-delegate-namespaces", "%lu", c->delegate_namespaces);
45✔
2389
                if (r < 0)
45✔
2390
                        return r;
2391
        }
2392

2393
#if HAVE_LIBBPF
2394
        if (exec_context_restrict_filesystems_set(c)) {
4,971✔
2395
                char *fs;
×
2396
                SET_FOREACH(fs, c->restrict_filesystems) {
×
2397
                        r = serialize_item(f, "exec-context-restrict-filesystems", fs);
×
2398
                        if (r < 0)
×
2399
                                return r;
×
2400
                }
2401
        }
2402

2403
        r = serialize_bool_elide(f, "exec-context-restrict-filesystems-allow-list", c->restrict_filesystems_allow_list);
4,971✔
2404
        if (r < 0)
4,971✔
2405
                return r;
2406
#endif
2407

2408
        if (!set_isempty(c->address_families)) {
4,971✔
2409
                void *afp;
484✔
2410

2411
                SET_FOREACH(afp, c->address_families) {
2,018✔
2412
                        int af = PTR_TO_INT(afp);
1,534✔
2413

2414
                        if (af <= 0 || af >= af_max())
1,534✔
2415
                                continue;
×
2416

2417
                        r = serialize_item_format(f, "exec-context-address-families", "%d", af);
1,534✔
2418
                        if (r < 0)
1,534✔
2419
                                return r;
×
2420
                }
2421
        }
2422

2423
        r = serialize_bool_elide(f, "exec-context-address-families-allow-list", c->address_families_allow_list);
4,971✔
2424
        if (r < 0)
4,971✔
2425
                return r;
2426

2427
        r = serialize_item(f, "exec-context-user-namespace-path", c->user_namespace_path);
4,971✔
2428
        if (r < 0)
4,971✔
2429
                return r;
2430

2431
        r = serialize_item(f, "exec-context-network-namespace-path", c->network_namespace_path);
4,971✔
2432
        if (r < 0)
4,971✔
2433
                return r;
2434

2435
        r = serialize_item(f, "exec-context-ipc-namespace-path", c->ipc_namespace_path);
4,971✔
2436
        if (r < 0)
4,971✔
2437
                return r;
2438

2439
        FOREACH_ARRAY(mount, c->mount_images, c->n_mount_images) {
4,973✔
2440
                _cleanup_free_ char *s = NULL, *source_escaped = NULL, *dest_escaped = NULL;
2✔
2441

2442
                source_escaped = shell_escape(mount->source, WHITESPACE);
2✔
2443
                if (!source_escaped)
2✔
2444
                        return log_oom_debug();
×
2445

2446
                dest_escaped = shell_escape(mount->destination, WHITESPACE);
2✔
2447
                if (!dest_escaped)
2✔
2448
                        return log_oom_debug();
×
2449

2450
                s = strjoin(mount->ignore_enoent ? "-" : "",
4✔
2451
                            source_escaped,
2452
                            " ",
2453
                            dest_escaped);
2454
                if (!s)
2✔
2455
                        return log_oom_debug();
×
2456

2457
                r = serialize_mount_options(mount->mount_options, &s);
2✔
2458
                if (r < 0)
2✔
2459
                        return r;
2460

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

2466
        FOREACH_ARRAY(mount, c->extension_images, c->n_extension_images) {
4,991✔
2467
                _cleanup_free_ char *s = NULL, *source_escaped = NULL;
20✔
2468

2469
                source_escaped = shell_escape(mount->source, ":" WHITESPACE);
20✔
2470
                if (!source_escaped)
20✔
2471
                        return log_oom_debug();
×
2472

2473
                s = strjoin(mount->ignore_enoent ? "-" : "",
40✔
2474
                            source_escaped);
2475
                if (!s)
20✔
2476
                        return log_oom_debug();
×
2477

2478
                r = serialize_mount_options(mount->mount_options, &s);
20✔
2479
                if (r < 0)
20✔
2480
                        return r;
2481

2482
                r = serialize_item(f, "exec-context-extension-image", s);
20✔
2483
                if (r < 0)
20✔
2484
                        return r;
2485
        }
2486

2487
        r = serialize_strv(f, "exec-context-extension-directories", c->extension_directories);
4,971✔
2488
        if (r < 0)
4,971✔
2489
                return r;
2490

2491
        ExecSetCredential *sc;
4,971✔
2492
        HASHMAP_FOREACH(sc, c->set_credentials) {
4,981✔
2493
                _cleanup_free_ char *data = NULL;
10✔
2494

2495
                if (base64mem(sc->data, sc->size, &data) < 0)
10✔
2496
                        return log_oom_debug();
×
2497

2498
                r = serialize_item_format(f, "exec-context-set-credentials", "%s %s %s", sc->id, data, yes_no(sc->encrypted));
20✔
2499
                if (r < 0)
10✔
2500
                        return r;
2501
        }
2502

2503
        ExecLoadCredential *lc;
4,971✔
2504
        HASHMAP_FOREACH(lc, c->load_credentials) {
4,982✔
2505
                r = serialize_item_format(f, "exec-context-load-credentials", "%s %s %s", lc->id, lc->path, yes_no(lc->encrypted));
21✔
2506
                if (r < 0)
11✔
2507
                        return r;
×
2508
        }
2509

2510
        ExecImportCredential *ic;
4,971✔
2511
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
6,309✔
2512
                r = serialize_item_format(f, "exec-context-import-credentials", "%s%s%s",
2,614✔
2513
                                          ic->glob,
2514
                                          ic->rename ? " " : "",
2515
                                          strempty(ic->rename));
1,338✔
2516
                if (r < 0)
1,338✔
2517
                        return r;
×
2518
        }
2519

2520
        r = serialize_image_policy(f, "exec-context-root-image-policy", c->root_image_policy);
4,971✔
2521
        if (r < 0)
4,971✔
2522
                return r;
2523

2524
        r = serialize_image_policy(f, "exec-context-mount-image-policy", c->mount_image_policy);
4,971✔
2525
        if (r < 0)
4,971✔
2526
                return r;
2527

2528
        r = serialize_image_policy(f, "exec-context-extension-image-policy", c->extension_image_policy);
4,971✔
2529
        if (r < 0)
4,971✔
2530
                return r;
2531

2532
        fputc('\n', f); /* End marker */
4,971✔
2533

2534
        return 0;
2535
}
2536

2537
static int exec_context_deserialize(ExecContext *c, FILE *f) {
12,789✔
2538
        int r;
12,789✔
2539

2540
        assert(f);
12,789✔
2541

2542
        if (!c)
12,789✔
2543
                return 0;
2544

2545
        for (;;) {
1,226,166✔
2546
                _cleanup_free_ char *l = NULL;
1,213,377✔
2547
                const char *val;
1,226,166✔
2548

2549
                r = deserialize_read_line(f, &l);
1,226,166✔
2550
                if (r < 0)
1,226,166✔
2551
                        return r;
2552
                if (r == 0) /* eof or end marker */
1,226,166✔
2553
                        break;
2554

2555
                if ((val = startswith(l, "exec-context-environment="))) {
1,213,377✔
2556
                        r = deserialize_strv(val, &c->environment);
4,798✔
2557
                        if (r < 0)
4,798✔
2558
                                return r;
2559
                } else if ((val = startswith(l, "exec-context-environment-files="))) {
1,208,579✔
2560
                        r = deserialize_strv(val, &c->environment_files);
380✔
2561
                        if (r < 0)
380✔
2562
                                return r;
2563
                } else if ((val = startswith(l, "exec-context-pass-environment="))) {
1,208,199✔
2564
                        r = deserialize_strv(val, &c->pass_environment);
346✔
2565
                        if (r < 0)
346✔
2566
                                return r;
2567
                } else if ((val = startswith(l, "exec-context-unset-environment="))) {
1,207,853✔
2568
                        r = deserialize_strv(val, &c->unset_environment);
1,103✔
2569
                        if (r < 0)
1,103✔
2570
                                return r;
2571
                } else if ((val = startswith(l, "exec-context-working-directory="))) {
1,206,750✔
2572
                        ssize_t k;
843✔
2573
                        char *p;
843✔
2574

2575
                        k = cunescape(val, 0, &p);
843✔
2576
                        if (k < 0)
843✔
2577
                                return k;
×
2578
                        free_and_replace(c->working_directory, p);
843✔
2579
                } else if ((val = startswith(l, "exec-context-root-directory="))) {
1,205,907✔
2580
                        ssize_t k;
7✔
2581
                        char *p;
7✔
2582

2583
                        k = cunescape(val, 0, &p);
7✔
2584
                        if (k < 0)
7✔
2585
                                return k;
×
2586
                        free_and_replace(c->root_directory, p);
7✔
2587
                } else if ((val = startswith(l, "exec-context-root-image="))) {
1,205,900✔
2588
                        ssize_t k;
11✔
2589
                        char *p;
11✔
2590

2591
                        k = cunescape(val, 0, &p);
11✔
2592
                        if (k < 0)
11✔
2593
                                return k;
×
2594
                        free_and_replace(c->root_image, p);
11✔
2595
                } else if ((val = startswith(l, "exec-context-root-image-options="))) {
1,205,889✔
2596
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
2597

2598
                        r = deserialize_mount_options(val, &options);
1✔
2599
                        if (r < 0)
1✔
2600
                                return r;
×
2601

2602
                        free_and_replace_full(c->root_image_options, options, mount_options_free_all);
1✔
2603
                } else if ((val = startswith(l, "exec-context-root-verity="))) {
1,205,888✔
2604
                        r = free_and_strdup(&c->root_verity, val);
×
2605
                        if (r < 0)
×
2606
                                return r;
2607
                } else if ((val = startswith(l, "exec-context-root-hash-path="))) {
1,205,888✔
2608
                        r = free_and_strdup(&c->root_hash_path, val);
1✔
2609
                        if (r < 0)
1✔
2610
                                return r;
2611
                } else if ((val = startswith(l, "exec-context-root-hash-sig-path="))) {
1,205,887✔
2612
                        r = free_and_strdup(&c->root_hash_sig_path, val);
1✔
2613
                        if (r < 0)
1✔
2614
                                return r;
2615
                } else if ((val = startswith(l, "exec-context-root-hash="))) {
1,205,886✔
2616
                        iovec_done(&c->root_hash);
4✔
2617
                        r = unhexmem(val, &c->root_hash.iov_base, &c->root_hash.iov_len);
4✔
2618
                        if (r < 0)
4✔
2619
                                return r;
2620
                } else if ((val = startswith(l, "exec-context-root-hash-sig="))) {
1,205,882✔
2621
                        iovec_done(&c->root_hash_sig);
×
2622
                        r = unbase64mem(val, &c->root_hash_sig.iov_base, &c->root_hash_sig.iov_len);
×
2623
                        if (r < 0)
×
2624
                                return r;
2625
                } else if ((val = startswith(l, "exec-context-root-ephemeral="))) {
1,205,882✔
2626
                        r = parse_boolean(val);
×
2627
                        if (r < 0)
×
2628
                                return r;
2629
                        c->root_ephemeral = r;
×
2630
                } else if ((val = startswith(l, "exec-context-root-mstack="))) {
1,205,882✔
2631
                        ssize_t k;
4✔
2632
                        char *p;
4✔
2633

2634
                        k = cunescape(val, 0, &p);
4✔
2635
                        if (k < 0)
4✔
2636
                                return k;
×
2637
                        free_and_replace(c->root_mstack, p);
4✔
2638
                } else if ((val = startswith(l, "exec-context-umask="))) {
1,205,878✔
2639
                        r = parse_mode(val, &c->umask);
12,789✔
2640
                        if (r < 0)
12,789✔
2641
                                return r;
2642
                } else if ((val = startswith(l, "exec-context-private-non-blocking="))) {
1,193,089✔
2643
                        r = parse_boolean(val);
×
2644
                        if (r < 0)
×
2645
                                return r;
2646
                        c->non_blocking = r;
×
2647
                } else if ((val = startswith(l, "exec-context-private-mounts="))) {
1,193,089✔
2648
                        r = safe_atoi(val, &c->private_mounts);
153✔
2649
                        if (r < 0)
153✔
2650
                                return r;
2651
                } else if ((val = startswith(l, "exec-context-mount-api-vfs="))) {
1,192,936✔
2652
                        r = safe_atoi(val, &c->mount_apivfs);
29✔
2653
                        if (r < 0)
29✔
2654
                                return r;
2655
                } else if ((val = startswith(l, "exec-context-bind-log-sockets="))) {
1,192,907✔
2656
                        r = safe_atoi(val, &c->bind_log_sockets);
2✔
2657
                        if (r < 0)
2✔
2658
                                return r;
2659
                } else if ((val = startswith(l, "exec-context-memory-ksm="))) {
1,192,905✔
2660
                        r = safe_atoi(val, &c->memory_ksm);
×
2661
                        if (r < 0)
×
2662
                                return r;
2663
                } else if ((val = startswith(l, "exec-context-memory-thp="))) {
1,192,905✔
2664
                        c->memory_thp = exec_memory_thp_from_string(val);
12,789✔
2665
                        if (c->memory_thp < 0)
12,789✔
2666
                                return c->memory_thp;
2667
                } else if ((val = startswith(l, "exec-context-private-tmp="))) {
1,180,116✔
2668
                        c->private_tmp = private_tmp_from_string(val);
12,789✔
2669
                        if (c->private_tmp < 0)
12,789✔
2670
                                return c->private_tmp;
2671
                } else if ((val = startswith(l, "exec-context-private-var-tmp="))) {
1,167,327✔
2672
                        c->private_var_tmp = private_tmp_from_string(val);
12,789✔
2673
                        if (c->private_var_tmp < 0)
12,789✔
2674
                                return c->private_var_tmp;
2675
                } else if ((val = startswith(l, "exec-context-private-devices="))) {
1,154,538✔
2676
                        r = parse_boolean(val);
552✔
2677
                        if (r < 0)
552✔
2678
                                return r;
2679
                        c->private_devices = r;
552✔
2680
                } else if ((val = startswith(l, "exec-context-protect-kernel-tunables="))) {
1,153,986✔
2681
                        r = parse_boolean(val);
368✔
2682
                        if (r < 0)
368✔
2683
                                return r;
2684
                        c->protect_kernel_tunables = r;
368✔
2685
                } else if ((val = startswith(l, "exec-context-protect-kernel-modules="))) {
1,153,618✔
2686
                        r = parse_boolean(val);
1,215✔
2687
                        if (r < 0)
1,215✔
2688
                                return r;
2689
                        c->protect_kernel_modules = r;
1,215✔
2690
                } else if ((val = startswith(l, "exec-context-protect-kernel-logs="))) {
1,152,403✔
2691
                        r = parse_boolean(val);
1,215✔
2692
                        if (r < 0)
1,215✔
2693
                                return r;
2694
                        c->protect_kernel_logs = r;
1,215✔
2695
                } else if ((val = startswith(l, "exec-context-protect-clock="))) {
1,151,188✔
2696
                        r = parse_boolean(val);
973✔
2697
                        if (r < 0)
973✔
2698
                                return r;
2699
                        c->protect_clock = r;
973✔
2700
                } else if ((val = startswith(l, "exec-context-protect-control-groups="))) {
1,150,215✔
2701
                        r = protect_control_groups_from_string(val);
12,789✔
2702
                        if (r < 0)
12,789✔
2703
                                return r;
2704
                        c->protect_control_groups = r;
12,789✔
2705
                } else if ((val = startswith(l, "exec-context-private-network="))) {
1,137,426✔
2706
                        r = parse_boolean(val);
112✔
2707
                        if (r < 0)
112✔
2708
                                return r;
2709
                        c->private_network = r;
112✔
2710
                } else if ((val = startswith(l, "exec-context-private-users="))) {
1,137,314✔
2711
                        c->private_users = private_users_from_string(val);
12,789✔
2712
                        if (c->private_users < 0)
12,789✔
2713
                                return -EINVAL;
2714
                } else if ((val = startswith(l, "exec-context-private-ipc="))) {
1,124,525✔
2715
                        r = parse_boolean(val);
23✔
2716
                        if (r < 0)
23✔
2717
                                return r;
2718
                        c->private_ipc = r;
23✔
2719
                } else if ((val = startswith(l, "exec-context-private-pids="))) {
1,124,502✔
2720
                        c->private_pids = private_pids_from_string(val);
12,789✔
2721
                        if (c->private_pids < 0)
12,789✔
2722
                                return -EINVAL;
2723
                } else if ((val = startswith(l, "exec-context-remove-ipc="))) {
1,111,713✔
2724
                        r = parse_boolean(val);
59✔
2725
                        if (r < 0)
59✔
2726
                                return r;
2727
                        c->remove_ipc = r;
59✔
2728
                } else if ((val = startswith(l, "exec-context-protect-home="))) {
1,111,654✔
2729
                        c->protect_home = protect_home_from_string(val);
12,789✔
2730
                        if (c->protect_home < 0)
12,789✔
2731
                                return -EINVAL;
2732
                } else if ((val = startswith(l, "exec-context-protect-system="))) {
1,098,865✔
2733
                        c->protect_system = protect_system_from_string(val);
12,789✔
2734
                        if (c->protect_system < 0)
12,789✔
2735
                                return -EINVAL;
2736
                } else if ((val = startswith(l, "exec-context-same-pgrp="))) {
1,086,076✔
2737
                        r = parse_boolean(val);
857✔
2738
                        if (r < 0)
857✔
2739
                                return r;
2740
                        c->same_pgrp = r;
857✔
2741
                } else if ((val = startswith(l, "exec-context-non-blocking="))) {
1,085,219✔
2742
                        r = parse_boolean(val);
×
2743
                        if (r < 0)
×
2744
                                return r;
2745
                        c->non_blocking = r;
×
2746
                } else if ((val = startswith(l, "exec-context-ignore-sigpipe="))) {
1,085,219✔
2747
                        r = parse_boolean(val);
12,789✔
2748
                        if (r < 0)
12,789✔
2749
                                return r;
2750
                        c->ignore_sigpipe = r;
12,789✔
2751
                } else if ((val = startswith(l, "exec-context-memory-deny-write-execute="))) {
1,072,430✔
2752
                        r = parse_boolean(val);
1,839✔
2753
                        if (r < 0)
1,839✔
2754
                                return r;
2755
                        c->memory_deny_write_execute = r;
1,839✔
2756
                } else if ((val = startswith(l, "exec-context-restrict-realtime="))) {
1,070,591✔
2757
                        r = parse_boolean(val);
1,835✔
2758
                        if (r < 0)
1,835✔
2759
                                return r;
2760
                        c->restrict_realtime = r;
1,835✔
2761
                } else if ((val = startswith(l, "exec-context-restrict-suid-sgid="))) {
1,068,756✔
2762
                        r = parse_boolean(val);
1,509✔
2763
                        if (r < 0)
1,509✔
2764
                                return r;
2765
                        c->restrict_suid_sgid = r;
1,509✔
2766
                } else if ((val = startswith(l, "exec-context-keyring-mode="))) {
1,067,247✔
2767
                        c->keyring_mode = exec_keyring_mode_from_string(val);
12,789✔
2768
                        if (c->keyring_mode < 0)
12,789✔
2769
                                return -EINVAL;
2770
                } else if ((val = startswith(l, "exec-context-protect-hostname="))) {
1,054,458✔
2771
                        c->protect_hostname = protect_hostname_from_string(val);
12,789✔
2772
                        if (c->protect_hostname < 0)
12,789✔
2773
                                return -EINVAL;
2774
                } else if ((val = startswith(l, "exec-context-private-hostname="))) {
1,041,669✔
2775
                        r = free_and_strdup(&c->private_hostname, val);
5✔
2776
                        if (r < 0)
5✔
2777
                                return r;
2778
                } else if ((val = startswith(l, "exec-context-protect-proc="))) {
1,041,664✔
2779
                        c->protect_proc = protect_proc_from_string(val);
12,789✔
2780
                        if (c->protect_proc < 0)
12,789✔
2781
                                return -EINVAL;
2782
                } else if ((val = startswith(l, "exec-context-proc-subset="))) {
1,028,875✔
2783
                        c->proc_subset = proc_subset_from_string(val);
12,789✔
2784
                        if (c->proc_subset < 0)
12,789✔
2785
                                return -EINVAL;
2786
                } else if ((val = startswith(l, "exec-context-private-bpf="))) {
1,016,086✔
2787
                        c->private_bpf = private_bpf_from_string(val);
12,789✔
2788
                        if (c->private_bpf < 0)
12,789✔
2789
                                return -EINVAL;
2790
                } else if ((val = startswith(l, "exec-context-bpf-delegate-commands="))) {
1,003,297✔
2791
                        r = safe_atoux64(val, &c->bpf_delegate_commands);
2✔
2792
                        if (r < 0)
2✔
2793
                                return r;
2794
                } else if ((val = startswith(l, "exec-context-bpf-delegate-maps="))) {
1,003,295✔
2795
                        r = safe_atoux64(val, &c->bpf_delegate_maps);
1✔
2796
                        if (r < 0)
1✔
2797
                                return r;
2798
                } else if ((val = startswith(l, "exec-context-bpf-delegate-programs="))) {
1,003,294✔
2799
                        r = safe_atoux64(val, &c->bpf_delegate_programs);
1✔
2800
                        if (r < 0)
1✔
2801
                                return r;
2802
                } else if ((val = startswith(l, "exec-context-bpf-delegate-attachments="))) {
1,003,293✔
2803
                        r = safe_atoux64(val, &c->bpf_delegate_attachments);
1✔
2804
                        if (r < 0)
1✔
2805
                                return r;
2806
                } else if ((val = startswith(l, "exec-context-runtime-directory-preserve-mode="))) {
1,003,292✔
2807
                        c->runtime_directory_preserve_mode = exec_preserve_mode_from_string(val);
12,789✔
2808
                        if (c->runtime_directory_preserve_mode < 0)
12,789✔
2809
                                return -EINVAL;
2810
                } else if ((val = startswith(l, "exec-context-directories-"))) {
990,503✔
2811
                        _cleanup_free_ char *type = NULL, *mode = NULL;
×
2812
                        ExecDirectoryType dt;
63,945✔
2813

2814
                        r = extract_many_words(&val, "= ", 0, &type, &mode);
63,945✔
2815
                        if (r < 0)
63,945✔
2816
                                return r;
2817
                        if (r == 0 || !mode)
63,945✔
2818
                                return -EINVAL;
2819

2820
                        dt = exec_directory_type_from_string(type);
63,945✔
2821
                        if (dt < 0)
63,945✔
2822
                                return dt;
2823

2824
                        r = parse_mode(mode, &c->directories[dt].mode);
63,945✔
2825
                        if (r < 0)
63,945✔
2826
                                return r;
2827

2828
                        for (;;) {
67,127✔
2829
                                _cleanup_free_ char *tuple = NULL, *path = NULL, *only_create = NULL, *read_only = NULL;
67,020✔
2830
                                ExecDirectoryFlags exec_directory_flags = 0;
67,127✔
2831
                                const char *p;
67,127✔
2832

2833
                                /* Use EXTRACT_UNESCAPE_RELAX here, as we unescape the colons in subsequent calls */
2834
                                r = extract_first_word(&val, &tuple, WHITESPACE, EXTRACT_UNESCAPE_SEPARATORS|EXTRACT_UNESCAPE_RELAX);
67,127✔
2835
                                if (r < 0)
67,127✔
2836
                                        return r;
2837
                                if (r == 0)
67,127✔
2838
                                        break;
2839

2840
                                p = tuple;
3,182✔
2841
                                r = extract_many_words(&p, ":", EXTRACT_UNESCAPE_SEPARATORS, &path, &only_create, &read_only);
3,182✔
2842
                                if (r < 0)
3,182✔
2843
                                        return r;
2844
                                if (r < 2)
3,182✔
2845
                                        continue;
×
2846

2847
                                r = parse_boolean(only_create);
3,182✔
2848
                                if (r < 0)
3,182✔
2849
                                        return r;
2850
                                if (r > 0)
3,182✔
2851
                                        exec_directory_flags |= EXEC_DIRECTORY_ONLY_CREATE;
5✔
2852

2853
                                r = parse_boolean(read_only);
3,182✔
2854
                                if (r < 0)
3,182✔
2855
                                        return r;
2856
                                if (r > 0)
3,182✔
2857
                                        exec_directory_flags |= EXEC_DIRECTORY_READ_ONLY;
50✔
2858

2859
                                r = exec_directory_add(&c->directories[dt], path, /* symlink= */ NULL, exec_directory_flags);
3,182✔
2860
                                if (r < 0)
3,182✔
2861
                                        return r;
2862

2863
                                if (isempty(p))
3,182✔
2864
                                        continue;
3,075✔
2865

2866
                                for (;;) {
385✔
2867
                                        _cleanup_free_ char *link = NULL;
246✔
2868

2869
                                        r = extract_first_word(&p, &link, ":", EXTRACT_UNESCAPE_SEPARATORS);
246✔
2870
                                        if (r < 0)
246✔
2871
                                                return r;
2872
                                        if (r == 0)
246✔
2873
                                                break;
2874

2875
                                        r = strv_consume(&c->directories[dt].items[c->directories[dt].n_items - 1].symlinks, TAKE_PTR(link));
139✔
2876
                                        if (r < 0)
139✔
2877
                                                return r;
2878
                                }
2879
                        }
2880
                } else if ((val = startswith(l, "exec-context-quota-accounting-directories-"))) {
926,558✔
2881
                        _cleanup_free_ char *type = NULL, *quota_accounting = NULL;
×
2882
                        ExecDirectoryType dt;
×
2883

2884
                        r = split_pair(val, "=", &type, &quota_accounting);
×
2885
                        if (r < 0)
×
2886
                                return r;
2887

2888
                        dt = exec_directory_type_from_string(type);
×
2889
                        if (dt < 0)
×
2890
                                return dt;
2891

2892
                        r = parse_boolean(quota_accounting);
×
2893
                        if (r < 0)
×
2894
                                return r;
2895

2896
                        c->directories[dt].exec_quota.quota_accounting = r;
×
2897
                } else if ((val = startswith(l, "exec-context-quota-directories-"))) {
926,558✔
2898
                        _cleanup_free_ char *type = NULL, *quota_info = NULL, *quota_absolute = NULL, *quota_scale = NULL;
×
2899
                        ExecDirectoryType dt;
×
2900

2901
                        r = split_pair(val, "=", &type, &quota_info);
×
2902
                        if (r < 0)
×
2903
                                return r;
2904

2905
                        r = split_pair(quota_info, " ", &quota_absolute, &quota_scale);
×
2906
                        if (r < 0)
×
2907
                                return r;
2908

2909
                        dt = exec_directory_type_from_string(type);
×
2910
                        if (dt < 0)
×
2911
                                return dt;
2912

2913
                        r = safe_atou64(quota_absolute, &c->directories[dt].exec_quota.quota_absolute);
×
2914
                        if (r < 0)
×
2915
                               return r;
2916

2917
                        r = safe_atou32(quota_scale, &c->directories[dt].exec_quota.quota_scale);
×
2918
                        if (r < 0)
×
2919
                               return r;
2920

2921
                        c->directories[dt].exec_quota.quota_enforce = true;
×
2922
                } else if ((val = startswith(l, "exec-context-timeout-clean-usec="))) {
926,558✔
2923
                        r = deserialize_usec(val, &c->timeout_clean_usec);
×
2924
                        if (r < 0)
×
2925
                                return r;
2926
                } else if ((val = startswith(l, "exec-context-nice="))) {
926,558✔
2927
                        r = safe_atoi(val, &c->nice);
21✔
2928
                        if (r < 0)
21✔
2929
                                return r;
2930
                        c->nice_set = true;
21✔
2931
                } else if ((val = startswith(l, "exec-context-working-directory-missing-ok="))) {
926,537✔
2932
                        r = parse_boolean(val);
782✔
2933
                        if (r < 0)
782✔
2934
                                return r;
2935
                        c->working_directory_missing_ok = r;
782✔
2936
                } else if ((val = startswith(l, "exec-context-working-directory-home="))) {
925,755✔
2937
                        r = parse_boolean(val);
241✔
2938
                        if (r < 0)
241✔
2939
                                return r;
2940
                        c->working_directory_home = r;
241✔
2941
                } else if ((val = startswith(l, "exec-context-oom-score-adjust="))) {
925,514✔
2942
                        r = safe_atoi(val, &c->oom_score_adjust);
1,213✔
2943
                        if (r < 0)
1,213✔
2944
                                return r;
2945
                        c->oom_score_adjust_set = true;
1,213✔
2946
                } else if ((val = startswith(l, "exec-context-coredump-filter="))) {
924,301✔
2947
                        r = safe_atoux64(val, &c->coredump_filter);
2✔
2948
                        if (r < 0)
2✔
2949
                                return r;
2950
                        c->coredump_filter_set = true;
2✔
2951
                } else if ((val = startswith(l, "exec-context-limit-"))) {
924,299✔
2952
                        _cleanup_free_ struct rlimit *rlimit = NULL;
×
2953
                        _cleanup_free_ char *limit = NULL;
25,573✔
2954
                        int type;
25,573✔
2955

2956
                        r = extract_first_word(&val, &limit, "=", 0);
25,573✔
2957
                        if (r < 0)
25,573✔
2958
                                return r;
2959
                        if (r == 0 || !val)
25,573✔
2960
                                return -EINVAL;
2961

2962
                        type = rlimit_from_string(limit);
25,573✔
2963
                        if (type < 0)
25,573✔
2964
                                return -EINVAL;
2965

2966
                        if (!c->rlimit[type]) {
25,573✔
2967
                                rlimit = new0(struct rlimit, 1);
25,573✔
2968
                                if (!rlimit)
25,573✔
2969
                                        return log_oom_debug();
×
2970

2971
                                r = rlimit_parse(type, val, rlimit);
25,573✔
2972
                                if (r < 0)
25,573✔
2973
                                        return r;
2974

2975
                                c->rlimit[type] = TAKE_PTR(rlimit);
25,573✔
2976
                        } else {
2977
                                r = rlimit_parse(type, val, c->rlimit[type]);
×
2978
                                if (r < 0)
×
2979
                                        return r;
2980
                        }
2981
                } else if ((val = startswith(l, "exec-context-ioprio="))) {
898,726✔
2982
                        r = safe_atoi(val, &c->ioprio);
16✔
2983
                        if (r < 0)
16✔
2984
                                return r;
2985
                        c->ioprio_is_set = true;
16✔
2986
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-policy="))) {
898,710✔
2987
                        c->cpu_sched_policy = sched_policy_from_string(val);
×
2988
                        if (c->cpu_sched_policy < 0)
×
2989
                                return -EINVAL;
2990
                        c->cpu_sched_set = true;
×
2991
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-priority="))) {
898,710✔
2992
                        r = safe_atoi(val, &c->cpu_sched_priority);
×
2993
                        if (r < 0)
×
2994
                                return r;
2995
                        c->cpu_sched_set = true;
×
2996
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-reset-on-fork="))) {
898,710✔
2997
                        r = parse_boolean(val);
×
2998
                        if (r < 0)
×
2999
                                return r;
3000
                        c->cpu_sched_reset_on_fork = r;
×
3001
                        c->cpu_sched_set = true;
×
3002
                } else if ((val = startswith(l, "exec-context-cpu-affinity="))) {
898,710✔
3003
                        if (c->cpu_set.set)
×
3004
                                return -EINVAL; /* duplicated */
3005

3006
                        r = parse_cpu_set(val, &c->cpu_set);
×
3007
                        if (r < 0)
×
3008
                                return r;
3009
                } else if ((val = startswith(l, "exec-context-numa-mask="))) {
898,710✔
3010
                        if (c->numa_policy.nodes.set)
25✔
3011
                                return -EINVAL; /* duplicated */
3012

3013
                        r = parse_cpu_set(val, &c->numa_policy.nodes);
25✔
3014
                        if (r < 0)
25✔
3015
                                return r;
3016
                } else if ((val = startswith(l, "exec-context-numa-policy="))) {
898,685✔
3017
                        r = safe_atoi(val, &c->numa_policy.type);
25✔
3018
                        if (r < 0)
25✔
3019
                                return r;
3020
                } else if ((val = startswith(l, "exec-context-cpu-affinity-from-numa="))) {
898,660✔
3021
                        r = parse_boolean(val);
2✔
3022
                        if (r < 0)
2✔
3023
                                return r;
3024
                        c->cpu_affinity_from_numa = r;
2✔
3025
                } else if ((val = startswith(l, "exec-context-timer-slack-nsec="))) {
898,658✔
3026
                        r = deserialize_usec(val, (usec_t *)&c->timer_slack_nsec);
×
3027
                        if (r < 0)
×
3028
                                return r;
3029
                } else if ((val = startswith(l, "exec-context-root-directory-as-fd="))) {
898,658✔
3030
                        r = parse_boolean(val);
2✔
3031
                        if (r < 0)
2✔
3032
                                return r;
3033
                        c->root_directory_as_fd = r;
2✔
3034
                } else if ((val = startswith(l, "exec-context-std-input="))) {
898,656✔
3035
                        c->std_input = exec_input_from_string(val);
12,789✔
3036
                        if (c->std_input < 0)
12,789✔
3037
                                return c->std_input;
3038
                } else if ((val = startswith(l, "exec-context-std-output="))) {
885,867✔
3039
                        c->std_output = exec_output_from_string(val);
12,789✔
3040
                        if (c->std_output < 0)
12,789✔
3041
                                return c->std_output;
3042
                } else if ((val = startswith(l, "exec-context-std-error="))) {
873,078✔
3043
                        c->std_error = exec_output_from_string(val);
12,789✔
3044
                        if (c->std_error < 0)
12,789✔
3045
                                return c->std_error;
3046
                } else if ((val = startswith(l, "exec-context-stdio-as-fds="))) {
860,289✔
3047
                        r = parse_boolean(val);
618✔
3048
                        if (r < 0)
618✔
3049
                                return r;
3050
                        c->stdio_as_fds = r;
618✔
3051
                } else if ((val = startswith(l, "exec-context-std-input-data="))) {
859,671✔
3052
                        if (c->stdin_data)
1✔
3053
                                return -EINVAL; /* duplicated */
3054

3055
                        r = unbase64mem(val, &c->stdin_data, &c->stdin_data_size);
1✔
3056
                        if (r < 0)
1✔
3057
                                return r;
3058
                } else if ((val = startswith(l, "exec-context-std-input-fd-name="))) {
859,670✔
3059
                        r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], val);
×
3060
                        if (r < 0)
×
3061
                                return r;
3062
                } else if ((val = startswith(l, "exec-context-std-output-fd-name="))) {
859,670✔
3063
                        r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], val);
×
3064
                        if (r < 0)
×
3065
                                return r;
3066
                } else if ((val = startswith(l, "exec-context-std-error-fd-name="))) {
859,670✔
3067
                        r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], val);
×
3068
                        if (r < 0)
×
3069
                                return r;
3070
                } else if ((val = startswith(l, "exec-context-std-input-file="))) {
859,670✔
3071
                        ssize_t k;
×
3072
                        char *p;
×
3073

3074
                        k = cunescape(val, 0, &p);
×
3075
                        if (k < 0)
×
3076
                                return k;
×
3077

3078
                        free_and_replace(c->stdio_file[STDIN_FILENO], p);
×
3079

3080
                } else if ((val = startswith(l, "exec-context-std-output-file="))) {
859,670✔
3081
                        ssize_t k;
58✔
3082
                        char *p;
58✔
3083

3084
                        k = cunescape(val, 0, &p);
58✔
3085
                        if (k < 0)
58✔
3086
                                return k;
×
3087

3088
                        free_and_replace(c->stdio_file[STDOUT_FILENO], p);
58✔
3089

3090
                } else if ((val = startswith(l, "exec-context-std-error-file="))) {
859,612✔
3091
                        ssize_t k;
54✔
3092
                        char *p;
54✔
3093

3094
                        k = cunescape(val, 0, &p);
54✔
3095
                        if (k < 0)
54✔
3096
                                return k;
×
3097

3098
                        free_and_replace(c->stdio_file[STDERR_FILENO], p);
54✔
3099

3100
                } else if ((val = startswith(l, "exec-context-tty-path="))) {
859,558✔
3101
                        r = free_and_strdup(&c->tty_path, val);
154✔
3102
                        if (r < 0)
154✔
3103
                                return r;
3104
                } else if ((val = startswith(l, "exec-context-tty-reset="))) {
859,404✔
3105
                        r = parse_boolean(val);
245✔
3106
                        if (r < 0)
245✔
3107
                                return r;
3108
                        c->tty_reset = r;
245✔
3109
                } else if ((val = startswith(l, "exec-context-tty-vhangup="))) {
859,159✔
3110
                        r = parse_boolean(val);
127✔
3111
                        if (r < 0)
127✔
3112
                                return r;
3113
                        c->tty_vhangup = r;
127✔
3114
                } else if ((val = startswith(l, "exec-context-tty-vt-disallocate="))) {
859,032✔
3115
                        r = parse_boolean(val);
53✔
3116
                        if (r < 0)
53✔
3117
                                return r;
3118
                        c->tty_vt_disallocate = r;
53✔
3119
                } else if ((val = startswith(l, "exec-context-tty-rows="))) {
858,979✔
3120
                        r = safe_atou(val, &c->tty_rows);
12,789✔
3121
                        if (r < 0)
12,789✔
3122
                                return r;
3123
                } else if ((val = startswith(l, "exec-context-tty-columns="))) {
846,190✔
3124
                        r = safe_atou(val, &c->tty_cols);
12,789✔
3125
                        if (r < 0)
12,789✔
3126
                                return r;
3127
                } else if ((val = startswith(l, "exec-context-syslog-priority="))) {
833,401✔
3128
                        r = safe_atoi(val, &c->syslog_priority);
12,789✔
3129
                        if (r < 0)
12,789✔
3130
                                return r;
3131
                } else if ((val = startswith(l, "exec-context-syslog-level-prefix="))) {
820,612✔
3132
                        r = parse_boolean(val);
12,789✔
3133
                        if (r < 0)
12,789✔
3134
                                return r;
3135
                        c->syslog_level_prefix = r;
12,789✔
3136
                } else if ((val = startswith(l, "exec-context-syslog-identifier="))) {
807,823✔
3137
                        r = free_and_strdup(&c->syslog_identifier, val);
1✔
3138
                        if (r < 0)
1✔
3139
                                return r;
3140
                } else if ((val = startswith(l, "exec-context-log-level-max="))) {
807,822✔
3141
                        /* See comment in serialization. */
3142
                        r = safe_atoi(val, &c->log_level_max);
12,789✔
3143
                        if (r < 0)
12,789✔
3144
                                return r;
3145
                } else if ((val = startswith(l, "exec-context-log-ratelimit-interval-usec="))) {
795,033✔
3146
                        r = deserialize_usec(val, &c->log_ratelimit.interval);
×
3147
                        if (r < 0)
×
3148
                                return r;
3149
                } else if ((val = startswith(l, "exec-context-log-ratelimit-burst="))) {
795,033✔
3150
                        r = safe_atou(val, &c->log_ratelimit.burst);
×
3151
                        if (r < 0)
×
3152
                                return r;
3153
                } else if ((val = startswith(l, "exec-context-log-filter-allowed-patterns="))) {
795,033✔
3154
                        r = set_put_strdup(&c->log_filter_allowed_patterns, val);
20✔
3155
                        if (r < 0)
20✔
3156
                                return r;
3157
                } else if ((val = startswith(l, "exec-context-log-filter-denied-patterns="))) {
795,013✔
3158
                        r = set_put_strdup(&c->log_filter_denied_patterns, val);
13✔
3159
                        if (r < 0)
13✔
3160
                                return r;
3161
                } else if ((val = startswith(l, "exec-context-log-extra-fields="))) {
795,000✔
3162
                        if (c->n_log_extra_fields >= LOG_EXTRA_FIELDS_MAX) {
2,900✔
3163
                                log_warning("Too many extra log fields, ignoring.");
×
3164
                                continue;
×
3165
                        }
3166

3167
                        if (!GREEDY_REALLOC(c->log_extra_fields, c->n_log_extra_fields + 1))
2,900✔
3168
                                return log_oom_debug();
×
3169

3170
                        char *field = strdup(val);
2,900✔
3171
                        if (!field)
2,900✔
3172
                                return log_oom_debug();
×
3173

3174
                        c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE_STRING(field);
2,900✔
3175
                } else if ((val = startswith(l, "exec-context-log-namespace="))) {
792,100✔
3176
                        r = free_and_strdup(&c->log_namespace, val);
2✔
3177
                        if (r < 0)
2✔
3178
                                return r;
3179
                } else if ((val = startswith(l, "exec-context-secure-bits="))) {
792,098✔
3180
                        r = safe_atoi(val, &c->secure_bits);
×
3181
                        if (r < 0)
×
3182
                                return r;
3183
                } else if ((val = startswith(l, "exec-context-capability-bounding-set="))) {
792,098✔
3184
                        r = safe_atou64(val, &c->capability_bounding_set);
12,789✔
3185
                        if (r < 0)
12,789✔
3186
                                return r;
3187
                } else if ((val = startswith(l, "exec-context-capability-ambient-set="))) {
779,309✔
3188
                        r = safe_atou64(val, &c->capability_ambient_set);
692✔
3189
                        if (r < 0)
692✔
3190
                                return r;
3191
                } else if ((val = startswith(l, "exec-context-user="))) {
778,617✔
3192
                        r = free_and_strdup(&c->user, val);
2,288✔
3193
                        if (r < 0)
2,288✔
3194
                                return r;
3195
                } else if ((val = startswith(l, "exec-context-group="))) {
776,329✔
3196
                        r = free_and_strdup(&c->group, val);
63✔
3197
                        if (r < 0)
63✔
3198
                                return r;
3199
                } else if ((val = startswith(l, "exec-context-dynamic-user="))) {
776,266✔
3200
                        r = parse_boolean(val);
49✔
3201
                        if (r < 0)
49✔
3202
                                return r;
3203
                        c->dynamic_user = r;
49✔
3204
                } else if ((val = startswith(l, "exec-context-supplementary-groups="))) {
776,217✔
3205
                        r = deserialize_strv(val, &c->supplementary_groups);
13✔
3206
                        if (r < 0)
13✔
3207
                                return r;
3208
                } else if ((val = startswith(l, "exec-context-set-login-environment="))) {
776,204✔
3209
                        r = safe_atoi(val, &c->set_login_environment);
×
3210
                        if (r < 0)
×
3211
                                return r;
3212
                } else if ((val = startswith(l, "exec-context-pam-name="))) {
776,204✔
3213
                        r = free_and_strdup(&c->pam_name, val);
583✔
3214
                        if (r < 0)
583✔
3215
                                return r;
3216
                } else if ((val = startswith(l, "exec-context-read-write-paths="))) {
775,621✔
3217
                        r = deserialize_strv(val, &c->read_write_paths);
922✔
3218
                        if (r < 0)
922✔
3219
                                return r;
3220
                } else if ((val = startswith(l, "exec-context-read-only-paths="))) {
774,699✔
3221
                        r = deserialize_strv(val, &c->read_only_paths);
3✔
3222
                        if (r < 0)
3✔
3223
                                return r;
3224
                } else if ((val = startswith(l, "exec-context-inaccessible-paths="))) {
774,696✔
3225
                        r = deserialize_strv(val, &c->inaccessible_paths);
5✔
3226
                        if (r < 0)
5✔
3227
                                return r;
3228
                } else if ((val = startswith(l, "exec-context-exec-paths="))) {
774,691✔
3229
                        r = deserialize_strv(val, &c->exec_paths);
1✔
3230
                        if (r < 0)
1✔
3231
                                return r;
3232
                } else if ((val = startswith(l, "exec-context-no-exec-paths="))) {
774,690✔
3233
                        r = deserialize_strv(val, &c->no_exec_paths);
1✔
3234
                        if (r < 0)
1✔
3235
                                return r;
3236
                } else if ((val = startswith(l, "exec-context-exec-search-path="))) {
774,689✔
3237
                        r = deserialize_strv(val, &c->exec_search_path);
×
3238
                        if (r < 0)
×
3239
                                return r;
3240
                } else if ((val = startswith(l, "exec-context-mount-propagation-flag="))) {
774,689✔
3241
                        r = safe_atolu(val, &c->mount_propagation_flag);
12,789✔
3242
                        if (r < 0)
12,789✔
3243
                                return r;
3244
                } else if ((val = startswith(l, "exec-context-bind-read-only-path="))) {
761,900✔
3245
                        _cleanup_free_ char *source = NULL, *destination = NULL;
7✔
3246
                        bool rbind = true, ignore_enoent = false;
7✔
3247
                        char *s = NULL, *d = NULL;
7✔
3248

3249
                        r = extract_first_word(&val,
7✔
3250
                                               &source,
3251
                                               ":" WHITESPACE,
3252
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3253
                        if (r < 0)
7✔
3254
                                return r;
3255
                        if (r == 0)
7✔
3256
                                return -EINVAL;
3257

3258
                        s = source;
7✔
3259
                        if (s[0] == '-') {
7✔
3260
                                ignore_enoent = true;
1✔
3261
                                s++;
1✔
3262
                        }
3263

3264
                        if (val && val[-1] == ':') {
7✔
3265
                                r = extract_first_word(&val,
7✔
3266
                                                       &destination,
3267
                                                       ":" WHITESPACE,
3268
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3269
                                if (r < 0)
7✔
3270
                                        return r;
3271
                                if (r == 0)
7✔
3272
                                        continue;
×
3273

3274
                                d = destination;
7✔
3275

3276
                                if (val && val[-1] == ':') {
7✔
3277
                                        _cleanup_free_ char *options = NULL;
7✔
3278

3279
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
7✔
3280
                                        if (r < 0)
7✔
3281
                                                return r;
×
3282

3283
                                        if (isempty(options) || streq(options, "rbind"))
15✔
3284
                                                rbind = true;
3285
                                        else if (streq(options, "norbind"))
1✔
3286
                                                rbind = false;
3287
                                        else
3288
                                                continue;
×
3289
                                }
3290
                        } else
3291
                                d = s;
3292

3293
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
14✔
3294
                                        &(BindMount) {
7✔
3295
                                                .source = s,
3296
                                                .destination = d,
3297
                                                .read_only = true,
3298
                                                .recursive = rbind,
3299
                                                .ignore_enoent = ignore_enoent,
3300
                                        });
3301
                        if (r < 0)
7✔
3302
                                return log_oom_debug();
×
3303
                } else if ((val = startswith(l, "exec-context-bind-path="))) {
761,893✔
3304
                        _cleanup_free_ char *source = NULL, *destination = NULL;
25✔
3305
                        bool rbind = true, ignore_enoent = false;
25✔
3306
                        char *s = NULL, *d = NULL;
25✔
3307

3308
                        r = extract_first_word(&val,
25✔
3309
                                               &source,
3310
                                               ":" WHITESPACE,
3311
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3312
                        if (r < 0)
25✔
3313
                                return r;
3314
                        if (r == 0)
25✔
3315
                                return -EINVAL;
3316

3317
                        s = source;
25✔
3318
                        if (s[0] == '-') {
25✔
3319
                                ignore_enoent = true;
1✔
3320
                                s++;
1✔
3321
                        }
3322

3323
                        if (val && val[-1] == ':') {
25✔
3324
                                r = extract_first_word(&val,
25✔
3325
                                                       &destination,
3326
                                                       ":" WHITESPACE,
3327
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3328
                                if (r < 0)
25✔
3329
                                        return r;
3330
                                if (r == 0)
25✔
3331
                                        continue;
×
3332

3333
                                d = destination;
25✔
3334

3335
                                if (val && val[-1] == ':') {
25✔
3336
                                        _cleanup_free_ char *options = NULL;
25✔
3337

3338
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
25✔
3339
                                        if (r < 0)
25✔
3340
                                                return r;
×
3341

3342
                                        if (isempty(options) || streq(options, "rbind"))
53✔
3343
                                                rbind = true;
3344
                                        else if (streq(options, "norbind"))
3✔
3345
                                                rbind = false;
3346
                                        else
3347
                                                continue;
×
3348
                                }
3349
                        } else
3350
                                d = s;
3351

3352
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
50✔
3353
                                        &(BindMount) {
25✔
3354
                                                .source = s,
3355
                                                .destination = d,
3356
                                                .read_only = false,
3357
                                                .recursive = rbind,
3358
                                                .ignore_enoent = ignore_enoent,
3359
                                        });
3360
                        if (r < 0)
25✔
3361
                                return log_oom_debug();
×
3362
                } else if ((val = startswith(l, "exec-context-temporary-filesystems="))) {
761,868✔
3363
                        _cleanup_free_ char *path = NULL, *options = NULL;
67✔
3364

3365
                        r = extract_many_words(&val, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &path, &options);
67✔
3366
                        if (r < 0)
67✔
3367
                                return r;
3368
                        if (r < 1)
67✔
3369
                                continue;
×
3370

3371
                        r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
67✔
3372
                        if (r < 0)
67✔
3373
                                return log_oom_debug();
×
3374
                } else if ((val = startswith(l, "exec-context-utmp-id="))) {
761,801✔
3375
                        r = free_and_strdup(&c->utmp_id, val);
135✔
3376
                        if (r < 0)
135✔
3377
                                return r;
3378
                } else if ((val = startswith(l, "exec-context-utmp-mode="))) {
761,666✔
3379
                        c->utmp_mode = exec_utmp_mode_from_string(val);
12,789✔
3380
                        if (c->utmp_mode < 0)
12,789✔
3381
                                return c->utmp_mode;
3382
                } else if ((val = startswith(l, "exec-context-no-new-privileges="))) {
748,877✔
3383
                        r = parse_boolean(val);
1,759✔
3384
                        if (r < 0)
1,759✔
3385
                                return r;
3386
                        c->no_new_privileges = r;
1,759✔
3387
                } else if ((val = startswith(l, "exec-context-selinux-context="))) {
747,118✔
3388
                        if (val[0] == '-') {
×
3389
                                c->selinux_context_ignore = true;
×
3390
                                val++;
×
3391
                        } else
3392
                                c->selinux_context_ignore = false;
×
3393

3394
                        r = free_and_strdup(&c->selinux_context, val);
×
3395
                        if (r < 0)
×
3396
                                return r;
3397
                } else if ((val = startswith(l, "exec-context-apparmor-profile="))) {
747,118✔
3398
                        if (val[0] == '-') {
×
3399
                                c->apparmor_profile_ignore = true;
×
3400
                                val++;
×
3401
                        } else
3402
                                c->apparmor_profile_ignore = false;
×
3403

3404
                        r = free_and_strdup(&c->apparmor_profile, val);
×
3405
                        if (r < 0)
×
3406
                                return r;
3407
                } else if ((val = startswith(l, "exec-context-smack-process-label="))) {
747,118✔
3408
                        if (val[0] == '-') {
×
3409
                                c->smack_process_label_ignore = true;
×
3410
                                val++;
×
3411
                        } else
3412
                                c->smack_process_label_ignore = false;
×
3413

3414
                        r = free_and_strdup(&c->smack_process_label, val);
×
3415
                        if (r < 0)
×
3416
                                return r;
3417
                } else if ((val = startswith(l, "exec-context-personality="))) {
747,118✔
3418
                        c->personality = personality_from_string(val);
×
3419
                        if (c->personality == PERSONALITY_INVALID)
×
3420
                                return -EINVAL;
3421
                } else if ((val = startswith(l, "exec-context-lock-personality="))) {
747,118✔
3422
                        r = parse_boolean(val);
1,843✔
3423
                        if (r < 0)
1,843✔
3424
                                return r;
3425
                        c->lock_personality = r;
1,843✔
3426
#if HAVE_SECCOMP
3427
                } else if ((val = startswith(l, "exec-context-syscall-filter="))) {
745,275✔
3428
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
713,795✔
3429
                        int id, errno_num;
713,795✔
3430

3431
                        r = extract_many_words(&val, NULL, 0, &s_id, &s_errno_num);
713,795✔
3432
                        if (r < 0)
713,795✔
3433
                                return r;
3434
                        if (r != 2)
713,795✔
3435
                                continue;
×
3436

3437
                        r = safe_atoi(s_id, &id);
713,795✔
3438
                        if (r < 0)
713,795✔
3439
                                return r;
3440

3441
                        r = safe_atoi(s_errno_num, &errno_num);
713,795✔
3442
                        if (r < 0)
713,795✔
3443
                                return r;
3444

3445
                        r = hashmap_ensure_put(&c->syscall_filter, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
713,795✔
3446
                        if (r < 0)
713,795✔
3447
                                return r;
3448
                } else if ((val = startswith(l, "exec-context-syscall-archs="))) {
31,480✔
3449
                        unsigned id;
1,839✔
3450

3451
                        r = safe_atou(val, &id);
1,839✔
3452
                        if (r < 0)
1,839✔
3453
                                return r;
×
3454

3455
                        r = set_ensure_put(&c->syscall_archs, NULL, UINT_TO_PTR(id + 1));
1,839✔
3456
                        if (r < 0)
1,839✔
3457
                                return r;
3458
                } else if ((val = startswith(l, "exec-context-syscall-errno="))) {
29,641✔
3459
                        r = safe_atoi(val, &c->syscall_errno);
12,789✔
3460
                        if (r < 0)
12,789✔
3461
                                return r;
3462
                } else if ((val = startswith(l, "exec-context-syscall-allow-list="))) {
16,852✔
3463
                        r = parse_boolean(val);
1,814✔
3464
                        if (r < 0)
1,814✔
3465
                                return r;
3466
                        c->syscall_allow_list = r;
1,814✔
3467
                } else if ((val = startswith(l, "exec-context-syscall-log="))) {
15,038✔
3468
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
×
3469
                        int id, errno_num;
×
3470

3471
                        r = extract_many_words(&val, " ", 0, &s_id, &s_errno_num);
×
3472
                        if (r < 0)
×
3473
                                return r;
3474
                        if (r != 2)
×
3475
                                continue;
×
3476

3477
                        r = safe_atoi(s_id, &id);
×
3478
                        if (r < 0)
×
3479
                                return r;
3480

3481
                        r = safe_atoi(s_errno_num, &errno_num);
×
3482
                        if (r < 0)
×
3483
                                return r;
3484

3485
                        r = hashmap_ensure_put(&c->syscall_log, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
×
3486
                        if (r < 0)
×
3487
                                return r;
3488
                } else if ((val = startswith(l, "exec-context-syscall-log-allow-list="))) {
15,038✔
3489
                        r = parse_boolean(val);
×
3490
                        if (r < 0)
×
3491
                                return r;
3492
                        c->syscall_log_allow_list = r;
×
3493
#endif
3494
                } else if ((val = startswith(l, "exec-context-restrict-namespaces="))) {
15,038✔
3495
                        r = safe_atolu(val, &c->restrict_namespaces);
1,553✔
3496
                        if (r < 0)
1,553✔
3497
                                return r;
3498
                } else if ((val = startswith(l, "exec-context-delegate-namespaces="))) {
13,485✔
3499
                        r = safe_atolu(val, &c->delegate_namespaces);
21✔
3500
                        if (r < 0)
21✔
3501
                                return r;
3502
                } else if ((val = startswith(l, "exec-context-restrict-filesystems="))) {
13,464✔
3503
                        r = set_put_strdup(&c->restrict_filesystems, val);
×
3504
                        if (r < 0)
×
3505
                                return r;
3506
                } else if ((val = startswith(l, "exec-context-restrict-filesystems-allow-list="))) {
13,464✔
3507
                        r = parse_boolean(val);
×
3508
                        if (r < 0)
×
3509
                                return r;
3510
                        c->restrict_filesystems_allow_list = r;
×
3511
                } else if ((val = startswith(l, "exec-context-address-families="))) {
13,464✔
3512
                        int af;
6,919✔
3513

3514
                        r = safe_atoi(val, &af);
6,919✔
3515
                        if (r < 0)
6,919✔
3516
                                return r;
×
3517

3518
                        r = set_ensure_put(&c->address_families, NULL, INT_TO_PTR(af));
6,919✔
3519
                        if (r < 0)
6,919✔
3520
                                return r;
3521
                } else if ((val = startswith(l, "exec-context-address-families-allow-list="))) {
6,545✔
3522
                        r = parse_boolean(val);
1,833✔
3523
                        if (r < 0)
1,833✔
3524
                                return r;
3525
                        c->address_families_allow_list = r;
1,833✔
3526
                } else if ((val = startswith(l, "exec-context-network-namespace-path="))) {
4,712✔
3527
                        r = free_and_strdup(&c->network_namespace_path, val);
2✔
3528
                        if (r < 0)
2✔
3529
                                return r;
3530
                } else if ((val = startswith(l, "exec-context-user-namespace-path="))) {
4,710✔
3531
                        r = free_and_strdup(&c->user_namespace_path, val);
3✔
3532
                        if (r < 0)
3✔
3533
                                return r;
3534
                } else if ((val = startswith(l, "exec-context-ipc-namespace-path="))) {
4,707✔
3535
                        r = free_and_strdup(&c->ipc_namespace_path, val);
×
3536
                        if (r < 0)
×
3537
                                return r;
3538
                } else if ((val = startswith(l, "exec-context-mount-image="))) {
4,707✔
3539
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3540
                        _cleanup_free_ char *source = NULL, *destination = NULL;
60✔
3541
                        bool permissive = false;
60✔
3542
                        char *s;
60✔
3543

3544
                        r = extract_many_words(&val,
60✔
3545
                                               NULL,
3546
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3547
                                               &source,
3548
                                               &destination);
3549
                        if (r < 0)
60✔
3550
                                return r;
3551
                        if (r == 0)
60✔
3552
                                return -EINVAL;
3553

3554
                        s = source;
60✔
3555
                        if (s[0] == '-') {
60✔
3556
                                permissive = true;
×
3557
                                s++;
×
3558
                        }
3559

3560
                        if (isempty(destination))
60✔
3561
                                continue;
×
3562

3563
                        r = deserialize_mount_options(val, &options);
60✔
3564
                        if (r < 0)
60✔
3565
                                return r;
3566

3567
                        r = mount_image_add(&c->mount_images, &c->n_mount_images,
120✔
3568
                                        &(MountImage) {
60✔
3569
                                                .source = s,
3570
                                                .destination = destination,
3571
                                                .mount_options = options,
3572
                                                .ignore_enoent = permissive,
3573
                                                .type = MOUNT_IMAGE_DISCRETE,
3574
                                        });
3575
                        if (r < 0)
60✔
3576
                                return log_oom_debug();
×
3577
                } else if ((val = startswith(l, "exec-context-extension-image="))) {
4,647✔
3578
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3579
                        _cleanup_free_ char *source = NULL;
16✔
3580
                        bool permissive = false;
16✔
3581
                        char *s;
16✔
3582

3583
                        r = extract_first_word(&val,
16✔
3584
                                               &source,
3585
                                               NULL,
3586
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS);
3587
                        if (r < 0)
16✔
3588
                                return r;
3589
                        if (r == 0)
16✔
3590
                                return -EINVAL;
3591

3592
                        s = source;
16✔
3593
                        if (s[0] == '-') {
16✔
3594
                                permissive = true;
3✔
3595
                                s++;
3✔
3596
                        }
3597

3598
                        r = deserialize_mount_options(val, &options);
16✔
3599
                        if (r < 0)
16✔
3600
                                return r;
3601

3602
                        r = mount_image_add(&c->extension_images, &c->n_extension_images,
32✔
3603
                                        &(MountImage) {
16✔
3604
                                                .source = s,
3605
                                                .mount_options = options,
3606
                                                .ignore_enoent = permissive,
3607
                                                .type = MOUNT_IMAGE_EXTENSION,
3608
                                        });
3609
                        if (r < 0)
16✔
3610
                                return log_oom_debug();
×
3611
                } else if ((val = startswith(l, "exec-context-extension-directories="))) {
4,631✔
3612
                        r = deserialize_strv(val, &c->extension_directories);
10✔
3613
                        if (r < 0)
10✔
3614
                                return r;
3615
                } else if ((val = startswith(l, "exec-context-set-credentials="))) {
4,621✔
3616
                        _cleanup_free_ char *id = NULL, *data = NULL, *encrypted = NULL;
×
3617

3618
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &data, &encrypted);
97✔
3619
                        if (r < 0)
97✔
3620
                                return r;
3621
                        if (r != 3)
97✔
3622
                                return -EINVAL;
3623

3624
                        r = parse_boolean(encrypted);
97✔
3625
                        if (r < 0)
97✔
3626
                                return r;
3627
                        bool e = r;
97✔
3628

3629
                        _cleanup_free_ void *d = NULL;
97✔
3630
                        size_t size;
97✔
3631

3632
                        r = unbase64mem_full(data, SIZE_MAX, /* secure= */ true, &d, &size);
97✔
3633
                        if (r < 0)
97✔
3634
                                return r;
3635

3636
                        r = exec_context_put_set_credential(c, id, TAKE_PTR(d), size, e);
97✔
3637
                        if (r < 0)
97✔
3638
                                return r;
3639
                } else if ((val = startswith(l, "exec-context-load-credentials="))) {
4,524✔
3640
                        _cleanup_free_ char *id = NULL, *path = NULL, *encrypted = NULL;
34✔
3641

3642
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &path, &encrypted);
34✔
3643
                        if (r < 0)
34✔
3644
                                return r;
3645
                        if (r != 3)
34✔
3646
                                return -EINVAL;
3647

3648
                        r = parse_boolean(encrypted);
34✔
3649
                        if (r < 0)
34✔
3650
                                return r;
3651

3652
                        r = exec_context_put_load_credential(c, id, path, r > 0);
34✔
3653
                        if (r < 0)
34✔
3654
                                return r;
3655
                } else if ((val = startswith(l, "exec-context-import-credentials="))) {
4,490✔
3656
                        _cleanup_free_ char *glob = NULL, *rename = NULL;
4,484✔
3657

3658
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &glob, &rename);
4,484✔
3659
                        if (r < 0)
4,484✔
3660
                                return r;
3661
                        if (r == 0)
4,484✔
3662
                                return -EINVAL;
3663

3664
                        r = exec_context_put_import_credential(c, glob, rename);
4,484✔
3665
                        if (r < 0)
4,484✔
3666
                                return r;
3667
                } else if ((val = startswith(l, "exec-context-root-image-policy="))) {
6✔
3668
                        if (c->root_image_policy)
4✔
3669
                                return -EINVAL; /* duplicated */
3670

3671
                        r = image_policy_from_string(val, /* graceful= */ false, &c->root_image_policy);
4✔
3672
                        if (r < 0)
4✔
3673
                                return r;
3674
                } else if ((val = startswith(l, "exec-context-mount-image-policy="))) {
2✔
3675
                        if (c->mount_image_policy)
×
3676
                                return -EINVAL; /* duplicated */
3677

3678
                        r = image_policy_from_string(val, /* graceful= */ false, &c->mount_image_policy);
×
3679
                        if (r < 0)
×
3680
                                return r;
3681
                } else if ((val = startswith(l, "exec-context-extension-image-policy="))) {
2✔
3682
                        if (c->extension_image_policy)
2✔
3683
                                return -EINVAL; /* duplicated */
3684

3685
                        r = image_policy_from_string(val, /* graceful= */ false, &c->extension_image_policy);
2✔
3686
                        if (r < 0)
2✔
3687
                                return r;
3688
                } else
3689
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3690
        }
3691

3692
        return 0;
12,789✔
3693
}
3694

3695
static int exec_command_serialize(const ExecCommand *c, FILE *f) {
4,971✔
3696
        int r;
4,971✔
3697

3698
        assert(c);
4,971✔
3699
        assert(f);
4,971✔
3700

3701
        r = serialize_item(f, "exec-command-path", c->path);
4,971✔
3702
        if (r < 0)
4,971✔
3703
                return r;
3704

3705
        r = serialize_strv(f, "exec-command-argv", c->argv);
4,971✔
3706
        if (r < 0)
4,971✔
3707
                return r;
3708

3709
        r = serialize_item_format(f, "exec-command-flags", "%d", (int) c->flags);
4,971✔
3710
        if (r < 0)
4,971✔
3711
                return r;
3712

3713
        fputc('\n', f); /* End marker */
4,971✔
3714

3715
        return 0;
4,971✔
3716
}
3717

3718
static int exec_command_deserialize(ExecCommand *c, FILE *f) {
12,789✔
3719
        int r;
12,789✔
3720

3721
        assert(c);
12,789✔
3722
        assert(f);
12,789✔
3723

3724
        for (;;) {
133,575✔
3725
                _cleanup_free_ char *l = NULL;
60,393✔
3726
                const char *val;
73,182✔
3727

3728
                r = deserialize_read_line(f, &l);
73,182✔
3729
                if (r < 0)
73,182✔
3730
                        return r;
3731
                if (r == 0) /* eof or end marker */
73,182✔
3732
                        break;
3733

3734
                if ((val = startswith(l, "exec-command-path="))) {
60,393✔
3735
                        r = free_and_strdup(&c->path, val);
12,789✔
3736
                        if (r < 0)
12,789✔
3737
                                return r;
3738
                } else if ((val = startswith(l, "exec-command-argv="))) {
47,604✔
3739
                        r = deserialize_strv(val, &c->argv);
34,815✔
3740
                        if (r < 0)
34,815✔
3741
                                return r;
3742
                } else if ((val = startswith(l, "exec-command-flags="))) {
12,789✔
3743
                        r = safe_atoi(val, &c->flags);
12,789✔
3744
                        if (r < 0)
12,789✔
3745
                                return r;
3746
                } else
3747
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3748

3749
        }
3750

3751
        return 0;
12,789✔
3752
}
3753

3754
int exec_serialize_invocation(
4,971✔
3755
                FILE *f,
3756
                FDSet *fds,
3757
                const ExecContext *ctx,
3758
                const ExecCommand *cmd,
3759
                const ExecParameters *p,
3760
                const ExecRuntime *rt,
3761
                const CGroupContext *cg) {
3762

3763
        int r;
4,971✔
3764

3765
        assert(f);
4,971✔
3766
        assert(fds);
4,971✔
3767

3768
        r = exec_context_serialize(ctx, f);
4,971✔
3769
        if (r < 0)
4,971✔
3770
                return log_debug_errno(r, "Failed to serialize context: %m");
×
3771

3772
        r = exec_command_serialize(cmd, f);
4,971✔
3773
        if (r < 0)
4,971✔
3774
                return log_debug_errno(r, "Failed to serialize command: %m");
×
3775

3776
        r = exec_parameters_serialize(p, ctx, f, fds);
4,971✔
3777
        if (r < 0)
4,971✔
3778
                return log_debug_errno(r, "Failed to serialize parameters: %m");
×
3779

3780
        r = exec_runtime_serialize(rt, f, fds);
4,971✔
3781
        if (r < 0)
4,971✔
3782
                return log_debug_errno(r, "Failed to serialize runtime: %m");
×
3783

3784
        r = exec_cgroup_context_serialize(cg, f);
4,971✔
3785
        if (r < 0)
4,971✔
3786
                return log_debug_errno(r, "Failed to serialize cgroup context: %m");
×
3787

3788
        return 0;
3789
}
3790

3791
int exec_deserialize_invocation(
12,789✔
3792
                FILE *f,
3793
                FDSet *fds,
3794
                ExecContext *ctx,
3795
                ExecCommand *cmd,
3796
                ExecParameters *p,
3797
                ExecRuntime *rt,
3798
                CGroupContext *cg) {
3799

3800
        int r;
12,789✔
3801

3802
        assert(f);
12,789✔
3803
        assert(fds);
12,789✔
3804

3805
        r = exec_context_deserialize(ctx, f);
12,789✔
3806
        if (r < 0)
12,789✔
3807
                return log_debug_errno(r, "Failed to deserialize context: %m");
×
3808

3809
        r = exec_command_deserialize(cmd, f);
12,789✔
3810
        if (r < 0)
12,789✔
3811
                return log_debug_errno(r, "Failed to deserialize command: %m");
×
3812

3813
        r = exec_parameters_deserialize(p, f, fds);
12,789✔
3814
        if (r < 0)
12,789✔
3815
                return log_debug_errno(r, "Failed to deserialize parameters: %m");
×
3816

3817
        r = exec_runtime_deserialize(rt, f, fds);
12,789✔
3818
        if (r < 0)
12,789✔
3819
                return log_debug_errno(r, "Failed to deserialize runtime: %m");
×
3820

3821
        r = exec_cgroup_context_deserialize(cg, f);
12,789✔
3822
        if (r < 0)
12,789✔
3823
                return log_debug_errno(r, "Failed to deserialize cgroup context: %m");
×
3824

3825
        return 0;
3826
}
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