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

systemd / systemd / 20800761525

07 Jan 2026 08:58PM UTC coverage: 72.582% (-0.1%) from 72.714%
20800761525

push

github

yuwata
meson: do not install standalone binaries if the meson option is disabled

A recent commit made the standalone binaries always buildable
on demand, but as a side effect due to how 'meson install' works,
they are always built and installed by 'meson install' even
if the standalone-binaries= option is disabled.
Fix it so that 'meson install' only installs them if the
option is explicitly enabled, while still allowing
building them on demand.

Follow-up for 54492552a

309720 of 426715 relevant lines covered (72.58%)

1183537.54 hits per line

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

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

3
#include <unistd.h>
4

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

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

42
        assert(f);
2,422✔
43

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

435
        fputc('\n', f); /* End marker */
2,422✔
436

437
        return 0;
438
}
439

440
static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
10,013✔
441
        int r;
10,013✔
442

443
        assert(f);
10,013✔
444

445
        if (!c)
10,013✔
446
                return 0;
447

448
        for (;;) {
373,555✔
449
                _cleanup_free_ char *l = NULL;
181,771✔
450
                const char *val;
191,784✔
451

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

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

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

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

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

524
                        r = parse_cpu_set(val, &c->startup_cpuset_mems);
10,013✔
525
                        if (r < 0)
10,013✔
526
                                return r;
527
                } else if ((val = startswith(l, "exec-cgroup-context-io-weight="))) {
122,011✔
528
                        r = safe_atou64(val, &c->io_weight);
×
529
                        if (r < 0)
×
530
                                return r;
531
                } else if ((val = startswith(l, "exec-cgroup-context-startup-io-weight="))) {
122,011✔
532
                        r = safe_atou64(val, &c->startup_io_weight);
×
533
                        if (r < 0)
×
534
                                return r;
535
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-min="))) {
122,011✔
536
                        r = safe_atou64(val, &c->default_memory_min);
×
537
                        if (r < 0)
×
538
                                return r;
539
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-low="))) {
122,011✔
540
                        r = safe_atou64(val, &c->default_memory_low);
×
541
                        if (r < 0)
×
542
                                return r;
543
                } else if ((val = startswith(l, "exec-cgroup-context-memory-min="))) {
122,011✔
544
                        r = safe_atou64(val, &c->memory_min);
1✔
545
                        if (r < 0)
1✔
546
                                return r;
547
                } else if ((val = startswith(l, "exec-cgroup-context-memory-low="))) {
122,010✔
548
                        r = safe_atou64(val, &c->memory_low);
1✔
549
                        if (r < 0)
1✔
550
                                return r;
551
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low="))) {
122,009✔
552
                        r = safe_atou64(val, &c->startup_memory_low);
×
553
                        if (r < 0)
×
554
                                return r;
555
                } else if ((val = startswith(l, "exec-cgroup-context-memory-high="))) {
122,009✔
556
                        r = safe_atou64(val, &c->memory_high);
10✔
557
                        if (r < 0)
10✔
558
                                return r;
559
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high="))) {
121,999✔
560
                        r = safe_atou64(val, &c->startup_memory_high);
×
561
                        if (r < 0)
×
562
                                return r;
563
                } else if ((val = startswith(l, "exec-cgroup-context-memory-max="))) {
121,999✔
564
                        r = safe_atou64(val, &c->memory_max);
10✔
565
                        if (r < 0)
10✔
566
                                return r;
567
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max="))) {
121,989✔
568
                        r = safe_atou64(val, &c->startup_memory_max);
×
569
                        if (r < 0)
×
570
                                return r;
571
                } else if ((val = startswith(l, "exec-cgroup-context-memory-swap-max="))) {
121,989✔
572
                        r = safe_atou64(val, &c->memory_swap_max);
9✔
573
                        if (r < 0)
9✔
574
                                return r;
575
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max="))) {
121,980✔
576
                        r = safe_atou64(val, &c->startup_memory_swap_max);
×
577
                        if (r < 0)
×
578
                                return r;
579
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-max="))) {
121,980✔
580
                        r = safe_atou64(val, &c->memory_zswap_max);
1✔
581
                        if (r < 0)
1✔
582
                                return r;
583
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max="))) {
121,979✔
584
                        r = safe_atou64(val, &c->startup_memory_zswap_max);
×
585
                        if (r < 0)
×
586
                                return r;
587
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-writeback="))) {
121,979✔
588
                        r = parse_boolean(val);
10,013✔
589
                        if (r < 0)
10,013✔
590
                                return r;
591
                        c->memory_zswap_writeback = r;
10,013✔
592
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-value="))) {
111,966✔
593
                        r = safe_atou64(val, &c->tasks_max.value);
9,713✔
594
                        if (r < 0)
9,713✔
595
                                return r;
596
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-scale="))) {
102,253✔
597
                        r = safe_atou64(val, &c->tasks_max.scale);
9,672✔
598
                        if (r < 0)
9,672✔
599
                                return r;
600
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-min-set="))) {
92,581✔
601
                        r = parse_boolean(val);
×
602
                        if (r < 0)
×
603
                                return r;
604
                        c->default_memory_min_set = r;
×
605
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-low-set="))) {
92,581✔
606
                        r = parse_boolean(val);
×
607
                        if (r < 0)
×
608
                                return r;
609
                        c->default_memory_low_set = r;
×
610
                } else if ((val = startswith(l, "exec-cgroup-context-default-startup-memory-low-set="))) {
92,581✔
611
                        r = parse_boolean(val);
×
612
                        if (r < 0)
×
613
                                return r;
614
                        c->default_startup_memory_low_set = r;
×
615
                } else if ((val = startswith(l, "exec-cgroup-context-memory-min-set="))) {
92,581✔
616
                        r = parse_boolean(val);
1✔
617
                        if (r < 0)
1✔
618
                                return r;
619
                        c->memory_min_set = r;
1✔
620
                } else if ((val = startswith(l, "exec-cgroup-context-memory-low-set="))) {
92,580✔
621
                        r = parse_boolean(val);
1✔
622
                        if (r < 0)
1✔
623
                                return r;
624
                        c->memory_low_set = r;
1✔
625
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low-set="))) {
92,579✔
626
                        r = parse_boolean(val);
×
627
                        if (r < 0)
×
628
                                return r;
629
                        c->startup_memory_low_set = r;
×
630
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high-set="))) {
92,579✔
631
                        r = parse_boolean(val);
×
632
                        if (r < 0)
×
633
                                return r;
634
                        c->startup_memory_high_set = r;
×
635
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max-set="))) {
92,579✔
636
                        r = parse_boolean(val);
×
637
                        if (r < 0)
×
638
                                return r;
639
                        c->startup_memory_max_set = r;
×
640
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max-set="))) {
92,579✔
641
                        r = parse_boolean(val);
×
642
                        if (r < 0)
×
643
                                return r;
644
                        c->startup_memory_swap_max_set = r;
×
645
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max-set="))) {
92,579✔
646
                        r = parse_boolean(val);
×
647
                        if (r < 0)
×
648
                                return r;
649
                        c->startup_memory_zswap_max_set = r;
×
650
                } else if ((val = startswith(l, "exec-cgroup-context-device-policy="))) {
92,579✔
651
                        c->device_policy = cgroup_device_policy_from_string(val);
10,013✔
652
                        if (c->device_policy < 0)
10,013✔
653
                                return -EINVAL;
654
                } else if ((val = startswith(l, "exec-cgroup-context-disable-controllers="))) {
82,566✔
655
                        r = cg_mask_from_string(val, &c->disable_controllers);
×
656
                        if (r < 0)
×
657
                                return r;
658
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-controllers="))) {
82,566✔
659
                        r = cg_mask_from_string(val, &c->delegate_controllers);
581✔
660
                        if (r < 0)
581✔
661
                                return r;
662
                } else if ((val = startswith(l, "exec-cgroup-context-delegate="))) {
81,985✔
663
                        r = parse_boolean(val);
697✔
664
                        if (r < 0)
697✔
665
                                return r;
666
                        c->delegate = r;
697✔
667
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-swap="))) {
81,288✔
668
                        c->moom_swap = managed_oom_mode_from_string(val);
10,013✔
669
                        if (c->moom_swap < 0)
10,013✔
670
                                return -EINVAL;
671
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure="))) {
71,275✔
672
                        c->moom_mem_pressure = managed_oom_mode_from_string(val);
10,013✔
673
                        if (c->moom_mem_pressure < 0)
10,013✔
674
                                return -EINVAL;
675
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-limit="))) {
61,262✔
676
                        r = safe_atou32(val, &c->moom_mem_pressure_limit);
10,013✔
677
                        if (r < 0)
10,013✔
678
                                return r;
679
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-preference="))) {
51,249✔
680
                        c->moom_preference = managed_oom_preference_from_string(val);
10,013✔
681
                        if (c->moom_preference < 0)
10,013✔
682
                                return -EINVAL;
683
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec="))) {
41,236✔
684
                        r = deserialize_usec(val, &c->moom_mem_pressure_duration_usec);
1✔
685
                        if (r < 0)
1✔
686
                                return r;
687
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-watch="))) {
41,235✔
688
                        c->memory_pressure_watch = cgroup_pressure_watch_from_string(val);
10,013✔
689
                        if (c->memory_pressure_watch < 0)
10,013✔
690
                                return -EINVAL;
691
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-subgroup="))) {
31,222✔
692
                        r = free_and_strdup(&c->delegate_subgroup, val);
350✔
693
                        if (r < 0)
350✔
694
                                return r;
695
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-threshold-usec="))) {
30,872✔
696
                        r = deserialize_usec(val, &c->memory_pressure_threshold_usec);
10,013✔
697
                        if (r < 0)
10,013✔
698
                                return r;
699
                } else if ((val = startswith(l, "exec-cgroup-context-device-allow="))) {
20,859✔
700
                        _cleanup_free_ char *path = NULL, *rwm = NULL;
3,337✔
701
                        CGroupDevicePermissions p;
3,337✔
702

703
                        r = extract_many_words(&val, " ", 0, &path, &rwm);
3,337✔
704
                        if (r < 0)
3,337✔
705
                                return r;
706
                        if (r == 0)
3,337✔
707
                                return -EINVAL;
708

709
                        p = isempty(rwm) ? 0 : cgroup_device_permissions_from_string(rwm);
6,674✔
710
                        if (p < 0)
3,337✔
711
                                return p;
712

713
                        r = cgroup_context_add_or_update_device_allow(c, path, p);
3,337✔
714
                        if (r < 0)
3,337✔
715
                                return r;
716
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-weight="))) {
17,522✔
717
                        _cleanup_free_ char *path = NULL, *weight = NULL;
×
718
                        CGroupIODeviceWeight *a = NULL;
×
719

720
                        r = extract_many_words(&val, " ", 0, &path, &weight);
×
721
                        if (r < 0)
×
722
                                return r;
723
                        if (r != 2)
×
724
                                return -EINVAL;
725

726
                        LIST_FOREACH(device_weights, b, c->io_device_weights)
×
727
                                if (path_equal(b->path, path)) {
×
728
                                        a = b;
729
                                        break;
730
                                }
731

732
                        if (!a) {
×
733
                                a = new0(CGroupIODeviceWeight, 1);
×
734
                                if (!a)
×
735
                                        return log_oom_debug();
×
736

737
                                a->path = TAKE_PTR(path);
×
738

739
                                LIST_PREPEND(device_weights, c->io_device_weights, a);
×
740
                        }
741

742
                        r = safe_atou64(weight, &a->weight);
×
743
                        if (r < 0)
×
744
                                return r;
745
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-latency-target-usec="))) {
17,522✔
746
                        _cleanup_free_ char *path = NULL, *target = NULL;
×
747
                        CGroupIODeviceLatency *a = NULL;
×
748

749
                        r = extract_many_words(&val, " ", 0, &path, &target);
×
750
                        if (r < 0)
×
751
                                return r;
752
                        if (r != 2)
×
753
                                return -EINVAL;
754

755
                        LIST_FOREACH(device_latencies, b, c->io_device_latencies)
×
756
                                if (path_equal(b->path, path)) {
×
757
                                        a = b;
758
                                        break;
759
                                }
760

761
                        if (!a) {
×
762
                                a = new0(CGroupIODeviceLatency, 1);
×
763
                                if (!a)
×
764
                                        return log_oom_debug();
×
765

766
                                a->path = TAKE_PTR(path);
×
767

768
                                LIST_PREPEND(device_latencies, c->io_device_latencies, a);
×
769
                        }
770

771
                        r = deserialize_usec(target, &a->target_usec);
×
772
                        if (r < 0)
×
773
                                return r;
774
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-limit-"))) {
17,522✔
775
                        _cleanup_free_ char *type = NULL, *path = NULL, *limits = NULL;
×
776
                        CGroupIODeviceLimit *limit = NULL;
×
777
                        CGroupIOLimitType t;
×
778

779
                        r = extract_many_words(&val, "= ", 0, &type, &path, &limits);
×
780
                        if (r < 0)
×
781
                                return r;
782
                        if (r != 3)
×
783
                                return -EINVAL;
784

785
                        t = cgroup_io_limit_type_from_string(type);
×
786
                        if (t < 0)
×
787
                                return t;
788

789
                        LIST_FOREACH(device_limits, i, c->io_device_limits)
×
790
                                if (path_equal(path, i->path)) {
×
791
                                        limit = i;
792
                                        break;
793
                                }
794

795
                        if (!limit) {
×
796
                                limit = new0(CGroupIODeviceLimit, 1);
×
797
                                if (!limit)
×
798
                                        return log_oom_debug();
×
799

800
                                limit->path = TAKE_PTR(path);
×
801
                                for (CGroupIOLimitType i = 0; i < _CGROUP_IO_LIMIT_TYPE_MAX; i++)
×
802
                                        limit->limits[i] = cgroup_io_limit_defaults[i];
×
803

804
                                LIST_PREPEND(device_limits, c->io_device_limits, limit);
×
805
                        }
806

807
                        r = safe_atou64(limits, &limit->limits[t]);
×
808
                        if (r < 0)
×
809
                                return r;
810
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow="))) {
17,522✔
811
                        struct in_addr_prefix a;
×
812

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

817
                        r = in_addr_prefix_add(&c->ip_address_allow, &a);
×
818
                        if (r < 0)
×
819
                                return r;
820
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny="))) {
17,522✔
821
                        struct in_addr_prefix a;
1,366✔
822

823
                        r = in_addr_prefix_from_string_auto(val, &a.family, &a.address, &a.prefixlen);
1,366✔
824
                        if (r < 0)
1,366✔
825
                                return r;
×
826

827
                        r = in_addr_prefix_add(&c->ip_address_deny, &a);
1,366✔
828
                        if (r < 0)
1,366✔
829
                                return r;
830
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow-reduced="))) {
16,156✔
831
                        r = parse_boolean(val);
8,066✔
832
                        if (r < 0)
8,066✔
833
                                return r;
834
                        c->ip_address_allow_reduced = r;
8,066✔
835
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny-reduced="))) {
8,090✔
836
                        r = parse_boolean(val);
8,066✔
837
                        if (r < 0)
8,066✔
838
                                return r;
839
                        c->ip_address_deny_reduced = r;
8,066✔
840
                } else if ((val = startswith(l, "exec-cgroup-context-ip-ingress-filter-path="))) {
24✔
841
                        r = deserialize_strv(val, &c->ip_filters_ingress);
×
842
                        if (r < 0)
×
843
                                return r;
844
                } else if ((val = startswith(l, "exec-cgroup-context-ip-egress-filter-path="))) {
24✔
845
                        r = deserialize_strv(val, &c->ip_filters_egress);
×
846
                        if (r < 0)
×
847
                                return r;
848
                } else if ((val = startswith(l, "exec-cgroup-context-bpf-program="))) {
24✔
849
                        _cleanup_free_ char *type = NULL, *path = NULL;
×
850
                        uint32_t t;
×
851

852
                        r = extract_many_words(&val, " ", 0, &type, &path);
×
853
                        if (r < 0)
×
854
                                return r;
855
                        if (r != 2)
×
856
                                return -EINVAL;
857

858
                        r = safe_atou32(type, &t);
×
859
                        if (r < 0)
×
860
                                return r;
861

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

870
                        r = parse_socket_bind_item(val, &af, &ip_protocol, &nr_ports, &port_min);
×
871
                        if (r < 0)
×
872
                                return r;
×
873

874
                        item = new(CGroupSocketBindItem, 1);
×
875
                        if (!item)
×
876
                                return log_oom_debug();
×
877
                        *item = (CGroupSocketBindItem) {
×
878
                                .address_family = af,
879
                                .ip_protocol = ip_protocol,
880
                                .nr_ports = nr_ports,
881
                                .port_min = port_min,
882
                        };
883

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

890
                        r = parse_socket_bind_item(val, &af, &ip_protocol, &nr_ports, &port_min);
×
891
                        if (r < 0)
×
892
                                return r;
×
893

894
                        item = new(CGroupSocketBindItem, 1);
×
895
                        if (!item)
×
896
                                return log_oom_debug();
×
897
                        *item = (CGroupSocketBindItem) {
×
898
                                .address_family = af,
899
                                .ip_protocol = ip_protocol,
900
                                .nr_ports = nr_ports,
901
                                .port_min = port_min,
902
                        };
903

904
                        LIST_PREPEND(socket_bind_items, c->socket_bind_deny, item);
×
905
                } else if ((val = startswith(l, "exec-cgroup-context-restrict-network-interfaces="))) {
24✔
906
                        r = set_put_strdup(&c->restrict_network_interfaces, val);
15✔
907
                        if (r < 0)
15✔
908
                                return r;
909
                } else if ((val = startswith(l, "exec-cgroup-context-restrict-network-interfaces-is-allow-list="))) {
9✔
910
                        r = parse_boolean(val);
9✔
911
                        if (r < 0)
9✔
912
                                return r;
913
                        c->restrict_network_interfaces_is_allow_list = r;
9✔
914
                } else if ((val = startswith(l, "exec-cgroup-context-bind-iface="))) {
×
915
                        r = free_and_strdup(&c->bind_network_interface, val);
×
916
                        if (r < 0)
×
917
                                return r;
918
                } else
