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

systemd / systemd / 16104615022

06 Jul 2025 08:06PM UTC coverage: 72.1% (+0.04%) from 72.057%
16104615022

push

github

web-flow
Two follow-ups for recent PRs (#38062)

12 of 13 new or added lines in 2 files covered. (92.31%)

1207 existing lines in 43 files now uncovered.

300846 of 417265 relevant lines covered (72.1%)

718237.88 hits per line

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

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

3
#include <unistd.h>
4

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

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

42
        assert(f);
2,244✔
43

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

433
        return 0;
434
}
435

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

439
        assert(f);
11,832✔
440

441
        if (!c)
11,832✔
442
                return 0;
443

444
        for (;;) {
427,398✔
445
                _cleanup_free_ char *l = NULL;
207,783✔
446
                const char *val;
219,615✔
447

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

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

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

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

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

520
                        r = parse_cpu_set(val, &c->startup_cpuset_mems);
11,832✔
521
                        if (r < 0)
11,832✔
522
                                return r;
523
                } else if ((val = startswith(l, "exec-cgroup-context-io-weight="))) {
137,020✔
524
                        r = safe_atou64(val, &c->io_weight);
×
525
                        if (r < 0)
×
526
                                return r;
527
                } else if ((val = startswith(l, "exec-cgroup-context-startup-io-weight="))) {
137,020✔
528
                        r = safe_atou64(val, &c->startup_io_weight);
×
529
                        if (r < 0)
×
530
                                return r;
531
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-min="))) {
137,020✔
532
                        r = safe_atou64(val, &c->default_memory_min);
×
533
                        if (r < 0)
×
534
                                return r;
535
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-low="))) {
137,020✔
536
                        r = safe_atou64(val, &c->default_memory_low);
×
537
                        if (r < 0)
×
538
                                return r;
539
                } else if ((val = startswith(l, "exec-cgroup-context-memory-min="))) {
137,020✔
540
                        r = safe_atou64(val, &c->memory_min);
1✔
541
                        if (r < 0)
1✔
542
                                return r;
543
                } else if ((val = startswith(l, "exec-cgroup-context-memory-low="))) {
137,019✔
544
                        r = safe_atou64(val, &c->memory_low);
1✔
545
                        if (r < 0)
1✔
546
                                return r;
547
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low="))) {
137,018✔
548
                        r = safe_atou64(val, &c->startup_memory_low);
×
549
                        if (r < 0)
×
550
                                return r;
551
                } else if ((val = startswith(l, "exec-cgroup-context-memory-high="))) {
137,018✔
552
                        r = safe_atou64(val, &c->memory_high);
10✔
553
                        if (r < 0)
10✔
554
                                return r;
555
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high="))) {
137,008✔
556
                        r = safe_atou64(val, &c->startup_memory_high);
×
557
                        if (r < 0)
×
558
                                return r;
559
                } else if ((val = startswith(l, "exec-cgroup-context-memory-max="))) {
137,008✔
560
                        r = safe_atou64(val, &c->memory_max);
2✔
561
                        if (r < 0)
2✔
562
                                return r;
563
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max="))) {
137,006✔
564
                        r = safe_atou64(val, &c->startup_memory_max);
×
565
                        if (r < 0)
×
566
                                return r;
567
                } else if ((val = startswith(l, "exec-cgroup-context-memory-swap-max="))) {
137,006✔
568
                        r = safe_atou64(val, &c->memory_swap_max);
1✔
569
                        if (r < 0)
1✔
570
                                return r;
571
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max="))) {
137,005✔
572
                        r = safe_atou64(val, &c->startup_memory_swap_max);
×
573
                        if (r < 0)
×
574
                                return r;
575
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-max="))) {
137,005✔
576
                        r = safe_atou64(val, &c->memory_zswap_max);
1✔
577
                        if (r < 0)
1✔
578
                                return r;
579
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max="))) {
137,004✔
580
                        r = safe_atou64(val, &c->startup_memory_zswap_max);
×
581
                        if (r < 0)
×
582
                                return r;
583
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-writeback="))) {
137,004✔
584
                        r = parse_boolean(val);
11,832✔
585
                        if (r < 0)
11,832✔
586
                                return r;
587
                        c->memory_zswap_writeback = r;
11,832✔
588
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-value="))) {
125,172✔
589
                        r = safe_atou64(val, &c->tasks_max.value);
11,545✔
590
                        if (r < 0)
11,545✔
591
                                return r;
592
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-scale="))) {
113,627✔
593
                        r = safe_atou64(val, &c->tasks_max.scale);
11,510✔
594
                        if (r < 0)
11,510✔
595
                                return r;
596
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-min-set="))) {
102,117✔
597
                        r = parse_boolean(val);
×
598
                        if (r < 0)
×
599
                                return r;
600
                        c->default_memory_min_set = r;
×
601
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-low-set="))) {
102,117✔
602
                        r = parse_boolean(val);
×
603
                        if (r < 0)
×
604
                                return r;
605
                        c->default_memory_low_set = r;
×
606
                } else if ((val = startswith(l, "exec-cgroup-context-default-startup-memory-low-set="))) {
102,117✔
607
                        r = parse_boolean(val);
×
608
                        if (r < 0)
×
609
                                return r;
610
                        c->default_startup_memory_low_set = r;
×
611
                } else if ((val = startswith(l, "exec-cgroup-context-memory-min-set="))) {
102,117✔
612
                        r = parse_boolean(val);
1✔
613
                        if (r < 0)
1✔
614
                                return r;
615
                        c->memory_min_set = r;
1✔
616
                } else if ((val = startswith(l, "exec-cgroup-context-memory-low-set="))) {
102,116✔
617
                        r = parse_boolean(val);
1✔
618
                        if (r < 0)
1✔
619
                                return r;
620
                        c->memory_low_set = r;
1✔
621
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low-set="))) {
102,115✔
622
                        r = parse_boolean(val);
×
623
                        if (r < 0)
×
624
                                return r;
625
                        c->startup_memory_low_set = r;
×
626
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high-set="))) {
102,115✔
627
                        r = parse_boolean(val);
×
628
                        if (r < 0)
×
629
                                return r;
630
                        c->startup_memory_high_set = r;
×
631
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max-set="))) {
102,115✔
632
                        r = parse_boolean(val);
×
633
                        if (r < 0)
×
634
                                return r;
635
                        c->startup_memory_max_set = r;
×
636
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max-set="))) {
102,115✔
637
                        r = parse_boolean(val);
×
638
                        if (r < 0)
×
639
                                return r;
640
                        c->startup_memory_swap_max_set = r;
×
641
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max-set="))) {
102,115✔
642
                        r = parse_boolean(val);
×
643
                        if (r < 0)
×
644
                                return r;
645
                        c->startup_memory_zswap_max_set = r;
×
646
                } else if ((val = startswith(l, "exec-cgroup-context-device-policy="))) {
102,115✔
647
                        c->device_policy = cgroup_device_policy_from_string(val);
11,832✔
648
                        if (c->device_policy < 0)
11,832✔
649
                                return -EINVAL;
650
                } else if ((val = startswith(l, "exec-cgroup-context-disable-controllers="))) {
90,283✔
651
                        r = cg_mask_from_string(val, &c->disable_controllers);
×
652
                        if (r < 0)
×
653
                                return r;
654
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-controllers="))) {
90,283✔
655
                        r = cg_mask_from_string(val, &c->delegate_controllers);
559✔
656
                        if (r < 0)
559✔
657
                                return r;
658
                } else if ((val = startswith(l, "exec-cgroup-context-delegate="))) {
89,724✔
659
                        r = parse_boolean(val);
673✔
660
                        if (r < 0)
673✔
661
                                return r;
662
                        c->delegate = r;
673✔
663
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-swap="))) {
89,051✔
664
                        c->moom_swap = managed_oom_mode_from_string(val);
11,832✔
665
                        if (c->moom_swap < 0)
11,832✔
666
                                return -EINVAL;
667
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure="))) {
77,219✔
668
                        c->moom_mem_pressure = managed_oom_mode_from_string(val);
11,832✔
669
                        if (c->moom_mem_pressure < 0)
11,832✔
670
                                return -EINVAL;
671
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-limit="))) {
65,387✔
672
                        r = safe_atou32(val, &c->moom_mem_pressure_limit);
11,832✔
673
                        if (r < 0)
11,832✔
674
                                return r;
675
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-preference="))) {
53,555✔
676
                        c->moom_preference = managed_oom_preference_from_string(val);
11,832✔
677
                        if (c->moom_preference < 0)
11,832✔
678
                                return -EINVAL;
679
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec="))) {
41,723✔
680
                        r = deserialize_usec(val, &c->moom_mem_pressure_duration_usec);
1✔
681
                        if (r < 0)
1✔
682
                                return r;
683
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-watch="))) {
41,722✔
684
                        c->memory_pressure_watch = cgroup_pressure_watch_from_string(val);
11,832✔
685
                        if (c->memory_pressure_watch < 0)
11,832✔
686
                                return -EINVAL;
687
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-subgroup="))) {
29,890✔
688
                        r = free_and_strdup(&c->delegate_subgroup, val);
330✔
689
                        if (r < 0)
330✔
690
                                return r;
691
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-threshold-usec="))) {
29,560✔
692
                        r = deserialize_usec(val, &c->memory_pressure_threshold_usec);
11,832✔
693
                        if (r < 0)
11,832✔
694
                                return r;
695
                } else if ((val = startswith(l, "exec-cgroup-context-device-allow="))) {
17,728✔
696
                        _cleanup_free_ char *path = NULL, *rwm = NULL;
4,576✔
697
                        CGroupDevicePermissions p;
4,576✔
698

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

705
                        p = isempty(rwm) ? 0 : cgroup_device_permissions_from_string(rwm);
9,152✔
706
                        if (p < 0)
4,576✔
707
                                return p;
708

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

914
        return 0;
11,832✔
915
}
916

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

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

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

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

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

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

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

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

954
        if (rt->dynamic_creds) {
71✔
955
                r = dynamic_user_serialize_one(rt->dynamic_creds->user, "exec-runtime-dynamic-creds-user", f, fds);
1✔
956
                if (r < 0)
1✔
957
                        return r;
958
        }
959

960
        if (rt->dynamic_creds && rt->dynamic_creds->group && rt->dynamic_creds->group == rt->dynamic_creds->user) {
71✔
961
                r = serialize_bool(f, "exec-runtime-dynamic-creds-group-copy", true);
1✔
962
                if (r < 0)
1✔
963
                        return r;
964
        } else if (rt->dynamic_creds) {
70✔
965
                r = dynamic_user_serialize_one(rt->dynamic_creds->group, "exec-runtime-dynamic-creds-group", f, fds);
×
966
                if (r < 0)
×
967
                        return r;
968
        }
969

970
        r = serialize_item(f, "exec-runtime-ephemeral-copy", rt->ephemeral_copy);
71✔
971
        if (r < 0)
71✔
972
                return r;
973

974
        if (rt->ephemeral_storage_socket[0] >= 0 && rt->ephemeral_storage_socket[1] >= 0) {
71✔
975
                r = serialize_fd_many(f, fds, "exec-runtime-ephemeral-storage-socket", rt->ephemeral_storage_socket, 2);
×
976
                if (r < 0)
×
977
                        return r;
978
        }
979

980
        fputc('\n', f); /* End marker */
71✔
981

982
        return 0;
71✔
983
}
984

985
static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) {
11,832✔
986
        int r;
11,832✔
987

988
        assert(rt);
11,832✔
989
        assert(rt->shared);
11,832✔
990
        assert(rt->dynamic_creds);
11,832✔
991
        assert(f);
11,832✔
992
        assert(fds);
11,832✔
993

994
        for (;;) {
13,045✔
995
                _cleanup_free_ char *l = NULL;
1,213✔
996
                const char *val;
13,045✔
997

998
                r = deserialize_read_line(f, &l);
13,045✔
999
                if (r < 0)
13,045✔
1000
                        return r;
1001
                if (r == 0) /* eof or end marker */
13,045✔
1002
                        break;
1003

1004
                if ((val = startswith(l, "exec-runtime-id="))) {
1,213✔
1005
                        r = free_and_strdup(&rt->shared->id, val);
353✔
1006
                        if (r < 0)
353✔
1007
                                return r;
1008
                } else if ((val = startswith(l, "exec-runtime-tmp-dir="))) {
860✔
1009
                        r = free_and_strdup(&rt->shared->tmp_dir, val);
333✔
1010
                        if (r < 0)
333✔
1011
                                return r;
1012
                } else if ((val = startswith(l, "exec-runtime-var-tmp-dir="))) {
527✔
1013
                        r = free_and_strdup(&rt->shared->var_tmp_dir, val);
333✔
1014
                        if (r < 0)
333✔
1015
                                return r;
1016
                } else if ((val = startswith(l, "exec-runtime-netns-storage-socket="))) {
194✔
1017

1018
                        r = deserialize_fd_many(fds, val, 2, rt->shared->netns_storage_socket);
64✔
1019
                        if (r < 0)
64✔
1020
                                continue;
×
1021

1022
                } else if ((val = startswith(l, "exec-runtime-ipcns-storage-socket="))) {
130✔
1023

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

1028
                } else if ((val = startswith(l, "exec-runtime-dynamic-creds-user=")))
124✔
1029
                        dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->user);
62✔
1030
                else if ((val = startswith(l, "exec-runtime-dynamic-creds-group=")))
62✔
1031
                        dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->group);
×
1032
                else if ((val = startswith(l, "exec-runtime-dynamic-creds-group-copy="))) {
62✔
1033
                        r = parse_boolean(val);
62✔
1034
                        if (r < 0)
62✔
1035
                                return r;
1036
                        if (!r)
62✔
1037
                                continue; /* Nothing to do */
×
1038

1039
                        if (!rt->dynamic_creds->user)
62✔
1040
                                return -EINVAL;
1041

1042
                        rt->dynamic_creds->group = dynamic_user_ref(rt->dynamic_creds->user);
62✔
1043
                } else if ((val = startswith(l, "exec-runtime-ephemeral-copy="))) {
×
1044
                        r = free_and_strdup(&rt->ephemeral_copy, val);
×
1045
                        if (r < 0)
×
1046
                                return r;
1047
                } else if ((val = startswith(l, "exec-runtime-ephemeral-storage-socket="))) {
×
1048

1049
                        r = deserialize_fd_many(fds, val, 2, rt->ephemeral_storage_socket);
×
1050
                        if (r < 0)
×
1051
                                continue;
×
1052
                } else
1053
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
1054
        }
1055

1056
        return 0;
11,832✔
1057
}
1058

1059
static bool exec_parameters_is_idle_pipe_set(const ExecParameters *p) {
2,244✔
1060
        assert(p);
2,244✔
1061

1062
        return p->idle_pipe &&
2,272✔
1063
                p->idle_pipe[0] >= 0 &&
28✔
1064
                p->idle_pipe[1] >= 0 &&
26✔
1065
                p->idle_pipe[2] >= 0 &&
2,270✔
1066
                p->idle_pipe[3] >= 0;
26✔
1067
}
1068

