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

systemd / systemd / 28411991350

29 Jun 2026 02:22PM UTC coverage: 72.809% (+0.1%) from 72.714%
28411991350

push

github

yuwata
locale-util: drop libintl dependency

Both glibc and musl provides dgettext(). Hence it is not necessary to
use libintl.so provided by gettext.

This partially reverts 590e22643,
fully reverts commit e6e65dc26 and
bd19ffd9c.

Then, introduce minimal libintl.h for musl build, to avoid using
libintl.h by gettext, which is typically installed on musl-based
build systems.

341580 of 469146 relevant lines covered (72.81%)

1326844.04 hits per line

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

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

3
#include <unistd.h>
4

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

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

43
        assert(f);
4,967✔
44

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

436
        return 0;
437
}
438

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

442
        assert(f);
12,786✔
443

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

447
        for (;;) {
576,540✔
448
                _cleanup_free_ char *l = NULL;
281,877✔
449
                const char *val;
294,663✔
450

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

912
        return 0;
12,786✔
913
}
914

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

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

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

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

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

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

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

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

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

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

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

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

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

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

986
        return 0;
252✔
987
}
988

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1066
        return 0;
12,786✔
1067
}
1068

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

1072
        return p->idle_pipe &&
5,003✔
1073
                p->idle_pipe[0] >= 0 &&
36✔
1074
                p->idle_pipe[1] >= 0 &&
34✔
1075
                p->idle_pipe[2] >= 0 &&
5,001✔
1076
                p->idle_pipe[3] >= 0;
34✔
1077
}
1078

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1254
        return 0;
4,967✔
1255
}
1256

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1537
        return 0;
1538
}
1539

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

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

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

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

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

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

1564
        return 0;
1565
}
1566

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

1571
        assert(ret_mount_options);
79✔
1572

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

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

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

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

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

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

1608
        return 0;
79✔
1609
}
1610

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

1614
        assert(f);
4,967✔
1615

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2087

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2534
        return 0;
2535
}
2536

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

2540
        assert(f);
12,786✔
2541

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

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

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

2555
                if ((val = startswith(l, "exec-context-environment="))) {
1,213,283✔
2556
                        r = deserialize_strv(val, &c->environment);
4,794✔
2557
                        if (r < 0)
4,794✔
2558
                                return r;
2559
                } else if ((val = startswith(l, "exec-context-environment-files="))) {
1,208,489✔
2560
                        r = deserialize_strv(val, &c->environment_files);
378✔
2561
                        if (r < 0)
378✔
2562
                                return r;
2563
                } else if ((val = startswith(l, "exec-context-pass-environment="))) {
1,208,111✔
2564
                        r = deserialize_strv(val, &c->pass_environment);
350✔
2565
                        if (r < 0)
350✔
2566
                                return r;
2567
                } else if ((val = startswith(l, "exec-context-unset-environment="))) {
1,207,761✔
2568
                        r = deserialize_strv(val, &c->unset_environment);
1,100✔
2569
                        if (r < 0)
1,100✔
2570
                                return r;
2571
                } else if ((val = startswith(l, "exec-context-working-directory="))) {
1,206,661✔
2572
                        ssize_t k;
852✔
2573
                        char *p;
852✔
2574

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2863
                                if (isempty(p))
3,187✔
2864
                                        continue;
3,080✔
2865

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3274
                                d = destination;
7✔
3275

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

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

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

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

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

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

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

3333
                                d = destination;
25✔
3334

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3692
        return 0;
12,786✔
3693
}
3694

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

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

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

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

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

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

3715
        return 0;
4,967✔
3716
}
3717

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

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

3724
        for (;;) {
133,712✔
3725
                _cleanup_free_ char *l = NULL;
60,463✔
3726
                const char *val;
73,249✔
3727

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

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

3749
        }
3750

3751
        return 0;
12,786✔
3752
}
3753

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

3763
        int r;
4,967✔
3764

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

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

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

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

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

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

3788
        return 0;
3789
}
3790

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

3800
        int r;
12,786✔
3801

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

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

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

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

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

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

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

© 2026 Coveralls, Inc