919
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
920
        }
921

922
        return 0;
10,013✔
923
}
924

925
static int exec_runtime_serialize(const ExecRuntime *rt, FILE *f, FDSet *fds) {
2,422✔
926
        int r;
2,422✔
927

928
        assert(f);
2,422✔
929
        assert(fds);
2,422✔
930

931
        if (!rt) {
2,422✔
932
                fputc('\n', f); /* End marker */
2,344✔
933
                return 0;
2,344✔
934
        }
935

936
        if (rt->shared) {
78✔
937
                r = serialize_item(f, "exec-runtime-id", rt->shared->id);
75✔
938
                if (r < 0)
75✔
939
                        return r;
940

941
                r = serialize_item(f, "exec-runtime-tmp-dir", rt->shared->tmp_dir);
75✔
942
                if (r < 0)
75✔
943
                        return r;
944

945
                r = serialize_item(f, "exec-runtime-var-tmp-dir", rt->shared->var_tmp_dir);
75✔
946
                if (r < 0)
75✔
947
                        return r;
948

949
                if (rt->shared->userns_storage_socket[0] >= 0 && rt->shared->userns_storage_socket[1] >= 0) {
75✔
950
                        r = serialize_fd_many(f, fds, "exec-runtime-userns-storage-socket", rt->shared->userns_storage_socket, 2);
×
951
                        if (r < 0)
×
952
                                return r;
953
                }
954

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

961
                if (rt->shared->ipcns_storage_socket[0] >= 0 && rt->shared->ipcns_storage_socket[1] >= 0) {
75✔
962
                        r = serialize_fd_many(f, fds, "exec-runtime-ipcns-storage-socket", rt->shared->ipcns_storage_socket, 2);
2✔
963
                        if (r < 0)
2✔
964
                                return r;
965
                }
966
        }
967

968
        if (rt->dynamic_creds) {
78✔
969
                r = dynamic_user_serialize_one(rt->dynamic_creds->user, "exec-runtime-dynamic-creds-user", f, fds);
3✔
970
                if (r < 0)
3✔
971
                        return r;
972
        }
973

974
        if (rt->dynamic_creds && rt->dynamic_creds->group && rt->dynamic_creds->group == rt->dynamic_creds->user) {
78✔
975
                r = serialize_bool(f, "exec-runtime-dynamic-creds-group-copy", true);
2✔
976
                if (r < 0)
2✔
977
                        return r;
978
        } else if (rt->dynamic_creds) {
76✔
979
                r = dynamic_user_serialize_one(rt->dynamic_creds->group, "exec-runtime-dynamic-creds-group", f, fds);
1✔
980
                if (r < 0)
1✔
981
                        return r;
982
        }
983

984
        r = serialize_item(f, "exec-runtime-ephemeral-copy", rt->ephemeral_copy);
78✔
985
        if (r < 0)
78✔
986
                return r;
987

988
        if (rt->ephemeral_storage_socket[0] >= 0 && rt->ephemeral_storage_socket[1] >= 0) {
78✔
989
                r = serialize_fd_many(f, fds, "exec-runtime-ephemeral-storage-socket", rt->ephemeral_storage_socket, 2);
×
990
                if (r < 0)
×
991
                        return r;
992
        }
993

994
        fputc('\n', f); /* End marker */
78✔
995

996
        return 0;
78✔
997
}
998

999
static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) {
10,013✔
1000
        int r;
10,013✔
1001

1002
        assert(rt);
10,013✔
1003
        assert(rt->shared);
10,013✔
1004
        assert(rt->dynamic_creds);
10,013✔
1005
        assert(f);
10,013✔
1006
        assert(fds);
10,013✔
1007

1008
        for (;;) {
11,258✔
1009
                _cleanup_free_ char *l = NULL;
1,245✔
1010
                const char *val;
11,258✔
1011

1012
                r = deserialize_read_line(f, &l);
11,258✔
1013
                if (r < 0)
11,258✔
1014
                        return r;
1015
                if (r == 0) /* eof or end marker */
11,258✔
1016
                        break;
1017

1018
                if ((val = startswith(l, "exec-runtime-id="))) {
1,245✔
1019
                        r = free_and_strdup(&rt->shared->id, val);
373✔
1020
                        if (r < 0)
373✔
1021
                                return r;
1022
                } else if ((val = startswith(l, "exec-runtime-tmp-dir="))) {
872✔
1023
                        r = free_and_strdup(&rt->shared->tmp_dir, val);
349✔
1024
                        if (r < 0)
349✔
1025
                                return r;
1026
                } else if ((val = startswith(l, "exec-runtime-var-tmp-dir="))) {
523✔
1027
                        r = free_and_strdup(&rt->shared->var_tmp_dir, val);
349✔
1028
                        if (r < 0)
349✔
1029
                                return r;
1030
                } else if ((val = startswith(l, "exec-runtime-userns-storage-socket="))) {
174✔
1031

1032
                        r = deserialize_fd_many(fds, val, 2, rt->shared->userns_storage_socket);
3✔
1033
                        if (r < 0)
3✔
1034
                                continue;
×
1035

1036
                } else if ((val = startswith(l, "exec-runtime-netns-storage-socket="))) {
171✔
1037

1038
                        r = deserialize_fd_many(fds, val, 2, rt->shared->netns_storage_socket);
71✔
1039
                        if (r < 0)
71✔
1040
                                continue;
×
1041

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

1044
                        r = deserialize_fd_many(fds, val, 2, rt->shared->ipcns_storage_socket);
6✔
1045
                        if (r < 0)
6✔
1046
                                continue;
×
1047

1048
                } else if ((val = startswith(l, "exec-runtime-dynamic-creds-user=")))
94✔
1049
                        dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->user);
47✔
1050
                else if ((val = startswith(l, "exec-runtime-dynamic-creds-group=")))
47✔
1051
                        dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->group);
×
1052
                else if ((val = startswith(l, "exec-runtime-dynamic-creds-group-copy="))) {
47✔
1053
                        r = parse_boolean(val);
47✔
1054
                        if (r < 0)
47✔
1055
                                return r;
1056
                        if (!r)
47✔
1057
                                continue; /* Nothing to do */
×
1058

1059
                        if (!rt->dynamic_creds->user)
47✔
1060
                                return -EINVAL;
1061

1062
                        rt->dynamic_creds->group = dynamic_user_ref(rt->dynamic_creds->user);
47✔
1063
                } else if ((val = startswith(l, "exec-runtime-ephemeral-copy="))) {
×
1064
                        r = free_and_strdup(&rt->ephemeral_copy, val);
×
1065
                        if (r < 0)
×
1066
                                return r;
1067
                } else if ((val = startswith(l, "exec-runtime-ephemeral-storage-socket="))) {
×
1068

1069
                        r = deserialize_fd_many(fds, val, 2, rt->ephemeral_storage_socket);
×
1070
                        if (r < 0)
×
1071
                                continue;
×
1072
                } else
1073
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
1074
        }
1075

1076
        return 0;
10,013✔
1077
}
1078

1079
static bool exec_parameters_is_idle_pipe_set(const ExecParameters *p) {
2,422✔
1080
        assert(p);
2,422✔
1081

1082
        return p->idle_pipe &&
2,451✔
1083
                p->idle_pipe[0] >= 0 &&
29✔
1084
                p->idle_pipe[1] >= 0 &&
27✔
1085
                p->idle_pipe[2] >= 0 &&
2,449✔
1086
                p->idle_pipe[3] >= 0;
27✔
1087
}
1088

1089
static int exec_parameters_serialize(const ExecParameters *p, const ExecContext *c, FILE *f, FDSet *fds) {
2,422✔
1090
        int r;
2,422✔
1091

1092
        assert(f);
2,422✔
1093
        assert(fds);
2,422✔
1094

1095
        if (!p)
2,422✔
1096
                return 0;
1097

1098
        r = serialize_item(f, "exec-parameters-runtime-scope", runtime_scope_to_string(p->runtime_scope));
2,422✔
1099
        if (r < 0)
2,422✔
1100
                return r;
1101

1102
        r = serialize_strv(f, "exec-parameters-environment", p->environment);
2,422✔
1103
        if (r < 0)
2,422✔
1104
                return r;
1105

1106
        if (p->fds) {
2,422✔
1107
                if (p->n_socket_fds > 0) {
534✔
1108
                        r = serialize_item_format(f, "exec-parameters-n-socket-fds", "%zu", p->n_socket_fds);
533✔
1109
                        if (r < 0)
533✔
1110
                                return r;
1111
                }
1112

1113
                if (p->n_stashed_fds > 0) {
534✔
1114
                        r = serialize_item_format(f, "exec-parameters-n-stashed-fds", "%zu", p->n_stashed_fds);
4✔
1115
                        if (r < 0)
4✔
1116
                                return r;
1117
                }
1118

1119
                r = serialize_fd_many(f, fds, "exec-parameters-fds", p->fds, p->n_socket_fds + p->n_stashed_fds);
534✔
1120
                if (r < 0)
534✔
1121
                        return r;
1122

1123
                r = serialize_strv(f, "exec-parameters-fd-names", p->fd_names);
534✔
1124
                if (r < 0)
534✔
1125
                        return r;
1126
        }
1127

1128
        if (p->flags != 0) {
2,422✔
1129
                r = serialize_item_format(f, "exec-parameters-flags", "%u", (unsigned) p->flags);
2,422✔
1130
                if (r < 0)
2,422✔
1131
                        return r;
1132
        }
1133

1134
        r = serialize_bool_elide(f, "exec-parameters-selinux-context-net", p->selinux_context_net);
2,422✔
1135
        if (r < 0)
2,422✔
1136
                return r;
1137

1138
        r = serialize_item(f, "exec-parameters-cgroup-path", p->cgroup_path);
2,422✔
1139
        if (r < 0)
2,422✔
1140
                return r;
1141

1142
        r = serialize_item_format(f, "exec-parameters-cgroup-id", "%" PRIu64, p->cgroup_id);
2,422✔
1143
        if (r < 0)
2,422✔
1144
                return r;
1145

1146
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
14,532✔
1147
                _cleanup_free_ char *key = NULL;
12,110✔
1148

1149
                key = strjoin("exec-parameters-prefix-directories-", exec_directory_type_to_string(dt));
12,110✔
1150
                if (!key)
12,110✔
1151
                        return log_oom_debug();
×
1152

1153
                /* Always serialize, even an empty prefix, as this is a fixed array and we always expect
1154
                 * to have all elements (unless fuzzing is happening, hence the NULL check). */
1155
                r = serialize_item(f, key, strempty(p->prefix ? p->prefix[dt] : NULL));
12,110✔
1156
                if (r < 0)
12,110✔
1157
                        return r;
1158
        }
1159

1160
        r = serialize_item(f, "exec-parameters-received-credentials-directory", p->received_credentials_directory);
2,422✔
1161
        if (r < 0)
2,422✔
1162
                return r;
1163

1164
        r = serialize_item(f, "exec-parameters-received-encrypted-credentials-directory", p->received_encrypted_credentials_directory);
2,422✔
1165
        if (r < 0)
2,422✔
1166
                return r;
1167

1168
        r = serialize_item(f, "exec-parameters-confirm-spawn", p->confirm_spawn);
2,422✔
1169
        if (r < 0)
2,422✔
1170
                return r;
1171

1172
        r = serialize_bool_elide(f, "exec-parameters-shall-confirm-spawn", p->shall_confirm_spawn);
2,422✔
1173
        if (r < 0)
2,422✔
1174
                return r;
1175

1176
        if (p->watchdog_usec > 0) {
2,422✔
1177
                r = serialize_usec(f, "exec-parameters-watchdog-usec", p->watchdog_usec);
232✔
1178
                if (r < 0)
232✔
1179
                        return r;
1180
        }
1181

1182
        if (exec_parameters_is_idle_pipe_set(p)) {
2,422✔
1183
                r = serialize_fd_many(f, fds, "exec-parameters-idle-pipe", p->idle_pipe, 4);
27✔
1184
                if (r < 0)
27✔
1185
                        return r;
1186
        }
1187

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

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

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

1200
        r = serialize_fd(f, fds, "exec-parameters-root-directory-fd", p->root_directory_fd);
2,422✔
1201
        if (r < 0)
2,422✔
1202
                return r;
1203

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

1208
        r = serialize_fd(f, fds, "exec-parameters-handoff-timestamp-fd", p->handoff_timestamp_fd);
2,422✔
1209
        if (r < 0)
2,422✔
1210
                return r;
1211

1212
        r = serialize_fd(f, fds, "exec-parameters-pidref-transport-fd", p->pidref_transport_fd);
2,422✔
1213
        if (r < 0)
2,422✔
1214
                return r;
1215

1216
        if (c && exec_context_restrict_filesystems_set(c)) {
2,422✔
1217
                r = serialize_fd(f, fds, "exec-parameters-bpf-outer-map-fd", p->bpf_restrict_fs_map_fd);
×
1218
                if (r < 0)
×
1219
                        return r;
1220
        }
1221

1222
        r = serialize_item(f, "exec-parameters-notify-socket", p->notify_socket);
2,422✔
1223
        if (r < 0)
2,422✔
1224
                return r;
1225

1226
        LIST_FOREACH(open_files, file, p->open_files) {
2,422✔
1227
                _cleanup_free_ char *ofs = NULL;
×
1228

1229
                r = open_file_to_string(file, &ofs);
×
1230
                if (r < 0)
×
1231
                        return r;
1232

1233
                r = serialize_item(f, "exec-parameters-open-file", ofs);
×
1234
                if (r < 0)
×
1235
                        return r;
1236
        }
1237

1238
        r = serialize_item(f, "exec-parameters-fallback-smack-process-label", p->fallback_smack_process_label);
2,422✔
1239
        if (r < 0)
2,422✔
1240
                return r;
1241

1242
        r = serialize_fd(f, fds, "exec-parameters-user-lookup-fd", p->user_lookup_fd);
2,422✔
1243
        if (r < 0)
2,422✔
1244
                return r;
1245

1246
        r = serialize_strv(f, "exec-parameters-files-env", p->files_env);
2,422✔
1247
        if (r < 0)
2,422✔
1248
                return r;
1249

1250
        r = serialize_item(f, "exec-parameters-unit-id", p->unit_id);
2,422✔
1251
        if (r < 0)
2,422✔
1252
                return r;
1253

1254
        r = serialize_item(f, "exec-parameters-invocation-id-string", p->invocation_id_string);
2,422✔
1255
        if (r < 0)
2,422✔
1256
                return r;
1257

1258
        r = serialize_bool_elide(f, "exec-parameters-debug-invocation", p->debug_invocation);
2,422✔
1259
        if (r < 0)
2,422✔
1260
                return r;
1261

1262
        fputc('\n', f); /* End marker */
2,422✔
1263

1264
        return 0;
2,422✔
1265
}
1266

1267
static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
10,013✔
1268
        int r;
10,013✔
1269

1270
        assert(p);
10,013✔
1271
        assert(f);
10,013✔
1272
        assert(fds);
10,013✔
1273

1274
        unsigned nr_open = MAX(read_nr_open(), NR_OPEN_MINIMUM);
10,013✔
1275