1069
static int exec_parameters_serialize(const ExecParameters *p, const ExecContext *c, FILE *f, FDSet *fds) {
2,244✔
1070
        int r;
2,244✔
1071

1072
        assert(f);
2,244✔
1073
        assert(fds);
2,244✔
1074

1075
        if (!p)
2,244✔
1076
                return 0;
1077

1078
        r = serialize_item(f, "exec-parameters-runtime-scope", runtime_scope_to_string(p->runtime_scope));
2,244✔
1079
        if (r < 0)
2,244✔
1080
                return r;
1081

1082
        r = serialize_strv(f, "exec-parameters-environment", p->environment);
2,244✔
1083
        if (r < 0)
2,244✔
1084
                return r;
1085

1086
        if (p->fds) {
2,244✔
1087
                if (p->n_socket_fds > 0) {
414✔
1088
                        r = serialize_item_format(f, "exec-parameters-n-socket-fds", "%zu", p->n_socket_fds);
413✔
1089
                        if (r < 0)
413✔
1090
                                return r;
1091
                }
1092

1093
                if (p->n_storage_fds > 0) {
414✔
1094
                        r = serialize_item_format(f, "exec-parameters-n-storage-fds", "%zu", p->n_storage_fds);
4✔
1095
                        if (r < 0)
4✔
1096
                                return r;
1097
                }
1098

1099
                if (p->n_extra_fds > 0) {
414✔
1100
                        r = serialize_item_format(f, "exec-parameters-n-extra-fds", "%zu", p->n_extra_fds);
1✔
1101
                        if (r < 0)
1✔
1102
                                return r;
1103
                }
1104

1105
                r = serialize_fd_many(f, fds, "exec-parameters-fds", p->fds, p->n_socket_fds + p->n_storage_fds + p->n_extra_fds);
414✔
1106
                if (r < 0)
414✔
1107
                        return r;
1108
        }
1109

1110
        r = serialize_strv(f, "exec-parameters-fd-names", p->fd_names);
2,244✔
1111
        if (r < 0)
2,244✔
1112
                return r;
1113

1114
        if (p->flags != 0) {
2,244✔
1115
                r = serialize_item_format(f, "exec-parameters-flags", "%u", (unsigned) p->flags);
2,244✔
1116
                if (r < 0)
2,244✔
1117
                        return r;
1118
        }
1119

1120
        r = serialize_bool_elide(f, "exec-parameters-selinux-context-net", p->selinux_context_net);
2,244✔
1121
        if (r < 0)
2,244✔
1122
                return r;
1123

1124
        if (p->cgroup_supported != 0) {
2,244✔
1125
                r = serialize_item_format(f, "exec-parameters-cgroup-supported", "%u", (unsigned) p->cgroup_supported);
2,233✔
1126
                if (r < 0)
2,233✔
1127
                        return r;
1128
        }
1129

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

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

1138
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
13,464✔
1139
                _cleanup_free_ char *key = NULL;
11,220✔
1140

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

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

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

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

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

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

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

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

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

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

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

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

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

1200
        r = serialize_fd(f, fds, "exec-parameters-pidref-transport-fd", p->pidref_transport_fd);
2,244✔
1201
        if (r < 0)
2,244✔
1202
                return r;
1203

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

1210
        r = serialize_item(f, "exec-parameters-notify-socket", p->notify_socket);
2,244✔
1211
        if (r < 0)
2,244✔
1212
                return r;
1213

1214
        LIST_FOREACH(open_files, file, p->open_files) {
2,244✔
1215
                _cleanup_free_ char *ofs = NULL;
×
1216

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

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

1226
        r = serialize_item(f, "exec-parameters-fallback-smack-process-label", p->fallback_smack_process_label);
2,244✔
1227
        if (r < 0)
2,244✔
1228
                return r;
1229

1230
        r = serialize_fd(f, fds, "exec-parameters-user-lookup-fd", p->user_lookup_fd);
2,244✔
1231
        if (r < 0)
2,244✔
1232
                return r;
1233

1234
        r = serialize_strv(f, "exec-parameters-files-env", p->files_env);
2,244✔
1235
        if (r < 0)
2,244✔
1236
                return r;
1237

1238
        r = serialize_item(f, "exec-parameters-unit-id", p->unit_id);
2,244✔
1239
        if (r < 0)
2,244✔
1240
                return r;
1241

1242
        r = serialize_item(f, "exec-parameters-invocation-id-string", p->invocation_id_string);
2,244✔
1243
        if (r < 0)
2,244✔
1244
                return r;
1245

1246
        r = serialize_bool_elide(f, "exec-parameters-debug-invocation", p->debug_invocation);
2,244✔
1247
        if (r < 0)
2,244✔
1248
                return r;
1249

1250
        fputc('\n', f); /* End marker */
2,244✔
1251

1252
        return 0;
2,244✔
1253
}
1254

1255
static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
11,832✔
1256
        int r;
11,832✔
1257

1258
        assert(p);
11,832✔
1259
        assert(f);
11,832✔
1260
        assert(fds);
11,832✔
1261

1262
        unsigned nr_open = MAX(read_nr_open(), NR_OPEN_MINIMUM);
11,832✔
1263

1264
        for (;;) {
265,881✔
1265
                _cleanup_free_ char *l = NULL;
254,049✔
1266
                const char *val;
265,881✔
1267

1268
                r = deserialize_read_line(f, &l);
265,881✔
1269
                if (r < 0)
265,881✔
1270
                        return r;
1271
                if (r == 0) /* eof or end marker */
265,881✔
1272
                        break;
1273

1274
                if ((val = startswith(l, "exec-parameters-runtime-scope="))) {
254,049✔
1275
                        p->runtime_scope = runtime_scope_from_string(val);
11,832✔
1276
                        if (p->runtime_scope < 0)
11,832✔
1277
                                return p->runtime_scope;
1278
                } else if ((val = startswith(l, "exec-parameters-environment="))) {
242,217✔
1279
                        r = deserialize_strv(val, &p->environment);
49,716✔
1280
                        if (r < 0)
49,716✔
1281
                                return r;
1282
                } else if ((val = startswith(l, "exec-parameters-n-socket-fds="))) {
192,501✔
1283
                        if (p->fds)
2,395✔
1284
                                return -EINVAL; /* Already received */
1285

1286
                        r = safe_atozu(val, &p->n_socket_fds);
2,395✔
1287
                        if (r < 0)
2,395✔
1288
                                return r;
1289

1290
                        if (p->n_socket_fds > nr_open)
2,395✔
1291
                                return -EINVAL; /* too many, someone is playing games with us */
1292
                } else if ((val = startswith(l, "exec-parameters-n-storage-fds="))) {
190,106✔
1293
                        if (p->fds)
143✔
1294
                                return -EINVAL; /* Already received */
1295

1296
                        r = safe_atozu(val, &p->n_storage_fds);
143✔
1297
                        if (r < 0)
143✔
1298
                                return r;
1299

1300
                        if (p->n_storage_fds > nr_open)
143✔
1301
                                return -EINVAL; /* too many, someone is playing games with us */
1302
                } else if ((val = startswith(l, "exec-parameters-n-extra-fds="))) {
189,963✔
1303
                        if (p->fds)
2✔
1304
                                return -EINVAL; /* Already received */
1305

1306
                        r = safe_atozu(val, &p->n_extra_fds);
2✔
1307
                        if (r < 0)
2✔
1308
                                return r;
1309

1310
                        if (p->n_extra_fds > nr_open)
2✔
1311
                                return -EINVAL; /* too many, someone is playing games with us */
1312
                } else if ((val = startswith(l, "exec-parameters-fds="))) {
189,961✔
1313
                        if (p->n_socket_fds + p->n_storage_fds + p->n_extra_fds == 0)
2,400✔
UNCOV
1314
                                return log_warning_errno(
×
1315
                                                SYNTHETIC_ERRNO(EINVAL),
1316
                                                "Got exec-parameters-fds= without "
1317
                                                "prior exec-parameters-n-socket-fds= or exec-parameters-n-storage-fds= or exec-parameters-n-extra-fds=");
1318
                        if (p->n_socket_fds + p->n_storage_fds + p->n_extra_fds > nr_open)
2,400✔
1319
                                return -EINVAL; /* too many, someone is playing games with us */
1320

1321
                        if (p->fds)
2,400✔
1322
                                return -EINVAL; /* duplicated */
1323

1324
                        p->fds = new(int, p->n_socket_fds + p->n_storage_fds + p->n_extra_fds);
2,400✔
1325
                        if (!p->fds)
2,400✔
UNCOV
1326
                                return log_oom_debug();
×
1327

1328
                        /* Ensure we don't leave any FD uninitialized on error, it makes the fuzzer sad */
1329
                        FOREACH_ARRAY(i, p->fds, p->n_socket_fds + p->n_storage_fds + p->n_extra_fds)
7,352✔
1330
                                *i = -EBADF;
4,952✔
1331

1332
                        r = deserialize_fd_many(fds, val, p->n_socket_fds + p->n_storage_fds + p->n_extra_fds, p->fds);
2,400✔
1333
                        if (r < 0)
2,400✔
UNCOV
1334
                                continue;
×
1335

1336
                } else if ((val = startswith(l, "exec-parameters-fd-names="))) {
187,561✔
1337
                        r = deserialize_strv(val, &p->fd_names);
4,952✔
1338
                        if (r < 0)
4,952✔
1339
                                return r;
1340
                } else if ((val = startswith(l, "exec-parameters-flags="))) {
182,609✔
1341
                        unsigned flags;
11,832✔
1342

1343
                        r = safe_atou(val, &flags);
11,832✔
1344
                        if (r < 0)
11,832✔
UNCOV
1345
                                return r;
×
1346
                        p->flags = flags;
11,832✔
1347
                } else if ((val = startswith(l, "exec-parameters-selinux-context-net="))) {
170,777✔
1348
                        r = parse_boolean(val);
×
UNCOV
1349
                        if (r < 0)
×
1350
                                return r;
1351

1352
                        p->selinux_context_net = r;
×
1353
                } else if ((val = startswith(l, "exec-parameters-cgroup-supported="))) {
170,777✔
1354
                        unsigned cgroup_supported;
11,821✔
1355

1356
                        r = safe_atou(val, &cgroup_supported);
11,821✔
1357
                        if (r < 0)
11,821✔
UNCOV
1358
                                return r;
×
1359
                        p->cgroup_supported = cgroup_supported;
11,821✔
1360
                } else if ((val = startswith(l, "exec-parameters-cgroup-path="))) {
158,956✔
1361
                        r = free_and_strdup(&p->cgroup_path, val);
11,832✔
1362
                        if (r < 0)
11,832✔
1363
                                return r;
1364
                } else if ((val = startswith(l, "exec-parameters-cgroup-id="))) {
147,124✔
1365
                        r = safe_atou64(val, &p->cgroup_id);
11,832✔
1366
                        if (r < 0)
11,832✔
1367
                                return r;
1368
                } else if ((val = startswith(l, "exec-parameters-prefix-directories-"))) {
135,292✔
1369
                        _cleanup_free_ char *type = NULL, *prefix = NULL;
59,160✔
1370
                        ExecDirectoryType dt;
59,160✔
1371

1372
                        r = extract_many_words(&val, "= ", 0, &type, &prefix);
59,160✔
1373
                        if (r < 0)
59,160✔
1374
                                return r;
1375
                        if (r == 0)
59,160✔
1376
                                return -EINVAL;
1377

1378
                        dt = exec_directory_type_from_string(type);
59,160✔
1379
                        if (dt < 0)
59,160✔
1380
                                return -EINVAL;
1381

1382
                        if (!p->prefix) {
59,160✔
1383
                                p->prefix = new0(char*, _EXEC_DIRECTORY_TYPE_MAX+1);
11,832✔
1384
                                if (!p->prefix)
11,832✔
UNCOV
1385
                                        return log_oom_debug();
×
1386
                        }
1387

1388
                        if (isempty(prefix))
59,160✔
UNCOV
1389
                                p->prefix[dt] = mfree(p->prefix[dt]);
×
1390
                        else
1391
                                free_and_replace(p->prefix[dt], prefix);
59,160✔
1392
                } else if ((val = startswith(l, "exec-parameters-received-credentials-directory="))) {
76,132✔
1393
                        r = free_and_strdup(&p->received_credentials_directory, val);
11,026✔
1394
                        if (r < 0)
11,026✔
1395
                                return r;
1396
                } else if ((val = startswith(l, "exec-parameters-received-encrypted-credentials-directory="))) {
65,106✔
UNCOV
1397
                        r = free_and_strdup(&p->received_encrypted_credentials_directory, val);
×
UNCOV
1398
                        if (r < 0)
×
1399
                                return r;
1400
                } else if ((val = startswith(l, "exec-parameters-confirm-spawn="))) {
65,106✔
1401
                        r = free_and_strdup(&p->confirm_spawn, val);
×
UNCOV
1402
                        if (r < 0)
×
1403
                                return r;
1404
                } else if ((val = startswith(l, "exec-parameters-shall-confirm-spawn="))) {
65,106✔
1405
                        r = parse_boolean(val);
×
UNCOV
1406
                        if (r < 0)
×
1407
                                return r;
1408

1409
                        p->shall_confirm_spawn = r;
×
1410
                } else if ((val = startswith(l, "exec-parameters-watchdog-usec="))) {
65,106✔
1411
                        r = deserialize_usec(val, &p->watchdog_usec);
2,247✔
1412
                        if (r < 0)
2,247✔
1413
                                return r;
1414
                } else if ((val = startswith(l, "exec-parameters-idle-pipe="))) {
62,859✔
1415
                        if (p->idle_pipe)
151✔
1416
                                return -EINVAL; /* duplicated */
1417

1418
                        p->idle_pipe = new(int, 4);
151✔
1419
                        if (!p->idle_pipe)
151✔
UNCOV
1420
                                return log_oom_debug();
×
1421

1422
                        p->idle_pipe[0] = p->idle_pipe[1] = p->idle_pipe[2] = p->idle_pipe[3] = -EBADF;
151✔
1423

1424
                        r = deserialize_fd_many(fds, val, 4, p->idle_pipe);
151✔
1425
                        if (r < 0)
151✔
UNCOV
1426
                                continue;
×
1427

1428
                } else if ((val = startswith(l, "exec-parameters-stdin-fd="))) {
62,708✔
1429
                        int fd;
551✔
1430

1431
                        fd = deserialize_fd(fds, val);
551✔
1432
                        if (fd < 0)
551✔
UNCOV
1433
                                continue;
×
1434

1435
                        close_and_replace(p->stdin_fd, fd);
551✔
1436

1437
                } else if ((val = startswith(l, "exec-parameters-stdout-fd="))) {
62,157✔
1438
                        int fd;
551✔
1439

1440
                        fd = deserialize_fd(fds, val);
551✔
1441
                        if (fd < 0)
551✔
UNCOV
1442
                                continue;
×
1443

1444
                        close_and_replace(p->stdout_fd, fd);
551✔
1445

1446
                } else if ((val = startswith(l, "exec-parameters-stderr-fd="))) {
61,606✔
1447
                        int fd;
551✔
1448

1449
                        fd = deserialize_fd(fds, val);
551✔
1450
                        if (fd < 0)
551✔
UNCOV
1451
                                continue;
×
1452

1453
                        close_and_replace(p->stderr_fd, fd);
551✔
1454
                } else if ((val = startswith(l, "exec-parameters-exec-fd="))) {
61,055✔
1455
                        int fd;
400✔
1456

1457
                        fd = deserialize_fd(fds, val);
400✔
1458
                        if (fd < 0)
400✔
UNCOV
1459
                                continue;
×
1460

1461
                        close_and_replace(p->exec_fd, fd);
400✔
1462
                } else if ((val = startswith(l, "exec-parameters-handoff-timestamp-fd="))) {
60,655✔
1463
                        int fd;
11,832✔
1464

1465
                        fd = deserialize_fd(fds, val);
11,832✔
1466
                        if (fd < 0)
11,832✔
UNCOV
1467
                                continue;
×
1468

1469
                        close_and_replace(p->handoff_timestamp_fd, fd);
11,832✔
1470
                } else if ((val = startswith(l, "exec-parameters-pidref-transport-fd="))) {
48,823✔
1471
                        int fd;
10,673✔
1472

1473
                        fd = deserialize_fd(fds, val);
10,673✔
1474
                        if (fd < 0)
10,673✔
UNCOV
1475
                                continue;
×
1476

1477
                        close_and_replace(p->pidref_transport_fd, fd);
10,673✔
1478
                } else if ((val = startswith(l, "exec-parameters-bpf-outer-map-fd="))) {
38,150✔
UNCOV
1479
                        int fd;
×
1480

UNCOV
1481
                        fd = deserialize_fd(fds, val);
×
1482
                        if (fd < 0)
×
UNCOV
1483
                                continue;
×
1484

1485
                        close_and_replace(p->bpf_restrict_fs_map_fd, fd);
×
1486
                } else if ((val = startswith(l, "exec-parameters-notify-socket="))) {
38,150✔
1487
                        r = free_and_strdup(&p->notify_socket, val);
2,645✔
1488
                        if (r < 0)
2,645✔
1489
                                return r;
1490
                } else if ((val = startswith(l, "exec-parameters-open-file="))) {
35,505✔
1491
                        OpenFile *of;
5✔
1492

1493
                        r = open_file_parse(val, &of);
5✔
1494
                        if (r < 0)
5✔
UNCOV
1495
                                return r;
×
1496

1497
                        LIST_APPEND(open_files, p->open_files, of);
5✔
1498
                } else if ((val = startswith(l, "exec-parameters-fallback-smack-process-label="))) {
35,500✔
UNCOV
1499
                        r = free_and_strdup(&p->fallback_smack_process_label, val);
×
UNCOV
1500
                        if (r < 0)
×
1501
                                return r;
1502
                } else if ((val = startswith(l, "exec-parameters-user-lookup-fd="))) {
35,500✔
1503
                        int fd;
11,832✔
1504

1505
                        fd = deserialize_fd(fds, val);
11,832✔
1506
                        if (fd < 0)
11,832✔
UNCOV
1507
                                continue;
×
1508

1509
                        close_and_replace(p->user_lookup_fd, fd);
11,832✔
1510
                } else if ((val = startswith(l, "exec-parameters-files-env="))) {
23,668✔
1511
                        r = deserialize_strv(val, &p->files_env);
2✔
1512
                        if (r < 0)
2✔
1513
                                return r;
1514
                } else if ((val = startswith(l, "exec-parameters-unit-id="))) {
23,666✔
1515
                        r = free_and_strdup(&p->unit_id, val);
11,832✔
1516
                        if (r < 0)
11,832✔
1517
                                return r;
1518
                } else if ((val = startswith(l, "exec-parameters-invocation-id-string="))) {
11,834✔
1519
                        if (strlen(val) > SD_ID128_STRING_MAX - 1)
11,832✔
1520
                                return -EINVAL;
1521

1522
                        r = sd_id128_from_string(val, &p->invocation_id);
11,832✔
1523
                        if (r < 0)
11,832✔
1524
                                return r;
1525

1526
                        sd_id128_to_string(p->invocation_id, p->invocation_id_string);
11,832✔
1527
                } else if ((val = startswith(l, "exec-parameters-debug-invocation="))) {
2✔
1528
                        r = parse_boolean(val);
2✔
1529
                        if (r < 0)
2✔
1530
                                return r;
1531

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

1537
        /* Bail out if we got exec-parameters-n-{socket/storage}-fds= but no corresponding
1538
         * exec-parameters-fds= */
1539
        if (p->n_socket_fds + p->n_storage_fds > 0 && !p->fds)
11,832✔
UNCOV
1540
                return -EINVAL;
×
1541

1542
        return 0;
1543
}
1544

1545
static int serialize_std_out_err(const ExecContext *c, FILE *f, int fileno) {
4,488✔
1546
        char *key, *value;
4,488✔
1547
        const char *type;
4,488✔
1548

1549
        assert(c);
4,488✔
1550
        assert(f);
4,488✔
1551
        assert(IN_SET(fileno, STDOUT_FILENO, STDERR_FILENO));
4,488✔
1552

1553
        type = fileno == STDOUT_FILENO ? "output" : "error";
4,488✔
1554

1555
        switch (fileno == STDOUT_FILENO ? c->std_output : c->std_error) {
4,488✔
UNCOV
1556
        case EXEC_OUTPUT_NAMED_FD:
×
UNCOV
1557
                key = strjoina("exec-context-std-", type, "-fd-name");
×
UNCOV
1558
                value = c->stdio_fdname[fileno];
×
1559

1560
                break;
×
1561

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

1566
                break;
2✔
1567

UNCOV
1568
        case EXEC_OUTPUT_FILE_APPEND:
×
UNCOV
1569
                key = strjoina("exec-context-std-", type, "-file-append");
×
UNCOV
1570
                value = c->stdio_file[fileno];
×
1571

1572
                break;
×
1573

UNCOV
1574
        case EXEC_OUTPUT_FILE_TRUNCATE:
×
1575
                key = strjoina("exec-context-std-", type, "-file-truncate");
×
UNCOV
1576
                value = c->stdio_file[fileno];
×
1577

1578
                break;
×
1579

1580
        default:
1581
                return 0;
1582
        }
1583

1584
        return serialize_item(f, key, value);
2✔
1585
}
1586

1587
static int exec_context_serialize(const ExecContext *c, FILE *f) {
2,244✔
1588
        int r;
2,244✔
1589

1590
        assert(f);
2,244✔
1591

1592
        if (!c)
2,244✔
1593
                return 0;
2,244✔
1594

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

1599
        r = serialize_strv(f, "exec-context-environment-files", c->environment_files);
2,244✔
1600
        if (r < 0)
2,244✔
1601
                return r;
1602

1603
        r = serialize_strv(f, "exec-context-pass-environment", c->pass_environment);
2,244✔
1604
        if (r < 0)
2,244✔
1605
                return r;
1606

1607
        r = serialize_strv(f, "exec-context-unset-environment", c->unset_environment);
2,244✔
1608
        if (r < 0)
2,244✔
1609
                return r;
1610

1611
        r = serialize_item_escaped(f, "exec-context-working-directory", c->working_directory);
2,244✔
1612
        if (r < 0)
2,244✔
1613
                return r;
1614

1615
        r = serialize_bool_elide(f, "exec-context-working-directory-missing-ok", c->working_directory_missing_ok);
2,244✔
1616
        if (r < 0)
2,244✔
1617
                return r;
1618

1619
        r = serialize_bool_elide(f, "exec-context-working-directory-home", c->working_directory_home);
2,244✔
1620
        if (r < 0)
2,244✔
1621
                return r;
1622

1623
        r = serialize_item_escaped(f, "exec-context-root-directory", c->root_directory);
2,244✔
1624
        if (r < 0)
2,244✔
1625
                return r;
1626

1627
        r = serialize_item_escaped(f, "exec-context-root-image", c->root_image);
2,244✔
1628
        if (r < 0)
2,244✔
1629
                return r;
1630

1631
        if (c->root_image_options) {
2,244✔
UNCOV
1632
                _cleanup_free_ char *options = NULL;
×
1633

UNCOV
1634
                LIST_FOREACH(mount_options, o, c->root_image_options) {
×
1635
                        if (isempty(o->options))
×
UNCOV
1636
                                continue;
×
1637

1638
                        _cleanup_free_ char *escaped = NULL;
×
1639
                        escaped = shell_escape(o->options, ":");
×
UNCOV
1640
                        if (!escaped)
×
1641
                                return log_oom_debug();
×
1642

1643
                        if (!strextend(&options,
×
1644
                                        " ",
1645
                                        partition_designator_to_string(o->partition_designator),
1646
                                               ":",
1647
                                               escaped))
UNCOV
1648
                                        return log_oom_debug();
×
1649
                }
1650

1651
                r = serialize_item(f, "exec-context-root-image-options", options);
×
UNCOV
1652
                if (r < 0)
×
1653
                        return r;
1654
        }
1655

1656
        r = serialize_item(f, "exec-context-root-verity", c->root_verity);
2,244✔
1657
        if (r < 0)
2,244✔
1658
                return r;
1659

1660
        r = serialize_item(f, "exec-context-root-hash-path", c->root_hash_path);
2,244✔
1661
        if (r < 0)
2,244✔
1662
                return r;
1663

1664
        r = serialize_item(f, "exec-context-root-hash-sig-path", c->root_hash_sig_path);
2,244✔
1665
        if (r < 0)
2,244✔
1666
                return r;
1667

1668
        r = serialize_item_hexmem(f, "exec-context-root-hash", c->root_hash, c->root_hash_size);
2,244✔
1669
        if (r < 0)
2,244✔
1670
                return r;
1671

1672
        r = serialize_item_base64mem(f, "exec-context-root-hash-sig", c->root_hash_sig, c->root_hash_sig_size);
2,244✔
1673
        if (r < 0)
2,244✔
1674
                return r;
1675

1676
        r = serialize_bool_elide(f, "exec-context-root-ephemeral", c->root_ephemeral);
2,244✔
1677
        if (r < 0)
2,244✔
1678
                return r;
1679

1680
        r = serialize_item_format(f, "exec-context-umask", "%04o", c->umask);
2,244✔
1681
        if (r < 0)
2,244✔
1682
                return r;
1683

1684
        r = serialize_bool_elide(f, "exec-context-non-blocking", c->non_blocking);
2,244✔
1685
        if (r < 0)
2,244✔
1686
                return r;
1687

1688
        r = serialize_item_tristate(f, "exec-context-private-mounts", c->private_mounts);
2,244✔
1689
        if (r < 0)
26✔
1690
                return r;
1691

1692
        r = serialize_item_tristate(f, "exec-context-mount-api-vfs", c->mount_apivfs);
2,244✔
1693
        if (r < 0)
2✔
1694
                return r;
1695

1696
        r = serialize_item_tristate(f, "exec-context-bind-log-sockets", c->bind_log_sockets);
2,244✔
UNCOV
1697
        if (r < 0)
×
1698
                return r;
1699

1700
        r = serialize_item_tristate(f, "exec-context-memory-ksm", c->memory_ksm);
2,244✔
UNCOV
1701
        if (r < 0)
×
1702
                return r;
1703

1704
        r = serialize_item(f, "exec-context-private-tmp", private_tmp_to_string(c->private_tmp));
2,244✔
1705
        if (r < 0)
2,244✔
1706
                return r;
1707

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

1714
        r = serialize_bool_elide(f, "exec-context-private-devices", c->private_devices);
2,244✔
1715
        if (r < 0)
2,244✔
1716
                return r;
1717

1718
        r = serialize_bool_elide(f, "exec-context-protect-kernel-tunables", c->protect_kernel_tunables);
2,244✔
1719
        if (r < 0)
2,244✔
1720
                return r;
1721

1722
        r = serialize_bool_elide(f, "exec-context-protect-kernel-modules", c->protect_kernel_modules);
2,244✔
1723
        if (r < 0)
2,244✔
1724
                return r;
1725

1726
        r = serialize_bool_elide(f, "exec-context-protect-kernel-logs", c->protect_kernel_logs);
2,244✔
1727
        if (r < 0)
2,244✔
1728
                return r;
1729

1730
        r = serialize_bool_elide(f, "exec-context-protect-clock", c->protect_clock);
2,244✔
1731
        if (r < 0)
2,244✔
1732
                return r;
1733

1734
        r = serialize_item(f, "exec-context-protect-control-groups", protect_control_groups_to_string(c->protect_control_groups));
2,244✔
1735
        if (r < 0)
2,244✔
1736
                return r;
1737

1738
        r = serialize_bool_elide(f, "exec-context-private-network", c->private_network);
2,244✔
1739
        if (r < 0)
2,244✔
1740
                return r;
1741

1742
        r = serialize_item(f, "exec-context-private-users", private_users_to_string(c->private_users));
2,244✔
1743
        if (r < 0)
2,244✔
1744
                return r;
1745

1746
        r = serialize_bool_elide(f, "exec-context-private-ipc", c->private_ipc);
2,244✔
1747
        if (r < 0)
2,244✔
1748
                return r;
1749

1750
        r = serialize_item(f, "exec-context-private-pids", private_pids_to_string(c->private_pids));
2,244✔
1751
        if (r < 0)
2,244✔
1752
                return r;
1753

1754
        r = serialize_bool_elide(f, "exec-context-remove-ipc", c->remove_ipc);
2,244✔
1755
        if (r < 0)
2,244✔
1756
                return r;
1757

1758
        r = serialize_item(f, "exec-context-protect-home", protect_home_to_string(c->protect_home));
2,244✔
1759
        if (r < 0)
2,244✔
1760
                return r;
1761

1762
        r = serialize_item(f, "exec-context-protect-system", protect_system_to_string(c->protect_system));
2,244✔
1763
        if (r < 0)
2,244✔
1764
                return r;
1765

1766
        r = serialize_bool_elide(f, "exec-context-same-pgrp", c->same_pgrp);
2,244✔
1767
        if (r < 0)
2,244✔
1768
                return r;
1769

1770
        r = serialize_bool(f, "exec-context-ignore-sigpipe", c->ignore_sigpipe);
2,244✔
1771
        if (r < 0)
2,244✔
1772
                return r;
1773

1774
        r = serialize_bool_elide(f, "exec-context-memory-deny-write-execute", c->memory_deny_write_execute);
2,244✔
1775
        if (r < 0)
2,244✔
1776
                return r;
1777

1778
        r = serialize_bool_elide(f, "exec-context-restrict-realtime", c->restrict_realtime);
2,244✔
1779
        if (r < 0)
2,244✔
1780
                return r;
1781

1782
        r = serialize_bool_elide(f, "exec-context-restrict-suid-sgid", c->restrict_suid_sgid);
2,244✔
1783
        if (r < 0)
2,244✔
1784
                return r;
1785

1786
        r = serialize_item(f, "exec-context-keyring-mode", exec_keyring_mode_to_string(c->keyring_mode));
2,244✔
1787
        if (r < 0)
2,244✔
1788
                return r;
1789

1790
        r = serialize_item(f, "exec-context-protect-hostname", protect_hostname_to_string(c->protect_hostname));
2,244✔
1791
        if (r < 0)
2,244✔
1792
                return r;
1793

1794
        r = serialize_item(f, "exec-context-private-hostname", c->private_hostname);
2,244✔
1795
        if (r < 0)
2,244✔
1796
                return r;
1797

1798
        r = serialize_item(f, "exec-context-protect-proc", protect_proc_to_string(c->protect_proc));
2,244✔
1799
        if (r < 0)
2,244✔
1800
                return r;
1801

1802
        r = serialize_item(f, "exec-context-proc-subset", proc_subset_to_string(c->proc_subset));
2,244✔
1803
        if (r < 0)
2,244✔
1804
                return r;
1805

1806
        r = serialize_item(f, "exec-context-runtime-directory-preserve-mode", exec_preserve_mode_to_string(c->runtime_directory_preserve_mode));
2,244✔
1807
        if (r < 0)
2,244✔
1808
                return r;
1809

1810
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
13,464✔
1811
                _cleanup_free_ char *key = NULL, *value = NULL;
11,220✔
1812

1813
                key = strjoin("exec-context-directories-", exec_directory_type_to_string(dt));
11,220✔
1814
                if (!key)
11,220✔
UNCOV
1815
                        return log_oom_debug();
×
1816

1817
                if (asprintf(&value, "%04o", c->directories[dt].mode) < 0)
11,220✔
1818
                        return log_oom_debug();
×
1819

1820
                FOREACH_ARRAY(i, c->directories[dt].items, c->directories[dt].n_items) {
11,638✔
1821
                        _cleanup_free_ char *path_escaped = NULL;
418✔
1822

1823
                        path_escaped = shell_escape(i->path, ":" WHITESPACE);
418✔
1824
                        if (!path_escaped)
418✔
UNCOV
1825
                                return log_oom_debug();
×
1826

1827
                        if (!strextend(&value, " ", path_escaped))
418✔
1828
                                return log_oom_debug();
×
1829

1830
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE))))
831✔
1831
                                return log_oom_debug();