1276
        for (;;) {
213,785✔
1277
                _cleanup_free_ char *l = NULL;
203,772✔
1278
                const char *val;
213,785✔
1279

1280
                r = deserialize_read_line(f, &l);
213,785✔
1281
                if (r < 0)
213,785✔
1282
                        return r;
1283
                if (r == 0) /* eof or end marker */
213,785✔
1284
                        break;
1285

1286
                if ((val = startswith(l, "exec-parameters-runtime-scope="))) {
203,772✔
1287
                        p->runtime_scope = runtime_scope_from_string(val);
10,013✔
1288
                        if (p->runtime_scope < 0)
10,013✔
1289
                                return p->runtime_scope;
1290
                } else if ((val = startswith(l, "exec-parameters-environment="))) {
193,759✔
1291
                        r = deserialize_strv(val, &p->environment);
42,627✔
1292
                        if (r < 0)
42,627✔
1293
                                return r;
1294
                } else if ((val = startswith(l, "exec-parameters-n-socket-fds="))) {
151,132✔
1295
                        if (p->fds)
1,744✔
1296
                                return -EINVAL; /* Already received */
1297

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

1302
                        if (p->n_socket_fds > nr_open)
1,744✔
1303
                                return -EINVAL; /* too many, someone is playing games with us */
1304
                } else if ((val = startswith(l, "exec-parameters-n-stashed-fds="))) {
149,388✔
1305
                        if (p->fds)
110✔
1306
                                return -EINVAL; /* Already received */
1307

1308
                        r = safe_atozu(val, &p->n_stashed_fds);
110✔
1309
                        if (r < 0)
110✔
1310
                                return r;
1311

1312
                        if (p->n_stashed_fds > nr_open)
110✔
1313
                                return -EINVAL; /* too many, someone is playing games with us */
1314
                } else if ((val = startswith(l, "exec-parameters-fds="))) {
149,278✔
1315
                        if (p->n_socket_fds + p->n_stashed_fds == 0)
1,749✔
1316
                                return log_warning_errno(
×
1317
                                                SYNTHETIC_ERRNO(EINVAL),
1318
                                                "Got exec-parameters-fds= without "
1319
                                                "prior exec-parameters-n-socket-fds= or exec-parameters-n-stashed-fds=");
1320
                        if (p->n_socket_fds + p->n_stashed_fds > nr_open)
1,749✔
1321
                                return -EINVAL; /* too many, someone is playing games with us */
1322

1323
                        if (p->fds)
1,749✔
1324
                                return -EINVAL; /* duplicated */
1325

1326
                        p->fds = new(int, p->n_socket_fds + p->n_stashed_fds);
1,749✔
1327
                        if (!p->fds)
1,749✔
1328
                                return log_oom_debug();
×
1329

1330
                        /* Ensure we don't leave any FD uninitialized on error, it makes the fuzzer sad */
1331
                        FOREACH_ARRAY(i, p->fds, p->n_socket_fds + p->n_stashed_fds)
5,430✔
1332
                                *i = -EBADF;
3,681✔
1333

1334
                        r = deserialize_fd_many(fds, val, p->n_socket_fds + p->n_stashed_fds, p->fds);
1,749✔
1335
                        if (r < 0)
1,749✔
1336
                                continue;
×
1337

1338
                } else if ((val = startswith(l, "exec-parameters-fd-names="))) {
147,529✔
1339
                        r = deserialize_strv(val, &p->fd_names);
3,681✔
1340
                        if (r < 0)
3,681✔
1341
                                return r;
1342
                } else if ((val = startswith(l, "exec-parameters-flags="))) {
143,848✔
1343
                        unsigned flags;
10,013✔
1344

1345
                        r = safe_atou(val, &flags);
10,013✔
1346
                        if (r < 0)
10,013✔
1347
                                return r;
×
1348
                        p->flags = flags;
10,013✔
1349
                } else if ((val = startswith(l, "exec-parameters-selinux-context-net="))) {
133,835✔
1350
                        r = parse_boolean(val);
×
1351
                        if (r < 0)
×
1352
                                return r;
1353

1354
                        p->selinux_context_net = r;
×
1355
                } else if ((val = startswith(l, "exec-parameters-cgroup-path="))) {
133,835✔
1356
                        r = free_and_strdup(&p->cgroup_path, val);
10,013✔
1357
                        if (r < 0)
10,013✔
1358
                                return r;
1359
                } else if ((val = startswith(l, "exec-parameters-cgroup-id="))) {
123,822✔
1360
                        r = safe_atou64(val, &p->cgroup_id);
10,013✔
1361
                        if (r < 0)
10,013✔
1362
                                return r;
1363
                } else if ((val = startswith(l, "exec-parameters-prefix-directories-"))) {
113,809✔
1364
                        _cleanup_free_ char *type = NULL, *prefix = NULL;
50,065✔
1365
                        ExecDirectoryType dt;
50,065✔
1366

1367
                        r = extract_many_words(&val, "= ", 0, &type, &prefix);
50,065✔
1368
                        if (r < 0)
50,065✔
1369
                                return r;
1370
                        if (r == 0)
50,065✔
1371
                                return -EINVAL;
1372

1373
                        dt = exec_directory_type_from_string(type);
50,065✔
1374
                        if (dt < 0)
50,065✔
1375
                                return -EINVAL;
1376

1377
                        if (!p->prefix) {
50,065✔
1378
                                p->prefix = new0(char*, _EXEC_DIRECTORY_TYPE_MAX+1);
10,013✔
1379
                                if (!p->prefix)
10,013✔
1380
                                        return log_oom_debug();
×
1381
                        }
1382

1383
                        if (isempty(prefix))
50,065✔
1384
                                p->prefix[dt] = mfree(p->prefix[dt]);
×
1385
                        else
1386
                                free_and_replace(p->prefix[dt], prefix);
50,065✔
1387
                } else if ((val = startswith(l, "exec-parameters-received-credentials-directory="))) {
63,744✔
1388
                        r = free_and_strdup(&p->received_credentials_directory, val);
9,323✔
1389
                        if (r < 0)
9,323✔
1390
                                return r;
1391
                } else if ((val = startswith(l, "exec-parameters-received-encrypted-credentials-directory="))) {
54,421✔
1392
                        r = free_and_strdup(&p->received_encrypted_credentials_directory, val);
×
1393
                        if (r < 0)
×
1394
                                return r;
1395
                } else if ((val = startswith(l, "exec-parameters-confirm-spawn="))) {
54,421✔
1396
                        r = free_and_strdup(&p->confirm_spawn, val);
×
1397
                        if (r < 0)
×
1398
                                return r;
1399
                } else if ((val = startswith(l, "exec-parameters-shall-confirm-spawn="))) {
54,421✔
1400
                        r = parse_boolean(val);
×
1401
                        if (r < 0)
×
1402
                                return r;
1403

1404
                        p->shall_confirm_spawn = r;
×
1405
                } else if ((val = startswith(l, "exec-parameters-watchdog-usec="))) {
54,421✔
1406
                        r = deserialize_usec(val, &p->watchdog_usec);
1,481✔
1407
                        if (r < 0)
1,481✔
1408
                                return r;
1409
                } else if ((val = startswith(l, "exec-parameters-idle-pipe="))) {
52,940✔
1410
                        if (p->idle_pipe)
85✔
1411
                                return -EINVAL; /* duplicated */
1412

1413
                        p->idle_pipe = new(int, 4);
85✔
1414
                        if (!p->idle_pipe)
85✔
1415
                                return log_oom_debug();
×
1416

1417
                        p->idle_pipe[0] = p->idle_pipe[1] = p->idle_pipe[2] = p->idle_pipe[3] = -EBADF;
85✔
1418

1419
                        r = deserialize_fd_many(fds, val, 4, p->idle_pipe);
85✔
1420
                        if (r < 0)
85✔
1421
                                continue;
×
1422

1423
                } else if ((val = startswith(l, "exec-parameters-stdin-fd="))) {
52,855✔
1424
                        int fd;
543✔
1425

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

1430
                        close_and_replace(p->stdin_fd, fd);
543✔
1431

1432
                } else if ((val = startswith(l, "exec-parameters-stdout-fd="))) {
52,312✔
1433
                        int fd;
543✔
1434

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

1439
                        close_and_replace(p->stdout_fd, fd);
543✔
1440

1441
                } else if ((val = startswith(l, "exec-parameters-stderr-fd="))) {
51,769✔
1442
                        int fd;
543✔
1443

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

1448
                        close_and_replace(p->stderr_fd, fd);
543✔
1449

1450
                } else if ((val = startswith(l, "exec-parameters-root-directory-fd="))) {
51,226✔
1451
                        int fd;
2✔
1452

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

1457
                        close_and_replace(p->root_directory_fd, fd);
2✔
1458

1459
                } else if ((val = startswith(l, "exec-parameters-exec-fd="))) {
51,224✔
1460
                        int fd;
428✔
1461

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

1466
                        close_and_replace(p->exec_fd, fd);
428✔
1467
                } else if ((val = startswith(l, "exec-parameters-handoff-timestamp-fd="))) {
50,796✔
1468
                        int fd;
10,013✔
1469

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

1474
                        close_and_replace(p->handoff_timestamp_fd, fd);
10,013✔
1475
                } else if ((val = startswith(l, "exec-parameters-pidref-transport-fd="))) {
40,783✔
1476
                        int fd;
8,854✔
1477

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

1482
                        close_and_replace(p->pidref_transport_fd, fd);
8,854✔
1483
                } else if ((val = startswith(l, "exec-parameters-bpf-outer-map-fd="))) {
31,929✔
1484
                        int fd;
×
1485

1486
                        fd = deserialize_fd(fds, val);
×
1487
                        if (fd < 0)
×
1488
                                continue;
×
1489

1490
                        close_and_replace(p->bpf_restrict_fs_map_fd, fd);
×
1491
                } else if ((val = startswith(l, "exec-parameters-notify-socket="))) {
31,929✔
1492
                        r = free_and_strdup(&p->notify_socket, val);
1,881✔
1493
                        if (r < 0)
1,881✔
1494
                                return r;
1495
                } else if ((val = startswith(l, "exec-parameters-open-file="))) {
30,048✔
1496
                        OpenFile *of;
5✔
1497

1498
                        r = open_file_parse(val, &of);
5✔
1499
                        if (r < 0)
5✔
1500
                                return r;
×
1501

1502
                        LIST_APPEND(open_files, p->open_files, of);
5✔
1503
                } else if ((val = startswith(l, "exec-parameters-fallback-smack-process-label="))) {
30,043✔
1504
                        r = free_and_strdup(&p->fallback_smack_process_label, val);
×
1505
                        if (r < 0)
×
1506
                                return r;
1507
                } else if ((val = startswith(l, "exec-parameters-user-lookup-fd="))) {
30,043✔
1508
                        int fd;
10,013✔
1509

1510
                        fd = deserialize_fd(fds, val);
10,013✔
1511
                        if (fd < 0)
10,013✔
1512
                                continue;
×
1513

1514
                        close_and_replace(p->user_lookup_fd, fd);
10,013✔
1515
                } else if ((val = startswith(l, "exec-parameters-files-env="))) {
20,030✔
1516
                        r = deserialize_strv(val, &p->files_env);
2✔
1517
                        if (r < 0)
2✔
1518
                                return r;
1519
                } else if ((val = startswith(l, "exec-parameters-unit-id="))) {
20,028✔
1520
                        r = free_and_strdup(&p->unit_id, val);
10,013✔
1521
                        if (r < 0)
10,013✔
1522
                                return r;
1523
                } else if ((val = startswith(l, "exec-parameters-invocation-id-string="))) {
10,015✔
1524
                        if (strlen(val) > SD_ID128_STRING_MAX - 1)
10,013✔
1525
                                return -EINVAL;
1526

1527
                        r = sd_id128_from_string(val, &p->invocation_id);
10,013✔
1528
                        if (r < 0)
10,013✔
1529
                                return r;
1530

1531
                        sd_id128_to_string(p->invocation_id, p->invocation_id_string);
10,013✔
1532
                } else if ((val = startswith(l, "exec-parameters-debug-invocation="))) {
2✔
1533
                        r = parse_boolean(val);
2✔
1534
                        if (r < 0)
2✔
1535
                                return r;
1536

1537
                        p->debug_invocation = r;
2✔
1538
                } else
1539
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
1540
        }
1541

1542
        /* Bail out if we got exec-parameters-n-{socket/stashed}-fds= but no corresponding
1543
         * exec-parameters-fds= */
1544
        if (p->n_socket_fds + p->n_stashed_fds > 0 && !p->fds)
10,013✔
1545
                return -EINVAL;
×
1546

1547
        return 0;
1548
}
1549

1550
static int serialize_mount_options(const MountOptions *mount_options, char **s) {
5✔
1551
        assert(s);
5✔
1552

1553
        if (!mount_options)
5✔
1554
                return 0;
1555

1556
        for (PartitionDesignator i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
×
1557
                _cleanup_free_ char *escaped = NULL;
×
1558

1559
                if (isempty(mount_options->options[i]))
×
1560
                        continue;
×
1561

1562
                escaped = shell_escape(mount_options->options[i], ":");
×
1563
                if (!escaped)
×
1564
                        return log_oom_debug();
×
1565

1566
                if (!strextend(s,
×
1567
                               " ",
1568
                               partition_designator_to_string(i),
1569
                               ":",
1570
                               escaped))
1571
                        return log_oom_debug();
×
1572
        }
1573

1574
        return 0;
1575
}
1576

1577
static int deserialize_mount_options(const char *s, MountOptions **ret_mount_options) {
70✔
1578
        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
70✔
1579
        int r;
70✔
1580

1581
        assert(ret_mount_options);
70✔
1582

1583
        for (;;) {
75✔
1584
                _cleanup_free_ char *word = NULL, *mount_options = NULL, *partition = NULL;
5✔
1585
                PartitionDesignator partition_designator;
75✔
1586
                const char *p;
75✔
1587

1588
                r = extract_first_word(&s, &word, NULL, 0);
75✔
1589
                if (r < 0)
75✔
1590
                        return r;
1591
                if (r == 0)
75✔
1592
                        break;
1593

1594
                p = word;
5✔
1595
                r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options);
5✔
1596
                if (r < 0)
5✔
1597
                        return r;
1598
                if (r == 0)
5✔
1599
                        continue;
×
1600
                if (r != 2) {
5✔
1601
                        log_warning("Failed to parse mount options entry '%s', ignoring.", word);
×
1602
                        continue;
×
1603
                }
1604

1605
                partition_designator = partition_designator_from_string(partition);
5✔
1606
                if (partition_designator < 0) {
5✔
1607
                        log_warning_errno(partition_designator, "Unknown partition designator '%s' in exec-context-root-image-options= entry, ignoring.", partition);
×
1608
                        continue;
×
1609
                }
1610

1611
                r = mount_options_set_and_consume(&options, partition_designator, TAKE_PTR(mount_options));
5✔
1612
                if (r < 0)
5✔
1613
                        return r;
1614
        }
1615

1616
        *ret_mount_options = TAKE_PTR(options);
70✔
1617

1618
        return 0;
70✔
1619
}
1620