×
1832

1833
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_READ_ONLY))))
834✔
1834
                                return log_oom_debug();
×
1835

1836
                        STRV_FOREACH(d, i->symlinks) {
424✔
1837
                                _cleanup_free_ char *link_escaped = NULL;
6✔
1838

1839
                                link_escaped = shell_escape(*d, ":" WHITESPACE);
6✔
1840
                                if (!link_escaped)
6✔
UNCOV
1841
                                        return log_oom_debug();
×
1842

1843
                                if (!strextend(&value, ":", link_escaped))
6✔
1844
                                        return log_oom_debug();
×
1845
                        }
1846
                }
1847

1848
                r = serialize_item(f, key, value);
11,220✔
1849
                if (r < 0)
11,220✔
1850
                        return r;
1851
        }
1852

1853
        r = serialize_usec(f, "exec-context-timeout-clean-usec", c->timeout_clean_usec);
2,244✔
1854
        if (r < 0)
2,244✔
1855
                return r;
1856

1857
        if (c->nice_set) {
2,244✔
1858
                r = serialize_item_format(f, "exec-context-nice", "%i", c->nice);
2✔
1859
                if (r < 0)
2✔
1860
                        return r;
1861
        }
1862

1863
        if (c->oom_score_adjust_set) {
2,244✔
1864
                r = serialize_item_format(f, "exec-context-oom-score-adjust", "%i", c->oom_score_adjust);
664✔
1865
                if (r < 0)
664✔
1866
                        return r;
1867
        }
1868

1869
        if (c->coredump_filter_set) {
2,244✔
UNCOV
1870
                r = serialize_item_format(f, "exec-context-coredump-filter", "%"PRIx64, c->coredump_filter);
×
UNCOV
1871
                if (r < 0)
×
1872
                        return r;
1873
        }
1874

1875
        for (unsigned i = 0; i < RLIM_NLIMITS; i++) {
38,148✔
1876
                _cleanup_free_ char *key = NULL, *limit = NULL;
4,481✔
1877

1878
                if (!c->rlimit[i])
35,904✔
1879
                        continue;
31,423✔
1880

1881
                key = strjoin("exec-context-limit-", rlimit_to_string(i));
4,481✔
1882
                if (!key)
4,481✔
UNCOV
1883
                        return log_oom_debug();
×
1884

1885
                r = rlimit_format(c->rlimit[i], &limit);
4,481✔
1886
                if (r < 0)
4,481✔
1887
                        return r;
1888

1889
                r = serialize_item(f, key, limit);
4,481✔
1890
                if (r < 0)
4,481✔
1891
                        return r;
1892
        }
1893

1894
        if (c->ioprio_is_set) {
2,244✔
1895
                r = serialize_item_format(f, "exec-context-ioprio", "%d", c->ioprio);
4✔
1896
                if (r < 0)
4✔
1897
                        return r;
1898
        }
1899

1900
        if (c->cpu_sched_set) {
2,244✔
UNCOV
1901
                _cleanup_free_ char *policy_str = NULL;
×
1902

UNCOV
1903
                r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
×
1904
                if (r < 0)
×
1905
                        return r;
1906

1907
                r = serialize_item(f, "exec-context-cpu-scheduling-policy", policy_str);
×
UNCOV
1908
                if (r < 0)
×
1909
                        return r;
1910

1911
                r = serialize_item_format(f, "exec-context-cpu-scheduling-priority", "%i", c->cpu_sched_priority);
×
UNCOV
1912
                if (r < 0)
×
1913
                        return r;
1914

1915
                r = serialize_bool_elide(f, "exec-context-cpu-scheduling-reset-on-fork", c->cpu_sched_reset_on_fork);
×
UNCOV
1916
                if (r < 0)
×
1917
                        return r;
1918
        }
1919

1920
        if (c->cpu_set.set) {
2,244✔
UNCOV
1921
                _cleanup_free_ char *affinity = NULL;
×
1922

UNCOV
1923
                affinity = cpu_set_to_range_string(&c->cpu_set);
×
1924
                if (!affinity)
×
UNCOV
1925
                        return log_oom_debug();
×
1926

1927
                r = serialize_item(f, "exec-context-cpu-affinity", affinity);
×
1928
                if (r < 0)
×
1929
                        return r;
1930
        }
1931

1932
        if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) {
2,244✔
UNCOV
1933
                _cleanup_free_ char *nodes = NULL;
×
1934

UNCOV
1935
                nodes = cpu_set_to_range_string(&c->numa_policy.nodes);
×
1936
                if (!nodes)
×
UNCOV
1937
                        return log_oom_debug();
×
1938

1939
                if (nodes) {
×
1940
                        r = serialize_item(f, "exec-context-numa-mask", nodes);
×
UNCOV
1941
                        if (r < 0)
×
1942
                                return r;
1943
                }
1944

UNCOV
1945
                r = serialize_item_format(f, "exec-context-numa-policy", "%d", c->numa_policy.type);
×
UNCOV
1946
                if (r < 0)
×
1947
                        return r;
1948
        }
1949

1950
        r = serialize_bool_elide(f, "exec-context-cpu-affinity-from-numa", c->cpu_affinity_from_numa);
2,244✔
1951
        if (r < 0)
2,244✔
1952
                return r;
1953

1954
        if (c->timer_slack_nsec != NSEC_INFINITY) {
2,244✔
UNCOV
1955
                r = serialize_item_format(f, "exec-context-timer-slack-nsec", NSEC_FMT, c->timer_slack_nsec);
×
UNCOV
1956
                if (r < 0)
×
1957
                        return r;
1958
        }
1959

1960
        r = serialize_item(f, "exec-context-std-input", exec_input_to_string(c->std_input));
2,244✔
1961
        if (r < 0)
2,244✔
1962
                return r;
1963

1964
        r = serialize_item(f, "exec-context-std-output", exec_output_to_string(c->std_output));
2,244✔
1965
        if (r < 0)
2,244✔
1966
                return r;
1967

1968
        r = serialize_item(f, "exec-context-std-error", exec_output_to_string(c->std_error));
2,244✔
1969
        if (r < 0)
2,244✔
1970
                return r;
1971

1972
        r = serialize_bool_elide(f, "exec-context-stdio-as-fds", c->stdio_as_fds);
2,244✔
1973
        if (r < 0)
2,244✔
1974
                return r;
1975

1976
        switch (c->std_input) {
2,244✔
UNCOV
1977
        case EXEC_INPUT_NAMED_FD:
×
UNCOV
1978
                r = serialize_item(f, "exec-context-std-input-fd-name", c->stdio_fdname[STDIN_FILENO]);
×
UNCOV
1979
                if (r < 0)
×
1980
                        return r;
1981
                break;
1982

UNCOV
1983
        case EXEC_INPUT_FILE:
×
UNCOV
1984
                r = serialize_item(f, "exec-context-std-input-file", c->stdio_file[STDIN_FILENO]);
×
UNCOV
1985
                if (r < 0)
×
1986
                        return r;
1987
                break;
1988

1989
        default:
2,244✔
1990
                ;
2,244✔
1991
        }
1992

1993
        r = serialize_std_out_err(c, f, STDOUT_FILENO);
2,244✔
1994
        if (r < 0)
2,244✔
1995
                return r;
1996

1997
        r = serialize_std_out_err(c, f, STDERR_FILENO);
2,244✔
1998
        if (r < 0)
2,244✔
1999
                return r;
2000

2001
        r = serialize_item_base64mem(f, "exec-context-stdin-data", c->stdin_data, c->stdin_data_size);
2,244✔
2002
        if (r < 0)
2,244✔
2003
                return r;
2004

2005
        r = serialize_item(f, "exec-context-tty-path", c->tty_path);
2,244✔
2006
        if (r < 0)
2,244✔
2007
                return r;
2008

2009
        r = serialize_bool_elide(f, "exec-context-tty-reset", c->tty_reset);
2,244✔
2010
        if (r < 0)
2,244✔
2011
                return r;
2012

2013
        r = serialize_bool_elide(f, "exec-context-tty-vhangup", c->tty_vhangup);
2,244✔
2014
        if (r < 0)
2,244✔
2015
                return r;
2016

2017
        r = serialize_bool_elide(f, "exec-context-tty-vt-disallocate", c->tty_vt_disallocate);
2,244✔
2018
        if (r < 0)
2,244✔
2019
                return r;
2020

2021
        r = serialize_item_format(f, "exec-context-tty-rows", "%u", c->tty_rows);
2,244✔
2022
        if (r < 0)
2,244✔
2023
                return r;
2024

2025
        r = serialize_item_format(f, "exec-context-tty-columns", "%u", c->tty_cols);
2,244✔
2026
        if (r < 0)
2,244✔
2027
                return r;
2028

2029
        r = serialize_item_format(f, "exec-context-syslog-priority", "%i", c->syslog_priority);
2,244✔
2030
        if (r < 0)
2,244✔
2031
                return r;
2032

2033
        r = serialize_bool(f, "exec-context-syslog-level-prefix", c->syslog_level_prefix);
2,244✔
2034
        if (r < 0)
2,244✔
2035
                return r;
2036

2037
        r = serialize_item(f, "exec-context-syslog-identifier", c->syslog_identifier);
2,244✔
2038
        if (r < 0)
2,244✔
2039
                return r;
2040

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

2047
        if (c->log_ratelimit.interval > 0) {
2,244✔
UNCOV
2048
                r = serialize_usec(f, "exec-context-log-ratelimit-interval-usec", c->log_ratelimit.interval);
×
UNCOV
2049
                if (r < 0)
×
2050
                        return r;
2051
        }
2052

2053
        if (c->log_ratelimit.burst > 0) {
2,244✔
UNCOV
2054
                r = serialize_item_format(f, "exec-context-log-ratelimit-burst", "%u", c->log_ratelimit.burst);
×
UNCOV
2055
                if (r < 0)
×
2056
                        return r;
2057
        }
2058

2059
        r = serialize_string_set(f, "exec-context-log-filter-allowed-patterns", c->log_filter_allowed_patterns);
2,244✔
2060
        if (r < 0)
2,244✔
2061
                return r;
2062

2063
        r = serialize_string_set(f, "exec-context-log-filter-denied-patterns", c->log_filter_denied_patterns);
2,244✔
2064
        if (r < 0)
2,244✔
2065
                return r;
2066

2067
        FOREACH_ARRAY(field, c->log_extra_fields, c->n_log_extra_fields) {
2,244✔
UNCOV
2068
                r = serialize_item(f, "exec-context-log-extra-fields", field->iov_base);
×
UNCOV
2069
                if (r < 0)
×
2070
                        return r;
2071
        }
2072

2073
        r = serialize_item(f, "exec-context-log-namespace", c->log_namespace);
2,244✔
2074
        if (r < 0)
2,244✔
2075
                return r;
2076

2077
        if (c->secure_bits != 0) {
2,244✔
UNCOV
2078
                r = serialize_item_format(f, "exec-context-secure-bits", "%d", c->secure_bits);
×
UNCOV
2079
                if (r < 0)
×
2080
                        return r;
2081
        }
2082

2083
        if (c->capability_bounding_set != CAP_MASK_UNSET) {
2,244✔
2084
                r = serialize_item_format(f, "exec-context-capability-bounding-set", "%" PRIu64, c->capability_bounding_set);
256✔
2085
                if (r < 0)
256✔
2086
                        return r;
2087
        }
2088

2089
        if (c->capability_ambient_set != 0) {
2,244✔
2090
                r = serialize_item_format(f, "exec-context-capability-ambient-set", "%" PRIu64, c->capability_ambient_set);
69✔
2091
                if (r < 0)
69✔
2092
                        return r;
2093
        }
2094

2095
        if (c->user) {
2,244✔
2096
                r = serialize_item(f, "exec-context-user", c->user);
150✔
2097
                if (r < 0)
150✔
2098
                        return r;
2099
        }
2100

2101
        r = serialize_item(f, "exec-context-group", c->group);
2,244✔
2102
        if (r < 0)
2,244✔
2103
                return r;
2104

2105
        r = serialize_bool_elide(f, "exec-context-dynamic-user", c->dynamic_user);
2,244✔
2106
        if (r < 0)
2,244✔
2107
                return r;
2108

2109
        r = serialize_strv(f, "exec-context-supplementary-groups", c->supplementary_groups);
2,244✔
2110
        if (r < 0)
2,244✔
2111
                return r;
2112

2113
        r = serialize_item_tristate(f, "exec-context-set-login-environment", c->set_login_environment);
2,244✔
UNCOV
2114
        if (r < 0)
×
2115
                return r;
2116

2117
        r = serialize_item(f, "exec-context-pam-name", c->pam_name);
2,244✔
2118
        if (r < 0)
2,244✔
2119
                return r;
2120

2121
        r = serialize_strv(f, "exec-context-read-write-paths", c->read_write_paths);
2,244✔
2122
        if (r < 0)
2,244✔
2123
                return r;
2124

2125
        r = serialize_strv(f, "exec-context-read-only-paths", c->read_only_paths);
2,244✔
2126
        if (r < 0)
2,244✔
2127
                return r;
2128

2129
        r = serialize_strv(f, "exec-context-inaccessible-paths", c->inaccessible_paths);
2,244✔
2130
        if (r < 0)
2,244✔
2131
                return r;
2132

2133
        r = serialize_strv(f, "exec-context-exec-paths", c->exec_paths);
2,244✔
2134
        if (r < 0)
2,244✔
2135
                return r;
2136

2137
        r = serialize_strv(f, "exec-context-no-exec-paths", c->no_exec_paths);
2,244✔
2138
        if (r < 0)
2,244✔
2139
                return r;
2140

2141
        r = serialize_strv(f, "exec-context-exec-search-path", c->exec_search_path);
2,244✔
2142
        if (r < 0)
2,244✔
2143
                return r;
2144

2145
        r = serialize_item_format(f, "exec-context-mount-propagation-flag", "%lu", c->mount_propagation_flag);
2,244✔
2146
        if (r < 0)
2,244✔
2147
                return r;
2148

2149
        FOREACH_ARRAY(mount, c->bind_mounts, c->n_bind_mounts) {
2,259✔
2150
                _cleanup_free_ char *src_escaped = NULL, *dst_escaped = NULL;
15✔
2151

2152
                src_escaped = shell_escape(mount->source, ":" WHITESPACE);
15✔
2153
                if (!src_escaped)
15✔
UNCOV
2154
                        return log_oom_debug();
×
2155

2156
                dst_escaped = shell_escape(mount->destination, ":" WHITESPACE);
15✔
2157
                if (!dst_escaped)
15✔
UNCOV
2158
                        return log_oom_debug();
×
2159

2160
                r = serialize_item_format(f,
15✔
2161
                                          mount->read_only ? "exec-context-bind-read-only-path" : "exec-context-bind-path",
15✔
2162
                                          "%s%s:%s:%s",
2163
                                          mount->ignore_enoent ? "-" : "",
15✔
2164
                                          src_escaped,
2165
                                          dst_escaped,
2166
                                          mount->recursive ? "rbind" : "norbind");
15✔
2167
                if (r < 0)
15✔
2168
                        return r;
2169
        }
2170

2171
        FOREACH_ARRAY(tmpfs, c->temporary_filesystems, c->n_temporary_filesystems) {
2,248✔
2172
                _cleanup_free_ char *escaped = NULL;
4✔
2173

2174
                if (!isempty(tmpfs->options)) {
4✔
UNCOV
2175
                        escaped = shell_escape(tmpfs->options, ":");
×
UNCOV
2176
                        if (!escaped)
×
UNCOV
2177
                                return log_oom_debug();
×
2178
                }
2179

2180
                r = serialize_item_format(f, "exec-context-temporary-filesystems", "%s%s%s",
×
2181
                                          tmpfs->path,
2182
                                          isempty(escaped) ? "" : ":",
4✔
2183
                                          strempty(escaped));
2184
                if (r < 0)
4✔
2185
                        return r;
2186
        }
2187

2188
        r = serialize_item(f, "exec-context-utmp-id", c->utmp_id);
2,244✔
2189
        if (r < 0)
2,244✔
2190
                return r;
2191

2192
        r = serialize_item(f, "exec-context-utmp-mode", exec_utmp_mode_to_string(c->utmp_mode));
2,244✔
2193
        if (r < 0)
2,244✔
2194
                return r;
2195

2196
        r = serialize_bool_elide(f, "exec-context-no-new-privileges", c->no_new_privileges);
2,244✔
2197
        if (r < 0)
2,244✔
2198
                return r;
2199

2200
        if (c->selinux_context) {
2,244✔
UNCOV
2201
                r = serialize_item_format(f, "exec-context-selinux-context",
×
2202
                                          "%s%s",
UNCOV
2203
                                          c->selinux_context_ignore ? "-" : "",
×
2204
                                          c->selinux_context);
UNCOV
2205
                if (r < 0)
×
2206
                        return r;
2207
        }
2208

2209
        if (c->apparmor_profile) {
2,244✔
UNCOV
2210
                r = serialize_item_format(f, "exec-context-apparmor-profile",
×
2211
                                          "%s%s",
UNCOV
2212
                                          c->apparmor_profile_ignore ? "-" : "",
×
2213
                                          c->apparmor_profile);
UNCOV
2214
                if (r < 0)
×
2215
                        return r;
2216
        }
2217

2218
        if (c->smack_process_label) {
2,244✔
UNCOV
2219
                r = serialize_item_format(f, "exec-context-smack-process-label",
×
2220
                                          "%s%s",
UNCOV
2221
                                          c->smack_process_label_ignore ? "-" : "",
×
2222
                                          c->smack_process_label);
UNCOV
2223
                if (r < 0)
×
2224
                        return r;
2225
        }
2226

2227
        if (c->personality != PERSONALITY_INVALID) {
2,244✔
UNCOV
2228
                r = serialize_item(f, "exec-context-personality", personality_to_string(c->personality));
×
UNCOV
2229
                if (r < 0)
×
2230
                        return r;
2231
        }
2232

2233
        r = serialize_bool_elide(f, "exec-context-lock-personality", c->lock_personality);
2,244✔
2234
        if (r < 0)
2,244✔
2235
                return r;
2236

2237
#if HAVE_SECCOMP
2238
        if (!hashmap_isempty(c->syscall_filter)) {
2,244✔
2239
                void *errno_num, *id;
217✔
2240
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_filter) {
85,064✔
2241
                        r = serialize_item_format(f, "exec-context-syscall-filter", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
84,847✔
2242
                        if (r < 0)
84,847✔
UNCOV
2243
                                return r;
×
2244
                }
2245
        }
2246

2247
        if (!set_isempty(c->syscall_archs)) {
2,244✔
2248
                void *id;
217✔
2249
                SET_FOREACH(id, c->syscall_archs) {
434✔
2250
                        r = serialize_item_format(f, "exec-context-syscall-archs", "%u", PTR_TO_UINT(id) - 1);
217✔
2251
                        if (r < 0)
217✔
UNCOV
2252
                                return r;
×
2253
                }
2254
        }