1621
static int exec_context_serialize(const ExecContext *c, FILE *f) {
2,422✔
1622
        int r;
2,422✔
1623

1624
        assert(f);
2,422✔
1625

1626
        if (!c)
2,422✔
1627
                return 0;
2,422✔
1628

1629
        r = serialize_strv(f, "exec-context-environment", c->environment);
2,422✔
1630
        if (r < 0)
2,422✔
1631
                return r;
1632

1633
        r = serialize_strv(f, "exec-context-environment-files", c->environment_files);
2,422✔
1634
        if (r < 0)
2,422✔
1635
                return r;
1636

1637
        r = serialize_strv(f, "exec-context-pass-environment", c->pass_environment);
2,422✔
1638
        if (r < 0)
2,422✔
1639
                return r;
1640

1641
        r = serialize_strv(f, "exec-context-unset-environment", c->unset_environment);
2,422✔
1642
        if (r < 0)
2,422✔
1643
                return r;
1644

1645
        r = serialize_item_escaped(f, "exec-context-working-directory", c->working_directory);
2,422✔
1646
        if (r < 0)
2,422✔
1647
                return r;
1648

1649
        r = serialize_bool_elide(f, "exec-context-working-directory-missing-ok", c->working_directory_missing_ok);
2,422✔
1650
        if (r < 0)
2,422✔
1651
                return r;
1652

1653
        r = serialize_bool_elide(f, "exec-context-working-directory-home", c->working_directory_home);
2,422✔
1654
        if (r < 0)
2,422✔
1655
                return r;
1656

1657
        r = serialize_item_escaped(f, "exec-context-root-directory", c->root_directory);
2,422✔
1658
        if (r < 0)
2,422✔
1659
                return r;
1660

1661
        r = serialize_item_escaped(f, "exec-context-root-image", c->root_image);
2,422✔
1662
        if (r < 0)
2,422✔
1663
                return r;
1664

1665
        if (c->root_image_options) {
2,422✔
1666
                _cleanup_free_ char *options = NULL;
×
1667

1668
                r = serialize_mount_options(c->root_image_options, &options);
×
1669
                if (r < 0)
×
1670
                        return r;
1671

1672
                r = serialize_item(f, "exec-context-root-image-options", options);
×
1673
                if (r < 0)
×
1674
                        return r;
1675
        }
1676

1677
        r = serialize_item(f, "exec-context-root-verity", c->root_verity);
2,422✔
1678
        if (r < 0)
2,422✔
1679
                return r;
1680

1681
        r = serialize_item(f, "exec-context-root-hash-path", c->root_hash_path);
2,422✔
1682
        if (r < 0)
2,422✔
1683
                return r;
1684

1685
        r = serialize_item(f, "exec-context-root-hash-sig-path", c->root_hash_sig_path);
2,422✔
1686
        if (r < 0)
2,422✔
1687
                return r;
1688

1689
        r = serialize_item_hexmem(f, "exec-context-root-hash", c->root_hash.iov_base, c->root_hash.iov_len);
2,422✔
1690
        if (r < 0)
2,422✔
1691
                return r;
1692

1693
        r = serialize_item_base64mem(f, "exec-context-root-hash-sig", c->root_hash_sig.iov_base, c->root_hash_sig.iov_len);
2,422✔
1694
        if (r < 0)
2,422✔
1695
                return r;
1696

1697
        r = serialize_bool_elide(f, "exec-context-root-ephemeral", c->root_ephemeral);
2,422✔
1698
        if (r < 0)
2,422✔
1699
                return r;
1700

1701
        r = serialize_item_format(f, "exec-context-umask", "%04o", c->umask);
2,422✔
1702
        if (r < 0)
2,422✔
1703
                return r;
1704

1705
        r = serialize_bool_elide(f, "exec-context-non-blocking", c->non_blocking);
2,422✔
1706
        if (r < 0)
2,422✔
1707
                return r;
1708

1709
        r = serialize_item_tristate(f, "exec-context-private-mounts", c->private_mounts);
2,422✔
1710
        if (r < 0)
28✔
1711
                return r;
1712

1713
        r = serialize_item_tristate(f, "exec-context-mount-api-vfs", c->mount_apivfs);
2,422✔
1714
        if (r < 0)
2✔
1715
                return r;
1716

1717
        r = serialize_item_tristate(f, "exec-context-bind-log-sockets", c->bind_log_sockets);
2,422✔
1718
        if (r < 0)
×
1719
                return r;
1720

1721
        r = serialize_item_tristate(f, "exec-context-memory-ksm", c->memory_ksm);
2,422✔
1722
        if (r < 0)
×
1723
                return r;
1724

1725
        r = serialize_item(f, "exec-context-memory-thp", memory_thp_to_string(c->memory_thp));
2,422✔
1726
        if (r < 0)
2,422✔
1727
                return r;
1728

1729
        r = serialize_item(f, "exec-context-private-tmp", private_tmp_to_string(c->private_tmp));
2,422✔
1730
        if (r < 0)
2,422✔
1731
                return r;
1732

1733
        /* This must be set in unit_patch_contexts() before executing a command. */
1734
        assert(c->private_var_tmp >= 0 && c->private_var_tmp < _PRIVATE_TMP_MAX);
2,422✔
1735
        r = serialize_item(f, "exec-context-private-var-tmp", private_tmp_to_string(c->private_var_tmp));
2,422✔
1736
        if (r < 0)
2,422✔
1737
                return r;
1738

1739
        r = serialize_bool_elide(f, "exec-context-private-devices", c->private_devices);
2,422✔
1740
        if (r < 0)
2,422✔
1741
                return r;
1742

1743
        r = serialize_bool_elide(f, "exec-context-protect-kernel-tunables", c->protect_kernel_tunables);
2,422✔
1744
        if (r < 0)
2,422✔
1745
                return r;
1746

1747
        r = serialize_bool_elide(f, "exec-context-protect-kernel-modules", c->protect_kernel_modules);
2,422✔
1748
        if (r < 0)
2,422✔
1749
                return r;
1750

1751
        r = serialize_bool_elide(f, "exec-context-protect-kernel-logs", c->protect_kernel_logs);
2,422✔
1752
        if (r < 0)
2,422✔
1753
                return r;
1754

1755
        r = serialize_bool_elide(f, "exec-context-protect-clock", c->protect_clock);
2,422✔
1756
        if (r < 0)
2,422✔
1757
                return r;
1758

1759
        r = serialize_item(f, "exec-context-protect-control-groups", protect_control_groups_to_string(c->protect_control_groups));
2,422✔
1760
        if (r < 0)
2,422✔
1761
                return r;
1762

1763
        r = serialize_bool_elide(f, "exec-context-private-network", c->private_network);
2,422✔
1764
        if (r < 0)
2,422✔
1765
                return r;
1766

1767
        r = serialize_item(f, "exec-context-private-users", private_users_to_string(c->private_users));
2,422✔
1768
        if (r < 0)
2,422✔
1769
                return r;
1770

1771
        r = serialize_bool_elide(f, "exec-context-private-ipc", c->private_ipc);
2,422✔
1772
        if (r < 0)
2,422✔
1773
                return r;
1774

1775
        r = serialize_item(f, "exec-context-private-pids", private_pids_to_string(c->private_pids));
2,422✔
1776
        if (r < 0)
2,422✔
1777
                return r;
1778

1779
        r = serialize_bool_elide(f, "exec-context-remove-ipc", c->remove_ipc);
2,422✔
1780
        if (r < 0)
2,422✔
1781
                return r;
1782

1783
        r = serialize_item(f, "exec-context-protect-home", protect_home_to_string(c->protect_home));
2,422✔
1784
        if (r < 0)
2,422✔
1785
                return r;
1786

1787
        r = serialize_item(f, "exec-context-protect-system", protect_system_to_string(c->protect_system));
2,422✔
1788
        if (r < 0)
2,422✔
1789
                return r;
1790

1791
        r = serialize_bool_elide(f, "exec-context-same-pgrp", c->same_pgrp);
2,422✔
1792
        if (r < 0)
2,422✔
1793
                return r;
1794

1795
        r = serialize_bool(f, "exec-context-ignore-sigpipe", c->ignore_sigpipe);
2,422✔
1796
        if (r < 0)
2,422✔
1797
                return r;
1798

1799
        r = serialize_bool_elide(f, "exec-context-memory-deny-write-execute", c->memory_deny_write_execute);
2,422✔
1800
        if (r < 0)
2,422✔
1801
                return r;
1802

1803
        r = serialize_bool_elide(f, "exec-context-restrict-realtime", c->restrict_realtime);
2,422✔
1804
        if (r < 0)
2,422✔
1805
                return r;
1806

1807
        r = serialize_bool_elide(f, "exec-context-restrict-suid-sgid", c->restrict_suid_sgid);
2,422✔
1808
        if (r < 0)
2,422✔
1809
                return r;
1810

1811
        r = serialize_item(f, "exec-context-keyring-mode", exec_keyring_mode_to_string(c->keyring_mode));
2,422✔
1812
        if (r < 0)
2,422✔
1813
                return r;
1814

1815
        r = serialize_item(f, "exec-context-protect-hostname", protect_hostname_to_string(c->protect_hostname));
2,422✔
1816
        if (r < 0)
2,422✔
1817
                return r;
1818

1819
        r = serialize_item(f, "exec-context-private-hostname", c->private_hostname);
2,422✔
1820
        if (r < 0)
2,422✔
1821
                return r;
1822

1823
        r = serialize_item(f, "exec-context-protect-proc", protect_proc_to_string(c->protect_proc));
2,422✔
1824
        if (r < 0)
2,422✔
1825
                return r;
1826

1827
        r = serialize_item(f, "exec-context-proc-subset", proc_subset_to_string(c->proc_subset));
2,422✔
1828
        if (r < 0)
2,422✔
1829
                return r;
1830

1831
        r = serialize_item(f, "exec-context-private-bpf", private_bpf_to_string(c->private_bpf));
2,422✔
1832
        if (r < 0)
2,422✔
1833
                return r;
1834

1835
        if (c->bpf_delegate_commands != 0) {
2,422✔
1836
                r = serialize_item_format(f, "exec-context-bpf-delegate-commands", "0x%"PRIx64, c->bpf_delegate_commands);
×
1837
                if (r < 0)
×
1838
                        return r;
1839
        }
1840

1841
        if (c->bpf_delegate_maps != 0) {
2,422✔
1842
                r = serialize_item_format(f, "exec-context-bpf-delegate-maps", "0x%"PRIx64, c->bpf_delegate_maps);
×
1843
                if (r < 0)
×
1844
                        return r;
1845
        }
1846

1847
        if (c->bpf_delegate_programs != 0) {
2,422✔
1848
                r = serialize_item_format(f, "exec-context-bpf-delegate-programs", "0x%"PRIx64, c->bpf_delegate_programs);
×
1849
                if (r < 0)
×
1850
                        return r;
1851
        }
1852

1853
        if (c->bpf_delegate_attachments != 0) {
2,422✔
1854
                r = serialize_item_format(f, "exec-context-bpf-delegate-attachments", "0x%"PRIx64, c->bpf_delegate_attachments);
×
1855
                if (r < 0)
×
1856
                        return r;
1857
        }
1858

1859
        r = serialize_item(f, "exec-context-runtime-directory-preserve-mode", exec_preserve_mode_to_string(c->runtime_directory_preserve_mode));
2,422✔
1860
        if (r < 0)
2,422✔
1861
                return r;
1862

1863
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
14,532✔
1864
                _cleanup_free_ char *key = NULL, *value = NULL;
12,110✔
1865

1866
                key = strjoin("exec-context-directories-", exec_directory_type_to_string(dt));
12,110✔
1867
                if (!key)
12,110✔
1868
                        return log_oom_debug();
×
1869

1870
                if (asprintf(&value, "%04o", c->directories[dt].mode) < 0)
12,110✔
1871
                        return log_oom_debug();
×
1872

1873
                FOREACH_ARRAY(i, c->directories[dt].items, c->directories[dt].n_items) {
12,535✔
1874
                        _cleanup_free_ char *path_escaped = NULL;
425✔
1875

1876
                        path_escaped = shell_escape(i->path, ":" WHITESPACE);
425✔
1877
                        if (!path_escaped)
425✔
1878
                                return log_oom_debug();
×
1879

1880
                        if (!strextend(&value, " ", path_escaped))
425✔
1881
                                return log_oom_debug();
×
1882

1883
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE))))
845✔
1884
                                return log_oom_debug();
×
1885

1886
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_READ_ONLY))))
848✔
1887
                                return log_oom_debug();
×
1888

1889
                        STRV_FOREACH(d, i->symlinks) {
431✔
1890
                                _cleanup_free_ char *link_escaped = NULL;
6✔
1891

1892
                                link_escaped = shell_escape(*d, ":" WHITESPACE);
6✔
1893
                                if (!link_escaped)
6✔
1894
                                        return log_oom_debug();
×
1895

1896
                                if (!strextend(&value, ":", link_escaped))
6✔
1897
                                        return log_oom_debug();
×
1898
                        }
1899
                }
1900

1901
                r = serialize_item(f, key, value);
12,110✔
1902
                if (r < 0)
12,110✔
1903
                        return r;
1904

1905
                if (c->directories[dt].exec_quota.quota_enforce) {
12,110✔
1906
                        _cleanup_free_ char *key_quota = NULL;
×
1907
                        key_quota = strjoin("exec-context-quota-directories-", exec_directory_type_to_string(dt));
×
1908
                        if (!key_quota)
×
1909
                                return log_oom_debug();
×
1910

1911
                        r = serialize_item_format(f, key_quota, "%" PRIu64 " %" PRIu32, c->directories[dt].exec_quota.quota_absolute,
×
1912
                                                                                        c->directories[dt].exec_quota.quota_scale);
×
1913
                        if (r < 0)
×
1914
                                return r;
1915

1916
                } else if (c->directories[dt].exec_quota.quota_accounting) {
12,110✔
1917
                        _cleanup_free_ char *key_quota = NULL;
×
1918
                        key_quota = strjoin("exec-context-quota-accounting-directories-", exec_directory_type_to_string(dt));
×
1919
                        if (!key_quota)
×
1920
                                return log_oom_debug();
×
1921

1922
                        r = serialize_bool(f, key_quota, c->directories[dt].exec_quota.quota_accounting);
×
1923
                        if (r < 0)
×
1924
                                return r;
1925
                }
1926
        }
1927

1928
        r = serialize_usec(f, "exec-context-timeout-clean-usec", c->timeout_clean_usec);
2,422✔
1929
        if (r < 0)
2,422✔
1930
                return r;
1931

1932
        if (c->nice_set) {
2,422✔
1933
                r = serialize_item_format(f, "exec-context-nice", "%i", c->nice);
3✔
1934
                if (r < 0)
3✔
1935
                        return r;
1936
        }
1937

1938
        if (c->oom_score_adjust_set) {
2,422✔
1939
                r = serialize_item_format(f, "exec-context-oom-score-adjust", "%i", c->oom_score_adjust);
596✔
1940
                if (r < 0)
596✔
1941
                        return r;
1942
        }
1943

1944
        if (c->coredump_filter_set) {
2,422✔
1945
                r = serialize_item_format(f, "exec-context-coredump-filter", "%"PRIx64, c->coredump_filter);
×
1946
                if (r < 0)
×
1947
                        return r;
1948
        }
1949

1950
        for (unsigned i = 0; i < RLIM_NLIMITS; i++) {
41,174✔
1951
                _cleanup_free_ char *key = NULL, *limit = NULL;
4,838✔
1952

1953
                if (!c->rlimit[i])
38,752✔
1954
                        continue;
33,914✔
1955

1956
                key = strjoin("exec-context-limit-", rlimit_to_string(i));
4,838✔
1957
                if (!key)
4,838✔
1958
                        return log_oom_debug();
×
1959

1960
                r = rlimit_format(c->rlimit[i], &limit);
4,838✔
1961
                if (r < 0)
4,838✔
1962
                        return r;
1963

1964
                r = serialize_item(f, key, limit);
4,838✔
1965
                if (r < 0)
4,838✔
1966
                        return r;
1967
        }
1968

1969
        if (c->ioprio_is_set) {
2,422✔
1970
                r = serialize_item_format(f, "exec-context-ioprio", "%d", c->ioprio);
4✔
1971
                if (r < 0)
4✔
1972
                        return r;
1973
        }
1974

1975
        if (c->cpu_sched_set) {
2,422✔
1976
                _cleanup_free_ char *policy_str = NULL;
×
1977

1978
                r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
×
1979
                if (r < 0)
×
1980
                        return r;
1981

1982
                r = serialize_item(f, "exec-context-cpu-scheduling-policy", policy_str);
×
1983
                if (r < 0)
×
1984
                        return r;
1985

1986
                r = serialize_item_format(f, "exec-context-cpu-scheduling-priority", "%i", c->cpu_sched_priority);
×
1987
                if (r < 0)
×
1988
                        return r;
1989

1990
                r = serialize_bool_elide(f, "exec-context-cpu-scheduling-reset-on-fork", c->cpu_sched_reset_on_fork);
×
1991
                if (r < 0)
×
1992
                        return r;
1993
        }
1994

1995
        if (c->cpu_set.set) {
2,422✔
1996
                _cleanup_free_ char *affinity = NULL;
×
1997

1998
                affinity = cpu_set_to_range_string(&c->cpu_set);
×
1999
                if (!affinity)
×
2000
                        return log_oom_debug();
×
2001

2002
                r = serialize_item(f, "exec-context-cpu-affinity", affinity);
×
2003
                if (r < 0)
×
2004
                        return r;
2005
        }
2006

2007
        if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) {
2,422✔
2008
                _cleanup_free_ char *nodes = NULL;
×
2009

2010
                nodes = cpu_set_to_range_string(&c->numa_policy.nodes);
×
2011
                if (!nodes)
×
2012
                        return log_oom_debug();
×
2013

2014
                if (nodes) {
×
2015
                        r = serialize_item(f, "exec-context-numa-mask", nodes);
×
2016
                        if (r < 0)
×
2017
                                return r;
2018
                }
2019

2020
                r = serialize_item_format(f, "exec-context-numa-policy", "%d", c->numa_policy.type);
×
2021
                if (r < 0)
×
2022
                        return r;
2023
        }
2024

2025
        r = serialize_bool_elide(f, "exec-context-cpu-affinity-from-numa", c->cpu_affinity_from_numa);
2,422✔
2026
        if (r < 0)
2,422✔
2027
                return r;
2028

2029
        if (c->timer_slack_nsec != NSEC_INFINITY) {
2,422✔
2030
                r = serialize_item_format(f, "exec-context-timer-slack-nsec", NSEC_FMT, c->timer_slack_nsec);
×
2031
                if (r < 0)
×
2032
                        return r;
2033
        }
2034

2035
        r = serialize_bool_elide(f, "exec-context-root-directory-as-fd", c->root_directory_as_fd);
2,422✔
2036
        if (r < 0)
2,422✔
2037
                return r;
2038

2039
        r = serialize_item(f, "exec-context-std-input", exec_input_to_string(c->std_input));
2,422✔
2040
        if (r < 0)
2,422✔
2041
                return r;
2042

2043
        r = serialize_item(f, "exec-context-std-output", exec_output_to_string(c->std_output));
2,422✔
2044
        if (r < 0)
2,422✔
2045
                return r;
2046

2047
        r = serialize_item(f, "exec-context-std-error", exec_output_to_string(c->std_error));
2,422✔
2048
        if (r < 0)
2,422✔
2049
                return r;
2050

2051
        r = serialize_bool_elide(f, "exec-context-stdio-as-fds", c->stdio_as_fds);
2,422✔
2052
        if (r < 0)
2,422✔
2053
                return r;
2054

2055
        switch (c->std_input) {
2,422✔
2056

2057
        case EXEC_INPUT_NAMED_FD:
×
2058
                r = serialize_item(f, "exec-context-std-input-fd-name", c->stdio_fdname[STDIN_FILENO]);
×
2059
                break;
2060

2061
        case EXEC_INPUT_FILE:
×
2062
                r = serialize_item_escaped(f, "exec-context-std-input-file", c->stdio_file[STDIN_FILENO]);
×
2063
                break;
2064

2065
        case EXEC_INPUT_DATA:
×
2066
                r = serialize_item_base64mem(f, "exec-context-std-input-data", c->stdin_data, c->stdin_data_size);
×
2067
                break;
2068

2069
        default:
2070
                r = 0;
2071
        }
2072
        if (r < 0)
×
2073
                return r;
2074

2075
        switch (c->std_output) {
2,422✔
2076

2077
        case EXEC_OUTPUT_NAMED_FD:
×
2078
                r = serialize_item(f, "exec-context-std-output-fd-name", c->stdio_fdname[STDOUT_FILENO]);
×
2079
                break;
2080

2081
        case EXEC_OUTPUT_FILE:
2✔
2082
        case EXEC_OUTPUT_FILE_APPEND:
2083
        case EXEC_OUTPUT_FILE_TRUNCATE:
2084
                r = serialize_item_escaped(f, "exec-context-std-output-file", c->stdio_file[STDOUT_FILENO]);
2✔
2085
                break;
2086

2087
        default:
2088
                r = 0;
2089
        }
2090
        if (r < 0)
2✔
2091
                return r;
2092

2093

2094
        switch (c->std_error) {
2,422✔
2095

2096
        case EXEC_OUTPUT_NAMED_FD:
×
2097
                r = serialize_item(f, "exec-context-std-error-fd-name", c->stdio_fdname[STDERR_FILENO]);
×
2098
                break;
2099

2100
        case EXEC_OUTPUT_FILE:
×
2101
        case EXEC_OUTPUT_FILE_APPEND:
2102
        case EXEC_OUTPUT_FILE_TRUNCATE:
2103
                r = serialize_item_escaped(f, "exec-context-std-error-file", c->stdio_file[STDERR_FILENO]);
×
2104
                break;
2105

2106
        default:
2107
                r = 0;
2108
        }
2109
        if (r < 0)
×
2110
                return r;
2111

2112
        r = serialize_item(f, "exec-context-tty-path", c->tty_path);
2,422✔
2113
        if (r < 0)
2,422✔
2114
                return r;
2115

2116
        r = serialize_bool_elide(f, "exec-context-tty-reset", c->tty_reset);
2,422✔
2117
        if (r < 0)
2,422✔
2118
                return r;
2119

2120
        r = serialize_bool_elide(f, "exec-context-tty-vhangup", c->tty_vhangup);
2,422✔
2121
        if (r < 0)
2,422✔
2122
                return r;
2123

2124
        r = serialize_bool_elide(f, "exec-context-tty-vt-disallocate", c->tty_vt_disallocate);
2,422✔
2125
        if (r < 0)
2,422✔
2126
                return r;
2127

2128
        r = serialize_item_format(f, "exec-context-tty-rows", "%u", c->tty_rows);
2,422✔
2129
        if (r < 0)
2,422✔
2130
                return r;
2131

2132
        r = serialize_item_format(f, "exec-context-tty-columns", "%u", c->tty_cols);
2,422✔
2133
        if (r < 0)
2,422✔
2134
                return r;
2135

2136
        r = serialize_item_format(f, "exec-context-syslog-priority", "%i", c->syslog_priority);
2,422✔
2137
        if (r < 0)
2,422✔
2138
                return r;
2139

2140
        r = serialize_bool(f, "exec-context-syslog-level-prefix", c->syslog_level_prefix);
2,422✔
2141
        if (r < 0)
2,422✔
2142
                return r;
2143

2144
        r = serialize_item(f, "exec-context-syslog-identifier", c->syslog_identifier);
2,422✔
2145
        if (r < 0)
2,422✔
2146
                return r;
2147

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

2154
        if (c->log_ratelimit.interval > 0) {
2,422✔
2155
                r = serialize_usec(f, "exec-context-log-ratelimit-interval-usec", c->log_ratelimit.interval);
×
2156
                if (r < 0)
×
2157
                        return r;
2158
        }
2159

2160
        if (c->log_ratelimit.burst > 0) {
2,422✔
2161
                r = serialize_item_format(f, "exec-context-log-ratelimit-burst", "%u", c->log_ratelimit.burst);
×
2162
                if (r < 0)
×
2163
                        return r;
2164
        }
2165