2255

2256
        if (c->syscall_errno > 0) {
2,244✔
2257
                r = serialize_item_format(f, "exec-context-syscall-errno", "%d", c->syscall_errno);
2,244✔
2258
                if (r < 0)
2,244✔
2259
                        return r;
2260
        }
2261

2262
        r = serialize_bool_elide(f, "exec-context-syscall-allow-list", c->syscall_allow_list);
2,244✔
2263
        if (r < 0)
2,244✔
2264
                return r;
2265

2266
        if (!hashmap_isempty(c->syscall_log)) {
2,244✔
UNCOV
2267
                void *errno_num, *id;
×
UNCOV
2268
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_log) {
×
UNCOV
2269
                        r = serialize_item_format(f, "exec-context-syscall-log", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
×
2270
                        if (r < 0)
×
2271
                                return r;
×
2272
                }
2273
        }
2274

2275
        r = serialize_bool_elide(f, "exec-context-syscall-log-allow-list", c->syscall_log_allow_list);
2,244✔
2276
        if (r < 0)
2,244✔
2277
                return r;
2278
#endif
2279

2280
        if (c->restrict_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,244✔
2281
                r = serialize_item_format(f, "exec-context-restrict-namespaces", "%lu", c->restrict_namespaces);
174✔
2282
                if (r < 0)
174✔
2283
                        return r;
2284
        }
2285

2286
        if (c->delegate_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,244✔
2287
                r = serialize_item_format(f, "exec-context-delegate-namespaces", "%lu", c->delegate_namespaces);
9✔
2288
                if (r < 0)
9✔
2289
                        return r;
2290
        }
2291

2292
#if HAVE_LIBBPF
2293
        if (exec_context_restrict_filesystems_set(c)) {
2,244✔
UNCOV
2294
                char *fs;
×
UNCOV
2295
                SET_FOREACH(fs, c->restrict_filesystems) {
×
UNCOV
2296
                        r = serialize_item(f, "exec-context-restrict-filesystems", fs);
×
2297
                        if (r < 0)
×
2298
                                return r;
×
2299
                }
2300
        }
2301

2302
        r = serialize_bool_elide(f, "exec-context-restrict-filesystems-allow-list", c->restrict_filesystems_allow_list);
2,244✔
2303
        if (r < 0)
2,244✔
2304
                return r;
2305
#endif
2306

2307
        if (!set_isempty(c->address_families)) {
2,244✔
2308
                void *afp;
217✔
2309

2310
                SET_FOREACH(afp, c->address_families) {
1,054✔
2311
                        int af = PTR_TO_INT(afp);
837✔
2312

2313
                        if (af <= 0 || af >= af_max())
837✔
UNCOV
2314
                                continue;
×
2315

2316
                        r = serialize_item_format(f, "exec-context-address-families", "%d", af);
837✔
2317
                        if (r < 0)
837✔
UNCOV
2318
                                return r;
×
2319
                }
2320
        }
2321

2322
        r = serialize_bool_elide(f, "exec-context-address-families-allow-list", c->address_families_allow_list);
2,244✔
2323
        if (r < 0)
2,244✔
2324
                return r;
2325

2326
        r = serialize_item(f, "exec-context-network-namespace-path", c->network_namespace_path);
2,244✔
2327
        if (r < 0)
2,244✔
2328
                return r;
2329

2330
        r = serialize_item(f, "exec-context-ipc-namespace-path", c->ipc_namespace_path);
2,244✔
2331
        if (r < 0)
2,244✔
2332
                return r;
2333

2334
        FOREACH_ARRAY(mount, c->mount_images, c->n_mount_images) {
2,244✔
UNCOV
2335
                _cleanup_free_ char *s = NULL, *source_escaped = NULL, *dest_escaped = NULL;
×
2336

UNCOV
2337
                source_escaped = shell_escape(mount->source, WHITESPACE);
×
2338
                if (!source_escaped)
×
UNCOV
2339
                        return log_oom_debug();
×
2340

2341
                dest_escaped = shell_escape(mount->destination, WHITESPACE);
×
2342
                if (!dest_escaped)
×
UNCOV
2343
                        return log_oom_debug();
×
2344

2345
                s = strjoin(mount->ignore_enoent ? "-" : "",
×
2346
                            source_escaped,
2347
                            " ",
2348
                            dest_escaped);
UNCOV
2349
                if (!s)
×
UNCOV
2350
                        return log_oom_debug();
×
2351

2352
                LIST_FOREACH(mount_options, o, mount->mount_options) {
×
2353
                        _cleanup_free_ char *escaped = NULL;
×
2354

2355
                        if (isempty(o->options))
×
2356
                                continue;
×
2357

2358
                        escaped = shell_escape(o->options, ":");
×
2359
                        if (!escaped)
×
UNCOV
2360
                                return log_oom_debug();
×
2361

2362
                        if (!strextend(&s,
×
2363
                                       " ",
2364
                                       partition_designator_to_string(o->partition_designator),
2365
                                       ":",
2366
                                       escaped))
UNCOV
2367
                                return log_oom_debug();
×
2368
                }
2369

2370
                r = serialize_item(f, "exec-context-mount-image", s);
×
UNCOV
2371
                if (r < 0)
×
2372
                        return r;
2373
        }
2374

2375
        FOREACH_ARRAY(mount, c->extension_images, c->n_extension_images) {
2,244✔
UNCOV
2376
                _cleanup_free_ char *s = NULL, *source_escaped = NULL;
×
2377

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

2382
                s = strjoin(mount->ignore_enoent ? "-" : "",
×
2383
                            source_escaped);
UNCOV
2384
                if (!s)
×
2385
                        return log_oom_debug();
×
2386

2387
                LIST_FOREACH(mount_options, o, mount->mount_options) {
×
2388
                        _cleanup_free_ char *escaped = NULL;
×
2389

2390
                        if (isempty(o->options))
×
2391
                                continue;
×
2392

2393
                        escaped = shell_escape(o->options, ":");
×
2394
                        if (!escaped)
×
UNCOV
2395
                                return log_oom_debug();
×
2396

2397
                        if (!strextend(&s,
×
2398
                                       " ",
2399
                                       partition_designator_to_string(o->partition_designator),
2400
                                       ":",
2401
                                       escaped))
UNCOV
2402
                                return log_oom_debug();
×
2403
                }
2404

2405
                r = serialize_item(f, "exec-context-extension-image", s);
×
UNCOV
2406
                if (r < 0)
×
2407
                        return r;
2408
        }
2409

2410
        r = serialize_strv(f, "exec-context-extension-directories", c->extension_directories);
2,244✔
2411
        if (r < 0)
2,244✔
2412
                return r;
2413

2414
        ExecSetCredential *sc;
2,244✔
2415
        HASHMAP_FOREACH(sc, c->set_credentials) {
2,244✔
UNCOV
2416
                _cleanup_free_ char *data = NULL;
×
2417

UNCOV
2418
                if (base64mem(sc->data, sc->size, &data) < 0)
×
2419
                        return log_oom_debug();
×
2420

2421
                r = serialize_item_format(f, "exec-context-set-credentials", "%s %s %s", sc->id, data, yes_no(sc->encrypted));
×
2422
                if (r < 0)
×
2423
                        return r;
2424
        }
2425

2426
        ExecLoadCredential *lc;
2,244✔
2427
        HASHMAP_FOREACH(lc, c->load_credentials) {
2,252✔
2428
                r = serialize_item_format(f, "exec-context-load-credentials", "%s %s %s", lc->id, lc->path, yes_no(lc->encrypted));
15✔
2429
                if (r < 0)
8✔
UNCOV
2430
                        return r;
×
2431
        }
2432

2433
        ExecImportCredential *ic;
2,244✔
2434
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
3,076✔
2435
                r = serialize_item_format(f, "exec-context-import-credentials", "%s%s%s",
1,616✔
2436
                                          ic->glob,
2437
                                          ic->rename ? " " : "",
2438
                                          strempty(ic->rename));
832✔
2439
                if (r < 0)
832✔
UNCOV
2440
                        return r;
×
2441
        }
2442

2443
        r = serialize_image_policy(f, "exec-context-root-image-policy", c->root_image_policy);
2,244✔
2444
        if (r < 0)
2,244✔
2445
                return r;
2446

2447
        r = serialize_image_policy(f, "exec-context-mount-image-policy", c->mount_image_policy);
2,244✔
2448
        if (r < 0)
2,244✔
2449
                return r;
2450

2451
        r = serialize_image_policy(f, "exec-context-extension-image-policy", c->extension_image_policy);
2,244✔
2452
        if (r < 0)
2,244✔
2453
                return r;
2454

2455
        fputc('\n', f); /* End marker */
2,244✔
2456

2457
        return 0;
2458
}
2459

2460
static int exec_context_deserialize(ExecContext *c, FILE *f) {
11,832✔
2461
        int r;
11,832✔
2462

2463
        assert(f);
11,832✔
2464

2465
        if (!c)
11,832✔
2466
                return 0;
2467

2468
        for (;;) {
1,320,396✔
2469
                _cleanup_free_ char *l = NULL;
1,308,564✔
2470
                const char *val;
1,320,396✔
2471

2472
                r = deserialize_read_line(f, &l);
1,320,396✔
2473
                if (r < 0)
1,320,396✔
2474
                        return r;
2475
                if (r == 0) /* eof or end marker */
1,320,396✔
2476
                        break;
2477

2478
                if ((val = startswith(l, "exec-context-environment="))) {
1,308,564✔
2479
                        r = deserialize_strv(val, &c->environment);
3,922✔
2480
                        if (r < 0)
3,922✔
2481
                                return r;
2482
                } else if ((val = startswith(l, "exec-context-environment-files="))) {
1,304,642✔
2483
                        r = deserialize_strv(val, &c->environment_files);
340✔
2484
                        if (r < 0)
340✔
2485
                                return r;
2486
                } else if ((val = startswith(l, "exec-context-pass-environment="))) {
1,304,302✔
2487
                        r = deserialize_strv(val, &c->pass_environment);
431✔
2488
                        if (r < 0)
431✔
2489
                                return r;
2490
                } else if ((val = startswith(l, "exec-context-unset-environment="))) {
1,303,871✔
2491
                        r = deserialize_strv(val, &c->unset_environment);
1,440✔
2492
                        if (r < 0)
1,440✔
2493
                                return r;
2494
                } else if ((val = startswith(l, "exec-context-working-directory="))) {
1,302,431✔
2495
                        ssize_t k;
871✔
2496
                        char *p;
871✔
2497

2498
                        k = cunescape(val, 0, &p);
871✔
2499
                        if (k < 0)
871✔
UNCOV
2500
                                return k;
×
2501
                        free_and_replace(c->working_directory, p);
871✔
2502
                } else if ((val = startswith(l, "exec-context-root-directory="))) {
1,301,560✔
2503
                        ssize_t k;
7✔
2504
                        char *p;
7✔
2505

2506
                        k = cunescape(val, 0, &p);
7✔
2507
                        if (k < 0)
7✔
UNCOV
2508
                                return k;
×
2509
                        free_and_replace(c->root_directory, p);
7✔
2510
                } else if ((val = startswith(l, "exec-context-root-image="))) {
1,301,553✔
2511
                        ssize_t k;
8✔
2512
                        char *p;
8✔
2513

2514
                        k = cunescape(val, 0, &p);
8✔
2515
                        if (k < 0)
8✔
UNCOV
2516
                                return k;
×
2517
                        free_and_replace(c->root_image, p);
8✔
2518
                } else if ((val = startswith(l, "exec-context-root-image-options="))) {
1,301,545✔
2519
                        for (;;) {
×
UNCOV
2520
                                _cleanup_free_ char *word = NULL, *mount_options = NULL, *partition = NULL;
×
UNCOV
2521
                                PartitionDesignator partition_designator;
×
2522
                                MountOptions *o = NULL;
×
2523
                                const char *p;
×
2524

2525
                                r = extract_first_word(&val, &word, NULL, 0);
×
2526
                                if (r < 0)
×
2527
                                        return r;
2528
                                if (r == 0)
×
2529
                                        break;
2530

2531
                                p = word;
×
UNCOV
2532
                                r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options);
×
UNCOV
2533
                                if (r < 0)
×
2534
                                        return r;
2535
                                if (r == 0)
×
2536
                                        continue;
×
2537

2538
                                partition_designator = partition_designator_from_string(partition);
×
2539
                                if (partition_designator < 0)
×
2540
                                        return -EINVAL;
2541

2542
                                o = new(MountOptions, 1);
×
UNCOV
2543
                                if (!o)
×
UNCOV
2544
                                        return log_oom_debug();
×
2545
                                *o = (MountOptions) {
×
2546
                                        .partition_designator = partition_designator,
2547
                                        .options = TAKE_PTR(mount_options),
×
2548
                                };
UNCOV
2549
                                LIST_APPEND(mount_options, c->root_image_options, o);
×
2550
                        }
2551
                } else if ((val = startswith(l, "exec-context-root-verity="))) {
1,301,545✔
2552
                        r = free_and_strdup(&c->root_verity, val);
×
UNCOV
2553
                        if (r < 0)
×
2554
                                return r;
2555
                } else if ((val = startswith(l, "exec-context-root-hash-path="))) {
1,301,545✔
2556
                        r = free_and_strdup(&c->root_hash_path, val);
×
UNCOV
2557
                        if (r < 0)
×
2558
                                return r;
2559
                } else if ((val = startswith(l, "exec-context-root-hash-sig-path="))) {
1,301,545✔
2560
                        r = free_and_strdup(&c->root_hash_sig_path, val);
×
UNCOV
2561
                        if (r < 0)
×
2562
                                return r;
2563
                } else if ((val = startswith(l, "exec-context-root-hash="))) {
1,301,545✔
2564
                        c->root_hash = mfree(c->root_hash);
4✔
2565
                        r = unhexmem(val, &c->root_hash, &c->root_hash_size);
4✔
2566
                        if (r < 0)
4✔
2567
                                return r;
2568
                } else if ((val = startswith(l, "exec-context-root-hash-sig="))) {
1,301,541✔
UNCOV
2569
                        c->root_hash_sig = mfree(c->root_hash_sig);
×
UNCOV
2570
                        r= unbase64mem(val, &c->root_hash_sig, &c->root_hash_sig_size);
×
UNCOV
2571
                        if (r < 0)
×
2572
                                return r;
2573
                } else if ((val = startswith(l, "exec-context-root-ephemeral="))) {
1,301,541✔
2574
                        r = parse_boolean(val);
×
UNCOV
2575
                        if (r < 0)
×
2576
                                return r;
2577
                        c->root_ephemeral = r;
×
2578
                } else if ((val = startswith(l, "exec-context-umask="))) {
1,301,541✔
2579
                        r = parse_mode(val, &c->umask);
11,832✔
2580
                        if (r < 0)
11,832✔
2581
                                return r;
2582
                } else if ((val = startswith(l, "exec-context-private-non-blocking="))) {
1,289,709✔
UNCOV
2583
                        r = parse_boolean(val);
×
UNCOV
2584
                        if (r < 0)
×
2585
                                return r;
2586
                        c->non_blocking = r;
×
2587
                } else if ((val = startswith(l, "exec-context-private-mounts="))) {
1,289,709✔
2588
                        r = safe_atoi(val, &c->private_mounts);
128✔
2589
                        if (r < 0)
128✔
2590
                                return r;
2591
                } else if ((val = startswith(l, "exec-context-mount-api-vfs="))) {
1,289,581✔
2592
                        r = safe_atoi(val, &c->mount_apivfs);
30✔
2593
                        if (r < 0)
30✔
2594
                                return r;
2595
                } else if ((val = startswith(l, "exec-context-bind-log-sockets="))) {
1,289,551✔
2596
                        r = safe_atoi(val, &c->bind_log_sockets);
2✔
2597
                        if (r < 0)
2✔
2598
                                return r;
2599
                } else if ((val = startswith(l, "exec-context-memory-ksm="))) {
1,289,549✔
UNCOV
2600
                        r = safe_atoi(val, &c->memory_ksm);
×
UNCOV
2601
                        if (r < 0)
×
2602
                                return r;
2603
                } else if ((val = startswith(l, "exec-context-private-tmp="))) {
1,289,549✔
2604
                        c->private_tmp = private_tmp_from_string(val);
11,832✔
2605
                        if (c->private_tmp < 0)
11,832✔
2606
                                return c->private_tmp;
2607
                } else if ((val = startswith(l, "exec-context-private-var-tmp="))) {
1,277,717✔
2608
                        c->private_var_tmp = private_tmp_from_string(val);
11,832✔
2609
                        if (c->private_var_tmp < 0)
11,832✔
2610
                                return c->private_var_tmp;
2611
                } else if ((val = startswith(l, "exec-context-private-devices="))) {
1,265,885✔
2612
                        r = parse_boolean(val);
720✔
2613
                        if (r < 0)
720✔
2614
                                return r;
2615
                        c->private_devices = r;
720✔
2616
                } else if ((val = startswith(l, "exec-context-protect-kernel-tunables="))) {
1,265,165✔
2617
                        r = parse_boolean(val);
533✔
2618
                        if (r < 0)
533✔
2619
                                return r;
2620
                        c->protect_kernel_tunables = r;
533✔
2621
                } else if ((val = startswith(l, "exec-context-protect-kernel-modules="))) {
1,264,632✔
2622
                        r = parse_boolean(val);
1,751✔
2623
                        if (r < 0)
1,751✔
2624
                                return r;
2625
                        c->protect_kernel_modules = r;
1,751✔
2626
                } else if ((val = startswith(l, "exec-context-protect-kernel-logs="))) {
1,262,881✔
2627
                        r = parse_boolean(val);
1,751✔
2628
                        if (r < 0)
1,751✔
2629
                                return r;
2630
                        c->protect_kernel_logs = r;
1,751✔
2631
                } else if ((val = startswith(l, "exec-context-protect-clock="))) {
1,261,130✔
2632
                        r = parse_boolean(val);
1,588✔
2633
                        if (r < 0)
1,588✔
2634
                                return r;
2635
                        c->protect_clock = r;
1,588✔
2636
                } else if ((val = startswith(l, "exec-context-protect-control-groups="))) {
1,259,542✔
2637
                        r = protect_control_groups_from_string(val);
11,832✔
2638
                        if (r < 0)
11,832✔
2639
                                return r;
2640
                        c->protect_control_groups = r;
11,832✔
2641
                } else if ((val = startswith(l, "exec-context-private-network="))) {
1,247,710✔
2642
                        r = parse_boolean(val);
64✔
2643
                        if (r < 0)
64✔
2644
                                return r;
2645
                        c->private_network = r;
64✔
2646
                } else if ((val = startswith(l, "exec-context-private-users="))) {
1,247,646✔
2647
                        c->private_users = private_users_from_string(val);
11,832✔
2648
                        if (c->private_users < 0)
11,832✔
2649
                                return -EINVAL;
2650
                } else if ((val = startswith(l, "exec-context-private-ipc="))) {
1,235,814✔
2651
                        r = parse_boolean(val);
6✔
2652
                        if (r < 0)
6✔
2653
                                return r;
2654
                        c->private_ipc = r;
6✔
2655
                } else if ((val = startswith(l, "exec-context-private-pids="))) {
1,235,808✔
2656
                        c->private_pids = private_pids_from_string(val);
11,832✔
2657
                        if (c->private_pids < 0)
11,832✔
2658
                                return -EINVAL;
2659
                } else if ((val = startswith(l, "exec-context-remove-ipc="))) {
1,223,976✔
2660
                        r = parse_boolean(val);
70✔
2661
                        if (r < 0)
70✔
2662
                                return r;
2663
                        c->remove_ipc = r;
70✔
2664
                } else if ((val = startswith(l, "exec-context-protect-home="))) {
1,223,906✔
2665
                        c->protect_home = protect_home_from_string(val);
11,832✔
2666
                        if (c->protect_home < 0)
11,832✔
2667
                                return -EINVAL;
2668
                } else if ((val = startswith(l, "exec-context-protect-system="))) {
1,212,074✔
2669
                        c->protect_system = protect_system_from_string(val);
11,832✔
2670
                        if (c->protect_system < 0)
11,832✔
2671
                                return -EINVAL;
2672
                } else if ((val = startswith(l, "exec-context-same-pgrp="))) {
1,200,242✔
2673
                        r = parse_boolean(val);
847✔
2674
                        if (r < 0)
847✔
2675
                                return r;
2676
                        c->same_pgrp = r;
847✔
2677
                } else if ((val = startswith(l, "exec-context-non-blocking="))) {
1,199,395✔
UNCOV
2678
                        r = parse_boolean(val);
×
UNCOV
2679
                        if (r < 0)
×
2680
                                return r;
2681
                        c->non_blocking = r;
×
2682
                } else if ((val = startswith(l, "exec-context-ignore-sigpipe="))) {
1,199,395✔
2683
                        r = parse_boolean(val);
11,832✔
2684
                        if (r < 0)
11,832✔
2685
                                return r;
2686
                        c->ignore_sigpipe = r;
11,832✔
2687
                } else if ((val = startswith(l, "exec-context-memory-deny-write-execute="))) {
1,187,563✔
2688
                        r = parse_boolean(val);
2,236✔
2689
                        if (r < 0)
2,236✔
2690
                                return r;
2691
                        c->memory_deny_write_execute = r;
2,236✔
2692
                } else if ((val = startswith(l, "exec-context-restrict-realtime="))) {
1,185,327✔
2693
                        r = parse_boolean(val);
2,236✔
2694
                        if (r < 0)
2,236✔
2695
                                return r;
2696
                        c->restrict_realtime = r;
2,236✔
2697
                } else if ((val = startswith(l, "exec-context-restrict-suid-sgid="))) {
1,183,091✔
2698
                        r = parse_boolean(val);
2,172✔
2699
                        if (r < 0)
2,172✔
2700
                                return r;
2701
                        c->restrict_suid_sgid = r;
2,172✔
2702
                } else if ((val = startswith(l, "exec-context-keyring-mode="))) {
1,180,919✔
2703
                        c->keyring_mode = exec_keyring_mode_from_string(val);
11,832✔
2704
                        if (c->keyring_mode < 0)
11,832✔
2705
                                return -EINVAL;
2706
                } else if ((val = startswith(l, "exec-context-protect-hostname="))) {
1,169,087✔
2707
                        c->protect_hostname = protect_hostname_from_string(val);
11,832✔
2708
                        if (c->protect_hostname < 0)
11,832✔
2709
                                return -EINVAL;
2710
                } else if ((val = startswith(l, "exec-context-private-hostname="))) {
1,157,255✔
2711
                        r = free_and_strdup(&c->private_hostname, val);
5✔
2712
                        if (r < 0)
5✔
2713
                                return r;
2714
                } else if ((val = startswith(l, "exec-context-protect-proc="))) {
1,157,250✔
2715
                        c->protect_proc = protect_proc_from_string(val);
11,832✔
2716
                        if (c->protect_proc < 0)
11,832✔
2717
                                return -EINVAL;
2718
                } else if ((val = startswith(l, "exec-context-proc-subset="))) {
1,145,418✔
2719
                        c->proc_subset = proc_subset_from_string(val);
11,832✔
2720
                        if (c->proc_subset < 0)
11,832✔
2721
                                return -EINVAL;
2722
                } else if ((val = startswith(l, "exec-context-runtime-directory-preserve-mode="))) {
1,133,586✔
2723
                        c->runtime_directory_preserve_mode = exec_preserve_mode_from_string(val);
11,832✔
2724
                        if (c->runtime_directory_preserve_mode < 0)
11,832✔
2725
                                return -EINVAL;
2726
                } else if ((val = startswith(l, "exec-context-directories-"))) {
1,121,754✔
UNCOV
2727
                        _cleanup_free_ char *type = NULL, *mode = NULL;
×
2728
                        ExecDirectoryType dt;
59,160✔
2729

2730
                        r = extract_many_words(&val, "= ", 0, &type, &mode);
59,160✔
2731
                        if (r < 0)
59,160✔
2732
                                return r;
2733
                        if (r == 0 || !mode)
59,160✔
2734
                                return -EINVAL;
2735

2736
                        dt = exec_directory_type_from_string(type);
59,160✔
2737
                        if (dt < 0)
59,160✔
2738
                                return -EINVAL;
2739

2740
                        r = parse_mode(mode, &c->directories[dt].mode);
59,160✔
2741
                        if (r < 0)
59,160✔
2742
                                return r;
2743

2744
                        for (;;) {
62,940✔
2745
                                _cleanup_free_ char *tuple = NULL, *path = NULL, *only_create = NULL, *read_only = NULL;
62,833✔
2746
                                ExecDirectoryFlags exec_directory_flags = 0;
62,940✔
2747
                                const char *p;
62,940✔
2748

2749
                                /* Use EXTRACT_UNESCAPE_RELAX here, as we unescape the colons in subsequent calls */
2750
                                r = extract_first_word(&val, &tuple, WHITESPACE, EXTRACT_UNESCAPE_SEPARATORS|EXTRACT_UNESCAPE_RELAX);
62,940✔
2751
                                if (r < 0)
62,940✔
2752
                                        return r;
2753
                                if (r == 0)
62,940✔
2754
                                        break;
2755

2756
                                p = tuple;
3,780✔
2757
                                r = extract_many_words(&p, ":", EXTRACT_UNESCAPE_SEPARATORS, &path, &only_create, &read_only);
3,780✔
2758
                                if (r < 0)
3,780✔
2759
                                        return r;
2760
                                if (r < 2)
3,780✔
UNCOV
2761
                                        continue;
×
2762

2763
                                r = parse_boolean(only_create);
3,780✔
2764
                                if (r < 0)
3,780✔
2765
                                        return r;
2766
                                if (r > 0)
3,780✔
2767
                                        exec_directory_flags |= EXEC_DIRECTORY_ONLY_CREATE;
5✔
2768

2769
                                r = parse_boolean(read_only);
3,780✔
2770
                                if (r < 0)
3,780✔
2771
                                        return r;
2772
                                if (r > 0)
3,780✔
2773
                                        exec_directory_flags |= EXEC_DIRECTORY_READ_ONLY;
50✔
2774

2775
                                r = exec_directory_add(&c->directories[dt], path, /* symlink= */ NULL, exec_directory_flags);
3,780✔
2776
                                if (r < 0)
3,780✔
2777
                                        return r;
2778

2779
                                if (isempty(p))
3,780✔
2780
                                        continue;
3,673✔
2781

2782
                                for (;;) {
385✔
2783
                                        _cleanup_free_ char *link = NULL;
246✔
2784

2785
                                        r = extract_first_word(&p, &link, ":", EXTRACT_UNESCAPE_SEPARATORS);
246✔
2786
                                        if (r < 0)
246✔
2787
                                                return r;
2788
                                        if (r == 0)
246✔
2789
                                                break;
2790

2791
                                        r = strv_consume(&c->directories[dt].items[c->directories[dt].n_items - 1].symlinks, TAKE_PTR(link));
139✔
2792
                                        if (r < 0)
139✔
2793
                                                return r;
2794
                                }
2795
                        }
2796
                } else if ((val = startswith(l, "exec-context-timeout-clean-usec="))) {
1,062,594✔
UNCOV
2797
                        r = deserialize_usec(val, &c->timeout_clean_usec);
×
UNCOV
2798
                        if (r < 0)
×
2799
                                return r;
2800
                } else if ((val = startswith(l, "exec-context-nice="))) {
1,062,594✔
2801
                        r = safe_atoi(val, &c->nice);
15✔
2802
                        if (r < 0)
15✔
2803
                                return r;
2804
                        c->nice_set = true;
15✔
2805
                } else if ((val = startswith(l, "exec-context-working-directory-missing-ok="))) {
1,062,579✔
2806
                        r = parse_boolean(val);
811✔
2807
                        if (r < 0)
811✔
2808
                                return r;
2809
                        c->working_directory_missing_ok = r;
811✔
2810
                } else if ((val = startswith(l, "exec-context-working-directory-home="))) {
1,061,768✔
2811
                        r = parse_boolean(val);
151✔
2812
                        if (r < 0)
151✔
2813
                                return r;
2814
                        c->working_directory_home = r;
151✔
2815
                } else if ((val = startswith(l, "exec-context-oom-score-adjust="))) {
1,061,617✔
2816
                        r = safe_atoi(val, &c->oom_score_adjust);
1,304✔
2817
                        if (r < 0)
1,304✔
2818
                                return r;
2819
                        c->oom_score_adjust_set = true;
1,304✔
2820
                } else if ((val = startswith(l, "exec-context-coredump-filter="))) {
1,060,313✔
2821
                        r = safe_atoux64(val, &c->coredump_filter);
2✔
2822
                        if (r < 0)
2✔
2823
                                return r;
2824
                        c->coredump_filter_set = true;
2✔
2825
                } else if ((val = startswith(l, "exec-context-limit-"))) {
1,060,311✔
UNCOV
2826
                        _cleanup_free_ struct rlimit *rlimit = NULL;
×
2827
                        _cleanup_free_ char *limit = NULL;
23,659✔
2828
                        int type;
23,659✔
2829

2830
                        r = extract_first_word(&val, &limit, "=", 0);
23,659✔
2831
                        if (r < 0)
23,659✔
2832
                                return r;
2833
                        if (r == 0 || !val)
23,659✔
2834
                                return -EINVAL;
2835

2836
                        type = rlimit_from_string(limit);
23,659✔
2837
                        if (type < 0)
23,659✔
2838
                                return -EINVAL;
2839

2840
                        if (!c->rlimit[type]) {
23,659✔
2841
                                rlimit = new0(struct rlimit, 1);
23,659✔
2842
                                if (!rlimit)
23,659✔
UNCOV
2843
                                        return log_oom_debug();
×
2844

2845
                                r = rlimit_parse(type, val, rlimit);
23,659✔
2846
                                if (r < 0)
23,659✔
2847
                                        return r;
2848

2849
                                c->rlimit[type] = TAKE_PTR(rlimit);
23,659✔
2850
                        } else {
UNCOV
2851
                                r = rlimit_parse(type, val, c->rlimit[type]);
×
UNCOV
2852
                                if (r < 0)
×
2853
                                        return r;
2854
                        }
2855
                } else if ((val = startswith(l, "exec-context-ioprio="))) {
1,036,652✔
2856
                        r = safe_atoi(val, &c->ioprio);
6✔
2857
                        if (r < 0)
6✔
2858
                                return r;
2859
                        c->ioprio_is_set = true;
6✔
2860
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-policy="))) {
1,036,646✔
UNCOV
2861
                        c->cpu_sched_policy = sched_policy_from_string(val);
×
UNCOV
2862
                        if (c->cpu_sched_policy < 0)
×
2863
                                return -EINVAL;
2864
                        c->cpu_sched_set = true;
×
2865
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-priority="))) {
1,036,646✔
UNCOV
2866
                        r = safe_atoi(val, &c->cpu_sched_priority);
×
2867
                        if (r < 0)
×
2868
                                return r;
2869
                        c->cpu_sched_set = true;
×
2870
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-reset-on-fork="))) {
1,036,646✔
UNCOV
2871
                        r = parse_boolean(val);
×
2872
                        if (r < 0)
×
2873
                                return r;
2874
                        c->cpu_sched_reset_on_fork = r;
×
2875
                        c->cpu_sched_set = true;
×
2876
                } else if ((val = startswith(l, "exec-context-cpu-affinity="))) {
1,036,646✔
2877
                        if (c->cpu_set.set)
×
2878
                                return -EINVAL; /* duplicated */
2879

2880
                        r = parse_cpu_set(val, &c->cpu_set);
×
UNCOV
2881
                        if (r < 0)
×
2882
                                return r;
2883
                } else if ((val = startswith(l, "exec-context-numa-mask="))) {
1,036,646✔
2884
                        if (c->numa_policy.nodes.set)
19✔
2885
                                return -EINVAL; /* duplicated */
2886

2887
                        r = parse_cpu_set(val, &c->numa_policy.nodes);
19✔
2888
                        if (r < 0)
19✔
2889
                                return r;
2890
                } else if ((val = startswith(l, "exec-context-numa-policy="))) {
1,036,627✔
2891
                        r = safe_atoi(val, &c->numa_policy.type);
19✔
2892
                        if (r < 0)
19✔
2893
                                return r;
2894
                } else if ((val = startswith(l, "exec-context-cpu-affinity-from-numa="))) {
1,036,608✔
2895
                        r = parse_boolean(val);
2✔
2896
                        if (r < 0)
2✔
2897
                                return r;
2898
                        c->cpu_affinity_from_numa = r;
2✔
2899
                } else if ((val = startswith(l, "exec-context-timer-slack-nsec="))) {
1,036,606✔
UNCOV
2900
                        r = deserialize_usec(val, (usec_t *)&c->timer_slack_nsec);
×
UNCOV
2901
                        if (r < 0)
×
2902
                                return r;
2903
                } else if ((val = startswith(l, "exec-context-std-input="))) {
1,036,606✔
2904
                        c->std_input = exec_input_from_string(val);
11,832✔
2905
                        if (c->std_input < 0)
11,832✔
2906
                                return c->std_input;
2907
                } else if ((val = startswith(l, "exec-context-std-output="))) {
1,024,774✔
2908
                        c->std_output = exec_output_from_string(val);
11,832✔
2909
                        if (c->std_output < 0)
11,832✔
2910
                                return c->std_output;
2911
                } else if ((val = startswith(l, "exec-context-std-error="))) {
1,012,942✔
2912
                        c->std_error = exec_output_from_string(val);
11,832✔
2913
                        if (c->std_error < 0)
11,832✔
2914
                                return c->std_error;
2915
                } else if ((val = startswith(l, "exec-context-stdio-as-fds="))) {
1,001,110✔
2916
                        r = parse_boolean(val);
551✔
2917
                        if (r < 0)
551✔
2918
                                return r;
2919
                        c->stdio_as_fds = r;
551✔
2920
                } else if ((val = startswith(l, "exec-context-std-input-fd-name="))) {
1,000,559✔
UNCOV
2921
                        r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], val);