2166
        r = serialize_string_set(f, "exec-context-log-filter-allowed-patterns", c->log_filter_allowed_patterns);
2,422✔
2167
        if (r < 0)
2,422✔
2168
                return r;
2169

2170
        r = serialize_string_set(f, "exec-context-log-filter-denied-patterns", c->log_filter_denied_patterns);
2,422✔
2171
        if (r < 0)
2,422✔
2172
                return r;
2173

2174
        FOREACH_ARRAY(field, c->log_extra_fields, c->n_log_extra_fields) {
2,663✔
2175
                r = serialize_item(f, "exec-context-log-extra-fields", field->iov_base);
241✔
2176
                if (r < 0)
241✔
2177
                        return r;
2178
        }
2179

2180
        r = serialize_item(f, "exec-context-log-namespace", c->log_namespace);
2,422✔
2181
        if (r < 0)
2,422✔
2182
                return r;
2183

2184
        if (c->secure_bits != 0) {
2,422✔
2185
                r = serialize_item_format(f, "exec-context-secure-bits", "%d", c->secure_bits);
×
2186
                if (r < 0)
×
2187
                        return r;
2188
        }
2189

2190
        if (c->capability_bounding_set != CAP_MASK_UNSET) {
2,422✔
2191
                r = serialize_item_format(f, "exec-context-capability-bounding-set", "%" PRIu64, c->capability_bounding_set);
2,422✔
2192
                if (r < 0)
2,422✔
2193
                        return r;
2194
        }
2195

2196
        if (c->capability_ambient_set != 0) {
2,422✔
2197
                r = serialize_item_format(f, "exec-context-capability-ambient-set", "%" PRIu64, c->capability_ambient_set);
69✔
2198
                if (r < 0)
69✔
2199
                        return r;
2200
        }
2201

2202
        if (c->user) {
2,422✔
2203
                r = serialize_item(f, "exec-context-user", c->user);
200✔
2204
                if (r < 0)
200✔
2205
                        return r;
2206
        }
2207

2208
        r = serialize_item(f, "exec-context-group", c->group);
2,422✔
2209
        if (r < 0)
2,422✔
2210
                return r;
2211

2212
        r = serialize_bool_elide(f, "exec-context-dynamic-user", c->dynamic_user);
2,422✔
2213
        if (r < 0)
2,422✔
2214
                return r;
2215

2216
        r = serialize_strv(f, "exec-context-supplementary-groups", c->supplementary_groups);
2,422✔
2217
        if (r < 0)
2,422✔
2218
                return r;
2219

2220
        r = serialize_item_tristate(f, "exec-context-set-login-environment", c->set_login_environment);
2,422✔
2221
        if (r < 0)
×
2222
                return r;
2223

2224
        r = serialize_item(f, "exec-context-pam-name", c->pam_name);
2,422✔
2225
        if (r < 0)
2,422✔
2226
                return r;
2227

2228
        r = serialize_strv(f, "exec-context-read-write-paths", c->read_write_paths);
2,422✔
2229
        if (r < 0)
2,422✔
2230
                return r;
2231

2232
        r = serialize_strv(f, "exec-context-read-only-paths", c->read_only_paths);
2,422✔
2233
        if (r < 0)
2,422✔
2234
                return r;
2235

2236
        r = serialize_strv(f, "exec-context-inaccessible-paths", c->inaccessible_paths);
2,422✔
2237
        if (r < 0)
2,422✔
2238
                return r;
2239

2240
        r = serialize_strv(f, "exec-context-exec-paths", c->exec_paths);
2,422✔
2241
        if (r < 0)
2,422✔
2242
                return r;
2243

2244
        r = serialize_strv(f, "exec-context-no-exec-paths", c->no_exec_paths);
2,422✔
2245
        if (r < 0)
2,422✔
2246
                return r;
2247

2248
        r = serialize_strv(f, "exec-context-exec-search-path", c->exec_search_path);
2,422✔
2249
        if (r < 0)
2,422✔
2250
                return r;
2251

2252
        r = serialize_item_format(f, "exec-context-mount-propagation-flag", "%lu", c->mount_propagation_flag);
2,422✔
2253
        if (r < 0)
2,422✔
2254
                return r;
2255

2256
        FOREACH_ARRAY(mount, c->bind_mounts, c->n_bind_mounts) {
2,437✔
2257
                _cleanup_free_ char *src_escaped = NULL, *dst_escaped = NULL;
15✔
2258

2259
                src_escaped = shell_escape(mount->source, ":" WHITESPACE);
15✔
2260
                if (!src_escaped)
15✔
2261
                        return log_oom_debug();
×
2262

2263
                dst_escaped = shell_escape(mount->destination, ":" WHITESPACE);
15✔
2264
                if (!dst_escaped)
15✔
2265
                        return log_oom_debug();
×
2266

2267
                r = serialize_item_format(f,
15✔
2268
                                          mount->read_only ? "exec-context-bind-read-only-path" : "exec-context-bind-path",
15✔
2269
                                          "%s%s:%s:%s",
2270
                                          mount->ignore_enoent ? "-" : "",
15✔
2271
                                          src_escaped,
2272
                                          dst_escaped,
2273
                                          mount->recursive ? "rbind" : "norbind");
15✔
2274
                if (r < 0)
15✔
2275
                        return r;
2276
        }
2277

2278
        FOREACH_ARRAY(tmpfs, c->temporary_filesystems, c->n_temporary_filesystems) {
2,426✔
2279
                _cleanup_free_ char *escaped = NULL;
4✔
2280

2281
                if (!isempty(tmpfs->options)) {
4✔
2282
                        escaped = shell_escape(tmpfs->options, ":");
×
2283
                        if (!escaped)
×
2284
                                return log_oom_debug();
×
2285
                }
2286

2287
                r = serialize_item_format(f, "exec-context-temporary-filesystems", "%s%s%s",
×
2288
                                          tmpfs->path,
2289
                                          isempty(escaped) ? "" : ":",
4✔
2290
                                          strempty(escaped));
2291
                if (r < 0)
4✔
2292
                        return r;
2293
        }
2294

2295
        r = serialize_item(f, "exec-context-utmp-id", c->utmp_id);
2,422✔
2296
        if (r < 0)
2,422✔
2297
                return r;
2298

2299
        r = serialize_item(f, "exec-context-utmp-mode", exec_utmp_mode_to_string(c->utmp_mode));
2,422✔
2300
        if (r < 0)
2,422✔
2301
                return r;
2302

2303
        r = serialize_bool_elide(f, "exec-context-no-new-privileges", c->no_new_privileges);
2,422✔
2304
        if (r < 0)
2,422✔
2305
                return r;
2306

2307
        if (c->selinux_context) {
2,422✔
2308
                r = serialize_item_format(f, "exec-context-selinux-context",
×
2309
                                          "%s%s",
2310
                                          c->selinux_context_ignore ? "-" : "",
×
2311
                                          c->selinux_context);
2312
                if (r < 0)
×
2313
                        return r;
2314
        }
2315

2316
        if (c->apparmor_profile) {
2,422✔
2317
                r = serialize_item_format(f, "exec-context-apparmor-profile",
×
2318
                                          "%s%s",
2319
                                          c->apparmor_profile_ignore ? "-" : "",
×
2320
                                          c->apparmor_profile);
2321
                if (r < 0)
×
2322
                        return r;
2323
        }
2324

2325
        if (c->smack_process_label) {
2,422✔
2326
                r = serialize_item_format(f, "exec-context-smack-process-label",
×
2327
                                          "%s%s",
2328
                                          c->smack_process_label_ignore ? "-" : "",
×
2329
                                          c->smack_process_label);
2330
                if (r < 0)
×
2331
                        return r;
2332
        }
2333

2334
        if (c->personality != PERSONALITY_INVALID) {
2,422✔
2335
                r = serialize_item(f, "exec-context-personality", personality_to_string(c->personality));
×
2336
                if (r < 0)
×
2337
                        return r;
2338
        }
2339

2340
        r = serialize_bool_elide(f, "exec-context-lock-personality", c->lock_personality);
2,422✔
2341
        if (r < 0)
2,422✔
2342
                return r;
2343

2344
#if HAVE_SECCOMP
2345
        if (!hashmap_isempty(c->syscall_filter)) {
2,422✔
2346
                void *errno_num, *id;
231✔
2347
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_filter) {
88,616✔
2348
                        r = serialize_item_format(f, "exec-context-syscall-filter", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
88,385✔
2349
                        if (r < 0)
88,385✔
2350
                                return r;
×
2351
                }
2352
        }
2353

2354
        if (!set_isempty(c->syscall_archs)) {
2,422✔
2355
                void *id;
228✔
2356
                SET_FOREACH(id, c->syscall_archs) {
456✔
2357
                        r = serialize_item_format(f, "exec-context-syscall-archs", "%u", PTR_TO_UINT(id) - 1);
228✔
2358
                        if (r < 0)
228✔
2359
                                return r;
×
2360
                }
2361
        }
2362

2363
        if (c->syscall_errno > 0) {
2,422✔
2364
                r = serialize_item_format(f, "exec-context-syscall-errno", "%d", c->syscall_errno);
2,422✔
2365
                if (r < 0)
2,422✔
2366
                        return r;
2367
        }
2368

2369
        r = serialize_bool_elide(f, "exec-context-syscall-allow-list", c->syscall_allow_list);
2,422✔
2370
        if (r < 0)
2,422✔
2371
                return r;
2372

2373
        if (!hashmap_isempty(c->syscall_log)) {
2,422✔
2374
                void *errno_num, *id;
×
2375
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_log) {
×
2376
                        r = serialize_item_format(f, "exec-context-syscall-log", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
×
2377
                        if (r < 0)
×
2378
                                return r;
×
2379
                }
2380
        }
2381

2382
        r = serialize_bool_elide(f, "exec-context-syscall-log-allow-list", c->syscall_log_allow_list);
2,422✔
2383
        if (r < 0)
2,422✔
2384
                return r;
2385
#endif
2386

2387
        if (c->restrict_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,422✔
2388
                r = serialize_item_format(f, "exec-context-restrict-namespaces", "%lu", c->restrict_namespaces);
178✔
2389
                if (r < 0)
178✔
2390
                        return r;
2391
        }
2392

2393
        if (c->delegate_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,422✔
2394
                r = serialize_item_format(f, "exec-context-delegate-namespaces", "%lu", c->delegate_namespaces);
9✔
2395
                if (r < 0)
9✔
2396
                        return r;
2397
        }
2398

2399
#if HAVE_LIBBPF
2400
        if (exec_context_restrict_filesystems_set(c)) {
2,422✔
2401
                char *fs;
×
2402
                SET_FOREACH(fs, c->restrict_filesystems) {
×
2403
                        r = serialize_item(f, "exec-context-restrict-filesystems", fs);
×
2404
                        if (r < 0)
×
2405
                                return r;
×
2406
                }
2407
        }
2408

2409
        r = serialize_bool_elide(f, "exec-context-restrict-filesystems-allow-list", c->restrict_filesystems_allow_list);
2,422✔
2410
        if (r < 0)
2,422✔
2411
                return r;
2412
#endif
2413

2414
        if (!set_isempty(c->address_families)) {
2,422✔
2415
                void *afp;
227✔
2416

2417
                SET_FOREACH(afp, c->address_families) {
1,109✔
2418
                        int af = PTR_TO_INT(afp);
882✔
2419

2420
                        if (af <= 0 || af >= af_max())
882✔
2421
                                continue;
×
2422

2423
                        r = serialize_item_format(f, "exec-context-address-families", "%d", af);
882✔
2424
                        if (r < 0)
882✔
2425
                                return r;
×
2426
                }
2427
        }
2428

2429
        r = serialize_bool_elide(f, "exec-context-address-families-allow-list", c->address_families_allow_list);
2,422✔
2430
        if (r < 0)
2,422✔
2431
                return r;
2432

2433
        r = serialize_item(f, "exec-context-user-namespace-path", c->user_namespace_path);
2,422✔
2434
        if (r < 0)
2,422✔
2435
                return r;
2436

2437
        r = serialize_item(f, "exec-context-network-namespace-path", c->network_namespace_path);
2,422✔
2438
        if (r < 0)
2,422✔
2439
                return r;
2440

2441
        r = serialize_item(f, "exec-context-ipc-namespace-path", c->ipc_namespace_path);
2,422✔
2442
        if (r < 0)
2,422✔
2443
                return r;
2444

2445
        FOREACH_ARRAY(mount, c->mount_images, c->n_mount_images) {
2,422✔
2446
                _cleanup_free_ char *s = NULL, *source_escaped = NULL, *dest_escaped = NULL;
×
2447

2448
                source_escaped = shell_escape(mount->source, WHITESPACE);
×
2449
                if (!source_escaped)
×
2450
                        return log_oom_debug();
×
2451

2452
                dest_escaped = shell_escape(mount->destination, WHITESPACE);
×
2453
                if (!dest_escaped)
×
2454
                        return log_oom_debug();
×
2455

2456
                s = strjoin(mount->ignore_enoent ? "-" : "",
×
2457
                            source_escaped,
2458
                            " ",
2459
                            dest_escaped);
2460
                if (!s)
×
2461
                        return log_oom_debug();
×
2462

2463
                r = serialize_mount_options(mount->mount_options, &s);
×
2464
                if (r < 0)
×
2465
                        return r;
2466

2467
                r = serialize_item(f, "exec-context-mount-image", s);
×
2468
                if (r < 0)
×
2469
                        return r;
2470
        }
2471

2472
        FOREACH_ARRAY(mount, c->extension_images, c->n_extension_images) {
2,427✔
2473
                _cleanup_free_ char *s = NULL, *source_escaped = NULL;
5✔
2474

2475
                source_escaped = shell_escape(mount->source, ":" WHITESPACE);
5✔
2476
                if (!source_escaped)
5✔
2477
                        return log_oom_debug();
×
2478

2479
                s = strjoin(mount->ignore_enoent ? "-" : "",
10✔
2480
                            source_escaped);
2481
                if (!s)
5✔
2482
                        return log_oom_debug();
×
2483

2484
                r = serialize_mount_options(mount->mount_options, &s);
5✔
2485
                if (r < 0)
5✔
2486
                        return r;
2487

2488
                r = serialize_item(f, "exec-context-extension-image", s);
5✔
2489
                if (r < 0)
5✔
2490
                        return r;
2491
        }
2492

2493
        r = serialize_strv(f, "exec-context-extension-directories", c->extension_directories);
2,422✔
2494
        if (r < 0)
2,422✔
2495
                return r;
2496

2497
        ExecSetCredential *sc;
2,422✔
2498
        HASHMAP_FOREACH(sc, c->set_credentials) {
2,428✔
2499
                _cleanup_free_ char *data = NULL;
6✔
2500

2501
                if (base64mem(sc->data, sc->size, &data) < 0)
6✔
2502
                        return log_oom_debug();
×
2503

2504
                r = serialize_item_format(f, "exec-context-set-credentials", "%s %s %s", sc->id, data, yes_no(sc->encrypted));
12✔
2505
                if (r < 0)
6✔
2506
                        return r;
2507
        }
2508

2509
        ExecLoadCredential *lc;
2,422✔
2510
        HASHMAP_FOREACH(lc, c->load_credentials) {
2,433✔
2511
                r = serialize_item_format(f, "exec-context-load-credentials", "%s %s %s", lc->id, lc->path, yes_no(lc->encrypted));
21✔
2512
                if (r < 0)
11✔
2513
                        return r;
×
2514
        }
2515

2516
        ExecImportCredential *ic;
2,422✔
2517
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
3,371✔
2518
                r = serialize_item_format(f, "exec-context-import-credentials", "%s%s%s",
1,848✔
2519
                                          ic->glob,
2520
                                          ic->rename ? " " : "",
2521
                                          strempty(ic->rename));
949✔
2522
                if (r < 0)
949✔
2523
                        return r;
×
2524
        }
2525

2526
        r = serialize_image_policy(f, "exec-context-root-image-policy", c->root_image_policy);
2,422✔
2527
        if (r < 0)
2,422✔
2528
                return r;
2529

2530
        r = serialize_image_policy(f, "exec-context-mount-image-policy", c->mount_image_policy);
2,422✔
2531
        if (r < 0)
2,422✔
2532
                return r;
2533

2534
        r = serialize_image_policy(f, "exec-context-extension-image-policy", c->extension_image_policy);
2,422✔
2535
        if (r < 0)
2,422✔
2536
                return r;
2537

2538
        fputc('\n', f); /* End marker */
2,422✔
2539

2540
        return 0;
2541
}
2542