×
UNCOV
2922
                        if (r < 0)
×
2923
                                return r;
2924
                } else if ((val = startswith(l, "exec-context-std-output-fd-name="))) {
1,000,559✔
2925
                        r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], val);
×
UNCOV
2926
                        if (r < 0)
×
2927
                                return r;
2928
                } else if ((val = startswith(l, "exec-context-std-error-fd-name="))) {
1,000,559✔
2929
                        r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], val);
×
UNCOV
2930
                        if (r < 0)
×
2931
                                return r;
2932
                } else if ((val = startswith(l, "exec-context-std-input-file="))) {
1,000,559✔
2933
                        r = free_and_strdup(&c->stdio_file[STDIN_FILENO], val);
×
UNCOV
2934
                        if (r < 0)
×
2935
                                return r;
2936
                } else if ((val = startswith(l, "exec-context-std-output-file="))) {
1,000,559✔
2937
                        r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], val);
5✔
2938
                        if (r < 0)
5✔
2939
                                return r;
2940
                } else if ((val = startswith(l, "exec-context-std-output-file-append="))) {
1,000,554✔
2941
                        r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], val);
1✔
2942
                        if (r < 0)
1✔
2943
                                return r;
2944
                } else if ((val = startswith(l, "exec-context-std-output-file-truncate="))) {
1,000,553✔
2945
                        r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], val);
2✔
2946
                        if (r < 0)
2✔
2947
                                return r;