2543
static int exec_context_deserialize(ExecContext *c, FILE *f) {
10,013✔
2544
        int r;
10,013✔
2545

2546
        assert(f);
10,013✔
2547

2548
        if (!c)
10,013✔
2549
                return 0;
2550

2551
        for (;;) {
968,312✔
2552
                _cleanup_free_ char *l = NULL;
958,299✔
2553
                const char *val;
968,312✔
2554

2555
                r = deserialize_read_line(f, &l);
968,312✔
2556
                if (r < 0)
968,312✔
2557
                        return r;
2558
                if (r == 0) /* eof or end marker */
968,312✔
2559
                        break;
2560

2561
                if ((val = startswith(l, "exec-context-environment="))) {
958,299✔
2562
                        r = deserialize_strv(val, &c->environment);
3,494✔
2563
                        if (r < 0)
3,494✔
2564
                                return r;
2565
                } else if ((val = startswith(l, "exec-context-environment-files="))) {
954,805✔
2566
                        r = deserialize_strv(val, &c->environment_files);
344✔
2567
                        if (r < 0)
344✔
2568
                                return r;
2569
                } else if ((val = startswith(l, "exec-context-pass-environment="))) {
954,461✔
2570
                        r = deserialize_strv(val, &c->pass_environment);
314✔
2571
                        if (r < 0)
314✔
2572
                                return r;
2573
                } else if ((val = startswith(l, "exec-context-unset-environment="))) {
954,147✔
2574
                        r = deserialize_strv(val, &c->unset_environment);
973✔
2575
                        if (r < 0)
973✔
2576
                                return r;
2577
                } else if ((val = startswith(l, "exec-context-working-directory="))) {
953,174✔
2578
                        ssize_t k;
756✔
2579
                        char *p;
756✔
2580

2581
                        k = cunescape(val, 0, &p);
756✔
2582
                        if (k < 0)
756✔
2583
                                return k;
×
2584
                        free_and_replace(c->working_directory, p);
756✔
2585
                } else if ((val = startswith(l, "exec-context-root-directory="))) {
952,418✔
2586
                        ssize_t k;
7✔
2587
                        char *p;
7✔
2588

2589
                        k = cunescape(val, 0, &p);
7✔
2590
                        if (k < 0)
7✔
2591
                                return k;
×
2592
                        free_and_replace(c->root_directory, p);
7✔
2593
                } else if ((val = startswith(l, "exec-context-root-image="))) {
952,411✔
2594
                        ssize_t k;
9✔
2595
                        char *p;
9✔
2596

2597
                        k = cunescape(val, 0, &p);
9✔
2598
                        if (k < 0)
9✔
2599
                                return k;
×
2600
                        free_and_replace(c->root_image, p);
9✔
2601
                } else if ((val = startswith(l, "exec-context-root-image-options="))) {
952,402✔
2602
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
2603

2604
                        r = deserialize_mount_options(val, &options);
×
2605
                        if (r < 0)
×
2606
                                return r;
×
2607

2608
                        free_and_replace_full(c->root_image_options, options, mount_options_free_all);
×
2609
                } else if ((val = startswith(l, "exec-context-root-verity="))) {
952,402✔
2610
                        r = free_and_strdup(&c->root_verity, val);
×
2611
                        if (r < 0)
×
2612
                                return r;
2613
                } else if ((val = startswith(l, "exec-context-root-hash-path="))) {
952,402✔
2614
                        r = free_and_strdup(&c->root_hash_path, val);
×
2615
                        if (r < 0)
×
2616
                                return r;
2617
                } else if ((val = startswith(l, "exec-context-root-hash-sig-path="))) {
952,402✔
2618
                        r = free_and_strdup(&c->root_hash_sig_path, val);
×
2619
                        if (r < 0)
×
2620
                                return r;
2621
                } else if ((val = startswith(l, "exec-context-root-hash="))) {
952,402✔
2622
                        iovec_done(&c->root_hash);
4✔
2623
                        r = unhexmem(val, &c->root_hash.iov_base, &c->root_hash.iov_len);
4✔
2624
                        if (r < 0)
4✔
2625
                                return r;
2626
                } else if ((val = startswith(l, "exec-context-root-hash-sig="))) {
952,398✔
2627
                        iovec_done(&c->root_hash_sig);
×
2628
                        r = unbase64mem(val, &c->root_hash_sig.iov_base, &c->root_hash_sig.iov_len);
×
2629
                        if (r < 0)
×
2630
                                return r;
2631
                } else if ((val = startswith(l, "exec-context-root-ephemeral="))) {
952,398✔
2632
                        r = parse_boolean(val);
×
2633
                        if (r < 0)
×
2634
                                return r;
2635
                        c->root_ephemeral = r;
×
2636
                } else if ((val = startswith(l, "exec-context-umask="))) {
952,398✔
2637
                        r = parse_mode(val, &c->umask);
10,013✔
2638
                        if (r < 0)
10,013✔
2639
                                return r;
2640
                } else if ((val = startswith(l, "exec-context-private-non-blocking="))) {
942,385✔
2641
                        r = parse_boolean(val);
×
2642
                        if (r < 0)
×
2643
                                return r;
2644
                        c->non_blocking = r;
×
2645
                } else if ((val = startswith(l, "exec-context-private-mounts="))) {
942,385✔
2646
                        r = safe_atoi(val, &c->private_mounts);
139✔
2647
                        if (r < 0)
139✔
2648
                                return r;
2649
                } else if ((val = startswith(l, "exec-context-mount-api-vfs="))) {
942,246✔
2650
                        r = safe_atoi(val, &c->mount_apivfs);
29✔
2651
                        if (r < 0)
29✔
2652
                                return r;
2653
                } else if ((val = startswith(l, "exec-context-bind-log-sockets="))) {
942,217✔
2654
                        r = safe_atoi(val, &c->bind_log_sockets);
2✔
2655
                        if (r < 0)
2✔
2656
                                return r;
2657
                } else if ((val = startswith(l, "exec-context-memory-ksm="))) {
942,215✔
2658
                        r = safe_atoi(val, &c->memory_ksm);
×
2659
                        if (r < 0)
×
2660
                                return r;
2661
                } else if ((val = startswith(l, "exec-context-memory-thp="))) {
942,215✔
2662
                        c->memory_thp = memory_thp_from_string(val);
10,013✔
2663
                        if (c->memory_thp < 0)
10,013✔
2664
                                return c->memory_thp;
2665
                } else if ((val = startswith(l, "exec-context-private-tmp="))) {
932,202✔
2666
                        c->private_tmp = private_tmp_from_string(val);
10,013✔
2667
                        if (c->private_tmp < 0)
10,013✔
2668
                                return c->private_tmp;
2669
                } else if ((val = startswith(l, "exec-context-private-var-tmp="))) {
922,189✔
2670
                        c->private_var_tmp = private_tmp_from_string(val);
10,013✔
2671
                        if (c->private_var_tmp < 0)
10,013✔
2672
                                return c->private_var_tmp;
2673
                } else if ((val = startswith(l, "exec-context-private-devices="))) {
912,176✔
2674
                        r = parse_boolean(val);
493✔
2675
                        if (r < 0)
493✔
2676
                                return r;
2677
                        c->private_devices = r;
493✔
2678
                } else if ((val = startswith(l, "exec-context-protect-kernel-tunables="))) {
911,683✔
2679
                        r = parse_boolean(val);
310✔
2680
                        if (r < 0)
310✔
2681
                                return r;
2682
                        c->protect_kernel_tunables = r;
310✔
2683
                } else if ((val = startswith(l, "exec-context-protect-kernel-modules="))) {
911,373✔
2684
                        r = parse_boolean(val);
1,104✔
2685
                        if (r < 0)
1,104✔
2686
                                return r;
2687
                        c->protect_kernel_modules = r;
1,104✔
2688
                } else if ((val = startswith(l, "exec-context-protect-kernel-logs="))) {
910,269✔
2689
                        r = parse_boolean(val);
1,104✔
2690
                        if (r < 0)
1,104✔
2691
                                return r;
2692
                        c->protect_kernel_logs = r;
1,104✔
2693
                } else if ((val = startswith(l, "exec-context-protect-clock="))) {
909,165✔
2694
                        r = parse_boolean(val);
899✔
2695
                        if (r < 0)
899✔
2696
                                return r;
2697
                        c->protect_clock = r;
899✔
2698
                } else if ((val = startswith(l, "exec-context-protect-control-groups="))) {
908,266✔
2699
                        r = protect_control_groups_from_string(val);
10,013✔
2700
                        if (r < 0)
10,013✔
2701
                                return r;
2702
                        c->protect_control_groups = r;
10,013✔
2703
                } else if ((val = startswith(l, "exec-context-private-network="))) {
898,253✔
2704
                        r = parse_boolean(val);
70✔
2705
                        if (r < 0)
70✔
2706
                                return r;
2707
                        c->private_network = r;
70✔
2708
                } else if ((val = startswith(l, "exec-context-private-users="))) {
898,183✔
2709
                        c->private_users = private_users_from_string(val);
10,013✔
2710
                        if (c->private_users < 0)
10,013✔
2711
                                return -EINVAL;
2712
                } else if ((val = startswith(l, "exec-context-private-ipc="))) {
888,170✔
2713
                        r = parse_boolean(val);
6✔
2714
                        if (r < 0)
6✔
2715
                                return r;
2716
                        c->private_ipc = r;
6✔
2717
                } else if ((val = startswith(l, "exec-context-private-pids="))) {
888,164✔
2718
                        c->private_pids = private_pids_from_string(val);
10,013✔
2719
                        if (c->private_pids < 0)
10,013✔
2720
                                return -EINVAL;
2721
                } else if ((val = startswith(l, "exec-context-remove-ipc="))) {
878,151✔
2722
                        r = parse_boolean(val);
55✔
2723
                        if (r < 0)
55✔
2724
                                return r;
2725
                        c->remove_ipc = r;
55✔
2726
                } else if ((val = startswith(l, "exec-context-protect-home="))) {
878,096✔
2727
                        c->protect_home = protect_home_from_string(val);
10,013✔
2728
                        if (c->protect_home < 0)
10,013✔
2729
                                return -EINVAL;
2730
                } else if ((val = startswith(l, "exec-context-protect-system="))) {
868,083✔
2731
                        c->protect_system = protect_system_from_string(val);
10,013✔
2732
                        if (c->protect_system < 0)
10,013✔
2733
                                return -EINVAL;
2734
                } else if ((val = startswith(l, "exec-context-same-pgrp="))) {
858,070✔
2735
                        r = parse_boolean(val);
836✔
2736
                        if (r < 0)
836✔
2737
                                return r;
2738
                        c->same_pgrp = r;
836✔
2739
                } else if ((val = startswith(l, "exec-context-non-blocking="))) {
857,234✔
2740
                        r = parse_boolean(val);
×
2741
                        if (r < 0)
×
2742
                                return r;
2743
                        c->non_blocking = r;
×
2744
                } else if ((val = startswith(l, "exec-context-ignore-sigpipe="))) {
857,234✔
2745
                        r = parse_boolean(val);
10,013✔
2746
                        if (r < 0)
10,013✔
2747
                                return r;
2748
                        c->ignore_sigpipe = r;
10,013✔
2749
                } else if ((val = startswith(l, "exec-context-memory-deny-write-execute="))) {
847,221✔
2750
                        r = parse_boolean(val);
1,466✔
2751
                        if (r < 0)
1,466✔
2752
                                return r;
2753
                        c->memory_deny_write_execute = r;
1,466✔
2754
                } else if ((val = startswith(l, "exec-context-restrict-realtime="))) {
845,755✔
2755
                        r = parse_boolean(val);
1,468✔
2756
                        if (r < 0)
1,468✔
2757
                                return r;
2758
                        c->restrict_realtime = r;
1,468✔
2759
                } else if ((val = startswith(l, "exec-context-restrict-suid-sgid="))) {
844,287✔
2760
                        r = parse_boolean(val);
1,370✔
2761
                        if (r < 0)
1,370✔
2762
                                return r;
2763
                        c->restrict_suid_sgid = r;
1,370✔
2764
                } else if ((val = startswith(l, "exec-context-keyring-mode="))) {
842,917✔
2765
                        c->keyring_mode = exec_keyring_mode_from_string(val);
10,013✔
2766
                        if (c->keyring_mode < 0)
10,013✔
2767
                                return -EINVAL;
2768
                } else if ((val = startswith(l, "exec-context-protect-hostname="))) {
832,904✔
2769
                        c->protect_hostname = protect_hostname_from_string(val);
10,013✔
2770
                        if (c->protect_hostname < 0)
10,013✔
2771
                                return -EINVAL;
2772
                } else if ((val = startswith(l, "exec-context-private-hostname="))) {
822,891✔
2773
                        r = free_and_strdup(&c->private_hostname, val);
5✔
2774
                        if (r < 0)
5✔
2775
                                return r;
2776
                } else if ((val = startswith(l, "exec-context-protect-proc="))) {
822,886✔
2777
                        c->protect_proc = protect_proc_from_string(val);
10,013✔
2778
                        if (c->protect_proc < 0)
10,013✔
2779
                                return -EINVAL;
2780
                } else if ((val = startswith(l, "exec-context-proc-subset="))) {
812,873✔
2781
                        c->proc_subset = proc_subset_from_string(val);
10,013✔
2782
                        if (c->proc_subset < 0)
10,013✔
2783
                                return -EINVAL;
2784
                } else if ((val = startswith(l, "exec-context-private-bpf="))) {
802,860✔
2785
                        c->private_bpf = private_bpf_from_string(val);
10,013✔
2786
                        if (c->private_bpf < 0)
10,013✔
2787
                                return -EINVAL;
2788
                } else if ((val = startswith(l, "exec-context-bpf-delegate-commands="))) {
792,847✔
2789
                        r = safe_atoux64(val, &c->bpf_delegate_commands);
2✔
2790
                        if (r < 0)
2✔
2791
                                return r;
2792
                } else if ((val = startswith(l, "exec-context-bpf-delegate-maps="))) {
792,845✔
2793
                        r = safe_atoux64(val, &c->bpf_delegate_maps);
1✔
2794
                        if (r < 0)
1✔
2795
                                return r;
2796
                } else if ((val = startswith(l, "exec-context-bpf-delegate-programs="))) {
792,844✔
2797
                        r = safe_atoux64(val, &c->bpf_delegate_programs);
1✔
2798
                        if (r < 0)
1✔
2799
                                return r;
2800
                } else if ((val = startswith(l, "exec-context-bpf-delegate-attachments="))) {
792,843✔
2801
                        r = safe_atoux64(val, &c->bpf_delegate_attachments);
1✔
2802
                        if (r < 0)
1✔
2803
                                return r;
2804
                } else if ((val = startswith(l, "exec-context-runtime-directory-preserve-mode="))) {
792,842✔
2805
                        c->runtime_directory_preserve_mode = exec_preserve_mode_from_string(val);
10,013✔
2806
                        if (c->runtime_directory_preserve_mode < 0)
10,013✔
2807
                                return -EINVAL;
2808
                } else if ((val = startswith(l, "exec-context-directories-"))) {
782,829✔
2809
                        _cleanup_free_ char *type = NULL, *mode = NULL;
×
2810
                        ExecDirectoryType dt;
50,065✔
2811

2812
                        r = extract_many_words(&val, "= ", 0, &type, &mode);
50,065✔
2813
                        if (r < 0)
50,065✔
2814
                                return r;
2815
                        if (r == 0 || !mode)
50,065✔
2816
                                return -EINVAL;
2817

2818
                        dt = exec_directory_type_from_string(type);
50,065✔
2819
                        if (dt < 0)
50,065✔
2820
                                return dt;
2821

2822
                        r = parse_mode(mode, &c->directories[dt].mode);
50,065✔
2823
                        if (r < 0)
50,065✔
2824
                                return r;
2825

2826
                        for (;;) {
53,016✔
2827
                                _cleanup_free_ char *tuple = NULL, *path = NULL, *only_create = NULL, *read_only = NULL;
52,909✔
2828
                                ExecDirectoryFlags exec_directory_flags = 0;
53,016✔
2829
                                const char *p;
53,016✔
2830

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

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

2845
                                r = parse_boolean(only_create);
2,951✔
2846
                                if (r < 0)
2,951✔
2847
                                        return r;
2848
                                if (r > 0)
2,951✔
2849
                                        exec_directory_flags |= EXEC_DIRECTORY_ONLY_CREATE;
5✔
2850

2851
                                r = parse_boolean(read_only);
2,951✔
2852
                                if (r < 0)
2,951✔
2853
                                        return r;
2854
                                if (r > 0)
2,951✔
2855
                                        exec_directory_flags |= EXEC_DIRECTORY_READ_ONLY;
50✔
2856

2857
                                r = exec_directory_add(&c->directories[dt], path, /* symlink= */ NULL, exec_directory_flags);
2,951✔
2858
                                if (r < 0)
2,951✔
2859
                                        return r;
2860

2861
                                if (isempty(p))
2,951✔
2862
                                        continue;
2,844✔
2863

2864
                                for (;;) {
385✔
2865
                                        _cleanup_free_ char *link = NULL;
246✔
2866

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

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

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

2886
                        dt = exec_directory_type_from_string(type);
×
2887
                        if (dt < 0)
×
2888
                                return dt;
2889

2890
                        r = parse_boolean(quota_accounting);
×
2891
                        if (r < 0)
×
2892
                                return r;
2893

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

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

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

2907
                        dt = exec_directory_type_from_string(type);
×
2908
                        if (dt < 0)
×
2909
                                return dt;
2910

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

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

2919
                        c->directories[dt].exec_quota.quota_enforce = true;
×
2920
                } else if ((val = startswith(l, "exec-context-timeout-clean-usec="))) {
732,764✔
2921
                        r = deserialize_usec(val, &c->timeout_clean_usec);
×
2922
                        if (r < 0)
×
2923
                                return r;
2924
                } else if ((val = startswith(l, "exec-context-nice="))) {
732,764✔
2925
                        r = safe_atoi(val, &c->nice);
19✔
2926
                        if (r < 0)
19✔
2927
                                return r;
2928
                        c->nice_set = true;
19✔
2929
                } else if ((val = startswith(l, "exec-context-working-directory-missing-ok="))) {
732,745✔
2930
                        r = parse_boolean(val);
695✔
2931
                        if (r < 0)
695✔
2932
                                return r;
2933
                        c->working_directory_missing_ok = r;
695✔
2934
                } else if ((val = startswith(l, "exec-context-working-directory-home="))) {
732,050✔
2935
                        r = parse_boolean(val);
179✔
2936
                        if (r < 0)
179✔
2937
                                return r;
2938
                        c->working_directory_home = r;
179✔
2939
                } else if ((val = startswith(l, "exec-context-oom-score-adjust="))) {
731,871✔
2940
                        r = safe_atoi(val, &c->oom_score_adjust);
1,081✔
2941
                        if (r < 0)
1,081✔
2942
                                return r;
2943
                        c->oom_score_adjust_set = true;
1,081✔
2944
                } else if ((val = startswith(l, "exec-context-coredump-filter="))) {
730,790✔
2945
                        r = safe_atoux64(val, &c->coredump_filter);
2✔
2946
                        if (r < 0)
2✔
2947
                                return r;
2948
                        c->coredump_filter_set = true;
2✔
2949
                } else if ((val = startswith(l, "exec-context-limit-"))) {
730,788✔
2950
                        _cleanup_free_ struct rlimit *rlimit = NULL;
×
2951
                        _cleanup_free_ char *limit = NULL;
20,021✔
2952
                        int type;
20,021✔
2953

2954
                        r = extract_first_word(&val, &limit, "=", 0);
20,021✔
2955
                        if (r < 0)
20,021✔
2956
                                return r;
2957
                        if (r == 0 || !val)
20,021✔
2958
                                return -EINVAL;
2959

2960
                        type = rlimit_from_string(limit);
20,021✔
2961
                        if (type < 0)
20,021✔
2962
                                return -EINVAL;
2963

2964
                        if (!c->rlimit[type]) {
20,021✔
2965
                                rlimit = new0(struct rlimit, 1);
20,021✔
2966
                                if (!rlimit)
20,021✔
2967
                                        return log_oom_debug();
×
2968

2969
                                r = rlimit_parse(type, val, rlimit);
20,021✔
2970
                                if (r < 0)
20,021✔
2971
                                        return r;
2972

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

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

3011
                        r = parse_cpu_set(val, &c->numa_policy.nodes);
19✔
3012
                        if (r < 0)
19✔
3013
                                return r;
3014
                } else if ((val = startswith(l, "exec-context-numa-policy="))) {
710,738✔
3015
                        r = safe_atoi(val, &c->numa_policy.type);
19✔
3016
                        if (r < 0)
19✔
3017
                                return r;
3018
                } else if ((val = startswith(l, "exec-context-cpu-affinity-from-numa="))) {
710,719✔
3019
                        r = parse_boolean(val);
2✔
3020
                        if (r < 0)
2✔
3021
                                return r;
3022
                        c->cpu_affinity_from_numa = r;
2✔
3023
                } else if ((val = startswith(l, "exec-context-timer-slack-nsec="))) {
710,717✔
3024
                        r = deserialize_usec(val, (usec_t *)&c->timer_slack_nsec);
×
3025
                        if (r < 0)
×
3026
                                return r;
3027
                } else if ((val = startswith(l, "exec-context-root-directory-as-fd="))) {
710,717✔
3028
                        r = parse_boolean(val);
2✔
3029
                        if (r < 0)
2✔
3030
                                return r;
3031
                        c->root_directory_as_fd = r;
2✔
3032
                } else if ((val = startswith(l, "exec-context-std-input="))) {
710,715✔
3033
                        c->std_input = exec_input_from_string(val);
10,013✔
3034
                        if (c->std_input < 0)
10,013✔
3035
                                return c->std_input;
3036
                } else if ((val = startswith(l, "exec-context-std-output="))) {
700,702✔
3037
                        c->std_output = exec_output_from_string(val);
10,013✔
3038
                        if (c->std_output < 0)
10,013✔
3039
                                return c->std_output;
3040
                } else if ((val = startswith(l, "exec-context-std-error="))) {
690,689✔
3041
                        c->std_error = exec_output_from_string(val);
10,013✔
3042
                        if (c->std_error < 0)
10,013✔
3043
                                return c->std_error;
3044
                } else if ((val = startswith(l, "exec-context-stdio-as-fds="))) {
680,676✔
3045
                        r = parse_boolean(val);
543✔
3046
                        if (r < 0)
543✔
3047
                                return r;
3048
                        c->stdio_as_fds = r;
543✔
3049
                } else if ((val = startswith(l, "exec-context-std-input-data="))) {
680,133✔
3050
                        if (c->stdin_data)
1✔
3051
                                return -EINVAL; /* duplicated */
3052

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

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

3076
                        free_and_replace(c->stdio_file[STDIN_FILENO], p);
×
3077

3078
                } else if ((val = startswith(l, "exec-context-std-output-file="))) {
680,132✔
3079
                        ssize_t k;
53✔
3080
                        char *p;
53✔
3081

3082
                        k = cunescape(val, 0, &p);
53✔
3083
                        if (k < 0)
53✔
3084
                                return k;
×
3085

3086
                        free_and_replace(c->stdio_file[STDOUT_FILENO], p);
53✔
3087

3088
                } else if ((val = startswith(l, "exec-context-std-error-file="))) {
680,079✔
3089
                        ssize_t k;
49✔
3090
                        char *p;
49✔
3091

3092
                        k = cunescape(val, 0, &p);
49✔
3093
                        if (k < 0)
49✔
3094
                                return k;
×
3095

3096
                        free_and_replace(c->stdio_file[STDERR_FILENO], p);
49✔
3097

3098
                } else if ((val = startswith(l, "exec-context-tty-path="))) {
680,030✔
3099
                        r = free_and_strdup(&c->tty_path, val);
104✔
3100
                        if (r < 0)
104✔
3101
                                return r;
3102
                } else if ((val = startswith(l, "exec-context-tty-reset="))) {
679,926✔
3103
                        r = parse_boolean(val);
192✔
3104
                        if (r < 0)
192✔
3105
                                return r;
3106
                        c->tty_reset = r;
192✔
3107
                } else if ((val = startswith(l, "exec-context-tty-vhangup="))) {
679,734✔
3108
                        r = parse_boolean(val);
83✔
3109
                        if (r < 0)
83✔
3110
                                return r;
3111
                        c->tty_vhangup = r;
83✔
3112
                } else if ((val = startswith(l, "exec-context-tty-vt-disallocate="))) {
679,651✔
3113
                        r = parse_boolean(val);
46✔
3114
                        if (r < 0)
46✔
3115
                                return r;
3116
                        c->tty_vt_disallocate = r;
46✔
3117
                } else if ((val = startswith(l, "exec-context-tty-rows="))) {
679,605✔
3118
                        r = safe_atou(val, &c->tty_rows);
10,013✔
3119
                        if (r < 0)
10,013✔
3120
                                return r;
3121
                } else if ((val = startswith(l, "exec-context-tty-columns="))) {
669,592✔
3122
                        r = safe_atou(val, &c->tty_cols);
10,013✔
3123
                        if (r < 0)
10,013✔
3124
                                return r;
3125
                } else if ((val = startswith(l, "exec-context-syslog-priority="))) {
659,579✔
3126
                        r = safe_atoi(val, &c->syslog_priority);
10,013✔
3127
                        if (r < 0)
10,013✔
3128
                                return r;
3129
                } else if ((val = startswith(l, "exec-context-syslog-level-prefix="))) {
649,566✔
3130
                        r = parse_boolean(val);
10,013✔
3131
                        if (r < 0)
10,013✔
3132
                                return r;
3133
                        c->syslog_level_prefix = r;
10,013✔
3134
                } else if ((val = startswith(l, "exec-context-syslog-identifier="))) {
639,553✔
3135
                        r = free_and_strdup(&c->syslog_identifier, val);
×
3136
                        if (r < 0)
×
3137
                                return r;
3138
                } else if ((val = startswith(l, "exec-context-log-level-max="))) {
639,553✔
3139
                        /* See comment in serialization. */
3140
                        r = safe_atoi(val, &c->log_level_max);
10,013✔
3141
                        if (r < 0)
10,013✔
3142
                                return r;
3143
                } else if ((val = startswith(l, "exec-context-log-ratelimit-interval-usec="))) {
629,540✔
3144
                        r = deserialize_usec(val, &c->log_ratelimit.interval);
×
3145
                        if (r < 0)
×
3146
                                return r;
3147
                } else if ((val = startswith(l, "exec-context-log-ratelimit-burst="))) {
629,540✔
3148
                        r = safe_atou(val, &c->log_ratelimit.burst);
×
3149
                        if (r < 0)
×
3150
                                return r;
3151
                } else if ((val = startswith(l, "exec-context-log-filter-allowed-patterns="))) {
629,540✔
3152
                        r = set_put_strdup(&c->log_filter_allowed_patterns, val);
20✔
3153
                        if (r < 0)
20✔
3154
                                return r;
3155
                } else if ((val = startswith(l, "exec-context-log-filter-denied-patterns="))) {
629,520✔
3156
                        r = set_put_strdup(&c->log_filter_denied_patterns, val);
13✔
3157
                        if (r < 0)
13✔
3158
                                return r;
3159
                } else if ((val = startswith(l, "exec-context-log-extra-fields="))) {
629,507✔
3160
                        if (!GREEDY_REALLOC(c->log_extra_fields, c->n_log_extra_fields + 1))
706✔
3161
                                return log_oom_debug();
×
3162

3163
                        c->log_extra_fields[c->n_log_extra_fields++].iov_base = strdup(val);
706✔
3164
                        if (!c->log_extra_fields[c->n_log_extra_fields-1].iov_base)
706✔
3165
                                return log_oom_debug();
×
3166
                } else if ((val = startswith(l, "exec-context-log-namespace="))) {
628,801✔
3167
                        r = free_and_strdup(&c->log_namespace, val);
2✔
3168
                        if (r < 0)
2✔
3169
                                return r;
3170
                } else if ((val = startswith(l, "exec-context-secure-bits="))) {
628,799✔
3171
                        r = safe_atoi(val, &c->secure_bits);
×
3172
                        if (r < 0)
×
3173
                                return r;
3174
                } else if ((val = startswith(l, "exec-context-capability-bounding-set="))) {
628,799✔
3175
                        r = safe_atou64(val, &c->capability_bounding_set);
10,013✔
3176
                        if (r < 0)
10,013✔
3177
                                return r;
3178
                } else if ((val = startswith(l, "exec-context-capability-ambient-set="))) {
618,786✔
3179
                        r = safe_atou64(val, &c->capability_ambient_set);
654✔
3180
                        if (r < 0)
654✔
3181
                                return r;
3182
                } else if ((val = startswith(l, "exec-context-user="))) {
618,132✔
3183
                        r = free_and_strdup(&c->user, val);
2,074✔
3184
                        if (r < 0)
2,074✔
3185
                                return r;
3186
                } else if ((val = startswith(l, "exec-context-group="))) {
616,058✔
3187
                        r = free_and_strdup(&c->group, val);
60✔
3188
                        if (r < 0)
60✔
3189
                                return r;
3190
                } else if ((val = startswith(l, "exec-context-dynamic-user="))) {
615,998✔
3191
                        r = parse_boolean(val);
47✔
3192
                        if (r < 0)
47✔
3193
                                return r;
3194
                        c->dynamic_user = r;
47✔
3195
                } else if ((val = startswith(l, "exec-context-supplementary-groups="))) {
615,951✔
3196
                        r = deserialize_strv(val, &c->supplementary_groups);
12✔
3197
                        if (r < 0)
12✔
3198
                                return r;
3199
                } else if ((val = startswith(l, "exec-context-set-login-environment="))) {
615,939✔
3200
                        r = safe_atoi(val, &c->set_login_environment);
×
3201
                        if (r < 0)
×
3202
                                return r;
3203
                } else if ((val = startswith(l, "exec-context-pam-name="))) {
615,939✔
3204
                        r = free_and_strdup(&c->pam_name, val);
507✔
3205
                        if (r < 0)
507✔
3206
                                return r;
3207
                } else if ((val = startswith(l, "exec-context-read-write-paths="))) {
615,432✔
3208
                        r = deserialize_strv(val, &c->read_write_paths);
822✔
3209
                        if (r < 0)
822✔
3210
                                return r;
3211
                } else if ((val = startswith(l, "exec-context-read-only-paths="))) {
614,610✔
3212
                        r = deserialize_strv(val, &c->read_only_paths);
2✔
3213
                        if (r < 0)
2✔
3214
                                return r;
3215
                } else if ((val = startswith(l, "exec-context-inaccessible-paths="))) {
614,608✔
3216
                        r = deserialize_strv(val, &c->inaccessible_paths);
5✔
3217
                        if (r < 0)
5✔
3218
                                return r;
3219
                } else if ((val = startswith(l, "exec-context-exec-paths="))) {
614,603✔
3220
                        r = deserialize_strv(val, &c->exec_paths);
1✔
3221
                        if (r < 0)
1✔
3222
                                return r;
3223
                } else if ((val = startswith(l, "exec-context-no-exec-paths="))) {
614,602✔
3224
                        r = deserialize_strv(val, &c->no_exec_paths);
1✔
3225
                        if (r < 0)
1✔
3226
                                return r;
3227
                } else if ((val = startswith(l, "exec-context-exec-search-path="))) {
614,601✔
3228
                        r = deserialize_strv(val, &c->exec_search_path);
×
3229
                        if (r < 0)
×
3230
                                return r;
3231
                } else if ((val = startswith(l, "exec-context-mount-propagation-flag="))) {
614,601✔
3232
                        r = safe_atolu(val, &c->mount_propagation_flag);
10,013✔
3233
                        if (r < 0)
10,013✔
3234
                                return r;
3235
                } else if ((val = startswith(l, "exec-context-bind-read-only-path="))) {
604,588✔
3236
                        _cleanup_free_ char *source = NULL, *destination = NULL;
7✔
3237
                        bool rbind = true, ignore_enoent = false;
7✔
3238
                        char *s = NULL, *d = NULL;
7✔
3239

3240
                        r = extract_first_word(&val,
7✔
3241
                                               &source,
3242
                                               ":" WHITESPACE,
3243
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3244
                        if (r < 0)
7✔
3245
                                return r;
3246
                        if (r == 0)
7✔
3247
                                return -EINVAL;
3248

3249
                        s = source;
7✔
3250
                        if (s[0] == '-') {
7✔
3251
                                ignore_enoent = true;
1✔
3252
                                s++;
1✔
3253
                        }
3254

3255
                        if (val && val[-1] == ':') {
7✔
3256
                                r = extract_first_word(&val,
7✔
3257
                                                       &destination,
3258
                                                       ":" WHITESPACE,
3259
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3260
                                if (r < 0)
7✔
3261
                                        return r;
3262
                                if (r == 0)
7✔
3263
                                        continue;
×
3264

3265
                                d = destination;
7✔
3266

3267
                                if (val && val[-1] == ':') {
7✔
3268
                                        _cleanup_free_ char *options = NULL;
7✔
3269

3270
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
7✔
3271
                                        if (r < 0)
7✔
3272
                                                return -r;
×
3273

3274
                                        if (isempty(options) || streq(options, "rbind"))
15✔
3275
                                                rbind = true;
3276
                                        else if (streq(options, "norbind"))
1✔
3277
                                                rbind = false;
3278
                                        else
3279
                                                continue;
×
3280
                                }
3281
                        } else
3282
                                d = s;
3283

3284
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
14✔
3285
                                        &(BindMount) {
7✔
3286
                                                .source = s,
3287
                                                .destination = d,
3288
                                                .read_only = true,
3289
                                                .recursive = rbind,
3290
                                                .ignore_enoent = ignore_enoent,
3291
                                        });
3292
                        if (r < 0)
7✔
3293
                                return log_oom_debug();
×
3294
                } else if ((val = startswith(l, "exec-context-bind-path="))) {
604,581✔
3295
                        _cleanup_free_ char *source = NULL, *destination = NULL;
20✔
3296
                        bool rbind = true, ignore_enoent = false;
20✔
3297
                        char *s = NULL, *d = NULL;
20✔
3298

3299
                        r = extract_first_word(&val,
20✔
3300
                                               &source,
3301
                                               ":" WHITESPACE,
3302
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3303
                        if (r < 0)
20✔
3304
                                return r;
3305
                        if (r == 0)
20✔
3306
                                return -EINVAL;
3307

3308
                        s = source;
20✔
3309
                        if (s[0] == '-') {
20✔
3310
                                ignore_enoent = true;
1✔
3311
                                s++;
1✔
3312
                        }
3313

3314
                        if (val && val[-1] == ':') {
20✔
3315
                                r = extract_first_word(&val,
20✔
3316
                                                       &destination,
3317
                                                       ":" WHITESPACE,
3318
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3319
                                if (r < 0)
20✔
3320
                                        return r;
3321
                                if (r == 0)
20✔
3322
                                        continue;
×
3323

3324
                                d = destination;
20✔
3325

3326
                                if (val && val[-1] == ':') {
20✔
3327
                                        _cleanup_free_ char *options = NULL;
20✔
3328

3329
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
20✔
3330
                                        if (r < 0)
20✔
3331
                                                return -r;
×
3332

3333
                                        if (isempty(options) || streq(options, "rbind"))
43✔
3334
                                                rbind = true;
3335
                                        else if (streq(options, "norbind"))
3✔
3336
                                                rbind = false;
3337
                                        else
3338
                                                continue;
×
3339
                                }
3340
                        } else
3341
                                d = s;
3342

3343
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
40✔
3344
                                        &(BindMount) {
20✔
3345
                                                .source = s,
3346
                                                .destination = d,
3347
                                                .read_only = false,
3348
                                                .recursive = rbind,
3349
                                                .ignore_enoent = ignore_enoent,
3350
                                        });
3351
                        if (r < 0)
20✔
3352
                                return log_oom_debug();
×
3353
                } else if ((val = startswith(l, "exec-context-temporary-filesystems="))) {
604,561✔
3354
                        _cleanup_free_ char *path = NULL, *options = NULL;
61✔
3355

3356
                        r = extract_many_words(&val, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &path, &options);
61✔
3357
                        if (r < 0)
61✔
3358
                                return r;
3359
                        if (r < 1)
61✔
3360
                                continue;
×
3361

3362
                        r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
61✔
3363
                        if (r < 0)
61✔
3364
                                return log_oom_debug();
×
3365
                } else if ((val = startswith(l, "exec-context-utmp-id="))) {
604,500✔
3366
                        r = free_and_strdup(&c->utmp_id, val);
90✔
3367
                        if (r < 0)
90✔
3368
                                return r;
3369
                } else if ((val = startswith(l, "exec-context-utmp-mode="))) {
604,410✔
3370
                        c->utmp_mode = exec_utmp_mode_from_string(val);
10,013✔
3371
                        if (c->utmp_mode < 0)
10,013✔
3372
                                return c->utmp_mode;
3373
                } else if ((val = startswith(l, "exec-context-no-new-privileges="))) {
594,397✔
3374
                        r = parse_boolean(val);
1,397✔
3375
                        if (r < 0)
1,397✔
3376
                                return r;
3377
                        c->no_new_privileges = r;
1,397✔
3378
                } else if ((val = startswith(l, "exec-context-selinux-context="))) {
593,000✔
3379
                        if (val[0] == '-') {
×
3380
                                c->selinux_context_ignore = true;
×
3381
                                val++;
×
3382
                        } else
3383
                                c->selinux_context_ignore = false;
×
3384

3385
                        r = free_and_strdup(&c->selinux_context, val);
×
3386
                        if (r < 0)
×
3387
                                return r;
3388
                } else if ((val = startswith(l, "exec-context-apparmor-profile="))) {
593,000✔
3389
                        if (val[0] == '-') {
×
3390
                                c->apparmor_profile_ignore = true;
×
3391
                                val++;
×
3392
                        } else
3393
                                c->apparmor_profile_ignore = false;
×
3394

3395
                        r = free_and_strdup(&c->apparmor_profile, val);
×
3396
                        if (r < 0)
×
3397
                                return r;
3398
                } else if ((val = startswith(l, "exec-context-smack-process-label="))) {
593,000✔
3399
                        if (val[0] == '-') {
×
3400
                                c->smack_process_label_ignore = true;
×
3401
                                val++;
×
3402
                        } else
3403
                                c->smack_process_label_ignore = false;
×
3404

3405
                        r = free_and_strdup(&c->smack_process_label, val);
×
3406
                        if (r < 0)
×
3407
                                return r;
3408
                } else if ((val = startswith(l, "exec-context-personality="))) {
593,000✔
3409
                        c->personality = personality_from_string(val);
×
3410
                        if (c->personality == PERSONALITY_INVALID)
×
3411
                                return -EINVAL;
3412
                } else if ((val = startswith(l, "exec-context-lock-personality="))) {
593,000✔
3413
                        r = parse_boolean(val);
1,471✔
3414
                        if (r < 0)
1,471✔
3415
                                return r;
3416
                        c->lock_personality = r;
1,471✔
3417
#if HAVE_SECCOMP
3418
                } else if ((val = startswith(l, "exec-context-syscall-filter="))) {
591,529✔
3419
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
565,908✔
3420
                        int id, errno_num;
565,908✔
3421

3422
                        r = extract_many_words(&val, NULL, 0, &s_id, &s_errno_num);
565,908✔
3423
                        if (r < 0)
565,908✔
3424
                                return r;
3425
                        if (r != 2)
565,908✔
3426
                                continue;
×
3427

3428
                        r = safe_atoi(s_id, &id);
565,908✔
3429
                        if (r < 0)
565,908✔
3430
                                return r;
3431

3432
                        r = safe_atoi(s_errno_num, &errno_num);
565,908✔
3433
                        if (r < 0)
565,908✔
3434
                                return r;
3435

3436
                        r = hashmap_ensure_put(&c->syscall_filter, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
565,908✔
3437
                        if (r < 0)
565,908✔
3438
                                return r;
3439
                } else if ((val = startswith(l, "exec-context-syscall-archs="))) {
25,621✔
3440
                        unsigned id;
1,473✔
3441

3442
                        r = safe_atou(val, &id);
1,473✔
3443
                        if (r < 0)
1,473✔
3444
                                return r;
×
3445

3446
                        r = set_ensure_put(&c->syscall_archs, NULL, UINT_TO_PTR(id + 1));
1,473✔
3447
                        if (r < 0)
1,473✔
3448
                                return r;
3449
                } else if ((val = startswith(l, "exec-context-syscall-errno="))) {
24,148✔
3450
                        r = safe_atoi(val, &c->syscall_errno);
10,013✔
3451
                        if (r < 0)
10,013✔
3452
                                return r;
3453
                } else if ((val = startswith(l, "exec-context-syscall-allow-list="))) {
14,135✔
3454
                        r = parse_boolean(val);
1,448✔
3455
                        if (r < 0)
1,448✔
3456
                                return r;
3457
                        c->syscall_allow_list = r;
1,448✔
3458
                } else if ((val = startswith(l, "exec-context-syscall-log="))) {
12,687✔
3459
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
×
3460
                        int id, errno_num;
×
3461

3462
                        r = extract_many_words(&val, " ", 0, &s_id, &s_errno_num);
×
3463
                        if (r < 0)
×
3464
                                return r;
3465
                        if (r != 2)
×
3466
                                continue;
×
3467

3468
                        r = safe_atoi(s_id, &id);
×
3469
                        if (r < 0)
×
3470
                                return r;
3471

3472
                        r = safe_atoi(s_errno_num, &errno_num);
×
3473
                        if (r < 0)
×
3474
                                return r;
3475

3476
                        r = hashmap_ensure_put(&c->syscall_log, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
×
3477
                        if (r < 0)
×
3478
                                return r;
3479
                } else if ((val = startswith(l, "exec-context-syscall-log-allow-list="))) {
12,687✔
3480
                        r = parse_boolean(val);
×
3481
                        if (r < 0)
×
3482
                                return r;
3483
                        c->syscall_log_allow_list = r;
×
3484
#endif
3485
                } else if ((val = startswith(l, "exec-context-restrict-namespaces="))) {
12,687✔
3486
                        r = safe_atolu(val, &c->restrict_namespaces);
1,219✔
3487
                        if (r < 0)
1,219✔
3488
                                return r;
3489
                } else if ((val = startswith(l, "exec-context-delegate-namespaces="))) {
11,468✔
3490
                        r = safe_atolu(val, &c->delegate_namespaces);
21✔
3491
                        if (r < 0)
21✔
3492
                                return r;
3493
                } else if ((val = startswith(l, "exec-context-restrict-filesystems="))) {
11,447✔
3494
                        r = set_put_strdup(&c->restrict_filesystems, val);
×
3495
                        if (r < 0)
×
3496
                                return r;
3497
                } else if ((val = startswith(l, "exec-context-restrict-filesystems-allow-list="))) {
11,447✔
3498
                        r = parse_boolean(val);
×
3499
                        if (r < 0)
×
3500
                                return r;
3501
                        c->restrict_filesystems_allow_list = r;
×
3502
                } else if ((val = startswith(l, "exec-context-address-families="))) {
11,447✔
3503
                        int af;
5,782✔
3504

3505
                        r = safe_atoi(val, &af);
5,782✔
3506
                        if (r < 0)
5,782✔
3507
                                return r;
×
3508

3509
                        r = set_ensure_put(&c->address_families, NULL, INT_TO_PTR(af));
5,782✔
3510
                        if (r < 0)
5,782✔
3511
                                return r;
3512
                } else if ((val = startswith(l, "exec-context-address-families-allow-list="))) {
5,665✔
3513
                        r = parse_boolean(val);
1,466✔
3514
                        if (r < 0)
1,466✔
3515
                                return r;
3516
                        c->address_families_allow_list = r;
1,466✔
3517
                } else if ((val = startswith(l, "exec-context-network-namespace-path="))) {
4,199✔
3518
                        r = free_and_strdup(&c->network_namespace_path, val);
1✔
3519
                        if (r < 0)
1✔
3520
                                return r;
3521
                } else if ((val = startswith(l, "exec-context-user-namespace-path="))) {
4,198✔
3522
                        r = free_and_strdup(&c->user_namespace_path, val);
3✔
3523
                        if (r < 0)
3✔
3524
                                return r;
3525
                } else if ((val = startswith(l, "exec-context-ipc-namespace-path="))) {
4,195✔
3526
                        r = free_and_strdup(&c->ipc_namespace_path, val);
×
3527
                        if (r < 0)
×
3528
                                return r;
3529
                } else if ((val = startswith(l, "exec-context-mount-image="))) {
4,195✔
3530
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3531
                        _cleanup_free_ char *source = NULL, *destination = NULL;
57✔
3532
                        bool permissive = false;
57✔
3533
                        char *s;
57✔
3534

3535
                        r = extract_many_words(&val,
57✔
3536
                                               NULL,
3537
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3538
                                               &source,
3539
                                               &destination);
3540
                        if (r < 0)
57✔
3541
                                return r;
3542
                        if (r == 0)
57✔
3543
                                return -EINVAL;
3544

3545
                        s = source;
57✔
3546
                        if (s[0] == '-') {
57✔
3547
                                permissive = true;
×
3548
                                s++;
×
3549
                        }
3550

3551
                        if (isempty(destination))
57✔
3552
                                continue;
×
3553

3554
                        r = deserialize_mount_options(val, &options);
57✔
3555
                        if (r < 0)
57✔
3556
                                return r;
3557

3558
                        r = mount_image_add(&c->mount_images, &c->n_mount_images,
114✔
3559
                                        &(MountImage) {
57✔
3560
                                                .source = s,
3561
                                                .destination = destination,
3562
                                                .mount_options = options,
3563
                                                .ignore_enoent = permissive,
3564
                                                .type = MOUNT_IMAGE_DISCRETE,
3565
                                        });
3566
                        if (r < 0)
57✔
3567
                                return log_oom_debug();
×
3568
                } else if ((val = startswith(l, "exec-context-extension-image="))) {
4,138✔
3569
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3570
                        _cleanup_free_ char *source = NULL;
13✔
3571
                        bool permissive = false;
13✔
3572
                        char *s;
13✔
3573

3574
                        r = extract_first_word(&val,
13✔
3575
                                               &source,
3576
                                               NULL,
3577
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS);
3578
                        if (r < 0)
13✔
3579
                                return r;
3580
                        if (r == 0)
13✔
3581
                                return -EINVAL;
3582

3583
                        s = source;
13✔
3584
                        if (s[0] == '-') {
13✔
3585
                                permissive = true;
3✔
3586
                                s++;
3✔
3587
                        }
3588

3589
                        r = deserialize_mount_options(val, &options);
13✔
3590
                        if (r < 0)
13✔
3591
                                return r;
3592

3593
                        r = mount_image_add(&c->extension_images, &c->n_extension_images,
26✔
3594
                                        &(MountImage) {
13✔
3595
                                                .source = s,
3596
                                                .mount_options = options,
3597
                                                .ignore_enoent = permissive,
3598
                                                .type = MOUNT_IMAGE_EXTENSION,
3599
                                        });
3600
                        if (r < 0)
13✔
3601
                                return log_oom_debug();
×
3602
                } else if ((val = startswith(l, "exec-context-extension-directories="))) {
4,125✔
3603
                        r = deserialize_strv(val, &c->extension_directories);
8✔
3604
                        if (r < 0)
8✔
3605
                                return r;
3606
                } else if ((val = startswith(l, "exec-context-set-credentials="))) {
4,117✔
3607
                        _cleanup_free_ char *id = NULL, *data = NULL, *encrypted = NULL;
×
3608

3609
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &data, &encrypted);
93✔
3610
                        if (r < 0)
93✔
3611
                                return r;
3612
                        if (r != 3)
93✔
3613
                                return -EINVAL;
3614

3615
                        r = parse_boolean(encrypted);
93✔
3616
                        if (r < 0)
93✔
3617
                                return r;
3618
                        bool e = r;
93✔
3619

3620
                        _cleanup_free_ void *d = NULL;
93✔
3621
                        size_t size;
93✔
3622

3623
                        r = unbase64mem_full(data, SIZE_MAX, /* secure= */ true, &d, &size);
93✔
3624
                        if (r < 0)
93✔
3625
                                return r;
3626

3627
                        r = exec_context_put_set_credential(c, id, TAKE_PTR(d), size, e);
93✔
3628
                        if (r < 0)
93✔
3629
                                return r;
3630
                } else if ((val = startswith(l, "exec-context-load-credentials="))) {
4,024✔
3631
                        _cleanup_free_ char *id = NULL, *path = NULL, *encrypted = NULL;
34✔
3632

3633
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &path, &encrypted);
34✔
3634
                        if (r < 0)
34✔
3635
                                return r;
3636
                        if (r != 3)
34✔
3637
                                return -EINVAL;
3638

3639
                        r = parse_boolean(encrypted);
34✔
3640
                        if (r < 0)
34✔
3641
                                return r;
3642

3643
                        r = exec_context_put_load_credential(c, id, path, r > 0);
34✔
3644
                        if (r < 0)
34✔
3645
                                return r;
3646
                } else if ((val = startswith(l, "exec-context-import-credentials="))) {
3,990✔
3647
                        _cleanup_free_ char *glob = NULL, *rename = NULL;
3,984✔
3648

3649
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &glob, &rename);
3,984✔
3650
                        if (r < 0)
3,984✔
3651
                                return r;
3652
                        if (r == 0)
3,984✔
3653
                                return -EINVAL;
3654

3655
                        r = exec_context_put_import_credential(c, glob, rename);
3,984✔
3656
                        if (r < 0)
3,984✔
3657
                                return r;
3658
                } else if ((val = startswith(l, "exec-context-root-image-policy="))) {
6✔
3659
                        if (c->root_image_policy)
4✔
3660
                                return -EINVAL; /* duplicated */
3661

3662
                        r = image_policy_from_string(val, /* graceful= */ false, &c->root_image_policy);
4✔
3663
                        if (r < 0)
4✔
3664
                                return r;
3665
                } else if ((val = startswith(l, "exec-context-mount-image-policy="))) {
2✔
3666
                        if (c->mount_image_policy)
×
3667
                                return -EINVAL; /* duplicated */
3668

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

3676
                        r = image_policy_from_string(val, /* graceful= */ false, &c->extension_image_policy);
2✔
3677
                        if (r < 0)
2✔
3678
                                return r;
3679
                } else
3680
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3681
        }
3682

3683
        return 0;
10,013✔
3684
}
3685

3686
static int exec_command_serialize(const ExecCommand *c, FILE *f) {
2,422✔
3687
        int r;
2,422✔
3688

3689
        assert(c);
2,422✔
3690
        assert(f);
2,422✔
3691

3692
        r = serialize_item(f, "exec-command-path", c->path);
2,422✔
3693
        if (r < 0)
2,422✔
3694
                return r;
3695

3696
        r = serialize_strv(f, "exec-command-argv", c->argv);
2,422✔
3697
        if (r < 0)
2,422✔
3698
                return r;
3699

3700
        r = serialize_item_format(f, "exec-command-flags", "%d", (int) c->flags);
2,422✔
3701
        if (r < 0)
2,422✔
3702
                return r;
3703

3704
        fputc('\n', f); /* End marker */
2,422✔
3705

3706
        return 0;
2,422✔
3707
}
3708

3709
static int exec_command_deserialize(ExecCommand *c, FILE *f) {
10,013✔
3710
        int r;
10,013✔
3711

3712
        assert(c);
10,013✔
3713
        assert(f);
10,013✔
3714

3715
        for (;;) {
108,371✔
3716
                _cleanup_free_ char *l = NULL;
49,179✔
3717
                const char *val;
59,192✔
3718

3719
                r = deserialize_read_line(f, &l);
59,192✔
3720
                if (r < 0)
59,192✔
3721
                        return r;
3722
                if (r == 0) /* eof or end marker */
59,192✔
3723
                        break;
3724

3725
                if ((val = startswith(l, "exec-command-path="))) {
49,179✔
3726
                        r = free_and_strdup(&c->path, val);
10,013✔
3727
                        if (r < 0)
10,013✔
3728
                                return r;
3729
                } else if ((val = startswith(l, "exec-command-argv="))) {
39,166✔
3730
                        r = deserialize_strv(val, &c->argv);
29,153✔
3731
                        if (r < 0)
29,153✔
3732
                                return r;
3733
                } else if ((val = startswith(l, "exec-command-flags="))) {
10,013✔
3734
                        r = safe_atoi(val, &c->flags);
10,013✔
3735
                        if (r < 0)
10,013✔
3736
                                return r;
3737
                } else
3738
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
×
3739

3740
        }
3741

3742
        return 0;
10,013✔
3743
}
3744

3745
int exec_serialize_invocation(
2,422✔
3746
                FILE *f,
3747
                FDSet *fds,
3748
                const ExecContext *ctx,
3749
                const ExecCommand *cmd,
3750
                const ExecParameters *p,
3751
                const ExecRuntime *rt,
3752
                const CGroupContext *cg) {
3753

3754
        int r;
2,422✔
3755

3756
        assert(f);
2,422✔
3757
        assert(fds);
2,422✔
3758

3759
        r = exec_context_serialize(ctx, f);
2,422✔
3760
        if (r < 0)
2,422✔
3761
                return log_debug_errno(r, "Failed to serialize context: %m");
×
3762

3763
        r = exec_command_serialize(cmd, f);
2,422✔
3764
        if (r < 0)
2,422✔
3765
                return log_debug_errno(r, "Failed to serialize command: %m");
×
3766

3767
        r = exec_parameters_serialize(p, ctx, f, fds);
2,422✔
3768
        if (r < 0)
2,422✔
3769
                return log_debug_errno(r, "Failed to serialize parameters: %m");
×
3770

3771
        r = exec_runtime_serialize(rt, f, fds);
2,422✔
3772
        if (r < 0)
2,422✔
3773
                return log_debug_errno(r, "Failed to serialize runtime: %m");
×
3774

3775
        r = exec_cgroup_context_serialize(cg, f);
2,422✔
3776
        if (r < 0)
2,422✔
3777
                return log_debug_errno(r, "Failed to serialize cgroup context: %m");
×
3778

3779
        return 0;
3780
}
3781

3782
int exec_deserialize_invocation(
10,013✔
3783
                FILE *f,
3784
                FDSet *fds,
3785
                ExecContext *ctx,
3786
                ExecCommand *cmd,
3787
                ExecParameters *p,
3788
                ExecRuntime *rt,
3789
                CGroupContext *cg) {
3790

3791
        int r;
10,013✔
3792

3793
        assert(f);
10,013✔
3794
        assert(fds);
10,013✔
3795

3796
        r = exec_context_deserialize(ctx, f);
10,013✔
3797
        if (r < 0)
10,013✔
3798
                return log_debug_errno(r, "Failed to deserialize context: %m");
×
3799

3800
        r = exec_command_deserialize(cmd, f);
10,013✔
3801
        if (r < 0)
10,013✔
3802
                return log_debug_errno(r, "Failed to deserialize command: %m");
×
3803

3804
        r = exec_parameters_deserialize(p, f, fds);
10,013✔
3805
        if (r < 0)
10,013✔
3806
                return log_debug_errno(r, "Failed to deserialize parameters: %m");
×
3807

3808
        r = exec_runtime_deserialize(rt, f, fds);
10,013✔
3809
        if (r < 0)
10,013✔
3810
                return log_debug_errno(r, "Failed to deserialize runtime: %m");
×
3811

3812
        r = exec_cgroup_context_deserialize(cg, f);
10,013✔
3813
        if (r < 0)
10,013✔
3814
                return log_debug_errno(r, "Failed to deserialize cgroup context: %m");
×
3815

3816
        return 0;
3817
}
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