2948
                } else if ((val = startswith(l, "exec-context-std-error-file="))) {
1,000,551✔
2949
                        r = free_and_strdup(&c->stdio_file[STDERR_FILENO], val);
2✔
2950
                        if (r < 0)
2✔
2951
                                return r;
2952
                } else if ((val = startswith(l, "exec-context-std-error-file-append="))) {
1,000,549✔
2953
                        r = free_and_strdup(&c->stdio_file[STDERR_FILENO], val);
1✔
2954
                        if (r < 0)
1✔
2955
                                return r;
2956
                } else if ((val = startswith(l, "exec-context-std-error-file-truncate="))) {
1,000,548✔
2957
                        r = free_and_strdup(&c->stdio_file[STDERR_FILENO], val);
1✔
2958
                        if (r < 0)
1✔
2959
                                return r;
2960
                } else if ((val = startswith(l, "exec-context-stdin-data="))) {
1,000,547✔
2961
                        if (c->stdin_data)
1✔
2962
                                return -EINVAL; /* duplicated */
2963

2964
                        r = unbase64mem(val, &c->stdin_data, &c->stdin_data_size);
1✔
2965
                        if (r < 0)
1✔
2966
                                return r;
2967
                } else if ((val = startswith(l, "exec-context-tty-path="))) {
1,000,546✔
2968
                        r = free_and_strdup(&c->tty_path, val);
165✔
2969
                        if (r < 0)
165✔
2970
                                return r;
2971
                } else if ((val = startswith(l, "exec-context-tty-reset="))) {
1,000,381✔
2972
                        r = parse_boolean(val);
154✔
2973
                        if (r < 0)
154✔
2974
                                return r;
2975
                        c->tty_reset = r;
154✔
2976
                } else if ((val = startswith(l, "exec-context-tty-vhangup="))) {
1,000,227✔
2977
                        r = parse_boolean(val);
149✔
2978
                        if (r < 0)
149✔
2979
                                return r;
2980
                        c->tty_vhangup = r;
149✔
2981
                } else if ((val = startswith(l, "exec-context-tty-vt-disallocate="))) {
1,000,078✔
2982
                        r = parse_boolean(val);
86✔
2983
                        if (r < 0)
86✔
2984
                                return r;
2985
                        c->tty_vt_disallocate = r;
86✔
2986
                } else if ((val = startswith(l, "exec-context-tty-rows="))) {
999,992✔
2987
                        r = safe_atou(val, &c->tty_rows);
11,832✔
2988
                        if (r < 0)
11,832✔
2989
                                return r;
2990
                } else if ((val = startswith(l, "exec-context-tty-columns="))) {
988,160✔
2991
                        r = safe_atou(val, &c->tty_cols);
11,832✔
2992
                        if (r < 0)
11,832✔
2993
                                return r;
2994
                } else if ((val = startswith(l, "exec-context-syslog-priority="))) {
976,328✔
2995
                        r = safe_atoi(val, &c->syslog_priority);
11,832✔
2996
                        if (r < 0)
11,832✔
2997
                                return r;
2998
                } else if ((val = startswith(l, "exec-context-syslog-level-prefix="))) {
964,496✔
2999
                        r = parse_boolean(val);
11,832✔
3000
                        if (r < 0)
11,832✔
3001
                                return r;
3002
                        c->syslog_level_prefix = r;
11,832✔
3003
                } else if ((val = startswith(l, "exec-context-syslog-identifier="))) {
952,664✔
UNCOV
3004
                        r = free_and_strdup(&c->syslog_identifier, val);
×
UNCOV
3005
                        if (r < 0)
×
3006
                                return r;
3007
                } else if ((val = startswith(l, "exec-context-log-level-max="))) {
952,664✔
3008
                        /* See comment in serialization. */
3009
                        r = safe_atoi(val, &c->log_level_max);
11,832✔
3010
                        if (r < 0)
11,832✔
3011
                                return r;
3012
                } else if ((val = startswith(l, "exec-context-log-ratelimit-interval-usec="))) {
940,832✔
UNCOV
3013
                        r = deserialize_usec(val, &c->log_ratelimit.interval);
×
UNCOV
3014
                        if (r < 0)
×
3015
                                return r;
3016
                } else if ((val = startswith(l, "exec-context-log-ratelimit-burst="))) {
940,832✔
3017
                        r = safe_atou(val, &c->log_ratelimit.burst);
×
UNCOV
3018
                        if (r < 0)
×
3019
                                return r;
3020
                } else if ((val = startswith(l, "exec-context-log-filter-allowed-patterns="))) {
940,832✔
3021
                        r = set_put_strdup(&c->log_filter_allowed_patterns, val);
9✔
3022
                        if (r < 0)
9✔
3023
                                return r;
3024
                } else if ((val = startswith(l, "exec-context-log-filter-denied-patterns="))) {
940,823✔
3025
                        r = set_put_strdup(&c->log_filter_denied_patterns, val);
5✔
3026
                        if (r < 0)
5✔
3027
                                return r;
3028
                } else if ((val = startswith(l, "exec-context-log-extra-fields="))) {
940,818✔
3029
                        if (!GREEDY_REALLOC(c->log_extra_fields, c->n_log_extra_fields + 1))
619✔
UNCOV
3030
                                return log_oom_debug();
×
3031

3032
                        c->log_extra_fields[c->n_log_extra_fields++].iov_base = strdup(val);
619✔
3033
                        if (!c->log_extra_fields[c->n_log_extra_fields-1].iov_base)
619✔
UNCOV
3034
                                return log_oom_debug();
×
3035
                } else if ((val = startswith(l, "exec-context-log-namespace="))) {
940,199✔
3036
                        r = free_and_strdup(&c->log_namespace, val);
2✔
3037
                        if (r < 0)
2✔
3038
                                return r;
3039
                } else if ((val = startswith(l, "exec-context-secure-bits="))) {
940,197✔
UNCOV
3040
                        r = safe_atoi(val, &c->secure_bits);
×
UNCOV
3041
                        if (r < 0)
×
3042
                                return r;
3043
                } else if ((val = startswith(l, "exec-context-capability-bounding-set="))) {
940,197✔
3044
                        r = safe_atou64(val, &c->capability_bounding_set);
2,366✔
3045
                        if (r < 0)
2,366✔
3046
                                return r;
3047
                } else if ((val = startswith(l, "exec-context-capability-ambient-set="))) {
937,831✔
3048
                        r = safe_atou64(val, &c->capability_ambient_set);
1,308✔
3049
                        if (r < 0)
1,308✔
3050
                                return r;
3051
                } else if ((val = startswith(l, "exec-context-user="))) {
936,523✔
3052
                        r = free_and_strdup(&c->user, val);
2,675✔
3053
                        if (r < 0)
2,675✔
3054
                                return r;
3055
                } else if ((val = startswith(l, "exec-context-group="))) {
933,848✔
3056
                        r = free_and_strdup(&c->group, val);
73✔
3057
                        if (r < 0)
73✔
3058
                                return r;
3059
                } else if ((val = startswith(l, "exec-context-dynamic-user="))) {
933,775✔
3060
                        r = parse_boolean(val);
62✔
3061
                        if (r < 0)
62✔
3062
                                return r;
3063
                        c->dynamic_user = r;
62✔
3064
                } else if ((val = startswith(l, "exec-context-supplementary-groups="))) {
933,713✔
3065
                        r = deserialize_strv(val, &c->supplementary_groups);
9✔
3066
                        if (r < 0)
9✔
3067
                                return r;
3068
                } else if ((val = startswith(l, "exec-context-set-login-environment="))) {
933,704✔
UNCOV
3069
                        r = safe_atoi(val, &c->set_login_environment);
×
UNCOV
3070
                        if (r < 0)
×
3071
                                return r;
3072
                } else if ((val = startswith(l, "exec-context-pam-name="))) {
933,704✔
3073
                        r = free_and_strdup(&c->pam_name, val);
455✔
3074
                        if (r < 0)
455✔
3075
                                return r;
3076
                } else if ((val = startswith(l, "exec-context-read-write-paths="))) {
933,249✔
3077
                        r = deserialize_strv(val, &c->read_write_paths);
817✔
3078
                        if (r < 0)
817✔
3079
                                return r;
3080
                } else if ((val = startswith(l, "exec-context-read-only-paths="))) {
932,432✔
3081
                        r = deserialize_strv(val, &c->read_only_paths);
2✔
3082
                        if (r < 0)
2✔
3083
                                return r;
3084
                } else if ((val = startswith(l, "exec-context-inaccessible-paths="))) {
932,430✔
3085
                        r = deserialize_strv(val, &c->inaccessible_paths);
5✔
3086
                        if (r < 0)
5✔
3087
                                return r;
3088
                } else if ((val = startswith(l, "exec-context-exec-paths="))) {
932,425✔
3089
                        r = deserialize_strv(val, &c->exec_paths);
1✔
3090
                        if (r < 0)
1✔
3091
                                return r;
3092
                } else if ((val = startswith(l, "exec-context-no-exec-paths="))) {
932,424✔
3093
                        r = deserialize_strv(val, &c->no_exec_paths);
1✔
3094
                        if (r < 0)
1✔
3095
                                return r;
3096
                } else if ((val = startswith(l, "exec-context-exec-search-path="))) {
932,423✔
UNCOV
3097
                        r = deserialize_strv(val, &c->exec_search_path);
×
UNCOV
3098
                        if (r < 0)
×
3099
                                return r;
3100
                } else if ((val = startswith(l, "exec-context-mount-propagation-flag="))) {
932,423✔
3101
                        r = safe_atolu(val, &c->mount_propagation_flag);
11,832✔
3102
                        if (r < 0)
11,832✔
3103
                                return r;
3104
                } else if ((val = startswith(l, "exec-context-bind-read-only-path="))) {
920,591✔
3105
                        _cleanup_free_ char *source = NULL, *destination = NULL;
7✔
3106
                        bool rbind = true, ignore_enoent = false;
7✔
3107
                        char *s = NULL, *d = NULL;
7✔
3108

3109
                        r = extract_first_word(&val,
7✔
3110
                                               &source,
3111
                                               ":" WHITESPACE,
3112
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3113
                        if (r < 0)
7✔
3114
                                return r;
3115
                        if (r == 0)
7✔
3116
                                return -EINVAL;
3117

3118
                        s = source;
7✔
3119
                        if (s[0] == '-') {
7✔
3120
                                ignore_enoent = true;
1✔
3121
                                s++;
1✔
3122
                        }
3123

3124
                        if (val && val[-1] == ':') {
7✔
3125
                                r = extract_first_word(&val,
7✔
3126
                                                       &destination,
3127
                                                       ":" WHITESPACE,
3128
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3129
                                if (r < 0)
7✔
3130
                                        return r;
3131
                                if (r == 0)
7✔
UNCOV
3132
                                        continue;
×
3133

3134
                                d = destination;
7✔
3135

3136
                                if (val && val[-1] == ':') {
7✔
3137
                                        _cleanup_free_ char *options = NULL;
7✔
3138

3139
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
7✔
3140
                                        if (r < 0)
7✔
UNCOV
3141
                                                return -r;
×
3142

3143
                                        if (isempty(options) || streq(options, "rbind"))
15✔
3144
                                                rbind = true;
3145
                                        else if (streq(options, "norbind"))
1✔
3146
                                                rbind = false;
3147
                                        else
UNCOV
3148
                                                continue;
×
3149
                                }
3150
                        } else
3151
                                d = s;
3152

3153
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
14✔
3154
                                        &(BindMount) {
7✔
3155
                                                .source = s,
3156
                                                .destination = d,
3157
                                                .read_only = true,
3158
                                                .recursive = rbind,
3159
                                                .ignore_enoent = ignore_enoent,
3160
                                        });
3161
                        if (r < 0)
7✔
UNCOV
3162
                                return log_oom_debug();
×
3163
                } else if ((val = startswith(l, "exec-context-bind-path="))) {
920,584✔
3164
                        _cleanup_free_ char *source = NULL, *destination = NULL;
20✔
3165
                        bool rbind = true, ignore_enoent = false;
20✔
3166
                        char *s = NULL, *d = NULL;
20✔
3167

3168
                        r = extract_first_word(&val,
20✔
3169
                                               &source,
3170
                                               ":" WHITESPACE,
3171
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3172
                        if (r < 0)
20✔
3173
                                return r;
3174
                        if (r == 0)
20✔
3175
                                return -EINVAL;
3176

3177
                        s = source;
20✔
3178
                        if (s[0] == '-') {
20✔
3179
                                ignore_enoent = true;
1✔
3180
                                s++;
1✔
3181
                        }
3182

3183
                        if (val && val[-1] == ':') {
20✔
3184
                                r = extract_first_word(&val,
20✔
3185
                                                       &destination,
3186
                                                       ":" WHITESPACE,
3187
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3188
                                if (r < 0)
20✔
3189
                                        return r;
3190
                                if (r == 0)
20✔
UNCOV
3191
                                        continue;
×
3192

3193
                                d = destination;
20✔
3194

3195
                                if (val && val[-1] == ':') {
20✔
3196
                                        _cleanup_free_ char *options = NULL;
20✔
3197

3198
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
20✔
3199
                                        if (r < 0)
20✔
UNCOV
3200
                                                return -r;
×
3201

3202
                                        if (isempty(options) || streq(options, "rbind"))
43✔
3203
                                                rbind = true;
3204
                                        else if (streq(options, "norbind"))
3✔
3205
                                                rbind = false;
3206
                                        else
UNCOV
3207
                                                continue;
×
3208
                                }
3209
                        } else
3210
                                d = s;
3211

3212
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
40✔
3213
                                        &(BindMount) {
20✔
3214
                                                .source = s,
3215
                                                .destination = d,
3216
                                                .read_only = false,
3217
                                                .recursive = rbind,
3218
                                                .ignore_enoent = ignore_enoent,
3219
                                        });
3220
                        if (r < 0)
20✔
UNCOV
3221
                                return log_oom_debug();
×
3222
                } else if ((val = startswith(l, "exec-context-temporary-filesystems="))) {
920,564✔
3223
                        _cleanup_free_ char *path = NULL, *options = NULL;
61✔
3224

3225
                        r = extract_many_words(&val, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &path, &options);
61✔
3226
                        if (r < 0)
61✔
3227
                                return r;
3228
                        if (r < 1)
61✔
UNCOV
3229
                                continue;
×
3230

3231
                        r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
61✔
3232
                        if (r < 0)
61✔
UNCOV
3233
                                return log_oom_debug();
×
3234
                } else if ((val = startswith(l, "exec-context-utmp-id="))) {
920,503✔
3235
                        r = free_and_strdup(&c->utmp_id, val);
156✔
3236
                        if (r < 0)
156✔
3237
                                return r;
3238
                } else if ((val = startswith(l, "exec-context-utmp-mode="))) {
920,347✔
3239
                        c->utmp_mode = exec_utmp_mode_from_string(val);
11,832✔
3240
                        if (c->utmp_mode < 0)
11,832✔
3241
                                return c->utmp_mode;
3242
                } else if ((val = startswith(l, "exec-context-no-new-privileges="))) {
908,515✔
3243
                        r = parse_boolean(val);
2,184✔
3244
                        if (r < 0)
2,184✔
3245
                                return r;
3246
                        c->no_new_privileges = r;
2,184✔
3247
                } else if ((val = startswith(l, "exec-context-selinux-context="))) {
906,331✔
UNCOV
3248
                        if (val[0] == '-') {
×
UNCOV
3249
                                c->selinux_context_ignore = true;
×
UNCOV
3250
                                val++;
×
3251
                        } else
3252
                                c->selinux_context_ignore = false;
×
3253

UNCOV
3254
                        r = free_and_strdup(&c->selinux_context, val);
×
3255
                        if (r < 0)
×
3256
                                return r;
3257
                } else if ((val = startswith(l, "exec-context-apparmor-profile="))) {
906,331✔
3258
                        if (val[0] == '-') {
×
UNCOV
3259
                                c->apparmor_profile_ignore = true;
×
UNCOV
3260
                                val++;
×
3261
                        } else
3262
                                c->apparmor_profile_ignore = false;
×
3263

UNCOV
3264
                        r = free_and_strdup(&c->apparmor_profile, val);
×
3265
                        if (r < 0)
×
3266
                                return r;
3267
                } else if ((val = startswith(l, "exec-context-smack-process-label="))) {
906,331✔
3268
                        if (val[0] == '-') {
×
UNCOV
3269
                                c->smack_process_label_ignore = true;
×
UNCOV
3270
                                val++;
×
3271
                        } else
3272
                                c->smack_process_label_ignore = false;
×
3273

UNCOV
3274
                        r = free_and_strdup(&c->smack_process_label, val);
×
3275
                        if (r < 0)
×
3276
                                return r;
3277
                } else if ((val = startswith(l, "exec-context-personality="))) {
906,331✔
3278
                        c->personality = personality_from_string(val);
×
UNCOV
3279
                        if (c->personality == PERSONALITY_INVALID)
×
3280
                                return -EINVAL;
3281
                } else if ((val = startswith(l, "exec-context-lock-personality="))) {
906,331✔
3282
                        r = parse_boolean(val);
2,239✔
3283
                        if (r < 0)
2,239✔
3284
                                return r;
3285
                        c->lock_personality = r;
2,239✔
3286
#if HAVE_SECCOMP
3287
                } else if ((val = startswith(l, "exec-context-syscall-filter="))) {
904,092✔
3288
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
866,742✔
3289
                        int id, errno_num;
866,742✔
3290

3291
                        r = extract_many_words(&val, NULL, 0, &s_id, &s_errno_num);
866,742✔
3292
                        if (r < 0)
866,742✔
3293
                                return r;
3294
                        if (r != 2)
866,742✔
UNCOV
3295
                                continue;
×
3296

3297
                        r = safe_atoi(s_id, &id);
866,742✔
3298
                        if (r < 0)
866,742✔
3299
                                return r;
3300

3301
                        r = safe_atoi(s_errno_num, &errno_num);
866,742✔
3302
                        if (r < 0)
866,742✔
3303
                                return r;
3304

3305
                        r = hashmap_ensure_put(&c->syscall_filter, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
866,742✔
3306
                        if (r < 0)
866,742✔
3307
                                return r;
3308
                } else if ((val = startswith(l, "exec-context-syscall-archs="))) {
37,350✔
3309
                        unsigned id;
2,239✔
3310

3311
                        r = safe_atou(val, &id);
2,239✔
3312
                        if (r < 0)
2,239✔
UNCOV
3313
                                return r;
×
3314

3315
                        r = set_ensure_put(&c->syscall_archs, NULL, UINT_TO_PTR(id + 1));
2,239✔
3316
                        if (r < 0)
2,239✔
3317
                                return r;
3318
                } else if ((val = startswith(l, "exec-context-syscall-errno="))) {
35,111✔
3319
                        r = safe_atoi(val, &c->syscall_errno);
11,832✔
3320
                        if (r < 0)
11,832✔
3321
                                return r;
3322
                } else if ((val = startswith(l, "exec-context-syscall-allow-list="))) {
23,279✔
3323
                        r = parse_boolean(val);
2,221✔
3324
                        if (r < 0)
2,221✔
3325
                                return r;
3326
                        c->syscall_allow_list = r;
2,221✔
3327
                } else if ((val = startswith(l, "exec-context-syscall-log="))) {
21,058✔
UNCOV
3328
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
×
UNCOV
3329
                        int id, errno_num;
×
3330

3331
                        r = extract_many_words(&val, " ", 0, &s_id, &s_errno_num);
×
3332
                        if (r < 0)
×
3333
                                return r;
3334
                        if (r != 2)
×
3335
                                continue;
×
3336

3337
                        r = safe_atoi(s_id, &id);
×
3338
                        if (r < 0)
×
3339
                                return r;
3340

3341
                        r = safe_atoi(s_errno_num, &errno_num);
×
UNCOV
3342
                        if (r < 0)
×
3343
                                return r;
3344

3345
                        r = hashmap_ensure_put(&c->syscall_log, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
×
UNCOV
3346
                        if (r < 0)
×
3347
                                return r;
3348
                } else if ((val = startswith(l, "exec-context-syscall-log-allow-list="))) {
21,058✔
3349
                        r = parse_boolean(val);
×
UNCOV
3350
                        if (r < 0)
×
3351
                                return r;
3352
                        c->syscall_log_allow_list = r;
×
3353
#endif
3354
                } else if ((val = startswith(l, "exec-context-restrict-namespaces="))) {
21,058✔
3355
                        r = safe_atolu(val, &c->restrict_namespaces);
1,986✔
3356
                        if (r < 0)
1,986✔
3357
                                return r;
3358
                } else if ((val = startswith(l, "exec-context-delegate-namespaces="))) {
19,072✔
3359
                        r = safe_atolu(val, &c->delegate_namespaces);
12✔
3360
                        if (r < 0)
12✔
3361
                                return r;
3362
                } else if ((val = startswith(l, "exec-context-restrict-filesystems="))) {
19,060✔
UNCOV
3363
                        r = set_put_strdup(&c->restrict_filesystems, val);
×
UNCOV
3364
                        if (r < 0)
×
3365
                                return r;
3366
                } else if ((val = startswith(l, "exec-context-restrict-filesystems-allow-list="))) {
19,060✔
3367
                        r = parse_boolean(val);
×
UNCOV
3368
                        if (r < 0)
×
3369
                                return r;
3370
                        c->restrict_filesystems_allow_list = r;
×
3371
                } else if ((val = startswith(l, "exec-context-address-families="))) {
19,060✔
3372
                        int af;
9,346✔
3373

3374
                        r = safe_atoi(val, &af);
9,346✔
3375
                        if (r < 0)
9,346✔
UNCOV
3376
                                return r;
×
3377

3378
                        r = set_ensure_put(&c->address_families, NULL, INT_TO_PTR(af));
9,346✔
3379
                        if (r < 0)
9,346✔
3380
                                return r;
3381
                } else if ((val = startswith(l, "exec-context-address-families-allow-list="))) {
9,714✔
3382
                        r = parse_boolean(val);
2,236✔
3383
                        if (r < 0)
2,236✔
3384
                                return r;
3385
                        c->address_families_allow_list = r;
2,236✔
3386
                } else if ((val = startswith(l, "exec-context-network-namespace-path="))) {
7,478✔
UNCOV
3387
                        r = free_and_strdup(&c->network_namespace_path, val);
×
UNCOV
3388
                        if (r < 0)
×
3389
                                return r;
3390
                } else if ((val = startswith(l, "exec-context-ipc-namespace-path="))) {
7,478✔
3391
                        r = free_and_strdup(&c->ipc_namespace_path, val);
×
UNCOV
3392
                        if (r < 0)
×
3393
                                return r;
3394
                } else if ((val = startswith(l, "exec-context-mount-image="))) {
7,478✔
3395
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3396
                        _cleanup_free_ char *source = NULL, *destination = NULL;
56✔
3397
                        bool permissive = false;
56✔
3398
                        char *s;
56✔
3399

3400
                        r = extract_many_words(&val,
56✔
3401
                                               NULL,
3402
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3403
                                               &source,
3404
                                               &destination);
3405
                        if (r < 0)
56✔
3406
                                return r;
3407
                        if (r == 0)
56✔
3408
                                return -EINVAL;
3409

3410
                        s = source;
56✔
3411
                        if (s[0] == '-') {
56✔
UNCOV
3412
                                permissive = true;
×
UNCOV
3413
                                s++;
×
3414
                        }
3415

3416
                        if (isempty(destination))
56✔
UNCOV
3417
                                continue;
×
3418

3419
                        for (;;) {
61✔
3420
                                _cleanup_free_ char *tuple = NULL, *partition = NULL, *opts = NULL;
5✔
3421
                                PartitionDesignator partition_designator;
61✔
3422
                                MountOptions *o = NULL;
61✔
3423
                                const char *p;
61✔
3424

3425
                                r = extract_first_word(&val, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
61✔
3426
                                if (r < 0)
61✔
3427
                                        return r;
3428
                                if (r == 0)
61✔
3429
                                        break;
3430

3431
                                p = tuple;
5✔
3432
                                r = extract_many_words(&p,
5✔
3433
                                                       ":",
3434
                                                       EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3435
                                                       &partition,
3436
                                                       &opts);
3437
                                if (r < 0)
5✔
3438
                                        return r;
3439
                                if (r == 0)
5✔
UNCOV
3440
                                        continue;
×
3441
                                if (r == 1) {
5✔
UNCOV
3442
                                        o = new(MountOptions, 1);
×
3443
                                        if (!o)
×
UNCOV
3444
                                                return log_oom_debug();
×
3445
                                        *o = (MountOptions) {
×
3446
                                                .partition_designator = PARTITION_ROOT,
3447
                                                .options = TAKE_PTR(partition),
×
3448
                                        };
UNCOV
3449
                                        LIST_APPEND(mount_options, options, o);
×
3450

UNCOV
3451
                                        continue;
×
3452
                                }
3453

3454
                                partition_designator = partition_designator_from_string(partition);
5✔
3455
                                if (partition_designator < 0)
5✔
UNCOV
3456
                                        continue;
×
3457

3458
                                o = new(MountOptions, 1);
5✔
3459
                                if (!o)
5✔
UNCOV
3460
                                        return log_oom_debug();
×
3461
                                *o = (MountOptions) {
5✔
3462
                                        .partition_designator = partition_designator,
3463
                                        .options = TAKE_PTR(opts),
5✔
3464
                                };
3465
                                LIST_APPEND(mount_options, options, o);
5✔
3466
                        }
3467

3468
                        r = mount_image_add(&c->mount_images, &c->n_mount_images,
112✔
3469
                                        &(MountImage) {
56✔
3470
                                                .source = s,
3471
                                                .destination = destination,
3472
                                                .mount_options = options,
3473
                                                .ignore_enoent = permissive,
3474
                                                .type = MOUNT_IMAGE_DISCRETE,
3475
                                        });
3476
                        if (r < 0)
56✔
UNCOV
3477
                                return log_oom_debug();
×
3478
                } else if ((val = startswith(l, "exec-context-extension-image="))) {
7,422✔
UNCOV
3479
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3480
                        _cleanup_free_ char *source = NULL;
9✔
3481
                        bool permissive = false;
9✔
3482
                        char *s;
9✔
3483

3484
                        r = extract_first_word(&val,
9✔
3485
                                               &source,
3486
                                               NULL,
3487
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS);
3488
                        if (r < 0)
9✔
3489
                                return r;
3490
                        if (r == 0)
9✔
3491
                                return -EINVAL;
3492

3493
                        s = source;
9✔
3494
                        if (s[0] == '-') {
9✔
3495
                                permissive = true;
3✔
3496
                                s++;
3✔
3497
                        }
3498

3499
                        for (;;) {
9✔
UNCOV
3500
                                _cleanup_free_ char *tuple = NULL, *partition = NULL, *opts = NULL;
×
3501
                                PartitionDesignator partition_designator;
9✔
3502
                                MountOptions *o = NULL;
9✔
3503
                                const char *p;
9✔
3504

3505
                                r = extract_first_word(&val, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
9✔
3506
                                if (r < 0)
9✔
3507
                                        return r;
3508
                                if (r == 0)
9✔
3509
                                        break;
3510

UNCOV
3511
                                p = tuple;
×
UNCOV
3512
                                r = extract_many_words(&p,
×
3513
                                                       ":",
3514
                                                       EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3515
                                                       &partition,
3516
                                                       &opts);
UNCOV
3517
                                if (r < 0)
×
3518
                                        return r;
UNCOV
3519
                                if (r == 0)
×
3520
                                        continue;
×
UNCOV
3521
                                if (r == 1) {
×
3522
                                        o = new(MountOptions, 1);
×
3523
                                        if (!o)
×
3524
                                                return log_oom_debug();
×
3525
                                        *o = (MountOptions) {
×
3526
                                                .partition_designator = PARTITION_ROOT,
3527
                                                .options = TAKE_PTR(partition),
×
3528
                                        };
UNCOV
3529
                                        LIST_APPEND(mount_options, options, o);
×
3530

UNCOV
3531
                                        continue;
×
3532
                                }
3533

3534
                                partition_designator = partition_designator_from_string(partition);
×
UNCOV
3535
                                if (partition_designator < 0)
×
UNCOV
3536
                                        continue;
×
3537

3538
                                o = new(MountOptions, 1);
×
3539
                                if (!o)
×
UNCOV
3540
                                        return log_oom_debug();
×
3541
                                *o = (MountOptions) {
×
3542
                                        .partition_designator = partition_designator,
3543
                                        .options = TAKE_PTR(opts),
×
3544
                                };
UNCOV
3545
                                LIST_APPEND(mount_options, options, o);
×
3546
                        }
3547

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3638
        return 0;
11,832✔
3639
}
3640

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

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

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

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

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

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

3661
        return 0;
2,244✔
3662
}
3663

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

3667
        assert(c);
11,832✔
3668
        assert(f);
11,832✔
3669

3670
        for (;;) {
126,188✔
3671
                _cleanup_free_ char *l = NULL;
57,178✔
3672
                const char *val;
69,010✔
3673

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

3680
                if ((val = startswith(l, "exec-command-path="))) {
57,178✔
3681
                        r = free_and_strdup(&c->path, val);
11,832✔
3682
                        if (r < 0)
11,832✔
3683
                                return r;
3684
                } else if ((val = startswith(l, "exec-command-argv="))) {
45,346✔
3685
                        r = deserialize_strv(val, &c->argv);
33,514✔
3686
                        if (r < 0)
33,514✔
3687
                                return r;
3688
                } else if ((val = startswith(l, "exec-command-flags="))) {
11,832✔
3689
                        r = safe_atoi(val, &c->flags);
11,832✔
3690
                        if (r < 0)
11,832✔
3691
                                return r;
3692
                } else
UNCOV
3693
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3694

3695
        }
3696

3697
        return 0;
11,832✔
3698
}
3699

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

3709
        int r;
2,244✔
3710

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

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

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

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

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

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

3734
        return 0;
3735
}
3736

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

3746
        int r;
11,832✔
3747

3748
        assert(f);
11,832✔
3749
        assert(fds);
11,832✔
3750

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

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

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

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

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

3771
        return 0;
3772
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc