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

systemd / systemd / 14458263136

14 Apr 2025 06:41PM UTC coverage: 72.031% (+0.001%) from 72.03%
14458263136

push

github

yuwata
test: drop error conditions for old kernels (<3.2)

Now our baseline on the kernel is 5.4.

2 of 4 new or added lines in 1 file covered. (50.0%)

1428 existing lines in 44 files now uncovered.

297292 of 412726 relevant lines covered (72.03%)

683119.61 hits per line

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

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

3
#include "af-list.h"
4
#include "capability-util.h"
5
#include "cgroup-setup.h"
6
#include "escape.h"
7
#include "exec-credential.h"
8
#include "execute-serialize.h"
9
#include "hexdecoct.h"
10
#include "fd-util.h"
11
#include "fileio.h"
12
#include "in-addr-prefix-util.h"
13
#include "parse-helpers.h"
14
#include "parse-util.h"
15
#include "percent-util.h"
16
#include "process-util.h"
17
#include "rlimit-util.h"
18
#include "serialize.h"
19
#include "string-util.h"
20
#include "strv.h"
21

22
static int exec_cgroup_context_serialize(const CGroupContext *c, FILE *f) {
2,187✔
23
        _cleanup_free_ char *disable_controllers_str = NULL, *delegate_controllers_str = NULL,
×
24
                            *cpuset_cpus = NULL, *cpuset_mems = NULL, *startup_cpuset_cpus = NULL,
×
25
                            *startup_cpuset_mems = NULL;
2,187✔
26
        char *iface;
2,187✔
27
        struct in_addr_prefix *iaai;
2,187✔
28
        int r;
2,187✔
29

30
        assert(f);
2,187✔
31

32
        if (!c)
2,187✔
33
                return 0;
34

35
        r = serialize_bool_elide(f, "exec-cgroup-context-cpu-accounting", c->cpu_accounting);
2,187✔
36
        if (r < 0)
2,187✔
37
                return r;
38

39
        r = serialize_bool_elide(f, "exec-cgroup-context-io-accounting", c->io_accounting);
2,187✔
40
        if (r < 0)
×
41
                return r;
42

43
        r = serialize_bool_elide(f, "exec-cgroup-context-block-io-accounting", c->blockio_accounting);
2,187✔
44
        if (r < 0)
×
45
                return r;
46

47
        r = serialize_bool_elide(f, "exec-cgroup-context-memory-accounting", c->memory_accounting);
2,187✔
48
        if (r < 0)
2,139✔
49
                return r;
50

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

55
        r = serialize_bool_elide(f, "exec-cgroup-context-ip-accounting", c->ip_accounting);
2,187✔
56
        if (r < 0)
1✔
57
                return r;
58

59
        r = serialize_bool_elide(f, "exec-cgroup-context-memory-oom-group", c->memory_oom_group);
2,187✔
60
        if (r < 0)
×
61
                return r;
62

63
        if (c->cpu_weight != CGROUP_WEIGHT_INVALID) {
2,187✔
64
                r = serialize_item_format(f, "exec-cgroup-context-cpu-weight", "%" PRIu64, c->cpu_weight);
1✔
65
                if (r < 0)
1✔
66
                        return r;
67
        }
68

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

75
        if (c->cpu_shares != CGROUP_CPU_SHARES_INVALID) {
2,187✔
76
                r = serialize_item_format(f, "exec-cgroup-context-cpu-shares", "%" PRIu64, c->cpu_shares);
×
77
                if (r < 0)
×
78
                        return r;
79
        }
80

81
        if (c->startup_cpu_shares != CGROUP_CPU_SHARES_INVALID) {
2,187✔
82
                r = serialize_item_format(f, "exec-cgroup-context-startup-cpu-shares", "%" PRIu64, c->startup_cpu_shares);
×
83
                if (r < 0)
×
84
                        return r;
85
        }
86

87
        if (c->cpu_quota_per_sec_usec != USEC_INFINITY) {
2,187✔
88
                r = serialize_usec(f, "exec-cgroup-context-cpu-quota-per-sec-usec", c->cpu_quota_per_sec_usec);
×
89
                if (r < 0)
×
90
                        return r;
91
        }
92

93
        if (c->cpu_quota_period_usec != USEC_INFINITY) {
2,187✔
94
                r = serialize_usec(f, "exec-cgroup-context-cpu-quota-period-usec", c->cpu_quota_period_usec);
×
95
                if (r < 0)
×
96
                        return r;
97
        }
98

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

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

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

111
        r = serialize_item(f, "exec-cgroup-context-startup-allowed-cpus", startup_cpuset_cpus);
2,187✔
112
        if (r < 0)
2,187✔
113
                return r;
114

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

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

123
        startup_cpuset_mems = cpu_set_to_range_string(&c->startup_cpuset_mems);
2,187✔
124
        if (!startup_cpuset_mems)
2,187✔
125
                return log_oom_debug();
×
126

127
        r = serialize_item(f, "exec-cgroup-context-startup-allowed-memory-nodes", startup_cpuset_mems);
2,187✔
128
        if (r < 0)
2,187✔
129
                return r;
130

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

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

143
        if (c->blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID) {
2,187✔
144
                r = serialize_item_format(f, "exec-cgroup-context-block-io-weight", "%" PRIu64, c->blockio_weight);
×
145
                if (r < 0)
×
146
                        return r;
147
        }
148

149
        if (c->startup_blockio_weight != CGROUP_BLKIO_WEIGHT_INVALID) {
2,187✔
150
                r = serialize_item_format(f, "exec-cgroup-context-startup-block-io-weight", "%" PRIu64, c->startup_blockio_weight);
×
151
                if (r < 0)
×
152
                        return r;
153
        }
154

155
        if (c->default_memory_min > 0) {
2,187✔
156
                r = serialize_item_format(f, "exec-cgroup-context-default-memory-min", "%" PRIu64, c->default_memory_min);
×
157
                if (r < 0)
×
158
                        return r;
159
        }
160

161
        if (c->default_memory_low > 0) {
2,187✔
162
                r = serialize_item_format(f, "exec-cgroup-context-default-memory-low", "%" PRIu64, c->default_memory_low);
×
163
                if (r < 0)
×
164
                        return r;
165
        }
166

167
        if (c->memory_min > 0) {
2,187✔
168
                r = serialize_item_format(f, "exec-cgroup-context-memory-min", "%" PRIu64, c->memory_min);
×
169
                if (r < 0)
×
170
                        return r;
171
        }
172

173
        if (c->memory_low > 0) {
2,187✔
174
                r = serialize_item_format(f, "exec-cgroup-context-memory-low", "%" PRIu64, c->memory_low);
×
175
                if (r < 0)
×
176
                        return r;
177
        }
178

179
        if (c->startup_memory_low > 0) {
2,187✔
180
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-low", "%" PRIu64, c->startup_memory_low);
×
181
                if (r < 0)
×
182
                        return r;
183
        }
184

185
        if (c->memory_high != CGROUP_LIMIT_MAX) {
2,187✔
186
                r = serialize_item_format(f, "exec-cgroup-context-memory-high", "%" PRIu64, c->memory_high);
2✔
187
                if (r < 0)
2✔
188
                        return r;
189
        }
190

191
        if (c->startup_memory_high != CGROUP_LIMIT_MAX) {
2,187✔
192
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-high", "%" PRIu64, c->startup_memory_high);
×
193
                if (r < 0)
×
194
                        return r;
195
        }
196

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

203
        if (c->startup_memory_max != CGROUP_LIMIT_MAX) {
2,187✔
204
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-max", "%" PRIu64, c->startup_memory_max);
×
205
                if (r < 0)
×
206
                        return r;
207
        }
208

209
        if (c->memory_swap_max != CGROUP_LIMIT_MAX) {
2,187✔
210
                r = serialize_item_format(f, "exec-cgroup-context-memory-swap-max", "%" PRIu64, c->memory_swap_max);
×
211
                if (r < 0)
×
212
                        return r;
213
        }
214

215
        if (c->startup_memory_swap_max != CGROUP_LIMIT_MAX) {
2,187✔
216
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-swap-max", "%" PRIu64, c->startup_memory_swap_max);
×
217
                if (r < 0)
×
218
                        return r;
219
        }
220

221
        if (c->memory_zswap_max != CGROUP_LIMIT_MAX) {
2,187✔
222
                r = serialize_item_format(f, "exec-cgroup-context-memory-zswap-max", "%" PRIu64, c->memory_zswap_max);
×
223
                if (r < 0)
×
224
                        return r;
225
        }
226

227
        if (c->startup_memory_zswap_max != CGROUP_LIMIT_MAX) {
2,187✔
228
                r = serialize_item_format(f, "exec-cgroup-context-startup-memory-zswap-max", "%" PRIu64, c->startup_memory_zswap_max);
×
229
                if (r < 0)
×
230
                        return r;
231
        }
232

233
        r = serialize_bool(f, "exec-cgroup-context-memory-zswap-writeback", c->memory_zswap_writeback);
2,187✔
234
        if (r < 0)
2,187✔
235
                return r;
236

237
        if (c->memory_limit != CGROUP_LIMIT_MAX) {
2,187✔
238
                r = serialize_item_format(f, "exec-cgroup-context-memory-limit", "%" PRIu64, c->memory_limit);
×
239
                if (r < 0)
×
240
                        return r;
241
        }
242

243
        if (c->tasks_max.value != UINT64_MAX) {
2,187✔
244
                r = serialize_item_format(f, "exec-cgroup-context-tasks-max-value", "%" PRIu64, c->tasks_max.value);
2,140✔
245
                if (r < 0)
2,140✔
246
                        return r;
247
        }
248

249
        if (c->tasks_max.scale > 0) {
2,187✔
250
                r = serialize_item_format(f, "exec-cgroup-context-tasks-max-scale", "%" PRIu64, c->tasks_max.scale);
2,139✔
251
                if (r < 0)
2,139✔
252
                        return r;
253
        }
254

255
        r = serialize_bool_elide(f, "exec-cgroup-context-default-memory-min-set", c->default_memory_min_set);
2,187✔
256
        if (r < 0)
×
257
                return r;
258

259
        r = serialize_bool_elide(f, "exec-cgroup-context-default-memory-low-set", c->default_memory_low_set);
2,187✔
260
        if (r < 0)
×
261
                return r;
262

263
        r = serialize_bool_elide(f, "exec-cgroup-context-default-startup-memory-low-set", c->default_startup_memory_low_set);
2,187✔
264
        if (r < 0)
×
265
                return r;
266

267
        r = serialize_bool_elide(f, "exec-cgroup-context-memory-min-set", c->memory_min_set);
2,187✔
268
        if (r < 0)
×
269
                return r;
270

271
        r = serialize_bool_elide(f, "exec-cgroup-context-memory-low-set", c->memory_low_set);
2,187✔
272
        if (r < 0)
×
273
                return r;
274

275
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-low-set", c->startup_memory_low_set);
2,187✔
276
        if (r < 0)
×
277
                return r;
278

279
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-high-set", c->startup_memory_high_set);
2,187✔
280
        if (r < 0)
×
281
                return r;
282

283
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-max-set", c->startup_memory_max_set);
2,187✔
284
        if (r < 0)
×
285
                return r;
286

287
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-swap-max-set", c->startup_memory_swap_max_set);
2,187✔
288
        if (r < 0)
×
289
                return r;
290

291
        r = serialize_bool_elide(f, "exec-cgroup-context-startup-memory-zswap-max-set", c->startup_memory_zswap_max_set);
2,187✔
292
        if (r < 0)
×
293
                return r;
294

295
        r = serialize_item(f, "exec-cgroup-context-device-policy", cgroup_device_policy_to_string(c->device_policy));
2,187✔
296
        if (r < 0)
2,187✔
297
                return r;
298

299
        r = cg_mask_to_string(c->disable_controllers, &disable_controllers_str);
2,187✔
300
        if (r < 0)
2,187✔
301
                return r;
302

303
        r = serialize_item(f, "exec-cgroup-context-disable-controllers", disable_controllers_str);
2,187✔
304
        if (r < 0)
2,187✔
305
                return r;
306

307
        r = cg_mask_to_string(c->delegate_controllers, &delegate_controllers_str);
2,187✔
308
        if (r < 0)
2,187✔
309
                return r;
310

311
        r = serialize_item(f, "exec-cgroup-context-delegate-controllers", delegate_controllers_str);
2,187✔
312
        if (r < 0)
2,187✔
313
                return r;
314

315
        r = serialize_bool_elide(f, "exec-cgroup-context-delegate", c->delegate);
2,187✔
316
        if (r < 0)
49✔
317
                return r;
318

319
        r = serialize_item(f, "exec-cgroup-context-managed-oom-swap", managed_oom_mode_to_string(c->moom_swap));
2,187✔
320
        if (r < 0)
2,187✔
321
                return r;
322

323
        r = serialize_item(f, "exec-cgroup-context-managed-oom-memory-pressure", managed_oom_mode_to_string(c->moom_mem_pressure));
2,187✔
324
        if (r < 0)
2,187✔
325
                return r;
326

327
        r = serialize_item_format(f, "exec-cgroup-context-managed-oom-memory-pressure-limit", "%" PRIu32, c->moom_mem_pressure_limit);
2,187✔
328
        if (r < 0)
2,187✔
329
                return r;
330

331
        r = serialize_usec(f, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec", c->moom_mem_pressure_duration_usec);
2,187✔
332
        if (r < 0)
2,187✔
333
                return r;
334

335
        r = serialize_item(f, "exec-cgroup-context-managed-oom-preference", managed_oom_preference_to_string(c->moom_preference));
2,187✔
336
        if (r < 0)
2,187✔
337
                return r;
338

339
        r = serialize_item(f, "exec-cgroup-context-memory-pressure-watch", cgroup_pressure_watch_to_string(c->memory_pressure_watch));
2,187✔
340
        if (r < 0)
2,187✔
341
                return r;
342

343
        r = serialize_item(f, "exec-cgroup-context-delegate-subgroup", c->delegate_subgroup);
2,187✔
344
        if (r < 0)
2,187✔
345
                return r;
346

347
        if (c->memory_pressure_threshold_usec != USEC_INFINITY) {
2,187✔
348
                r = serialize_usec(f, "exec-cgroup-context-memory-pressure-threshold-usec", c->memory_pressure_threshold_usec);
2,187✔
349
                if (r < 0)
2,187✔
350
                        return r;
351
        }
352

353
        LIST_FOREACH(device_allow, a, c->device_allow) {
2,677✔
354
                r = serialize_item_format(f, "exec-cgroup-context-device-allow", "%s %s",
490✔
355
                                          a->path,
356
                                          cgroup_device_permissions_to_string(a->permissions));
357
                if (r < 0)
490✔
358
                        return r;
359
        }
360

361
        LIST_FOREACH(device_weights, iw, c->io_device_weights) {
2,187✔
362
                r = serialize_item_format(f, "exec-cgroup-context-io-device-weight", "%s %" PRIu64,
×
363
                                          iw->path,
364
                                          iw->weight);
365
                if (r < 0)
×
366
                        return r;
367
        }
368

369
        LIST_FOREACH(device_latencies, l, c->io_device_latencies) {
2,187✔
370
                r = serialize_item_format(f, "exec-cgroup-context-io-device-latency-target-usec", "%s " USEC_FMT,
×
371
                                          l->path,
372
                                          l->target_usec);
373
                if (r < 0)
×
374
                        return r;
375
        }
376

377
        LIST_FOREACH(device_limits, il, c->io_device_limits)
2,187✔
378
                for (CGroupIOLimitType type = 0; type < _CGROUP_IO_LIMIT_TYPE_MAX; type++) {
×
379
                        _cleanup_free_ char *key = NULL;
×
380

381
                        if (il->limits[type] == cgroup_io_limit_defaults[type])
×
382
                                continue;
×
383

384
                        key = strjoin("exec-cgroup-context-io-device-limit-", cgroup_io_limit_type_to_string(type));
×
385
                        if (!key)
×
386
                                return -ENOMEM;
387

388
                        r = serialize_item_format(f, key, "%s %" PRIu64, il->path, il->limits[type]);
×
389
                        if (r < 0)
×
390
                                return r;
391
                }
392

393
        LIST_FOREACH(device_weights, w, c->blockio_device_weights) {
2,187✔
394
                r = serialize_item_format(f, "exec-cgroup-context-blockio-device-weight", "%s %" PRIu64,
×
395
                                          w->path,
396
                                          w->weight);
397
                if (r < 0)
×
398
                        return r;
399
        }
400

401
        LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) {
2,187✔
402
                if (b->rbps != CGROUP_LIMIT_MAX) {
×
403
                        r = serialize_item_format(f, "exec-cgroup-context-blockio-read-bandwidth", "%s %" PRIu64,
×
404
                                                  b->path,
405
                                                  b->rbps);
406
                        if (r < 0)
×
407
                                return r;
408
                }
409
                if (b->wbps != CGROUP_LIMIT_MAX) {
×
410
                        r = serialize_item_format(f, "exec-cgroup-context-blockio-write-bandwidth", "%s %" PRIu64,
×
411
                                                  b->path,
412
                                                  b->wbps);
413
                        if (r < 0)
×
414
                                return r;
415
                }
416
        }
417

418
        SET_FOREACH(iaai, c->ip_address_allow) {
2,187✔
419
                r = serialize_item(f,
×
420
                                   "exec-cgroup-context-ip-address-allow",
421
                                   IN_ADDR_PREFIX_TO_STRING(iaai->family, &iaai->address, iaai->prefixlen));
×
422
                if (r < 0)
×
423
                        return r;
×
424
        }
425
        SET_FOREACH(iaai, c->ip_address_deny) {
2,469✔
426
                r = serialize_item(f,
282✔
427
                                   "exec-cgroup-context-ip-address-deny",
428
                                   IN_ADDR_PREFIX_TO_STRING(iaai->family, &iaai->address, iaai->prefixlen));
282✔
429
                if (r < 0)
282✔
430
                        return r;
×
431
        }
432

433
        r = serialize_bool_elide(f, "exec-cgroup-context-ip-address-allow-reduced", c->ip_address_allow_reduced);
2,187✔
434
        if (r < 0)
589✔
435
                return r;
436

437
        r = serialize_bool_elide(f, "exec-cgroup-context-ip-address-deny-reduced", c->ip_address_deny_reduced);
2,187✔
438
        if (r < 0)
589✔
439
                return r;
440

441
        r = serialize_strv(f, "exec-cgroup-context-ip-ingress-filter-path", c->ip_filters_ingress);
2,187✔
442
        if (r < 0)
2,187✔
443
                return r;
444

445
        r = serialize_strv(f, "exec-cgroup-context-ip-egress-filter-path", c->ip_filters_egress);
2,187✔
446
        if (r < 0)
2,187✔
447
                return r;
448

449
        LIST_FOREACH(programs, p, c->bpf_foreign_programs) {
2,187✔
450
                r = serialize_item_format(f, "exec-cgroup-context-bpf-program", "%" PRIu32 " %s",
×
451
                                          p->attach_type,
452
                                          p->bpffs_path);
453
                if (r < 0)
×
454
                        return r;
455
        }
456

457
        LIST_FOREACH(socket_bind_items, bi, c->socket_bind_allow) {
2,187✔
458
                fprintf(f, "exec-cgroup-context-socket-bind-allow=");
×
459
                cgroup_context_dump_socket_bind_item(bi, f);
×
460
                fputc('\n', f);
×
461
        }
462

463
        LIST_FOREACH(socket_bind_items, bi, c->socket_bind_deny) {
2,187✔
464
                fprintf(f, "exec-cgroup-context-socket-bind-deny=");
×
465
                cgroup_context_dump_socket_bind_item(bi, f);
×
466
                fputc('\n', f);
×
467
        }
468

469
        SET_FOREACH(iface, c->restrict_network_interfaces) {
2,187✔
470
                r = serialize_item(f, "exec-cgroup-context-restrict-network-interfaces", iface);
×
471
                if (r < 0)
×
472
                        return r;
×
473
        }
474

475
        r = serialize_bool_elide(
4,374✔
476
                        f,
477
                        "exec-cgroup-context-restrict-network-interfaces-is-allow-list",
478
                        c->restrict_network_interfaces_is_allow_list);
2,187✔
479
        if (r < 0)
×
480
                return r;
481

482
        fputc('\n', f); /* End marker */
2,187✔
483

484
        return 0;
485
}
486

487
static int exec_cgroup_context_deserialize(CGroupContext *c, FILE *f) {
11,458✔
488
        int r;
11,458✔
489

490
        assert(f);
11,458✔
491

492
        if (!c)
11,458✔
493
                return 0;
494

495
        for (;;) {
437,178✔
496
                _cleanup_free_ char *l = NULL;
212,860✔
497
                const char *val;
224,318✔
498

499
                r = deserialize_read_line(f, &l);
224,318✔
500
                if (r < 0)
224,318✔
501
                        return r;
502
                if (r == 0) /* eof or end marker */
224,318✔
503
                        break;
504

505
                if ((val = startswith(l, "exec-cgroup-context-cpu-accounting="))) {
212,860✔
506
                        r = parse_boolean(val);
11,458✔
507
                        if (r < 0)
11,458✔
508
                                return r;
509
                        c->cpu_accounting = r;
11,458✔
510
                } else if ((val = startswith(l, "exec-cgroup-context-io-accounting="))) {
201,402✔
511
                        r = parse_boolean(val);
2✔
512
                        if (r < 0)
2✔
513
                                return r;
514
                        c->io_accounting = r;
2✔
515
                } else if ((val = startswith(l, "exec-cgroup-context-block-io-accounting="))) {
201,400✔
516
                        r = parse_boolean(val);
×
517
                        if (r < 0)
×
518
                                return r;
519
                        c->blockio_accounting = r;
×
520
                } else if ((val = startswith(l, "exec-cgroup-context-memory-accounting="))) {
201,400✔
521
                        r = parse_boolean(val);
11,234✔
522
                        if (r < 0)
11,234✔
523
                                return r;
524
                        c->memory_accounting = r;
11,234✔
525
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-accounting="))) {
190,166✔
526
                        r = parse_boolean(val);
11,458✔
527
                        if (r < 0)
11,458✔
528
                                return r;
529
                        c->tasks_accounting = r;
11,458✔
530
                } else if ((val = startswith(l, "exec-cgroup-context-ip-accounting="))) {
178,708✔
531
                        r = parse_boolean(val);
1✔
532
                        if (r < 0)
1✔
533
                                return r;
534
                        c->ip_accounting = r;
1✔
535
                } else if ((val = startswith(l, "exec-cgroup-context-memory-oom-group="))) {
178,707✔
536
                        r = parse_boolean(val);
×
537
                        if (r < 0)
×
538
                                return r;
539
                        c->memory_oom_group = r;
×
540
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-weight="))) {
178,707✔
541
                        r = safe_atou64(val, &c->cpu_weight);
2✔
542
                        if (r < 0)
2✔
543
                                return r;
544
                } else if ((val = startswith(l, "exec-cgroup-context-startup-cpu-weight="))) {
178,705✔
545
                        r = safe_atou64(val, &c->startup_cpu_weight);
×
546
                        if (r < 0)
×
547
                                return r;
548
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-shares="))) {
178,705✔
549
                        r = safe_atou64(val, &c->cpu_shares);
×
550
                        if (r < 0)
×
551
                                return r;
552
                } else if ((val = startswith(l, "exec-cgroup-context-startup-cpu-shares="))) {
178,705✔
553
                        r = safe_atou64(val, &c->startup_cpu_shares);
×
554
                        if (r < 0)
×
555
                                return r;
556
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-quota-per-sec-usec="))) {
178,705✔
557
                        r = deserialize_usec(val, &c->cpu_quota_per_sec_usec);
×
558
                        if (r < 0)
×
559
                                return r;
560
                } else if ((val = startswith(l, "exec-cgroup-context-cpu-quota-period-usec="))) {
178,705✔
561
                        r = deserialize_usec(val, &c->cpu_quota_period_usec);
×
562
                        if (r < 0)
×
563
                                return r;
564
                } else if ((val = startswith(l, "exec-cgroup-context-allowed-cpus="))) {
178,705✔
565
                        if (c->cpuset_cpus.set)
11,458✔
566
                                return -EINVAL; /* duplicated */
567

568
                        r = parse_cpu_set_full(
11,458✔
569
                                        val,
570
                                        &c->cpuset_cpus,
571
                                        /* warn= */ false,
572
                                        /* unit= */ NULL,
573
                                        /* filename= */ NULL,
574
                                        /* line= */ 0,
575
                                        /* lvalue= */ NULL);
576
                        if (r < 0)
11,458✔
577
                                return r;
578
                } else if ((val = startswith(l, "exec-cgroup-context-startup-allowed-cpus="))) {
167,247✔
579
                        if (c->startup_cpuset_cpus.set)
11,458✔
580
                                return -EINVAL; /* duplicated */
581

582
                        r = parse_cpu_set_full(
11,458✔
583
                                        val,
584
                                        &c->startup_cpuset_cpus,
585
                                        /* warn= */ false,
586
                                        /* unit= */ NULL,
587
                                        /* filename= */ NULL,
588
                                        /* line= */ 0,
589
                                        /* lvalue= */ NULL);
590
                        if (r < 0)
11,458✔
591
                                return r;
592
                } else if ((val = startswith(l, "exec-cgroup-context-allowed-memory-nodes="))) {
155,789✔
593
                        if (c->cpuset_mems.set)
11,458✔
594
                                return -EINVAL; /* duplicated */
595

596
                        r = parse_cpu_set_full(
11,458✔
597
                                        val,
598
                                        &c->cpuset_mems,
599
                                        /* warn= */ false,
600
                                        /* unit= */ NULL,
601
                                        /* filename= */ NULL,
602
                                        /* line= */ 0,
603
                                        /* lvalue= */ NULL);
604
                        if (r < 0)
11,458✔
605
                                return r;
606
                } else if ((val = startswith(l, "exec-cgroup-context-startup-allowed-memory-nodes="))) {
144,331✔
607
                        if (c->startup_cpuset_mems.set)
11,458✔
608
                                return -EINVAL; /* duplicated */
609

610
                        r = parse_cpu_set_full(
11,458✔
611
                                        val,
612
                                        &c->startup_cpuset_mems,
613
                                        /* warn= */ false,
614
                                        /* unit= */ NULL,
615
                                        /* filename= */ NULL,
616
                                        /* line= */ 0,
617
                                        /* lvalue= */ NULL);
618
                        if (r < 0)
11,458✔
619
                                return r;
620
                } else if ((val = startswith(l, "exec-cgroup-context-io-weight="))) {
132,873✔
621
                        r = safe_atou64(val, &c->io_weight);
×
622
                        if (r < 0)
×
623
                                return r;
624
                } else if ((val = startswith(l, "exec-cgroup-context-startup-io-weight="))) {
132,873✔
625
                        r = safe_atou64(val, &c->startup_io_weight);
×
626
                        if (r < 0)
×
627
                                return r;
628
                } else if ((val = startswith(l, "exec-cgroup-context-block-io-weight="))) {
132,873✔
629
                        r = safe_atou64(val, &c->blockio_weight);
×
630
                        if (r < 0)
×
631
                                return r;
632
                } else if ((val = startswith(l, "exec-cgroup-context-startup-block-io-weight="))) {
132,873✔
633
                        r = safe_atou64(val, &c->startup_blockio_weight);
×
634
                        if (r < 0)
×
635
                                return r;
636
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-min="))) {
132,873✔
637
                        r = safe_atou64(val, &c->default_memory_min);
×
638
                        if (r < 0)
×
639
                                return r;
640
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-low="))) {
132,873✔
641
                        r = safe_atou64(val, &c->default_memory_low);
×
642
                        if (r < 0)
×
643
                                return r;
644
                } else if ((val = startswith(l, "exec-cgroup-context-memory-min="))) {
132,873✔
645
                        r = safe_atou64(val, &c->memory_min);
1✔
646
                        if (r < 0)
1✔
647
                                return r;
648
                } else if ((val = startswith(l, "exec-cgroup-context-memory-low="))) {
132,872✔
649
                        r = safe_atou64(val, &c->memory_low);
1✔
650
                        if (r < 0)
1✔
651
                                return r;
652
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low="))) {
132,871✔
653
                        r = safe_atou64(val, &c->startup_memory_low);
×
654
                        if (r < 0)
×
655
                                return r;
656
                } else if ((val = startswith(l, "exec-cgroup-context-memory-high="))) {
132,871✔
657
                        r = safe_atou64(val, &c->memory_high);
10✔
658
                        if (r < 0)
10✔
659
                                return r;
660
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high="))) {
132,861✔
661
                        r = safe_atou64(val, &c->startup_memory_high);
×
662
                        if (r < 0)
×
663
                                return r;
664
                } else if ((val = startswith(l, "exec-cgroup-context-memory-max="))) {
132,861✔
665
                        r = safe_atou64(val, &c->memory_max);
2✔
666
                        if (r < 0)
2✔
667
                                return r;
668
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max="))) {
132,859✔
669
                        r = safe_atou64(val, &c->startup_memory_max);
×
670
                        if (r < 0)
×
671
                                return r;
672
                } else if ((val = startswith(l, "exec-cgroup-context-memory-swap-max="))) {
132,859✔
673
                        r = safe_atou64(val, &c->memory_swap_max);
1✔
674
                        if (r < 0)
1✔
675
                                return r;
676
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max="))) {
132,858✔
677
                        r = safe_atou64(val, &c->startup_memory_swap_max);
×
678
                        if (r < 0)
×
679
                                return r;
680
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-max="))) {
132,858✔
681
                        r = safe_atou64(val, &c->memory_zswap_max);
1✔
682
                        if (r < 0)
1✔
683
                                return r;
684
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max="))) {
132,857✔
685
                        r = safe_atou64(val, &c->startup_memory_zswap_max);
×
686
                        if (r < 0)
×
687
                                return r;
688
                } else if ((val = startswith(l, "exec-cgroup-context-memory-zswap-writeback="))) {
132,857✔
689
                        r = parse_boolean(val);
11,458✔
690
                        if (r < 0)
11,458✔
691
                                return r;
692
                        c->memory_zswap_writeback = r;
11,458✔
693
                } else if ((val = startswith(l, "exec-cgroup-context-memory-limit="))) {
121,399✔
694
                        r = safe_atou64(val, &c->memory_limit);
×
695
                        if (r < 0)
×
696
                                return r;
697
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-value="))) {
121,399✔
698
                        r = safe_atou64(val, &c->tasks_max.value);
11,174✔
699
                        if (r < 0)
11,174✔
700
                                return r;
701
                } else if ((val = startswith(l, "exec-cgroup-context-tasks-max-scale="))) {
110,225✔
702
                        r = safe_atou64(val, &c->tasks_max.scale);
11,138✔
703
                        if (r < 0)
11,138✔
704
                                return r;
705
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-min-set="))) {
99,087✔
706
                        r = parse_boolean(val);
×
707
                        if (r < 0)
×
708
                                return r;
709
                        c->default_memory_min_set = r;
×
710
                } else if ((val = startswith(l, "exec-cgroup-context-default-memory-low-set="))) {
99,087✔
711
                        r = parse_boolean(val);
×
712
                        if (r < 0)
×
713
                                return r;
714
                        c->default_memory_low_set = r;
×
715
                } else if ((val = startswith(l, "exec-cgroup-context-default-startup-memory-low-set="))) {
99,087✔
716
                        r = parse_boolean(val);
×
717
                        if (r < 0)
×
718
                                return r;
719
                        c->default_startup_memory_low_set = r;
×
720
                } else if ((val = startswith(l, "exec-cgroup-context-memory-min-set="))) {
99,087✔
721
                        r = parse_boolean(val);
1✔
722
                        if (r < 0)
1✔
723
                                return r;
724
                        c->memory_min_set = r;
1✔
725
                } else if ((val = startswith(l, "exec-cgroup-context-memory-low-set="))) {
99,086✔
726
                        r = parse_boolean(val);
1✔
727
                        if (r < 0)
1✔
728
                                return r;
729
                        c->memory_low_set = r;
1✔
730
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-low-set="))) {
99,085✔
731
                        r = parse_boolean(val);
×
732
                        if (r < 0)
×
733
                                return r;
734
                        c->startup_memory_low_set = r;
×
735
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-high-set="))) {
99,085✔
736
                        r = parse_boolean(val);
×
737
                        if (r < 0)
×
738
                                return r;
739
                        c->startup_memory_high_set = r;
×
740
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-max-set="))) {
99,085✔
741
                        r = parse_boolean(val);
×
742
                        if (r < 0)
×
743
                                return r;
744
                        c->startup_memory_max_set = r;
×
745
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-swap-max-set="))) {
99,085✔
746
                        r = parse_boolean(val);
×
747
                        if (r < 0)
×
748
                                return r;
749
                        c->startup_memory_swap_max_set = r;
×
750
                } else if ((val = startswith(l, "exec-cgroup-context-startup-memory-zswap-max-set="))) {
99,085✔
751
                        r = parse_boolean(val);
×
752
                        if (r < 0)
×
753
                                return r;
754
                        c->startup_memory_zswap_max_set = r;
×
755
                } else if ((val = startswith(l, "exec-cgroup-context-device-policy="))) {
99,085✔
756
                        c->device_policy = cgroup_device_policy_from_string(val);
11,458✔
757
                        if (c->device_policy < 0)
11,458✔
758
                                return -EINVAL;
759
                } else if ((val = startswith(l, "exec-cgroup-context-disable-controllers="))) {
87,627✔
760
                        r = cg_mask_from_string(val, &c->disable_controllers);
×
761
                        if (r < 0)
×
762
                                return r;
763
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-controllers="))) {
87,627✔
764
                        r = cg_mask_from_string(val, &c->delegate_controllers);
657✔
765
                        if (r < 0)
657✔
766
                                return r;
767
                } else if ((val = startswith(l, "exec-cgroup-context-delegate="))) {
86,970✔
768
                        r = parse_boolean(val);
661✔
769
                        if (r < 0)
661✔
770
                                return r;
771
                        c->delegate = r;
661✔
772
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-swap="))) {
86,309✔
773
                        c->moom_swap = managed_oom_mode_from_string(val);
11,458✔
774
                        if (c->moom_swap < 0)
11,458✔
775
                                return -EINVAL;
776
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure="))) {
74,851✔
777
                        c->moom_mem_pressure = managed_oom_mode_from_string(val);
11,458✔
778
                        if (c->moom_mem_pressure < 0)
11,458✔
779
                                return -EINVAL;
780
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-limit="))) {
63,393✔
781
                        r = safe_atou32(val, &c->moom_mem_pressure_limit);
11,458✔
782
                        if (r < 0)
11,458✔
783
                                return r;
784
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-preference="))) {
51,935✔
785
                        c->moom_preference = managed_oom_preference_from_string(val);
11,458✔
786
                        if (c->moom_preference < 0)
11,458✔
787
                                return -EINVAL;
788
                } else if ((val = startswith(l, "exec-cgroup-context-managed-oom-memory-pressure-duration-usec="))) {
40,477✔
789
                        r = deserialize_usec(val, &c->moom_mem_pressure_duration_usec);
1✔
790
                        if (r < 0)
1✔
791
                                return r;
792
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-watch="))) {
40,476✔
793
                        c->memory_pressure_watch = cgroup_pressure_watch_from_string(val);
11,458✔
794
                        if (c->memory_pressure_watch < 0)
11,458✔
795
                                return -EINVAL;
796
                } else if ((val = startswith(l, "exec-cgroup-context-delegate-subgroup="))) {
29,018✔
797
                        r = free_and_strdup(&c->delegate_subgroup, val);
321✔
798
                        if (r < 0)
321✔
799
                                return r;
800
                } else if ((val = startswith(l, "exec-cgroup-context-memory-pressure-threshold-usec="))) {
28,697✔
801
                        r = deserialize_usec(val, &c->memory_pressure_threshold_usec);
11,458✔
802
                        if (r < 0)
11,458✔
803
                                return r;
804
                } else if ((val = startswith(l, "exec-cgroup-context-device-allow="))) {
17,239✔
805
                        _cleanup_free_ char *path = NULL, *rwm = NULL;
4,359✔
806
                        CGroupDevicePermissions p;
4,359✔
807

808
                        r = extract_many_words(&val, " ", 0, &path, &rwm);
4,359✔
809
                        if (r < 0)
4,359✔
810
                                return r;
811
                        if (r == 0)
4,359✔
812
                                return -EINVAL;
813

814
                        p = isempty(rwm) ? 0 : cgroup_device_permissions_from_string(rwm);
8,718✔
815
                        if (p < 0)
4,359✔
816
                                return p;
817

818
                        r = cgroup_context_add_or_update_device_allow(c, path, p);
4,359✔
819
                        if (r < 0)
4,359✔
820
                                return r;
821
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-weight="))) {
12,880✔
822
                        _cleanup_free_ char *path = NULL, *weight = NULL;
×
823
                        CGroupIODeviceWeight *a = NULL;
×
824

825
                        r = extract_many_words(&val, " ", 0, &path, &weight);
×
826
                        if (r < 0)
×
827
                                return r;
828
                        if (r != 2)
×
829
                                return -EINVAL;
830

831
                        LIST_FOREACH(device_weights, b, c->io_device_weights)
×
832
                                if (path_equal(b->path, path)) {
×
833
                                        a = b;
834
                                        break;
835
                                }
836

837
                        if (!a) {
×
838
                                a = new0(CGroupIODeviceWeight, 1);
×
839
                                if (!a)
×
840
                                        return log_oom_debug();
×
841

842
                                a->path = TAKE_PTR(path);
×
843

844
                                LIST_PREPEND(device_weights, c->io_device_weights, a);
×
845
                        }
846

847
                        r = safe_atou64(weight, &a->weight);
×
848
                        if (r < 0)
×
849
                                return r;
850
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-latency-target-usec="))) {
12,880✔
851
                        _cleanup_free_ char *path = NULL, *target = NULL;
×
852
                        CGroupIODeviceLatency *a = NULL;
×
853

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

860
                        LIST_FOREACH(device_latencies, b, c->io_device_latencies)
×
861
                                if (path_equal(b->path, path)) {
×
862
                                        a = b;
863
                                        break;
864
                                }
865

866
                        if (!a) {
×
867
                                a = new0(CGroupIODeviceLatency, 1);
×
868
                                if (!a)
×
869
                                        return log_oom_debug();
×
870

871
                                a->path = TAKE_PTR(path);
×
872

873
                                LIST_PREPEND(device_latencies, c->io_device_latencies, a);
×
874
                        }
875

876
                        r = deserialize_usec(target, &a->target_usec);
×
877
                        if (r < 0)
×
878
                                return r;
879
                } else if ((val = startswith(l, "exec-cgroup-context-io-device-limit-"))) {
12,880✔
880
                        _cleanup_free_ char *type = NULL, *path = NULL, *limits = NULL;
×
881
                        CGroupIODeviceLimit *limit = NULL;
×
882
                        CGroupIOLimitType t;
×
883

884
                        r = extract_many_words(&val, "= ", 0, &type, &path, &limits);
×
885
                        if (r < 0)
×
886
                                return r;
887
                        if (r != 3)
×
888
                                return -EINVAL;
889

890
                        t = cgroup_io_limit_type_from_string(type);
×
891
                        if (t < 0)
×
892
                                return t;
893

894
                        LIST_FOREACH(device_limits, i, c->io_device_limits)
×
895
                                if (path_equal(path, i->path)) {
×
896
                                        limit = i;
897
                                        break;
898
                                }
899

900
                        if (!limit) {
×
901
                                limit = new0(CGroupIODeviceLimit, 1);
×
902
                                if (!limit)
×
903
                                        return log_oom_debug();
×
904

905
                                limit->path = TAKE_PTR(path);
×
906
                                for (CGroupIOLimitType i = 0; i < _CGROUP_IO_LIMIT_TYPE_MAX; i++)
×
907
                                        limit->limits[i] = cgroup_io_limit_defaults[i];
×
908

909
                                LIST_PREPEND(device_limits, c->io_device_limits, limit);
×
910
                        }
911

912
                        r = safe_atou64(limits, &limit->limits[t]);
×
913
                        if (r < 0)
×
914
                                return r;
915
                } else if ((val = startswith(l, "exec-cgroup-context-block-io-device-weight="))) {
12,880✔
916
                        _cleanup_free_ char *path = NULL, *weight = NULL;
×
917
                        CGroupBlockIODeviceWeight *a = NULL;
×
918

919
                        r = extract_many_words(&val, " ", 0, &path, &weight);
×
920
                        if (r < 0)
×
921
                                return r;
922
                        if (r != 2)
×
923
                                return -EINVAL;
924

925
                        a = new0(CGroupBlockIODeviceWeight, 1);
×
926
                        if (!a)
×
927
                                return log_oom_debug();
×
928

929
                        a->path = TAKE_PTR(path);
×
930

931
                        LIST_PREPEND(device_weights, c->blockio_device_weights, a);
×
932

933
                        r = safe_atou64(weight, &a->weight);
×
934
                        if (r < 0)
×
935
                                return r;
936
                } else if ((val = startswith(l, "exec-cgroup-context-block-io-read-bandwidth="))) {
12,880✔
937
                        _cleanup_free_ char *path = NULL, *bw = NULL;
×
938
                        CGroupBlockIODeviceBandwidth *a = NULL;
×
939

940
                        r = extract_many_words(&val, " ", 0, &path, &bw);
×
941
                        if (r < 0)
×
942
                                return r;
943
                        if (r != 2)
×
944
                                return -EINVAL;
945

946
                        LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths)
×
947
                                if (path_equal(b->path, path)) {
×
948
                                        a = b;
949
                                        break;
950
                                }
951

952
                        if (!a) {
×
953
                                a = new0(CGroupBlockIODeviceBandwidth, 1);
×
954
                                if (!a)
×
955
                                        return log_oom_debug();
×
956

957
                                a->path = TAKE_PTR(path);
×
958
                                a->wbps = CGROUP_LIMIT_MAX;
×
959

960
                                LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, a);
×
961
                        }
962

963
                        r = safe_atou64(bw, &a->rbps);
×
964
                        if (r < 0)
×
965
                                return r;
966
                } else if ((val = startswith(l, "exec-cgroup-context-block-io-write-bandwidth="))) {
12,880✔
967
                        _cleanup_free_ char *path = NULL, *bw = NULL;
×
968
                        CGroupBlockIODeviceBandwidth *a = NULL;
×
969

970
                        r = extract_many_words(&val, " ", 0, &path, &bw);
×
971
                        if (r < 0)
×
972
                                return r;
973
                        if (r != 2)
×
974
                                return -EINVAL;
975

976
                        LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths)
×
977
                                if (path_equal(b->path, path)) {
×
978
                                        a = b;
979
                                        break;
980
                                }
981

982
                        if (!a) {
×
983
                                a = new0(CGroupBlockIODeviceBandwidth, 1);
×
984
                                if (!a)
×
985
                                        return log_oom_debug();
×
986

987
                                a->path = TAKE_PTR(path);
×
988
                                a->rbps = CGROUP_LIMIT_MAX;
×
989

990
                                LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, a);
×
991
                        }
992

993
                        r = safe_atou64(bw, &a->wbps);
×
994
                        if (r < 0)
×
995
                                return r;
996
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow="))) {
12,880✔
997
                        struct in_addr_prefix a;
×
998

999
                        r = in_addr_prefix_from_string_auto(val, &a.family, &a.address, &a.prefixlen);
×
1000
                        if (r < 0)
×
1001
                                return r;
×
1002

1003
                        r = in_addr_prefix_add(&c->ip_address_allow, &a);
×
1004
                        if (r < 0)
×
1005
                                return r;
1006
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny="))) {
12,880✔
1007
                        struct in_addr_prefix a;
1,606✔
1008

1009
                        r = in_addr_prefix_from_string_auto(val, &a.family, &a.address, &a.prefixlen);
1,606✔
1010
                        if (r < 0)
1,606✔
1011
                                return r;
×
1012

1013
                        r = in_addr_prefix_add(&c->ip_address_deny, &a);
1,606✔
1014
                        if (r < 0)
1,606✔
1015
                                return r;
1016
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-allow-reduced="))) {
11,274✔
1017
                        r = parse_boolean(val);
5,625✔
1018
                        if (r < 0)
5,625✔
1019
                                return r;
1020
                        c->ip_address_allow_reduced = r;
5,625✔
1021
                } else if ((val = startswith(l, "exec-cgroup-context-ip-address-deny-reduced="))) {
5,649✔
1022
                        r = parse_boolean(val);
5,625✔
1023
                        if (r < 0)
5,625✔
1024
                                return r;
1025
                        c->ip_address_deny_reduced = r;
5,625✔
1026
                } else if ((val = startswith(l, "exec-cgroup-context-ip-ingress-filter-path="))) {
24✔
1027
                        r = deserialize_strv(val, &c->ip_filters_ingress);
×
1028
                        if (r < 0)
×
1029
                                return r;
1030
                } else if ((val = startswith(l, "exec-cgroup-context-ip-egress-filter-path="))) {
24✔
1031
                        r = deserialize_strv(val, &c->ip_filters_egress);
×
1032
                        if (r < 0)
×
1033
                                return r;
1034
                } else if ((val = startswith(l, "exec-cgroup-context-bpf-program="))) {
24✔
1035
                        _cleanup_free_ char *type = NULL, *path = NULL;
×
1036
                        uint32_t t;
×
1037

1038
                        r = extract_many_words(&val, " ", 0, &type, &path);
×
1039
                        if (r < 0)
×
1040
                                return r;
1041
                        if (r != 2)
×
1042
                                return -EINVAL;
1043

1044
                        r = safe_atou32(type, &t);
×
1045
                        if (r < 0)
×
1046
                                return r;
1047

1048
                        r = cgroup_context_add_bpf_foreign_program(c, t, path);
×
1049
                        if (r < 0)
×
1050
                                return r;
1051
                } else if ((val = startswith(l, "exec-cgroup-context-socket-bind-allow="))) {
24✔
1052
                        CGroupSocketBindItem *item;
×
1053
                        uint16_t nr_ports, port_min;
×
1054
                        int af, ip_protocol;
×
1055

1056
                        r = parse_socket_bind_item(val, &af, &ip_protocol, &nr_ports, &port_min);
×
1057
                        if (r < 0)
×
1058
                                return r;
×
1059

1060
                        item = new(CGroupSocketBindItem, 1);
×
1061
                        if (!item)
×
1062
                                return log_oom_debug();
×
1063
                        *item = (CGroupSocketBindItem) {
×
1064
                                .address_family = af,
1065
                                .ip_protocol = ip_protocol,
1066
                                .nr_ports = nr_ports,
1067
                                .port_min = port_min,
1068
                        };
1069

1070
                        LIST_PREPEND(socket_bind_items, c->socket_bind_allow, item);
×
1071
                } else if ((val = startswith(l, "exec-cgroup-context-socket-bind-deny="))) {
24✔
1072
                        CGroupSocketBindItem *item;
×
1073
                        uint16_t nr_ports, port_min;
×
1074
                        int af, ip_protocol;
×
1075

1076
                        r = parse_socket_bind_item(val, &af, &ip_protocol, &nr_ports, &port_min);
×
1077
                        if (r < 0)
×
1078
                                return r;
×
1079

1080
                        item = new(CGroupSocketBindItem, 1);
×
1081
                        if (!item)
×
1082
                                return log_oom_debug();
×
1083
                        *item = (CGroupSocketBindItem) {
×
1084
                                .address_family = af,
1085
                                .ip_protocol = ip_protocol,
1086
                                .nr_ports = nr_ports,
1087
                                .port_min = port_min,
1088
                        };
1089

1090
                        LIST_PREPEND(socket_bind_items, c->socket_bind_deny, item);
×
1091
                } else if ((val = startswith(l, "exec-cgroup-context-restrict-network-interfaces="))) {
24✔
1092
                        r = set_put_strdup(&c->restrict_network_interfaces, val);
15✔
1093
                        if (r < 0)
15✔
1094
                                return r;
1095
                } else if ((val = startswith(l, "exec-cgroup-context-restrict-network-interfaces-is-allow-list="))) {
9✔
1096
                        r = parse_boolean(val);
9✔
1097
                        if (r < 0)
9✔
1098
                                return r;
1099
                        c->restrict_network_interfaces_is_allow_list = r;
9✔
1100
                } else
1101
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
212,860✔
1102
        }
1103

1104
        return 0;
11,458✔
1105
}
1106

1107
static int exec_runtime_serialize(const ExecRuntime *rt, FILE *f, FDSet *fds) {
2,187✔
1108
        int r;
2,187✔
1109

1110
        assert(f);
2,187✔
1111
        assert(fds);
2,187✔
1112

1113
        if (!rt) {
2,187✔
1114
                fputc('\n', f); /* End marker */
2,117✔
1115
                return 0;
2,117✔
1116
        }
1117

1118
        if (rt->shared) {
70✔
1119
                r = serialize_item(f, "exec-runtime-id", rt->shared->id);
69✔
1120
                if (r < 0)
69✔
1121
                        return r;
1122

1123
                r = serialize_item(f, "exec-runtime-tmp-dir", rt->shared->tmp_dir);
69✔
1124
                if (r < 0)
69✔
1125
                        return r;
1126

1127
                r = serialize_item(f, "exec-runtime-var-tmp-dir", rt->shared->var_tmp_dir);
69✔
1128
                if (r < 0)
69✔
1129
                        return r;
1130

1131
                if (rt->shared->netns_storage_socket[0] >= 0 && rt->shared->netns_storage_socket[1] >= 0) {
69✔
1132
                        r = serialize_fd_many(f, fds, "exec-runtime-netns-storage-socket", rt->shared->netns_storage_socket, 2);
7✔
1133
                        if (r < 0)
7✔
1134
                                return r;
1135
                }
1136

1137
                if (rt->shared->ipcns_storage_socket[0] >= 0 && rt->shared->ipcns_storage_socket[1] >= 0) {
69✔
1138
                        r = serialize_fd_many(f, fds, "exec-runtime-ipcns-storage-socket", rt->shared->ipcns_storage_socket, 2);
2✔
1139
                        if (r < 0)
2✔
1140
                                return r;
1141
                }
1142
        }
1143

1144
        if (rt->dynamic_creds) {
70✔
1145
                r = dynamic_user_serialize_one(rt->dynamic_creds->user, "exec-runtime-dynamic-creds-user", f, fds);
1✔
1146
                if (r < 0)
1✔
1147
                        return r;
1148
        }
1149

1150
        if (rt->dynamic_creds && rt->dynamic_creds->group && rt->dynamic_creds->group == rt->dynamic_creds->user) {
70✔
1151
                r = serialize_bool(f, "exec-runtime-dynamic-creds-group-copy", true);
1✔
1152
                if (r < 0)
1✔
1153
                        return r;
1154
        } else if (rt->dynamic_creds) {
69✔
UNCOV
1155
                r = dynamic_user_serialize_one(rt->dynamic_creds->group, "exec-runtime-dynamic-creds-group", f, fds);
×
UNCOV
1156
                if (r < 0)
×
1157
                        return r;
1158
        }
1159

1160
        r = serialize_item(f, "exec-runtime-ephemeral-copy", rt->ephemeral_copy);
70✔
1161
        if (r < 0)
70✔
1162
                return r;
1163

1164
        if (rt->ephemeral_storage_socket[0] >= 0 && rt->ephemeral_storage_socket[1] >= 0) {
70✔
UNCOV
1165
                r = serialize_fd_many(f, fds, "exec-runtime-ephemeral-storage-socket", rt->ephemeral_storage_socket, 2);
×
UNCOV
1166
                if (r < 0)
×
1167
                        return r;
1168
        }
1169

1170
        fputc('\n', f); /* End marker */
70✔
1171

1172
        return 0;
70✔
1173
}
1174

1175
static int exec_runtime_deserialize(ExecRuntime *rt, FILE *f, FDSet *fds) {
11,458✔
1176
        int r;
11,458✔
1177

1178
        assert(rt);
11,458✔
1179
        assert(rt->shared);
11,458✔
1180
        assert(rt->dynamic_creds);
11,458✔
1181
        assert(f);
11,458✔
1182
        assert(fds);
11,458✔
1183

1184
        for (;;) {
12,649✔
1185
                _cleanup_free_ char *l = NULL;
1,191✔
1186
                const char *val;
12,649✔
1187

1188
                r = deserialize_read_line(f, &l);
12,649✔
1189
                if (r < 0)
12,649✔
1190
                        return r;
1191
                if (r == 0) /* eof or end marker */
12,649✔
1192
                        break;
1193

1194
                if ((val = startswith(l, "exec-runtime-id="))) {
1,191✔
1195
                        r = free_and_strdup(&rt->shared->id, val);
347✔
1196
                        if (r < 0)
347✔
1197
                                return r;
1198
                } else if ((val = startswith(l, "exec-runtime-tmp-dir="))) {
844✔
1199
                        r = free_and_strdup(&rt->shared->tmp_dir, val);
329✔
1200
                        if (r < 0)
329✔
1201
                                return r;
1202
                } else if ((val = startswith(l, "exec-runtime-var-tmp-dir="))) {
515✔
1203
                        r = free_and_strdup(&rt->shared->var_tmp_dir, val);
329✔
1204
                        if (r < 0)
329✔
1205
                                return r;
1206
                } else if ((val = startswith(l, "exec-runtime-netns-storage-socket="))) {
186✔
1207

1208
                        r = deserialize_fd_many(fds, val, 2, rt->shared->netns_storage_socket);
58✔
1209
                        if (r < 0)
58✔
UNCOV
1210
                                continue;
×
1211

1212
                } else if ((val = startswith(l, "exec-runtime-ipcns-storage-socket="))) {
128✔
1213

1214
                        r = deserialize_fd_many(fds, val, 2, rt->shared->ipcns_storage_socket);
4✔
1215
                        if (r < 0)
4✔
UNCOV
1216
                                continue;
×
1217

1218
                } else if ((val = startswith(l, "exec-runtime-dynamic-creds-user=")))
124✔
1219
                        dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->user);
62✔
1220
                else if ((val = startswith(l, "exec-runtime-dynamic-creds-group=")))
62✔
UNCOV
1221
                        dynamic_user_deserialize_one(/* m= */ NULL, val, fds, &rt->dynamic_creds->group);
×
1222
                else if ((val = startswith(l, "exec-runtime-dynamic-creds-group-copy="))) {
62✔
1223
                        r = parse_boolean(val);
62✔
1224
                        if (r < 0)
62✔
1225
                                return r;
1226
                        if (!r)
62✔
UNCOV
1227
                                continue; /* Nothing to do */
×
1228

1229
                        if (!rt->dynamic_creds->user)
62✔
1230
                                return -EINVAL;
1231

1232
                        rt->dynamic_creds->group = dynamic_user_ref(rt->dynamic_creds->user);
62✔
UNCOV
1233
                } else if ((val = startswith(l, "exec-runtime-ephemeral-copy="))) {
×
UNCOV
1234
                        r = free_and_strdup(&rt->ephemeral_copy, val);
×
UNCOV
1235
                        if (r < 0)
×
1236
                                return r;
1237
                } else if ((val = startswith(l, "exec-runtime-ephemeral-storage-socket="))) {
×
1238

1239
                        r = deserialize_fd_many(fds, val, 2, rt->ephemeral_storage_socket);
×
UNCOV
1240
                        if (r < 0)
×
1241
                                continue;
×
1242
                } else
1243
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
1,191✔
1244
        }
1245

1246
        return 0;
11,458✔
1247
}
1248

1249
static bool exec_parameters_is_idle_pipe_set(const ExecParameters *p) {
2,187✔
1250
        assert(p);
2,187✔
1251

1252
        return p->idle_pipe &&
2,215✔
1253
                p->idle_pipe[0] >= 0 &&
28✔
1254
                p->idle_pipe[1] >= 0 &&
26✔
1255
                p->idle_pipe[2] >= 0 &&
2,213✔
1256
                p->idle_pipe[3] >= 0;
26✔
1257
}
1258

1259
static int exec_parameters_serialize(const ExecParameters *p, const ExecContext *c, FILE *f, FDSet *fds) {
2,187✔
1260
        int r;
2,187✔
1261

1262
        assert(f);
2,187✔
1263
        assert(fds);
2,187✔
1264

1265
        if (!p)
2,187✔
1266
                return 0;
1267

1268
        r = serialize_item(f, "exec-parameters-runtime-scope", runtime_scope_to_string(p->runtime_scope));
2,187✔
1269
        if (r < 0)
2,187✔
1270
                return r;
1271

1272
        r = serialize_strv(f, "exec-parameters-environment", p->environment);
2,187✔
1273
        if (r < 0)
2,187✔
1274
                return r;
1275

1276
        if (p->fds) {
2,187✔
1277
                if (p->n_socket_fds > 0) {
363✔
1278
                        r = serialize_item_format(f, "exec-parameters-n-socket-fds", "%zu", p->n_socket_fds);
362✔
1279
                        if (r < 0)
362✔
1280
                                return r;
1281
                }
1282

1283
                if (p->n_storage_fds > 0) {
363✔
1284
                        r = serialize_item_format(f, "exec-parameters-n-storage-fds", "%zu", p->n_storage_fds);
4✔
1285
                        if (r < 0)
4✔
1286
                                return r;
1287
                }
1288

1289
                if (p->n_extra_fds > 0) {
363✔
1290
                        r = serialize_item_format(f, "exec-parameters-n-extra-fds", "%zu", p->n_extra_fds);
1✔
1291
                        if (r < 0)
1✔
1292
                                return r;
1293
                }
1294

1295
                r = serialize_fd_many(f, fds, "exec-parameters-fds", p->fds, p->n_socket_fds + p->n_storage_fds + p->n_extra_fds);
363✔
1296
                if (r < 0)
363✔
1297
                        return r;
1298
        }
1299

1300
        r = serialize_strv(f, "exec-parameters-fd-names", p->fd_names);
2,187✔
1301
        if (r < 0)
2,187✔
1302
                return r;
1303

1304
        if (p->flags != 0) {
2,187✔
1305
                r = serialize_item_format(f, "exec-parameters-flags", "%u", (unsigned) p->flags);
2,187✔
1306
                if (r < 0)
2,187✔
1307
                        return r;
1308
        }
1309

1310
        r = serialize_bool_elide(f, "exec-parameters-selinux-context-net", p->selinux_context_net);
2,187✔
UNCOV
1311
        if (r < 0)
×
1312
                return r;
1313

1314
        if (p->cgroup_supported != 0) {
2,187✔
1315
                r = serialize_item_format(f, "exec-parameters-cgroup-supported", "%u", (unsigned) p->cgroup_supported);
2,187✔
1316
                if (r < 0)
2,187✔
1317
                        return r;
1318
        }
1319

1320
        r = serialize_item(f, "exec-parameters-cgroup-path", p->cgroup_path);
2,187✔
1321
        if (r < 0)
2,187✔
1322
                return r;
1323

1324
        r = serialize_item_format(f, "exec-parameters-cgroup-id", "%" PRIu64, p->cgroup_id);
2,187✔
1325
        if (r < 0)
2,187✔
1326
                return r;
1327

1328
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
13,122✔
1329
                _cleanup_free_ char *key = NULL;
10,935✔
1330

1331
                key = strjoin("exec-parameters-prefix-directories-", exec_directory_type_to_string(dt));
10,935✔
1332
                if (!key)
10,935✔
UNCOV
1333
                        return log_oom_debug();
×
1334

1335
                /* Always serialize, even an empty prefix, as this is a fixed array and we always expect
1336
                 * to have all elements (unless fuzzing is happening, hence the NULL check). */
1337
                r = serialize_item(f, key, strempty(p->prefix ? p->prefix[dt] : NULL));
10,935✔
1338
                if (r < 0)
10,935✔
1339
                        return r;
1340
        }
1341

1342
        r = serialize_item(f, "exec-parameters-received-credentials-directory", p->received_credentials_directory);
2,187✔
1343
        if (r < 0)
2,187✔
1344
                return r;
1345

1346
        r = serialize_item(f, "exec-parameters-received-encrypted-credentials-directory", p->received_encrypted_credentials_directory);
2,187✔
1347
        if (r < 0)
2,187✔
1348
                return r;
1349

1350
        r = serialize_item(f, "exec-parameters-confirm-spawn", p->confirm_spawn);
2,187✔
1351
        if (r < 0)
2,187✔
1352
                return r;
1353

1354
        r = serialize_bool_elide(f, "exec-parameters-shall-confirm-spawn", p->shall_confirm_spawn);
2,187✔
UNCOV
1355
        if (r < 0)
×
1356
                return r;
1357

1358
        if (p->watchdog_usec > 0) {
2,187✔
1359
                r = serialize_usec(f, "exec-parameters-watchdog-usec", p->watchdog_usec);
235✔
1360
                if (r < 0)
235✔
1361
                        return r;
1362
        }
1363

1364
        if (exec_parameters_is_idle_pipe_set(p)) {
2,187✔
1365
                r = serialize_fd_many(f, fds, "exec-parameters-idle-pipe", p->idle_pipe, 4);
26✔
1366
                if (r < 0)
26✔
1367
                        return r;
1368
        }
1369

1370
        r = serialize_fd(f, fds, "exec-parameters-stdin-fd", p->stdin_fd);
2,187✔
1371
        if (r < 0)
2,187✔
1372
                return r;
1373

1374
        r = serialize_fd(f, fds, "exec-parameters-stdout-fd", p->stdout_fd);
2,187✔
1375
        if (r < 0)
2,187✔
1376
                return r;
1377

1378
        r = serialize_fd(f, fds, "exec-parameters-stderr-fd", p->stderr_fd);
2,187✔
1379
        if (r < 0)
2,187✔
1380
                return r;
1381

1382
        r = serialize_fd(f, fds, "exec-parameters-exec-fd", p->exec_fd);
2,187✔
1383
        if (r < 0)
2,187✔
1384
                return r;
1385

1386
        r = serialize_fd(f, fds, "exec-parameters-handoff-timestamp-fd", p->handoff_timestamp_fd);
2,187✔
1387
        if (r < 0)
2,187✔
1388
                return r;
1389

1390
        r = serialize_fd(f, fds, "exec-parameters-pidref-transport-fd", p->pidref_transport_fd);
2,187✔
1391
        if (r < 0)
2,187✔
1392
                return r;
1393

1394
        if (c && exec_context_restrict_filesystems_set(c)) {
2,187✔
UNCOV
1395
                r = serialize_fd(f, fds, "exec-parameters-bpf-outer-map-fd", p->bpf_restrict_fs_map_fd);
×
UNCOV
1396
                if (r < 0)
×
1397
                        return r;
1398
        }
1399

1400
        r = serialize_item(f, "exec-parameters-notify-socket", p->notify_socket);
2,187✔
1401
        if (r < 0)
2,187✔
1402
                return r;
1403

1404
        LIST_FOREACH(open_files, file, p->open_files) {
2,187✔
UNCOV
1405
                _cleanup_free_ char *ofs = NULL;
×
1406

UNCOV
1407
                r = open_file_to_string(file, &ofs);
×
UNCOV
1408
                if (r < 0)
×
1409
                        return r;
1410

1411
                r = serialize_item(f, "exec-parameters-open-file", ofs);
×
1412
                if (r < 0)
×
1413
                        return r;
1414
        }
1415

1416
        r = serialize_item(f, "exec-parameters-fallback-smack-process-label", p->fallback_smack_process_label);
2,187✔
1417
        if (r < 0)
2,187✔
1418
                return r;
1419

1420
        r = serialize_fd(f, fds, "exec-parameters-user-lookup-fd", p->user_lookup_fd);
2,187✔
1421
        if (r < 0)
2,187✔
1422
                return r;
1423

1424
        r = serialize_strv(f, "exec-parameters-files-env", p->files_env);
2,187✔
1425
        if (r < 0)
2,187✔
1426
                return r;
1427

1428
        r = serialize_item(f, "exec-parameters-unit-id", p->unit_id);
2,187✔
1429
        if (r < 0)
2,187✔
1430
                return r;
1431

1432
        r = serialize_item(f, "exec-parameters-invocation-id-string", p->invocation_id_string);
2,187✔
1433
        if (r < 0)
2,187✔
1434
                return r;
1435

1436
        r = serialize_bool_elide(f, "exec-parameters-debug-invocation", p->debug_invocation);
2,187✔
UNCOV
1437
        if (r < 0)
×
1438
                return r;
1439

1440
        fputc('\n', f); /* End marker */
2,187✔
1441

1442
        return 0;
2,187✔
1443
}
1444

1445
static int exec_parameters_deserialize(ExecParameters *p, FILE *f, FDSet *fds) {
11,458✔
1446
        int r, nr_open;
11,458✔
1447

1448
        assert(p);
11,458✔
1449
        assert(f);
11,458✔
1450
        assert(fds);
11,458✔
1451

1452
        nr_open = read_nr_open();
11,458✔
1453
        if (nr_open < 3)
11,458✔
UNCOV
1454
                nr_open = HIGH_RLIMIT_NOFILE;
×
1455
        assert(nr_open > 0); /* For compilers/static analyzers */
11,458✔
1456

1457
        for (;;) {
254,766✔
1458
                _cleanup_free_ char *l = NULL;
243,308✔
1459
                const char *val;
254,766✔
1460

1461
                r = deserialize_read_line(f, &l);
254,766✔
1462
                if (r < 0)
254,766✔
1463
                        return r;
1464
                if (r == 0) /* eof or end marker */
254,766✔
1465
                        break;
1466

1467
                if ((val = startswith(l, "exec-parameters-runtime-scope="))) {
243,308✔
1468
                        p->runtime_scope = runtime_scope_from_string(val);
11,458✔
1469
                        if (p->runtime_scope < 0)
11,458✔
1470
                                return p->runtime_scope;
1471
                } else if ((val = startswith(l, "exec-parameters-environment="))) {
231,850✔
1472
                        r = deserialize_strv(val, &p->environment);
47,706✔
1473
                        if (r < 0)
47,706✔
1474
                                return r;
1475
                } else if ((val = startswith(l, "exec-parameters-n-socket-fds="))) {
184,144✔
1476
                        if (p->fds)
1,916✔
1477
                                return -EINVAL; /* Already received */
1478

1479
                        r = safe_atozu(val, &p->n_socket_fds);
1,916✔
1480
                        if (r < 0)
1,916✔
1481
                                return r;
1482

1483
                        if (p->n_socket_fds > (size_t) nr_open)
1,916✔
1484
                                return -EINVAL; /* too many, someone is playing games with us */
1485
                } else if ((val = startswith(l, "exec-parameters-n-storage-fds="))) {
182,228✔
1486
                        if (p->fds)
136✔
1487
                                return -EINVAL; /* Already received */
1488

1489
                        r = safe_atozu(val, &p->n_storage_fds);
136✔
1490
                        if (r < 0)
136✔
1491
                                return r;
1492

1493
                        if (p->n_storage_fds > (size_t) nr_open)
136✔
1494
                                return -EINVAL; /* too many, someone is playing games with us */
1495
                } else if ((val = startswith(l, "exec-parameters-n-extra-fds="))) {
182,092✔
1496
                        if (p->fds)
2✔
1497
                                return -EINVAL; /* Already received */
1498

1499
                        r = safe_atozu(val, &p->n_extra_fds);
2✔
1500
                        if (r < 0)
2✔
1501
                                return r;
1502

1503
                        if (p->n_extra_fds > (size_t) nr_open)
2✔
1504
                                return -EINVAL; /* too many, someone is playing games with us */
1505
                } else if ((val = startswith(l, "exec-parameters-fds="))) {
182,090✔
1506
                        if (p->n_socket_fds + p->n_storage_fds + p->n_extra_fds == 0)
1,927✔
UNCOV
1507
                                return log_warning_errno(
×
1508
                                                SYNTHETIC_ERRNO(EINVAL),
1509
                                                "Got exec-parameters-fds= without "
1510
                                                "prior exec-parameters-n-socket-fds= or exec-parameters-n-storage-fds= or exec-parameters-n-extra-fds=");
1511
                        if (p->n_socket_fds + p->n_storage_fds + p->n_extra_fds > (size_t) nr_open)
1,927✔
1512
                                return -EINVAL; /* too many, someone is playing games with us */
1513

1514
                        if (p->fds)
1,927✔
1515
                                return -EINVAL; /* duplicated */
1516

1517
                        p->fds = new(int, p->n_socket_fds + p->n_storage_fds + p->n_extra_fds);
1,927✔
1518
                        if (!p->fds)
1,927✔
UNCOV
1519
                                return log_oom_debug();
×
1520

1521
                        /* Ensure we don't leave any FD uninitialized on error, it makes the fuzzer sad */
1522
                        FOREACH_ARRAY(i, p->fds, p->n_socket_fds + p->n_storage_fds + p->n_extra_fds)
5,219✔
1523
                                *i = -EBADF;
3,292✔
1524

1525
                        r = deserialize_fd_many(fds, val, p->n_socket_fds + p->n_storage_fds + p->n_extra_fds, p->fds);
1,927✔
1526
                        if (r < 0)
1,927✔
UNCOV
1527
                                continue;
×
1528

1529
                } else if ((val = startswith(l, "exec-parameters-fd-names="))) {
180,163✔
1530
                        r = deserialize_strv(val, &p->fd_names);
3,292✔
1531
                        if (r < 0)
3,292✔
1532
                                return r;
1533
                } else if ((val = startswith(l, "exec-parameters-flags="))) {
176,871✔
1534
                        unsigned flags;
11,458✔
1535

1536
                        r = safe_atou(val, &flags);
11,458✔
1537
                        if (r < 0)
11,458✔
UNCOV
1538
                                return r;
×
1539
                        p->flags = flags;
11,458✔
1540
                } else if ((val = startswith(l, "exec-parameters-selinux-context-net="))) {
165,413✔
UNCOV
1541
                        r = parse_boolean(val);
×
1542
                        if (r < 0)
×
1543
                                return r;
1544

1545
                        p->selinux_context_net = r;
×
1546
                } else if ((val = startswith(l, "exec-parameters-cgroup-supported="))) {
165,413✔
1547
                        unsigned cgroup_supported;
11,458✔
1548

1549
                        r = safe_atou(val, &cgroup_supported);
11,458✔
1550
                        if (r < 0)
11,458✔
UNCOV
1551
                                return r;
×
1552
                        p->cgroup_supported = cgroup_supported;
11,458✔
1553
                } else if ((val = startswith(l, "exec-parameters-cgroup-path="))) {
153,955✔
1554
                        r = free_and_strdup(&p->cgroup_path, val);
11,458✔
1555
                        if (r < 0)
11,458✔
1556
                                return r;
1557
                } else if ((val = startswith(l, "exec-parameters-cgroup-id="))) {
142,497✔
1558
                        r = safe_atou64(val, &p->cgroup_id);
11,458✔
1559
                        if (r < 0)
11,458✔
1560
                                return r;
1561
                } else if ((val = startswith(l, "exec-parameters-prefix-directories-"))) {
131,039✔
1562
                        _cleanup_free_ char *type = NULL, *prefix = NULL;
57,290✔
1563
                        ExecDirectoryType dt;
57,290✔
1564

1565
                        r = extract_many_words(&val, "= ", 0, &type, &prefix);
57,290✔
1566
                        if (r < 0)
57,290✔
1567
                                return r;
1568
                        if (r == 0)
57,290✔
1569
                                return -EINVAL;
1570

1571
                        dt = exec_directory_type_from_string(type);
57,290✔
1572
                        if (dt < 0)
57,290✔
1573
                                return -EINVAL;
1574

1575
                        if (!p->prefix) {
57,290✔
1576
                                p->prefix = new0(char*, _EXEC_DIRECTORY_TYPE_MAX+1);
11,458✔
1577
                                if (!p->prefix)
11,458✔
UNCOV
1578
                                        return log_oom_debug();
×
1579
                        }
1580

1581
                        if (isempty(prefix))
57,290✔
1582
                                p->prefix[dt] = mfree(p->prefix[dt]);
×
1583
                        else
1584
                                free_and_replace(p->prefix[dt], prefix);
57,290✔
1585
                } else if ((val = startswith(l, "exec-parameters-received-credentials-directory="))) {
73,749✔
1586
                        r = free_and_strdup(&p->received_credentials_directory, val);
10,676✔
1587
                        if (r < 0)
10,676✔
1588
                                return r;
1589
                } else if ((val = startswith(l, "exec-parameters-received-encrypted-credentials-directory="))) {
63,073✔
UNCOV
1590
                        r = free_and_strdup(&p->received_encrypted_credentials_directory, val);
×
UNCOV
1591
                        if (r < 0)
×
1592
                                return r;
1593
                } else if ((val = startswith(l, "exec-parameters-confirm-spawn="))) {
63,073✔
1594
                        r = free_and_strdup(&p->confirm_spawn, val);
×
1595
                        if (r < 0)
×
1596
                                return r;
1597
                } else if ((val = startswith(l, "exec-parameters-shall-confirm-spawn="))) {
63,073✔
1598
                        r = parse_boolean(val);
×
1599
                        if (r < 0)
×
1600
                                return r;
1601

1602
                        p->shall_confirm_spawn = r;
×
1603
                } else if ((val = startswith(l, "exec-parameters-watchdog-usec="))) {
63,073✔
1604
                        r = deserialize_usec(val, &p->watchdog_usec);
2,208✔
1605
                        if (r < 0)
2,208✔
1606
                                return r;
1607
                } else if ((val = startswith(l, "exec-parameters-idle-pipe="))) {
60,865✔
1608
                        if (p->idle_pipe)
148✔
1609
                                return -EINVAL; /* duplicated */
1610

1611
                        p->idle_pipe = new(int, 4);
148✔
1612
                        if (!p->idle_pipe)
148✔
UNCOV
1613
                                return log_oom_debug();
×
1614

1615
                        p->idle_pipe[0] = p->idle_pipe[1] = p->idle_pipe[2] = p->idle_pipe[3] = -EBADF;
148✔
1616

1617
                        r = deserialize_fd_many(fds, val, 4, p->idle_pipe);
148✔
1618
                        if (r < 0)
148✔
UNCOV
1619
                                continue;
×
1620

1621
                } else if ((val = startswith(l, "exec-parameters-stdin-fd="))) {
60,717✔
1622
                        int fd;
505✔
1623

1624
                        fd = deserialize_fd(fds, val);
505✔
1625
                        if (fd < 0)
505✔
UNCOV
1626
                                continue;
×
1627

1628
                        close_and_replace(p->stdin_fd, fd);
505✔
1629

1630
                } else if ((val = startswith(l, "exec-parameters-stdout-fd="))) {
60,212✔
1631
                        int fd;
505✔
1632

1633
                        fd = deserialize_fd(fds, val);
505✔
1634
                        if (fd < 0)
505✔
UNCOV
1635
                                continue;
×
1636

1637
                        close_and_replace(p->stdout_fd, fd);
505✔
1638

1639
                } else if ((val = startswith(l, "exec-parameters-stderr-fd="))) {
59,707✔
1640
                        int fd;
505✔
1641

1642
                        fd = deserialize_fd(fds, val);
505✔
1643
                        if (fd < 0)
505✔
UNCOV
1644
                                continue;
×
1645

1646
                        close_and_replace(p->stderr_fd, fd);
505✔
1647
                } else if ((val = startswith(l, "exec-parameters-exec-fd="))) {
59,202✔
1648
                        int fd;
361✔
1649

1650
                        fd = deserialize_fd(fds, val);
361✔
1651
                        if (fd < 0)
361✔
UNCOV
1652
                                continue;
×
1653

1654
                        close_and_replace(p->exec_fd, fd);
361✔
1655
                } else if ((val = startswith(l, "exec-parameters-handoff-timestamp-fd="))) {
58,841✔
1656
                        int fd;
11,458✔
1657

1658
                        fd = deserialize_fd(fds, val);
11,458✔
1659
                        if (fd < 0)
11,458✔
UNCOV
1660
                                continue;
×
1661

1662
                        close_and_replace(p->handoff_timestamp_fd, fd);
11,458✔
1663
                } else if ((val = startswith(l, "exec-parameters-pidref-transport-fd="))) {
47,383✔
1664
                        int fd;
10,408✔
1665

1666
                        fd = deserialize_fd(fds, val);
10,408✔
1667
                        if (fd < 0)
10,408✔
UNCOV
1668
                                continue;
×
1669

1670
                        close_and_replace(p->pidref_transport_fd, fd);
10,408✔
1671
                } else if ((val = startswith(l, "exec-parameters-bpf-outer-map-fd="))) {
36,975✔
1672
                        int fd;
×
1673

UNCOV
1674
                        fd = deserialize_fd(fds, val);
×
UNCOV
1675
                        if (fd < 0)
×
1676
                                continue;
×
1677

1678
                        close_and_replace(p->bpf_restrict_fs_map_fd, fd);
×
1679
                } else if ((val = startswith(l, "exec-parameters-notify-socket="))) {
36,975✔
1680
                        r = free_and_strdup(&p->notify_socket, val);
2,592✔
1681
                        if (r < 0)
2,592✔
1682
                                return r;
1683
                } else if ((val = startswith(l, "exec-parameters-open-file="))) {
34,383✔
1684
                        OpenFile *of;
5✔
1685

1686
                        r = open_file_parse(val, &of);
5✔
1687
                        if (r < 0)
5✔
UNCOV
1688
                                return r;
×
1689

1690
                        LIST_APPEND(open_files, p->open_files, of);
5✔
1691
                } else if ((val = startswith(l, "exec-parameters-fallback-smack-process-label="))) {
34,378✔
1692
                        r = free_and_strdup(&p->fallback_smack_process_label, val);
×
UNCOV
1693
                        if (r < 0)
×
1694
                                return r;
1695
                } else if ((val = startswith(l, "exec-parameters-user-lookup-fd="))) {
34,378✔
1696
                        int fd;
11,458✔
1697

1698
                        fd = deserialize_fd(fds, val);
11,458✔
1699
                        if (fd < 0)
11,458✔
UNCOV
1700
                                continue;
×
1701

1702
                        close_and_replace(p->user_lookup_fd, fd);
11,458✔
1703
                } else if ((val = startswith(l, "exec-parameters-files-env="))) {
22,920✔
1704
                        r = deserialize_strv(val, &p->files_env);
2✔
1705
                        if (r < 0)
2✔
1706
                                return r;
1707
                } else if ((val = startswith(l, "exec-parameters-unit-id="))) {
22,918✔
1708
                        r = free_and_strdup(&p->unit_id, val);
11,458✔
1709
                        if (r < 0)
11,458✔
1710
                                return r;
1711
                } else if ((val = startswith(l, "exec-parameters-invocation-id-string="))) {
11,460✔
1712
                        if (strlen(val) > SD_ID128_STRING_MAX - 1)
11,458✔
1713
                                return -EINVAL;
1714

1715
                        r = sd_id128_from_string(val, &p->invocation_id);
11,458✔
1716
                        if (r < 0)
11,458✔
1717
                                return r;
1718

1719
                        sd_id128_to_string(p->invocation_id, p->invocation_id_string);
11,458✔
1720
                } else if ((val = startswith(l, "exec-parameters-debug-invocation="))) {
2✔
1721
                        r = parse_boolean(val);
2✔
1722
                        if (r < 0)
2✔
1723
                                return r;
1724

1725
                        p->debug_invocation = r;
2✔
1726
                } else
1727
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
243,308✔
1728
        }
1729

1730
        /* Bail out if we got exec-parameters-n-{socket/storage}-fds= but no corresponding
1731
         * exec-parameters-fds= */
1732
        if (p->n_socket_fds + p->n_storage_fds > 0 && !p->fds)
11,458✔
UNCOV
1733
                return -EINVAL;
×
1734

1735
        return 0;
1736
}
1737

1738
static int serialize_std_out_err(const ExecContext *c, FILE *f, int fileno) {
4,374✔
1739
        char *key, *value;
4,374✔
1740
        const char *type;
4,374✔
1741

1742
        assert(c);
4,374✔
1743
        assert(f);
4,374✔
1744
        assert(IN_SET(fileno, STDOUT_FILENO, STDERR_FILENO));
4,374✔
1745

1746
        type = fileno == STDOUT_FILENO ? "output" : "error";
4,374✔
1747

1748
        switch (fileno == STDOUT_FILENO ? c->std_output : c->std_error) {
4,374✔
UNCOV
1749
        case EXEC_OUTPUT_NAMED_FD:
×
UNCOV
1750
                key = strjoina("exec-context-std-", type, "-fd-name");
×
UNCOV
1751
                value = c->stdio_fdname[fileno];
×
1752

1753
                break;
×
1754

1755
        case EXEC_OUTPUT_FILE:
2✔
1756
                key = strjoina("exec-context-std-", type, "-file");
14✔
1757
                value = c->stdio_file[fileno];
2✔
1758

1759
                break;
2✔
1760

UNCOV
1761
        case EXEC_OUTPUT_FILE_APPEND:
×
UNCOV
1762
                key = strjoina("exec-context-std-", type, "-file-append");
×
UNCOV
1763
                value = c->stdio_file[fileno];
×
1764

1765
                break;
×
1766

1767
        case EXEC_OUTPUT_FILE_TRUNCATE:
×
UNCOV
1768
                key = strjoina("exec-context-std-", type, "-file-truncate");
×
1769
                value = c->stdio_file[fileno];
×
1770

1771
                break;
×
1772

1773
        default:
1774
                return 0;
1775
        }
1776

1777
        return serialize_item(f, key, value);
2✔
1778
}
1779

1780
static int exec_context_serialize(const ExecContext *c, FILE *f) {
2,187✔
1781
        int r;
2,187✔
1782

1783
        assert(f);
2,187✔
1784

1785
        if (!c)
2,187✔
1786
                return 0;
2,187✔
1787

1788
        r = serialize_strv(f, "exec-context-environment", c->environment);
2,187✔
1789
        if (r < 0)
2,187✔
1790
                return r;
1791

1792
        r = serialize_strv(f, "exec-context-environment-files", c->environment_files);
2,187✔
1793
        if (r < 0)
2,187✔
1794
                return r;
1795

1796
        r = serialize_strv(f, "exec-context-pass-environment", c->pass_environment);
2,187✔
1797
        if (r < 0)
2,187✔
1798
                return r;
1799

1800
        r = serialize_strv(f, "exec-context-unset-environment", c->unset_environment);
2,187✔
1801
        if (r < 0)
2,187✔
1802
                return r;
1803

1804
        r = serialize_item_escaped(f, "exec-context-working-directory", c->working_directory);
2,187✔
1805
        if (r < 0)
2,187✔
1806
                return r;
1807

1808
        r = serialize_bool_elide(f, "exec-context-working-directory-missing-ok", c->working_directory_missing_ok);
2,187✔
1809
        if (r < 0)
783✔
1810
                return r;
1811

1812
        r = serialize_bool_elide(f, "exec-context-working-directory-home", c->working_directory_home);
2,187✔
UNCOV
1813
        if (r < 0)
×
1814
                return r;
1815

1816
        r = serialize_item_escaped(f, "exec-context-root-directory", c->root_directory);
2,187✔
1817
        if (r < 0)
2,187✔
1818
                return r;
1819

1820
        r = serialize_item_escaped(f, "exec-context-root-image", c->root_image);
2,187✔
1821
        if (r < 0)
2,187✔
1822
                return r;
1823

1824
        if (c->root_image_options) {
2,187✔
UNCOV
1825
                _cleanup_free_ char *options = NULL;
×
1826

UNCOV
1827
                LIST_FOREACH(mount_options, o, c->root_image_options) {
×
UNCOV
1828
                        if (isempty(o->options))
×
1829
                                continue;
×
1830

1831
                        _cleanup_free_ char *escaped = NULL;
×
1832
                        escaped = shell_escape(o->options, ":");
×
1833
                        if (!escaped)
×
UNCOV
1834
                                return log_oom_debug();
×
1835

1836
                        if (!strextend(&options,
×
1837
                                        " ",
1838
                                        partition_designator_to_string(o->partition_designator),
1839
                                               ":",
1840
                                               escaped))
UNCOV
1841
                                        return log_oom_debug();
×
1842
                }
1843

UNCOV
1844
                r = serialize_item(f, "exec-context-root-image-options", options);
×
1845
                if (r < 0)
×
1846
                        return r;
1847
        }
1848

1849
        r = serialize_item(f, "exec-context-root-verity", c->root_verity);
2,187✔
1850
        if (r < 0)
2,187✔
1851
                return r;
1852

1853
        r = serialize_item(f, "exec-context-root-hash-path", c->root_hash_path);
2,187✔
1854
        if (r < 0)
2,187✔
1855
                return r;
1856

1857
        r = serialize_item(f, "exec-context-root-hash-sig-path", c->root_hash_sig_path);
2,187✔
1858
        if (r < 0)
2,187✔
1859
                return r;
1860

1861
        r = serialize_item_hexmem(f, "exec-context-root-hash", c->root_hash, c->root_hash_size);
2,187✔
1862
        if (r < 0)
2,187✔
1863
                return r;
1864

1865
        r = serialize_item_base64mem(f, "exec-context-root-hash-sig", c->root_hash_sig, c->root_hash_sig_size);
2,187✔
1866
        if (r < 0)
2,187✔
1867
                return r;
1868

1869
        r = serialize_bool_elide(f, "exec-context-root-ephemeral", c->root_ephemeral);
2,187✔
UNCOV
1870
        if (r < 0)
×
1871
                return r;
1872

1873
        r = serialize_item_format(f, "exec-context-umask", "%04o", c->umask);
2,187✔
1874
        if (r < 0)
2,187✔
1875
                return r;
1876

1877
        r = serialize_bool_elide(f, "exec-context-non-blocking", c->non_blocking);
2,187✔
UNCOV
1878
        if (r < 0)
×
1879
                return r;
1880

1881
        r = serialize_item_tristate(f, "exec-context-private-mounts", c->private_mounts);
2,187✔
1882
        if (r < 0)
25✔
1883
                return r;
1884

1885
        r = serialize_item_tristate(f, "exec-context-mount-api-vfs", c->mount_apivfs);
2,187✔
1886
        if (r < 0)
2✔
1887
                return r;
1888

1889
        r = serialize_item_tristate(f, "exec-context-bind-log-sockets", c->bind_log_sockets);
2,187✔
UNCOV
1890
        if (r < 0)
×
1891
                return r;
1892

1893
        r = serialize_item_tristate(f, "exec-context-memory-ksm", c->memory_ksm);
2,187✔
1894
        if (r < 0)
×
1895
                return r;
1896

1897
        r = serialize_item(f, "exec-context-private-tmp", private_tmp_to_string(c->private_tmp));
2,187✔
1898
        if (r < 0)
2,187✔
1899
                return r;
1900

1901
        r = serialize_bool_elide(f, "exec-context-private-devices", c->private_devices);
2,187✔
1902
        if (r < 0)
152✔
1903
                return r;
1904

1905
        r = serialize_bool_elide(f, "exec-context-protect-kernel-tunables", c->protect_kernel_tunables);
2,187✔
1906
        if (r < 0)
53✔
1907
                return r;
1908

1909
        r = serialize_bool_elide(f, "exec-context-protect-kernel-modules", c->protect_kernel_modules);
2,187✔
1910
        if (r < 0)
167✔
1911
                return r;
1912

1913
        r = serialize_bool_elide(f, "exec-context-protect-kernel-logs", c->protect_kernel_logs);
2,187✔
1914
        if (r < 0)
166✔
1915
                return r;
1916

1917
        r = serialize_bool_elide(f, "exec-context-protect-clock", c->protect_clock);
2,187✔
1918
        if (r < 0)
118✔
1919
                return r;
1920

1921
        r = serialize_item(f, "exec-context-protect-control-groups", protect_control_groups_to_string(c->protect_control_groups));
2,187✔
1922
        if (r < 0)
2,187✔
1923
                return r;
1924

1925
        r = serialize_bool_elide(f, "exec-context-private-network", c->private_network);
2,187✔
1926
        if (r < 0)
7✔
1927
                return r;
1928

1929
        r = serialize_item(f, "exec-context-private-users", private_users_to_string(c->private_users));
2,187✔
1930
        if (r < 0)
2,187✔
1931
                return r;
1932

1933
        r = serialize_bool_elide(f, "exec-context-private-ipc", c->private_ipc);
2,187✔
1934
        if (r < 0)
2✔
1935
                return r;
1936

1937
        r = serialize_item(f, "exec-context-private-pids", private_pids_to_string(c->private_pids));
2,187✔
1938
        if (r < 0)
2,187✔
1939
                return r;
1940

1941
        r = serialize_bool_elide(f, "exec-context-remove-ipc", c->remove_ipc);
2,187✔
1942
        if (r < 0)
2✔
1943
                return r;
1944

1945
        r = serialize_item(f, "exec-context-protect-home", protect_home_to_string(c->protect_home));
2,187✔
1946
        if (r < 0)
2,187✔
1947
                return r;
1948

1949
        r = serialize_item(f, "exec-context-protect-system", protect_system_to_string(c->protect_system));
2,187✔
1950
        if (r < 0)
2,187✔
1951
                return r;
1952

1953
        r = serialize_bool_elide(f, "exec-context-same-pgrp", c->same_pgrp);
2,187✔
1954
        if (r < 0)
172✔
1955
                return r;
1956

1957
        r = serialize_bool(f, "exec-context-ignore-sigpipe", c->ignore_sigpipe);
2,187✔
1958
        if (r < 0)
2,187✔
1959
                return r;
1960

1961
        r = serialize_bool_elide(f, "exec-context-memory-deny-write-execute", c->memory_deny_write_execute);
2,187✔
1962
        if (r < 0)
238✔
1963
                return r;
1964

1965
        r = serialize_bool_elide(f, "exec-context-restrict-realtime", c->restrict_realtime);
2,187✔
1966
        if (r < 0)
238✔
1967
                return r;
1968

1969
        r = serialize_bool_elide(f, "exec-context-restrict-suid-sgid", c->restrict_suid_sgid);
2,187✔
1970
        if (r < 0)
215✔
1971
                return r;
1972

1973
        r = serialize_item(f, "exec-context-keyring-mode", exec_keyring_mode_to_string(c->keyring_mode));
2,187✔
1974
        if (r < 0)
2,187✔
1975
                return r;
1976

1977
        r = serialize_item(f, "exec-context-protect-hostname", protect_hostname_to_string(c->protect_hostname));
2,187✔
1978
        if (r < 0)
2,187✔
1979
                return r;
1980

1981
        r = serialize_item(f, "exec-context-private-hostname", c->private_hostname);
2,187✔
1982
        if (r < 0)
2,187✔
1983
                return r;
1984

1985
        r = serialize_item(f, "exec-context-protect-proc", protect_proc_to_string(c->protect_proc));
2,187✔
1986
        if (r < 0)
2,187✔
1987
                return r;
1988

1989
        r = serialize_item(f, "exec-context-proc-subset", proc_subset_to_string(c->proc_subset));
2,187✔
1990
        if (r < 0)
2,187✔
1991
                return r;
1992

1993
        r = serialize_item(f, "exec-context-runtime-directory-preserve-mode", exec_preserve_mode_to_string(c->runtime_directory_preserve_mode));
2,187✔
1994
        if (r < 0)
2,187✔
1995
                return r;
1996

1997
        for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
13,122✔
1998
                _cleanup_free_ char *key = NULL, *value = NULL;
10,935✔
1999

2000
                key = strjoin("exec-context-directories-", exec_directory_type_to_string(dt));
10,935✔
2001
                if (!key)
10,935✔
UNCOV
2002
                        return log_oom_debug();
×
2003

2004
                if (asprintf(&value, "%04o", c->directories[dt].mode) < 0)
10,935✔
UNCOV
2005
                        return log_oom_debug();
×
2006

2007
                FOREACH_ARRAY(i, c->directories[dt].items, c->directories[dt].n_items) {
11,367✔
2008
                        _cleanup_free_ char *path_escaped = NULL;
432✔
2009

2010
                        path_escaped = shell_escape(i->path, ":" WHITESPACE);
432✔
2011
                        if (!path_escaped)
432✔
UNCOV
2012
                                return log_oom_debug();
×
2013

2014
                        if (!strextend(&value, " ", path_escaped))
432✔
UNCOV
2015
                                return log_oom_debug();
×
2016

2017
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_ONLY_CREATE))))
859✔
UNCOV
2018
                                return log_oom_debug();
×
2019

2020
                        if (!strextend(&value, ":", yes_no(FLAGS_SET(i->flags, EXEC_DIRECTORY_READ_ONLY))))
862✔
UNCOV
2021
                                return log_oom_debug();
×
2022

2023
                        STRV_FOREACH(d, i->symlinks) {
438✔
2024
                                _cleanup_free_ char *link_escaped = NULL;
6✔
2025

2026
                                link_escaped = shell_escape(*d, ":" WHITESPACE);
6✔
2027
                                if (!link_escaped)
6✔
UNCOV
2028
                                        return log_oom_debug();
×
2029

2030
                                if (!strextend(&value, ":", link_escaped))
6✔
UNCOV
2031
                                        return log_oom_debug();
×
2032
                        }
2033
                }
2034

2035
                r = serialize_item(f, key, value);
10,935✔
2036
                if (r < 0)
10,935✔
2037
                        return r;
2038
        }
2039

2040
        r = serialize_usec(f, "exec-context-timeout-clean-usec", c->timeout_clean_usec);
2,187✔
2041
        if (r < 0)
2,187✔
2042
                return r;
2043

2044
        if (c->nice_set) {
2,187✔
2045
                r = serialize_item_format(f, "exec-context-nice", "%i", c->nice);
2✔
2046
                if (r < 0)
2✔
2047
                        return r;
2048
        }
2049

2050
        if (c->oom_score_adjust_set) {
2,187✔
2051
                r = serialize_item_format(f, "exec-context-oom-score-adjust", "%i", c->oom_score_adjust);
641✔
2052
                if (r < 0)
641✔
2053
                        return r;
2054
        }
2055

2056
        if (c->coredump_filter_set) {
2,187✔
UNCOV
2057
                r = serialize_item_format(f, "exec-context-coredump-filter", "%"PRIx64, c->coredump_filter);
×
UNCOV
2058
                if (r < 0)
×
2059
                        return r;
2060
        }
2061

2062
        for (unsigned i = 0; i < RLIM_NLIMITS; i++) {
37,179✔
2063
                _cleanup_free_ char *key = NULL, *limit = NULL;
4,367✔
2064

2065
                if (!c->rlimit[i])
34,992✔
2066
                        continue;
30,625✔
2067

2068
                key = strjoin("exec-context-limit-", rlimit_to_string(i));
4,367✔
2069
                if (!key)
4,367✔
UNCOV
2070
                        return log_oom_debug();
×
2071

2072
                r = rlimit_format(c->rlimit[i], &limit);
4,367✔
2073
                if (r < 0)
4,367✔
2074
                        return r;
2075

2076
                r = serialize_item(f, key, limit);
4,367✔
2077
                if (r < 0)
4,367✔
2078
                        return r;
2079
        }
2080

2081
        if (c->ioprio_set) {
2,187✔
2082
                r = serialize_item_format(f, "exec-context-ioprio", "%d", c->ioprio);
5✔
2083
                if (r < 0)
5✔
2084
                        return r;
2085
        }
2086

2087
        if (c->cpu_sched_set) {
2,187✔
UNCOV
2088
                _cleanup_free_ char *policy_str = NULL;
×
2089

UNCOV
2090
                r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
×
UNCOV
2091
                if (r < 0)
×
2092
                        return r;
2093

2094
                r = serialize_item(f, "exec-context-cpu-scheduling-policy", policy_str);
×
2095
                if (r < 0)
×
2096
                        return r;
2097

2098
                r = serialize_item_format(f, "exec-context-cpu-scheduling-priority", "%i", c->cpu_sched_priority);
×
2099
                if (r < 0)
×
2100
                        return r;
2101

2102
                r = serialize_bool_elide(f, "exec-context-cpu-scheduling-reset-on-fork", c->cpu_sched_reset_on_fork);
×
2103
                if (r < 0)
×
2104
                        return r;
2105
        }
2106

2107
        if (c->cpu_set.set) {
2,187✔
UNCOV
2108
                _cleanup_free_ char *affinity = NULL;
×
2109

UNCOV
2110
                affinity = cpu_set_to_range_string(&c->cpu_set);
×
UNCOV
2111
                if (!affinity)
×
2112
                        return log_oom_debug();
×
2113

2114
                r = serialize_item(f, "exec-context-cpu-affinity", affinity);
×
2115
                if (r < 0)
×
2116
                        return r;
2117
        }
2118

2119
        if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) {
2,187✔
UNCOV
2120
                _cleanup_free_ char *nodes = NULL;
×
2121

UNCOV
2122
                nodes = cpu_set_to_range_string(&c->numa_policy.nodes);
×
UNCOV
2123
                if (!nodes)
×
2124
                        return log_oom_debug();
×
2125

2126
                if (nodes) {
×
2127
                        r = serialize_item(f, "exec-context-numa-mask", nodes);
×
2128
                        if (r < 0)
×
2129
                                return r;
2130
                }
2131

2132
                r = serialize_item_format(f, "exec-context-numa-policy", "%d", c->numa_policy.type);
×
UNCOV
2133
                if (r < 0)
×
2134
                        return r;
2135
        }
2136

2137
        r = serialize_bool_elide(f, "exec-context-cpu-affinity-from-numa", c->cpu_affinity_from_numa);
2,187✔
UNCOV
2138
        if (r < 0)
×
2139
                return r;
2140

2141
        if (c->timer_slack_nsec != NSEC_INFINITY) {
2,187✔
2142
                r = serialize_item_format(f, "exec-context-timer-slack-nsec", NSEC_FMT, c->timer_slack_nsec);
×
UNCOV
2143
                if (r < 0)
×
2144
                        return r;
2145
        }
2146

2147
        r = serialize_item(f, "exec-context-std-input", exec_input_to_string(c->std_input));
2,187✔
2148
        if (r < 0)
2,187✔
2149
                return r;
2150

2151
        r = serialize_item(f, "exec-context-std-output", exec_output_to_string(c->std_output));
2,187✔
2152
        if (r < 0)
2,187✔
2153
                return r;
2154

2155
        r = serialize_item(f, "exec-context-std-error", exec_output_to_string(c->std_error));
2,187✔
2156
        if (r < 0)
2,187✔
2157
                return r;
2158

2159
        r = serialize_bool_elide(f, "exec-context-stdio-as-fds", c->stdio_as_fds);
2,187✔
2160
        if (r < 0)
80✔
2161
                return r;
2162

2163
        switch (c->std_input) {
2,187✔
UNCOV
2164
        case EXEC_INPUT_NAMED_FD:
×
UNCOV
2165
                r = serialize_item(f, "exec-context-std-input-fd-name", c->stdio_fdname[STDIN_FILENO]);
×
UNCOV
2166
                if (r < 0)
×
2167
                        return r;
2168
                break;
2169

2170
        case EXEC_INPUT_FILE:
×
UNCOV
2171
                r = serialize_item(f, "exec-context-std-input-file", c->stdio_file[STDIN_FILENO]);
×
UNCOV
2172
                if (r < 0)
×
2173
                        return r;
2174
                break;
2175

2176
        default:
2,187✔
2177
                ;
2,187✔
2178
        }
2179

2180
        r = serialize_std_out_err(c, f, STDOUT_FILENO);
2,187✔
2181
        if (r < 0)
2,187✔
2182
                return r;
2183

2184
        r = serialize_std_out_err(c, f, STDERR_FILENO);
2,187✔
2185
        if (r < 0)
2,187✔
2186
                return r;
2187

2188
        r = serialize_item_base64mem(f, "exec-context-stdin-data", c->stdin_data, c->stdin_data_size);
2,187✔
2189
        if (r < 0)
2,187✔
2190
                return r;
2191

2192
        r = serialize_item(f, "exec-context-tty-path", c->tty_path);
2,187✔
2193
        if (r < 0)
2,187✔
2194
                return r;
2195

2196
        r = serialize_bool_elide(f, "exec-context-tty-reset", c->tty_reset);
2,187✔
2197
        if (r < 0)
24✔
2198
                return r;
2199

2200
        r = serialize_bool_elide(f, "exec-context-tty-vhangup", c->tty_vhangup);
2,187✔
2201
        if (r < 0)
24✔
2202
                return r;
2203

2204
        r = serialize_bool_elide(f, "exec-context-tty-vt-disallocate", c->tty_vt_disallocate);
2,187✔
2205
        if (r < 0)
6✔
2206
                return r;
2207

2208
        r = serialize_item_format(f, "exec-context-tty-rows", "%u", c->tty_rows);
2,187✔
2209
        if (r < 0)
2,187✔
2210
                return r;
2211

2212
        r = serialize_item_format(f, "exec-context-tty-columns", "%u", c->tty_cols);
2,187✔
2213
        if (r < 0)
2,187✔
2214
                return r;
2215

2216
        r = serialize_item_format(f, "exec-context-syslog-priority", "%i", c->syslog_priority);
2,187✔
2217
        if (r < 0)
2,187✔
2218
                return r;
2219

2220
        r = serialize_bool(f, "exec-context-syslog-level-prefix", c->syslog_level_prefix);
2,187✔
2221
        if (r < 0)
2,187✔
2222
                return r;
2223

2224
        r = serialize_item(f, "exec-context-syslog-identifier", c->syslog_identifier);
2,187✔
2225
        if (r < 0)
2,187✔
2226
                return r;
2227

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

2234
        if (c->log_ratelimit.interval > 0) {
2,187✔
UNCOV
2235
                r = serialize_usec(f, "exec-context-log-ratelimit-interval-usec", c->log_ratelimit.interval);
×
UNCOV
2236
                if (r < 0)
×
2237
                        return r;
2238
        }
2239

2240
        if (c->log_ratelimit.burst > 0) {
2,187✔
UNCOV
2241
                r = serialize_item_format(f, "exec-context-log-ratelimit-burst", "%u", c->log_ratelimit.burst);
×
UNCOV
2242
                if (r < 0)
×
2243
                        return r;
2244
        }
2245

2246
        r = serialize_string_set(f, "exec-context-log-filter-allowed-patterns", c->log_filter_allowed_patterns);
2,187✔
2247
        if (r < 0)
2,187✔
2248
                return r;
2249

2250
        r = serialize_string_set(f, "exec-context-log-filter-denied-patterns", c->log_filter_denied_patterns);
2,187✔
2251
        if (r < 0)
2,187✔
2252
                return r;
2253

2254
        FOREACH_ARRAY(field, c->log_extra_fields, c->n_log_extra_fields) {
2,187✔
UNCOV
2255
                r = serialize_item(f, "exec-context-log-extra-fields", field->iov_base);
×
UNCOV
2256
                if (r < 0)
×
2257
                        return r;
2258
        }
2259

2260
        r = serialize_item(f, "exec-context-log-namespace", c->log_namespace);
2,187✔
2261
        if (r < 0)
2,187✔
2262
                return r;
2263

2264
        if (c->secure_bits != 0) {
2,187✔
UNCOV
2265
                r = serialize_item_format(f, "exec-context-secure-bits", "%d", c->secure_bits);
×
UNCOV
2266
                if (r < 0)
×
2267
                        return r;
2268
        }
2269

2270
        if (c->capability_bounding_set != CAP_MASK_UNSET) {
2,187✔
2271
                r = serialize_item_format(f, "exec-context-capability-bounding-set", "%" PRIu64, c->capability_bounding_set);
276✔
2272
                if (r < 0)
276✔
2273
                        return r;
2274
        }
2275

2276
        if (c->capability_ambient_set != 0) {
2,187✔
2277
                r = serialize_item_format(f, "exec-context-capability-ambient-set", "%" PRIu64, c->capability_ambient_set);
76✔
2278
                if (r < 0)
76✔
2279
                        return r;
2280
        }
2281

2282
        if (c->user) {
2,187✔
2283
                r = serialize_item(f, "exec-context-user", c->user);
157✔
2284
                if (r < 0)
157✔
2285
                        return r;
2286
        }
2287

2288
        r = serialize_item(f, "exec-context-group", c->group);
2,187✔
2289
        if (r < 0)
2,187✔
2290
                return r;
2291

2292
        r = serialize_bool_elide(f, "exec-context-dynamic-user", c->dynamic_user);
2,187✔
2293
        if (r < 0)
1✔
2294
                return r;
2295

2296
        r = serialize_strv(f, "exec-context-supplementary-groups", c->supplementary_groups);
2,187✔
2297
        if (r < 0)
2,187✔
2298
                return r;
2299

2300
        r = serialize_item_tristate(f, "exec-context-set-login-environment", c->set_login_environment);
2,187✔
UNCOV
2301
        if (r < 0)
×
2302
                return r;
2303

2304
        r = serialize_item(f, "exec-context-pam-name", c->pam_name);
2,187✔
2305
        if (r < 0)
2,187✔
2306
                return r;
2307

2308
        r = serialize_strv(f, "exec-context-read-write-paths", c->read_write_paths);
2,187✔
2309
        if (r < 0)
2,187✔
2310
                return r;
2311

2312
        r = serialize_strv(f, "exec-context-read-only-paths", c->read_only_paths);
2,187✔
2313
        if (r < 0)
2,187✔
2314
                return r;
2315

2316
        r = serialize_strv(f, "exec-context-inaccessible-paths", c->inaccessible_paths);
2,187✔
2317
        if (r < 0)
2,187✔
2318
                return r;
2319

2320
        r = serialize_strv(f, "exec-context-exec-paths", c->exec_paths);
2,187✔
2321
        if (r < 0)
2,187✔
2322
                return r;
2323

2324
        r = serialize_strv(f, "exec-context-no-exec-paths", c->no_exec_paths);
2,187✔
2325
        if (r < 0)
2,187✔
2326
                return r;
2327

2328
        r = serialize_strv(f, "exec-context-exec-search-path", c->exec_search_path);
2,187✔
2329
        if (r < 0)
2,187✔
2330
                return r;
2331

2332
        r = serialize_item_format(f, "exec-context-mount-propagation-flag", "%lu", c->mount_propagation_flag);
2,187✔
2333
        if (r < 0)
2,187✔
2334
                return r;
2335

2336
        FOREACH_ARRAY(mount, c->bind_mounts, c->n_bind_mounts) {
2,202✔
2337
                _cleanup_free_ char *src_escaped = NULL, *dst_escaped = NULL;
15✔
2338

2339
                src_escaped = shell_escape(mount->source, ":" WHITESPACE);
15✔
2340
                if (!src_escaped)
15✔
UNCOV
2341
                        return log_oom_debug();
×
2342

2343
                dst_escaped = shell_escape(mount->destination, ":" WHITESPACE);
15✔
2344
                if (!dst_escaped)
15✔
2345
                        return log_oom_debug();
×
2346

2347
                r = serialize_item_format(f,
15✔
2348
                                          mount->read_only ? "exec-context-bind-read-only-path" : "exec-context-bind-path",
15✔
2349
                                          "%s%s:%s:%s",
2350
                                          mount->ignore_enoent ? "-" : "",
15✔
2351
                                          src_escaped,
2352
                                          dst_escaped,
2353
                                          mount->recursive ? "rbind" : "norbind");
15✔
2354
                if (r < 0)
15✔
2355
                        return r;
2356
        }
2357

2358
        FOREACH_ARRAY(tmpfs, c->temporary_filesystems, c->n_temporary_filesystems) {
2,191✔
2359
                _cleanup_free_ char *escaped = NULL;
4✔
2360

2361
                if (!isempty(tmpfs->options)) {
4✔
UNCOV
2362
                        escaped = shell_escape(tmpfs->options, ":");
×
UNCOV
2363
                        if (!escaped)
×
UNCOV
2364
                                return log_oom_debug();
×
2365
                }
2366

2367
                r = serialize_item_format(f, "exec-context-temporary-filesystems", "%s%s%s",
×
2368
                                          tmpfs->path,
2369
                                          isempty(escaped) ? "" : ":",
4✔
2370
                                          strempty(escaped));
2371
                if (r < 0)
4✔
2372
                        return r;
2373
        }
2374

2375
        r = serialize_item(f, "exec-context-utmp-id", c->utmp_id);
2,187✔
2376
        if (r < 0)
2,187✔
2377
                return r;
2378

2379
        r = serialize_item(f, "exec-context-utmp-mode", exec_utmp_mode_to_string(c->utmp_mode));
2,187✔
2380
        if (r < 0)
2,187✔
2381
                return r;
2382

2383
        r = serialize_bool_elide(f, "exec-context-no-new-privileges", c->no_new_privileges);
2,187✔
2384
        if (r < 0)
225✔
2385
                return r;
2386

2387
        if (c->selinux_context) {
2,187✔
UNCOV
2388
                r = serialize_item_format(f, "exec-context-selinux-context",
×
2389
                                          "%s%s",
UNCOV
2390
                                          c->selinux_context_ignore ? "-" : "",
×
2391
                                          c->selinux_context);
2392
                if (r < 0)
×
2393
                        return r;
2394
        }
2395

2396
        if (c->apparmor_profile) {
2,187✔
UNCOV
2397
                r = serialize_item_format(f, "exec-context-apparmor-profile",
×
2398
                                          "%s%s",
UNCOV
2399
                                          c->apparmor_profile_ignore ? "-" : "",
×
2400
                                          c->apparmor_profile);
2401
                if (r < 0)
×
2402
                        return r;
2403
        }
2404

2405
        if (c->smack_process_label) {
2,187✔
UNCOV
2406
                r = serialize_item_format(f, "exec-context-smack-process-label",
×
2407
                                          "%s%s",
UNCOV
2408
                                          c->smack_process_label_ignore ? "-" : "",
×
2409
                                          c->smack_process_label);
2410
                if (r < 0)
×
2411
                        return r;
2412
        }
2413

2414
        if (c->personality != PERSONALITY_INVALID) {
2,187✔
UNCOV
2415
                r = serialize_item(f, "exec-context-personality", personality_to_string(c->personality));
×
UNCOV
2416
                if (r < 0)
×
2417
                        return r;
2418
        }
2419

2420
        r = serialize_bool_elide(f, "exec-context-lock-personality", c->lock_personality);
2,187✔
2421
        if (r < 0)
239✔
2422
                return r;
2423

2424
#if HAVE_SECCOMP
2425
        if (!hashmap_isempty(c->syscall_filter)) {
2,187✔
2426
                void *errno_num, *id;
238✔
2427
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_filter) {
93,082✔
2428
                        r = serialize_item_format(f, "exec-context-syscall-filter", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
92,844✔
2429
                        if (r < 0)
92,844✔
UNCOV
2430
                                return r;
×
2431
                }
2432
        }
2433

2434
        if (!set_isempty(c->syscall_archs)) {
2,187✔
2435
                void *id;
238✔
2436
                SET_FOREACH(id, c->syscall_archs) {
476✔
2437
                        r = serialize_item_format(f, "exec-context-syscall-archs", "%u", PTR_TO_UINT(id) - 1);
238✔
2438
                        if (r < 0)
238✔
UNCOV
2439
                                return r;
×
2440
                }
2441
        }
2442

2443
        if (c->syscall_errno > 0) {
2,187✔
2444
                r = serialize_item_format(f, "exec-context-syscall-errno", "%d", c->syscall_errno);
2,187✔
2445
                if (r < 0)
2,187✔
2446
                        return r;
2447
        }
2448

2449
        r = serialize_bool_elide(f, "exec-context-syscall-allow-list", c->syscall_allow_list);
2,187✔
2450
        if (r < 0)
238✔
2451
                return r;
2452

2453
        if (!hashmap_isempty(c->syscall_log)) {
2,187✔
UNCOV
2454
                void *errno_num, *id;
×
UNCOV
2455
                HASHMAP_FOREACH_KEY(errno_num, id, c->syscall_log) {
×
UNCOV
2456
                        r = serialize_item_format(f, "exec-context-syscall-log", "%d %d", PTR_TO_INT(id) - 1, PTR_TO_INT(errno_num));
×
UNCOV
2457
                        if (r < 0)
×
2458
                                return r;
×
2459
                }
2460
        }
2461

2462
        r = serialize_bool_elide(f, "exec-context-syscall-log-allow-list", c->syscall_log_allow_list);
2,187✔
UNCOV
2463
        if (r < 0)
×
2464
                return r;
2465
#endif
2466

2467
        if (c->restrict_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,187✔
2468
                r = serialize_item_format(f, "exec-context-restrict-namespaces", "%lu", c->restrict_namespaces);
188✔
2469
                if (r < 0)
188✔
2470
                        return r;
2471
        }
2472

2473
        if (c->delegate_namespaces != NAMESPACE_FLAGS_INITIAL) {
2,187✔
2474
                r = serialize_item_format(f, "exec-context-delegate-namespaces", "%lu", c->delegate_namespaces);
9✔
2475
                if (r < 0)
9✔
2476
                        return r;
2477
        }
2478

2479
#if HAVE_LIBBPF
2480
        if (exec_context_restrict_filesystems_set(c)) {
2,187✔
UNCOV
2481
                char *fs;
×
UNCOV
2482
                SET_FOREACH(fs, c->restrict_filesystems) {
×
UNCOV
2483
                        r = serialize_item(f, "exec-context-restrict-filesystems", fs);
×
UNCOV
2484
                        if (r < 0)
×
2485
                                return r;
×
2486
                }
2487
        }
2488

2489
        r = serialize_bool_elide(f, "exec-context-restrict-filesystems-allow-list", c->restrict_filesystems_allow_list);
2,187✔
UNCOV
2490
        if (r < 0)
×
2491
                return r;
2492
#endif
2493

2494
        if (!set_isempty(c->address_families)) {
2,187✔
2495
                void *afp;
238✔
2496

2497
                SET_FOREACH(afp, c->address_families) {
1,134✔
2498
                        int af = PTR_TO_INT(afp);
896✔
2499

2500
                        if (af <= 0 || af >= af_max())
896✔
UNCOV
2501
                                continue;
×
2502

2503
                        r = serialize_item_format(f, "exec-context-address-families", "%d", af);
896✔
2504
                        if (r < 0)
896✔
2505
                                return r;
×
2506
                }
2507
        }
2508

2509
        r = serialize_bool_elide(f, "exec-context-address-families-allow-list", c->address_families_allow_list);
2,187✔
2510
        if (r < 0)
238✔
2511
                return r;
2512

2513
        r = serialize_item(f, "exec-context-network-namespace-path", c->network_namespace_path);
2,187✔
2514
        if (r < 0)
2,187✔
2515
                return r;
2516

2517
        r = serialize_item(f, "exec-context-ipc-namespace-path", c->ipc_namespace_path);
2,187✔
2518
        if (r < 0)
2,187✔
2519
                return r;
2520

2521
        FOREACH_ARRAY(mount, c->mount_images, c->n_mount_images) {
2,187✔
UNCOV
2522
                _cleanup_free_ char *s = NULL, *source_escaped = NULL, *dest_escaped = NULL;
×
2523

UNCOV
2524
                source_escaped = shell_escape(mount->source, WHITESPACE);
×
UNCOV
2525
                if (!source_escaped)
×
2526
                        return log_oom_debug();
×
2527

2528
                dest_escaped = shell_escape(mount->destination, WHITESPACE);
×
2529
                if (!dest_escaped)
×
2530
                        return log_oom_debug();
×
2531

2532
                s = strjoin(mount->ignore_enoent ? "-" : "",
×
2533
                            source_escaped,
2534
                            " ",
2535
                            dest_escaped);
2536
                if (!s)
×
UNCOV
2537
                        return log_oom_debug();
×
2538

UNCOV
2539
                LIST_FOREACH(mount_options, o, mount->mount_options) {
×
2540
                        _cleanup_free_ char *escaped = NULL;
×
2541

UNCOV
2542
                        if (isempty(o->options))
×
2543
                                continue;
×
2544

UNCOV
2545
                        escaped = shell_escape(o->options, ":");
×
2546
                        if (!escaped)
×
2547
                                return log_oom_debug();
×
2548

2549
                        if (!strextend(&s,
×
2550
                                       " ",
2551
                                       partition_designator_to_string(o->partition_designator),
2552
                                       ":",
2553
                                       escaped))
UNCOV
2554
                                return log_oom_debug();
×
2555
                }
2556

UNCOV
2557
                r = serialize_item(f, "exec-context-mount-image", s);
×
2558
                if (r < 0)
×
2559
                        return r;
2560
        }
2561

2562
        FOREACH_ARRAY(mount, c->extension_images, c->n_extension_images) {
2,187✔
UNCOV
2563
                _cleanup_free_ char *s = NULL, *source_escaped = NULL;
×
2564

UNCOV
2565
                source_escaped = shell_escape(mount->source, ":" WHITESPACE);
×
UNCOV
2566
                if (!source_escaped)
×
2567
                        return log_oom_debug();
×
2568

2569
                s = strjoin(mount->ignore_enoent ? "-" : "",
×
2570
                            source_escaped);
2571
                if (!s)
×
UNCOV
2572
                        return log_oom_debug();
×
2573

UNCOV
2574
                LIST_FOREACH(mount_options, o, mount->mount_options) {
×
2575
                        _cleanup_free_ char *escaped = NULL;
×
2576

UNCOV
2577
                        if (isempty(o->options))
×
2578
                                continue;
×
2579

UNCOV
2580
                        escaped = shell_escape(o->options, ":");
×
2581
                        if (!escaped)
×
2582
                                return log_oom_debug();
×
2583

2584
                        if (!strextend(&s,
×
2585
                                       " ",
2586
                                       partition_designator_to_string(o->partition_designator),
2587
                                       ":",
2588
                                       escaped))
UNCOV
2589
                                return log_oom_debug();
×
2590
                }
2591

UNCOV
2592
                r = serialize_item(f, "exec-context-extension-image", s);
×
2593
                if (r < 0)
×
2594
                        return r;
2595
        }
2596

2597
        r = serialize_strv(f, "exec-context-extension-directories", c->extension_directories);
2,187✔
2598
        if (r < 0)
2,187✔
2599
                return r;
2600

2601
        ExecSetCredential *sc;
2,187✔
2602
        HASHMAP_FOREACH(sc, c->set_credentials) {
2,187✔
UNCOV
2603
                _cleanup_free_ char *data = NULL;
×
2604

UNCOV
2605
                if (base64mem(sc->data, sc->size, &data) < 0)
×
UNCOV
2606
                        return log_oom_debug();
×
2607

UNCOV
2608
                r = serialize_item_format(f, "exec-context-set-credentials", "%s %s %s", sc->id, data, yes_no(sc->encrypted));
×
2609
                if (r < 0)
×
2610
                        return r;
2611
        }
2612

2613
        ExecLoadCredential *lc;
2,187✔
2614
        HASHMAP_FOREACH(lc, c->load_credentials) {
2,195✔
2615
                r = serialize_item_format(f, "exec-context-load-credentials", "%s %s %s", lc->id, lc->path, yes_no(lc->encrypted));
15✔
2616
                if (r < 0)
8✔
UNCOV
2617
                        return r;
×
2618
        }
2619

2620
        ExecImportCredential *ic;
2,187✔
2621
        ORDERED_SET_FOREACH(ic, c->import_credentials) {
2,996✔
2622
                r = serialize_item_format(f, "exec-context-import-credentials", "%s%s%s",
1,570✔
2623
                                          ic->glob,
2624
                                          ic->rename ? " " : "",
2625
                                          strempty(ic->rename));
809✔
2626
                if (r < 0)
809✔
UNCOV
2627
                        return r;
×
2628
        }
2629

2630
        r = serialize_image_policy(f, "exec-context-root-image-policy", c->root_image_policy);
2,187✔
2631
        if (r < 0)
2,187✔
2632
                return r;
2633

2634
        r = serialize_image_policy(f, "exec-context-mount-image-policy", c->mount_image_policy);
2,187✔
2635
        if (r < 0)
2,187✔
2636
                return r;
2637

2638
        r = serialize_image_policy(f, "exec-context-extension-image-policy", c->extension_image_policy);
2,187✔
2639
        if (r < 0)
2,187✔
2640
                return r;
2641

2642
        fputc('\n', f); /* End marker */
2,187✔
2643

2644
        return 0;
2645
}
2646

2647
static int exec_context_deserialize(ExecContext *c, FILE *f) {
11,458✔
2648
        int r;
11,458✔
2649

2650
        assert(f);
11,458✔
2651

2652
        if (!c)
11,458✔
2653
                return 0;
2654

2655
        for (;;) {
1,278,024✔
2656
                _cleanup_free_ char *l = NULL;
1,266,566✔
2657
                const char *val;
1,278,024✔
2658

2659
                r = deserialize_read_line(f, &l);
1,278,024✔
2660
                if (r < 0)
1,278,024✔
2661
                        return r;
2662
                if (r == 0) /* eof or end marker */
1,278,024✔
2663
                        break;
2664

2665
                if ((val = startswith(l, "exec-context-environment="))) {
1,266,566✔
2666
                        r = deserialize_strv(val, &c->environment);
3,675✔
2667
                        if (r < 0)
3,675✔
2668
                                return r;
2669
                } else if ((val = startswith(l, "exec-context-environment-files="))) {
1,262,891✔
2670
                        r = deserialize_strv(val, &c->environment_files);
335✔
2671
                        if (r < 0)
335✔
2672
                                return r;
2673
                } else if ((val = startswith(l, "exec-context-pass-environment="))) {
1,262,556✔
2674
                        r = deserialize_strv(val, &c->pass_environment);
430✔
2675
                        if (r < 0)
430✔
2676
                                return r;
2677
                } else if ((val = startswith(l, "exec-context-unset-environment="))) {
1,262,126✔
2678
                        r = deserialize_strv(val, &c->unset_environment);
1,432✔
2679
                        if (r < 0)
1,432✔
2680
                                return r;
2681
                } else if ((val = startswith(l, "exec-context-working-directory="))) {
1,260,694✔
2682
                        ssize_t k;
845✔
2683
                        char *p;
845✔
2684

2685
                        k = cunescape(val, 0, &p);
845✔
2686
                        if (k < 0)
845✔
UNCOV
2687
                                return k;
×
2688
                        free_and_replace(c->working_directory, p);
845✔
2689
                } else if ((val = startswith(l, "exec-context-root-directory="))) {
1,259,849✔
2690
                        ssize_t k;
5✔
2691
                        char *p;
5✔
2692

2693
                        k = cunescape(val, 0, &p);
5✔
2694
                        if (k < 0)
5✔
UNCOV
2695
                                return k;
×
2696
                        free_and_replace(c->root_directory, p);
5✔
2697
                } else if ((val = startswith(l, "exec-context-root-image="))) {
1,259,844✔
2698
                        ssize_t k;
8✔
2699
                        char *p;
8✔
2700

2701
                        k = cunescape(val, 0, &p);
8✔
2702
                        if (k < 0)
8✔
UNCOV
2703
                                return k;
×
2704
                        free_and_replace(c->root_image, p);
8✔
2705
                } else if ((val = startswith(l, "exec-context-root-image-options="))) {
1,259,836✔
UNCOV
2706
                        for (;;) {
×
2707
                                _cleanup_free_ char *word = NULL, *mount_options = NULL, *partition = NULL;
×
UNCOV
2708
                                PartitionDesignator partition_designator;
×
UNCOV
2709
                                MountOptions *o = NULL;
×
2710
                                const char *p;
×
2711

2712
                                r = extract_first_word(&val, &word, NULL, 0);
×
2713
                                if (r < 0)
×
2714
                                        return r;
UNCOV
2715
                                if (r == 0)
×
2716
                                        break;
2717

UNCOV
2718
                                p = word;
×
2719
                                r = extract_many_words(&p, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &partition, &mount_options);
×
UNCOV
2720
                                if (r < 0)
×
2721
                                        return r;
2722
                                if (r == 0)
×
2723
                                        continue;
×
2724

UNCOV
2725
                                partition_designator = partition_designator_from_string(partition);
×
2726
                                if (partition_designator < 0)
×
2727
                                        return -EINVAL;
2728

2729
                                o = new(MountOptions, 1);
×
2730
                                if (!o)
×
UNCOV
2731
                                        return log_oom_debug();
×
UNCOV
2732
                                *o = (MountOptions) {
×
2733
                                        .partition_designator = partition_designator,
2734
                                        .options = TAKE_PTR(mount_options),
×
2735
                                };
2736
                                LIST_APPEND(mount_options, c->root_image_options, o);
×
2737
                        }
2738
                } else if ((val = startswith(l, "exec-context-root-verity="))) {
1,259,836✔
UNCOV
2739
                        r = free_and_strdup(&c->root_verity, val);
×
2740
                        if (r < 0)
×
2741
                                return r;
2742
                } else if ((val = startswith(l, "exec-context-root-hash-path="))) {
1,259,836✔
2743
                        r = free_and_strdup(&c->root_hash_path, val);
×
2744
                        if (r < 0)
×
2745
                                return r;
2746
                } else if ((val = startswith(l, "exec-context-root-hash-sig-path="))) {
1,259,836✔
2747
                        r = free_and_strdup(&c->root_hash_sig_path, val);
×
2748
                        if (r < 0)
×
2749
                                return r;
2750
                } else if ((val = startswith(l, "exec-context-root-hash="))) {
1,259,836✔
2751
                        c->root_hash = mfree(c->root_hash);
4✔
2752
                        r = unhexmem(val, &c->root_hash, &c->root_hash_size);
4✔
2753
                        if (r < 0)
4✔
2754
                                return r;
2755
                } else if ((val = startswith(l, "exec-context-root-hash-sig="))) {
1,259,832✔
UNCOV
2756
                        c->root_hash_sig = mfree(c->root_hash_sig);
×
UNCOV
2757
                        r= unbase64mem(val, &c->root_hash_sig, &c->root_hash_sig_size);
×
UNCOV
2758
                        if (r < 0)
×
2759
                                return r;
2760
                } else if ((val = startswith(l, "exec-context-root-ephemeral="))) {
1,259,832✔
2761
                        r = parse_boolean(val);
×
2762
                        if (r < 0)
×
2763
                                return r;
UNCOV
2764
                        c->root_ephemeral = r;
×
2765
                } else if ((val = startswith(l, "exec-context-umask="))) {
1,259,832✔
2766
                        r = parse_mode(val, &c->umask);
11,458✔
2767
                        if (r < 0)
11,458✔
2768
                                return r;
2769
                } else if ((val = startswith(l, "exec-context-private-non-blocking="))) {
1,248,374✔
UNCOV
2770
                        r = parse_boolean(val);
×
UNCOV
2771
                        if (r < 0)
×
2772
                                return r;
UNCOV
2773
                        c->non_blocking = r;
×
2774
                } else if ((val = startswith(l, "exec-context-private-mounts="))) {
1,248,374✔
2775
                        r = safe_atoi(val, &c->private_mounts);
124✔
2776
                        if (r < 0)
124✔
2777
                                return r;
2778
                } else if ((val = startswith(l, "exec-context-mount-api-vfs="))) {
1,248,250✔
2779
                        r = safe_atoi(val, &c->mount_apivfs);
30✔
2780
                        if (r < 0)
30✔
2781
                                return r;
2782
                } else if ((val = startswith(l, "exec-context-bind-log-sockets="))) {
1,248,220✔
UNCOV
2783
                        r = safe_atoi(val, &c->bind_log_sockets);
×
UNCOV
2784
                        if (r < 0)
×
2785
                                return r;
2786
                } else if ((val = startswith(l, "exec-context-memory-ksm="))) {
1,248,220✔
2787
                        r = safe_atoi(val, &c->memory_ksm);
×
2788
                        if (r < 0)
×
2789
                                return r;
2790
                } else if ((val = startswith(l, "exec-context-private-tmp="))) {
1,248,220✔
2791
                        c->private_tmp = private_tmp_from_string(val);
11,458✔
2792
                        if (c->private_tmp < 0)
11,458✔
2793
                                return c->private_tmp;
2794
                } else if ((val = startswith(l, "exec-context-private-devices="))) {
1,236,762✔
2795
                        r = parse_boolean(val);
840✔
2796
                        if (r < 0)
840✔
2797
                                return r;
2798
                        c->private_devices = r;
840✔
2799
                } else if ((val = startswith(l, "exec-context-protect-kernel-tunables="))) {
1,235,922✔
2800
                        r = parse_boolean(val);
527✔
2801
                        if (r < 0)
527✔
2802
                                return r;
2803
                        c->protect_kernel_tunables = r;
527✔
2804
                } else if ((val = startswith(l, "exec-context-protect-kernel-modules="))) {
1,235,395✔
2805
                        r = parse_boolean(val);
1,709✔
2806
                        if (r < 0)
1,709✔
2807
                                return r;
2808
                        c->protect_kernel_modules = r;
1,709✔
2809
                } else if ((val = startswith(l, "exec-context-protect-kernel-logs="))) {
1,233,686✔
2810
                        r = parse_boolean(val);
1,709✔
2811
                        if (r < 0)
1,709✔
2812
                                return r;
2813
                        c->protect_kernel_logs = r;
1,709✔
2814
                } else if ((val = startswith(l, "exec-context-protect-clock="))) {
1,231,977✔
2815
                        r = parse_boolean(val);
1,548✔
2816
                        if (r < 0)
1,548✔
2817
                                return r;
2818
                        c->protect_clock = r;
1,548✔
2819
                } else if ((val = startswith(l, "exec-context-protect-control-groups="))) {
1,230,429✔
2820
                        r = protect_control_groups_from_string(val);
11,458✔
2821
                        if (r < 0)
11,458✔
2822
                                return r;
2823
                        c->protect_control_groups = r;
11,458✔
2824
                } else if ((val = startswith(l, "exec-context-private-network="))) {
1,218,971✔
2825
                        r = parse_boolean(val);
58✔
2826
                        if (r < 0)
58✔
2827
                                return r;
2828
                        c->private_network = r;
58✔
2829
                } else if ((val = startswith(l, "exec-context-private-users="))) {
1,218,913✔
2830
                        c->private_users = private_users_from_string(val);
11,458✔
2831
                        if (c->private_users < 0)
11,458✔
2832
                                return -EINVAL;
2833
                } else if ((val = startswith(l, "exec-context-private-ipc="))) {
1,207,455✔
2834
                        r = parse_boolean(val);
4✔
2835
                        if (r < 0)
4✔
2836
                                return r;
2837
                        c->private_ipc = r;
4✔
2838
                } else if ((val = startswith(l, "exec-context-private-pids="))) {
1,207,451✔
2839
                        c->private_pids = private_pids_from_string(val);
11,458✔
2840
                        if (c->private_pids < 0)
11,458✔
2841
                                return -EINVAL;
2842
                } else if ((val = startswith(l, "exec-context-remove-ipc="))) {
1,195,993✔
2843
                        r = parse_boolean(val);
70✔
2844
                        if (r < 0)
70✔
2845
                                return r;
2846
                        c->remove_ipc = r;
70✔
2847
                } else if ((val = startswith(l, "exec-context-protect-home="))) {
1,195,923✔
2848
                        c->protect_home = protect_home_from_string(val);
11,458✔
2849
                        if (c->protect_home < 0)
11,458✔
2850
                                return -EINVAL;
2851
                } else if ((val = startswith(l, "exec-context-protect-system="))) {
1,184,465✔
2852
                        c->protect_system = protect_system_from_string(val);
11,458✔
2853
                        if (c->protect_system < 0)
11,458✔
2854
                                return -EINVAL;
2855
                } else if ((val = startswith(l, "exec-context-same-pgrp="))) {
1,173,007✔
2856
                        r = parse_boolean(val);
869✔
2857
                        if (r < 0)
869✔
2858
                                return r;
2859
                        c->same_pgrp = r;
869✔
2860
                } else if ((val = startswith(l, "exec-context-non-blocking="))) {
1,172,138✔
UNCOV
2861
                        r = parse_boolean(val);
×
UNCOV
2862
                        if (r < 0)
×
2863
                                return r;
UNCOV
2864
                        c->non_blocking = r;
×
2865
                } else if ((val = startswith(l, "exec-context-ignore-sigpipe="))) {
1,172,138✔
2866
                        r = parse_boolean(val);
11,458✔
2867
                        if (r < 0)
11,458✔
2868
                                return r;
2869
                        c->ignore_sigpipe = r;
11,458✔
2870
                } else if ((val = startswith(l, "exec-context-memory-deny-write-execute="))) {
1,160,680✔
2871
                        r = parse_boolean(val);
2,197✔
2872
                        if (r < 0)
2,197✔
2873
                                return r;
2874
                        c->memory_deny_write_execute = r;
2,197✔
2875
                } else if ((val = startswith(l, "exec-context-restrict-realtime="))) {
1,158,483✔
2876
                        r = parse_boolean(val);
2,197✔
2877
                        if (r < 0)
2,197✔
2878
                                return r;
2879
                        c->restrict_realtime = r;
2,197✔
2880
                } else if ((val = startswith(l, "exec-context-restrict-suid-sgid="))) {
1,156,286✔
2881
                        r = parse_boolean(val);
2,136✔
2882
                        if (r < 0)
2,136✔
2883
                                return r;
2884
                        c->restrict_suid_sgid = r;
2,136✔
2885
                } else if ((val = startswith(l, "exec-context-keyring-mode="))) {
1,154,150✔
2886
                        c->keyring_mode = exec_keyring_mode_from_string(val);
11,458✔
2887
                        if (c->keyring_mode < 0)
11,458✔
2888
                                return -EINVAL;
2889
                } else if ((val = startswith(l, "exec-context-protect-hostname="))) {
1,142,692✔
2890
                        c->protect_hostname = protect_hostname_from_string(val);
11,458✔
2891
                        if (c->protect_hostname < 0)
11,458✔
2892
                                return -EINVAL;
2893
                } else if ((val = startswith(l, "exec-context-private-hostname="))) {
1,131,234✔
2894
                        r = free_and_strdup(&c->private_hostname, val);
4✔
2895
                        if (r < 0)
4✔
2896
                                return r;
2897
                } else if ((val = startswith(l, "exec-context-protect-proc="))) {
1,131,230✔
2898
                        c->protect_proc = protect_proc_from_string(val);
11,458✔
2899
                        if (c->protect_proc < 0)
11,458✔
2900
                                return -EINVAL;
2901
                } else if ((val = startswith(l, "exec-context-proc-subset="))) {
1,119,772✔
2902
                        c->proc_subset = proc_subset_from_string(val);
11,458✔
2903
                        if (c->proc_subset < 0)
11,458✔
2904
                                return -EINVAL;
2905
                } else if ((val = startswith(l, "exec-context-runtime-directory-preserve-mode="))) {
1,108,314✔
2906
                        c->runtime_directory_preserve_mode = exec_preserve_mode_from_string(val);
11,458✔
2907
                        if (c->runtime_directory_preserve_mode < 0)
11,458✔
2908
                                return -EINVAL;
2909
                } else if ((val = startswith(l, "exec-context-directories-"))) {
1,096,856✔
UNCOV
2910
                        _cleanup_free_ char *type = NULL, *mode = NULL;
×
2911
                        ExecDirectoryType dt;
57,290✔
2912

2913
                        r = extract_many_words(&val, "= ", 0, &type, &mode);
57,290✔
2914
                        if (r < 0)
57,290✔
2915
                                return r;
2916
                        if (r == 0 || !mode)
57,290✔
2917
                                return -EINVAL;
2918

2919
                        dt = exec_directory_type_from_string(type);
57,290✔
2920
                        if (dt < 0)
57,290✔
2921
                                return -EINVAL;
2922

2923
                        r = parse_mode(mode, &c->directories[dt].mode);
57,290✔
2924
                        if (r < 0)
57,290✔
2925
                                return r;
2926

2927
                        for (;;) {
60,984✔
2928
                                _cleanup_free_ char *tuple = NULL, *path = NULL, *only_create = NULL, *read_only = NULL;
60,877✔
2929
                                ExecDirectoryFlags exec_directory_flags = 0;
60,984✔
2930
                                const char *p;
60,984✔
2931

2932
                                /* Use EXTRACT_UNESCAPE_RELAX here, as we unescape the colons in subsequent calls */
2933
                                r = extract_first_word(&val, &tuple, WHITESPACE, EXTRACT_UNESCAPE_SEPARATORS|EXTRACT_UNESCAPE_RELAX);
60,984✔
2934
                                if (r < 0)
60,984✔
2935
                                        return r;
2936
                                if (r == 0)
60,984✔
2937
                                        break;
2938

2939
                                p = tuple;
3,694✔
2940
                                r = extract_many_words(&p, ":", EXTRACT_UNESCAPE_SEPARATORS, &path, &only_create, &read_only);
3,694✔
2941
                                if (r < 0)
3,694✔
2942
                                        return r;
2943
                                if (r < 2)
3,694✔
UNCOV
2944
                                        continue;
×
2945

2946
                                r = parse_boolean(only_create);
3,694✔
2947
                                if (r < 0)
3,694✔
2948
                                        return r;
2949
                                if (r > 0)
3,694✔
2950
                                        exec_directory_flags |= EXEC_DIRECTORY_ONLY_CREATE;
5✔
2951

2952
                                r = parse_boolean(read_only);
3,694✔
2953
                                if (r < 0)
3,694✔
2954
                                        return r;
2955
                                if (r > 0)
3,694✔
2956
                                        exec_directory_flags |= EXEC_DIRECTORY_READ_ONLY;
50✔
2957

2958
                                r = exec_directory_add(&c->directories[dt], path, /* symlink= */ NULL, exec_directory_flags);
3,694✔
2959
                                if (r < 0)
3,694✔
2960
                                        return r;
2961

2962
                                if (isempty(p))
3,694✔
2963
                                        continue;
3,587✔
2964

2965
                                for (;;) {
385✔
2966
                                        _cleanup_free_ char *link = NULL;
246✔
2967

2968
                                        r = extract_first_word(&p, &link, ":", EXTRACT_UNESCAPE_SEPARATORS);
246✔
2969
                                        if (r < 0)
246✔
2970
                                                return r;
2971
                                        if (r == 0)
246✔
2972
                                                break;
2973

2974
                                        r = strv_consume(&c->directories[dt].items[c->directories[dt].n_items - 1].symlinks, TAKE_PTR(link));
139✔
2975
                                        if (r < 0)
139✔
2976
                                                return r;
2977
                                }
2978
                        }
2979
                } else if ((val = startswith(l, "exec-context-timeout-clean-usec="))) {
1,039,566✔
UNCOV
2980
                        r = deserialize_usec(val, &c->timeout_clean_usec);
×
UNCOV
2981
                        if (r < 0)
×
2982
                                return r;
2983
                } else if ((val = startswith(l, "exec-context-nice="))) {
1,039,566✔
2984
                        r = safe_atoi(val, &c->nice);
15✔
2985
                        if (r < 0)
15✔
2986
                                return r;
2987
                        c->nice_set = true;
15✔
2988
                } else if ((val = startswith(l, "exec-context-working-directory-missing-ok="))) {
1,039,551✔
2989
                        r = parse_boolean(val);
787✔
2990
                        if (r < 0)
787✔
2991
                                return r;
2992
                        c->working_directory_missing_ok = r;
787✔
2993
                } else if ((val = startswith(l, "exec-context-working-directory-home="))) {
1,038,764✔
2994
                        r = parse_boolean(val);
121✔
2995
                        if (r < 0)
121✔
2996
                                return r;
2997
                        c->working_directory_home = r;
121✔
2998
                } else if ((val = startswith(l, "exec-context-oom-score-adjust="))) {
1,038,643✔
2999
                        r = safe_atoi(val, &c->oom_score_adjust);
1,290✔
3000
                        if (r < 0)
1,290✔
3001
                                return r;
3002
                        c->oom_score_adjust_set = true;
1,290✔
3003
                } else if ((val = startswith(l, "exec-context-coredump-filter="))) {
1,037,353✔
3004
                        r = safe_atoux64(val, &c->coredump_filter);
2✔
3005
                        if (r < 0)
2✔
3006
                                return r;
3007
                        c->coredump_filter_set = true;
2✔
3008
                } else if ((val = startswith(l, "exec-context-limit-"))) {
1,037,351✔
UNCOV
3009
                        _cleanup_free_ struct rlimit *rlimit = NULL;
×
3010
                        _cleanup_free_ char *limit = NULL;
22,909✔
3011
                        int type;
22,909✔
3012

3013
                        r = extract_first_word(&val, &limit, "=", 0);
22,909✔
3014
                        if (r < 0)
22,909✔
3015
                                return r;
3016
                        if (r == 0 || !val)
22,909✔
3017
                                return -EINVAL;
3018

3019
                        type = rlimit_from_string(limit);
22,909✔
3020
                        if (type < 0)
22,909✔
3021
                                return -EINVAL;
3022

3023
                        if (!c->rlimit[type]) {
22,909✔
3024
                                rlimit = new0(struct rlimit, 1);
22,909✔
3025
                                if (!rlimit)
22,909✔
UNCOV
3026
                                        return log_oom_debug();
×
3027

3028
                                r = rlimit_parse(type, val, rlimit);
22,909✔
3029
                                if (r < 0)
22,909✔
3030
                                        return r;
3031

3032
                                c->rlimit[type] = TAKE_PTR(rlimit);
22,909✔
3033
                        } else {
UNCOV
3034
                                r = rlimit_parse(type, val, c->rlimit[type]);
×
UNCOV
3035
                                if (r < 0)
×
3036
                                        return r;
3037
                        }
3038
                } else if ((val = startswith(l, "exec-context-ioprio="))) {
1,014,442✔
3039
                        r = safe_atoi(val, &c->ioprio);
9✔
3040
                        if (r < 0)
9✔
3041
                                return r;
3042
                        c->ioprio_set = true;
9✔
3043
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-policy="))) {
1,014,433✔
UNCOV
3044
                        c->cpu_sched_policy = sched_policy_from_string(val);
×
UNCOV
3045
                        if (c->cpu_sched_policy < 0)
×
3046
                                return -EINVAL;
UNCOV
3047
                        c->cpu_sched_set = true;
×
3048
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-priority="))) {
1,014,433✔
3049
                        r = safe_atoi(val, &c->cpu_sched_priority);
×
UNCOV
3050
                        if (r < 0)
×
3051
                                return r;
UNCOV
3052
                        c->cpu_sched_set = true;
×
3053
                } else if ((val = startswith(l, "exec-context-cpu-scheduling-reset-on-fork="))) {
1,014,433✔
3054
                        r = parse_boolean(val);
×
UNCOV
3055
                        if (r < 0)
×
3056
                                return r;
UNCOV
3057
                        c->cpu_sched_reset_on_fork = r;
×
3058
                        c->cpu_sched_set = true;
×
3059
                } else if ((val = startswith(l, "exec-context-cpu-affinity="))) {
1,014,433✔
UNCOV
3060
                        if (c->cpu_set.set)
×
3061
                                return -EINVAL; /* duplicated */
3062

UNCOV
3063
                        r = parse_cpu_set(val, &c->cpu_set);
×
3064
                        if (r < 0)
×
3065
                                return r;
3066
                } else if ((val = startswith(l, "exec-context-numa-mask="))) {
1,014,433✔
3067
                        if (c->numa_policy.nodes.set)
19✔
3068
                                return -EINVAL; /* duplicated */
3069

3070
                        r = parse_cpu_set(val, &c->numa_policy.nodes);
19✔
3071
                        if (r < 0)
19✔
3072
                                return r;
3073
                } else if ((val = startswith(l, "exec-context-numa-policy="))) {
1,014,414✔
3074
                        r = safe_atoi(val, &c->numa_policy.type);
19✔
3075
                        if (r < 0)
19✔
3076
                                return r;
3077
                } else if ((val = startswith(l, "exec-context-cpu-affinity-from-numa="))) {
1,014,395✔
3078
                        r = parse_boolean(val);
2✔
3079
                        if (r < 0)
2✔
3080
                                return r;
3081
                        c->cpu_affinity_from_numa = r;
2✔
3082
                } else if ((val = startswith(l, "exec-context-timer-slack-nsec="))) {
1,014,393✔
UNCOV
3083
                        r = deserialize_usec(val, (usec_t *)&c->timer_slack_nsec);
×
UNCOV
3084
                        if (r < 0)
×
3085
                                return r;
3086
                } else if ((val = startswith(l, "exec-context-std-input="))) {
1,014,393✔
3087
                        c->std_input = exec_input_from_string(val);
11,458✔
3088
                        if (c->std_input < 0)
11,458✔
3089
                                return c->std_input;
3090
                } else if ((val = startswith(l, "exec-context-std-output="))) {
1,002,935✔
3091
                        c->std_output = exec_output_from_string(val);
11,458✔
3092
                        if (c->std_output < 0)
11,458✔
3093
                                return c->std_output;
3094
                } else if ((val = startswith(l, "exec-context-std-error="))) {
991,477✔
3095
                        c->std_error = exec_output_from_string(val);
11,458✔
3096
                        if (c->std_error < 0)
11,458✔
3097
                                return c->std_error;
3098
                } else if ((val = startswith(l, "exec-context-stdio-as-fds="))) {
980,019✔
3099
                        r = parse_boolean(val);
505✔
3100
                        if (r < 0)
505✔
3101
                                return r;
3102
                        c->stdio_as_fds = r;
505✔
3103
                } else if ((val = startswith(l, "exec-context-std-input-fd-name="))) {
979,514✔
UNCOV
3104
                        r = free_and_strdup(&c->stdio_fdname[STDIN_FILENO], val);
×
UNCOV
3105
                        if (r < 0)
×
3106
                                return r;
3107
                } else if ((val = startswith(l, "exec-context-std-output-fd-name="))) {
979,514✔
3108
                        r = free_and_strdup(&c->stdio_fdname[STDOUT_FILENO], val);
×
3109
                        if (r < 0)
×
3110
                                return r;
3111
                } else if ((val = startswith(l, "exec-context-std-error-fd-name="))) {
979,514✔
3112
                        r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], val);
×
3113
                        if (r < 0)
×
3114
                                return r;
3115
                } else if ((val = startswith(l, "exec-context-std-input-file="))) {
979,514✔
3116
                        r = free_and_strdup(&c->stdio_file[STDIN_FILENO], val);
×
3117
                        if (r < 0)
×
3118
                                return r;
3119
                } else if ((val = startswith(l, "exec-context-std-output-file="))) {
979,514✔
3120
                        r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], val);
4✔
3121
                        if (r < 0)
4✔
3122
                                return r;
3123
                } else if ((val = startswith(l, "exec-context-std-output-file-append="))) {
979,510✔
3124
                        r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], val);
1✔
3125
                        if (r < 0)
1✔
3126
                                return r;
3127
                } else if ((val = startswith(l, "exec-context-std-output-file-truncate="))) {
979,509✔
3128
                        r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], val);
2✔
3129
                        if (r < 0)
2✔
3130
                                return r;
3131
                } else if ((val = startswith(l, "exec-context-std-error-file="))) {
979,507✔
3132
                        r = free_and_strdup(&c->stdio_file[STDERR_FILENO], val);
2✔
3133
                        if (r < 0)
2✔
3134
                                return r;
3135
                } else if ((val = startswith(l, "exec-context-std-error-file-append="))) {
979,505✔
3136
                        r = free_and_strdup(&c->stdio_file[STDERR_FILENO], val);
1✔
3137
                        if (r < 0)
1✔
3138
                                return r;
3139
                } else if ((val = startswith(l, "exec-context-std-error-file-truncate="))) {
979,504✔
3140
                        r = free_and_strdup(&c->stdio_file[STDERR_FILENO], val);
1✔
3141
                        if (r < 0)
1✔
3142
                                return r;
3143
                } else if ((val = startswith(l, "exec-context-stdin-data="))) {
979,503✔
3144
                        if (c->stdin_data)
1✔
3145
                                return -EINVAL; /* duplicated */
3146

3147
                        r = unbase64mem(val, &c->stdin_data, &c->stdin_data_size);
1✔
3148
                        if (r < 0)
1✔
3149
                                return r;
3150
                } else if ((val = startswith(l, "exec-context-tty-path="))) {
979,502✔
3151
                        r = free_and_strdup(&c->tty_path, val);
162✔
3152
                        if (r < 0)
162✔
3153
                                return r;
3154
                } else if ((val = startswith(l, "exec-context-tty-reset="))) {
979,340✔
3155
                        r = parse_boolean(val);
151✔
3156
                        if (r < 0)
151✔
3157
                                return r;
3158
                        c->tty_reset = r;
151✔
3159
                } else if ((val = startswith(l, "exec-context-tty-vhangup="))) {
979,189✔
3160
                        r = parse_boolean(val);
146✔
3161
                        if (r < 0)
146✔
3162
                                return r;
3163
                        c->tty_vhangup = r;
146✔
3164
                } else if ((val = startswith(l, "exec-context-tty-vt-disallocate="))) {
979,043✔
3165
                        r = parse_boolean(val);
86✔
3166
                        if (r < 0)
86✔
3167
                                return r;
3168
                        c->tty_vt_disallocate = r;
86✔
3169
                } else if ((val = startswith(l, "exec-context-tty-rows="))) {
978,957✔
3170
                        r = safe_atou(val, &c->tty_rows);
11,458✔
3171
                        if (r < 0)
11,458✔
3172
                                return r;
3173
                } else if ((val = startswith(l, "exec-context-tty-columns="))) {
967,499✔
3174
                        r = safe_atou(val, &c->tty_cols);
11,458✔
3175
                        if (r < 0)
11,458✔
3176
                                return r;
3177
                } else if ((val = startswith(l, "exec-context-syslog-priority="))) {
956,041✔
3178
                        r = safe_atoi(val, &c->syslog_priority);
11,458✔
3179
                        if (r < 0)
11,458✔
3180
                                return r;
3181
                } else if ((val = startswith(l, "exec-context-syslog-level-prefix="))) {
944,583✔
3182
                        r = parse_boolean(val);
11,458✔
3183
                        if (r < 0)
11,458✔
3184
                                return r;
3185
                        c->syslog_level_prefix = r;
11,458✔
3186
                } else if ((val = startswith(l, "exec-context-syslog-identifier="))) {
933,125✔
UNCOV
3187
                        r = free_and_strdup(&c->syslog_identifier, val);
×
UNCOV
3188
                        if (r < 0)
×
3189
                                return r;
3190
                } else if ((val = startswith(l, "exec-context-log-level-max="))) {
933,125✔
3191
                        /* See comment in serialization. */
3192
                        r = safe_atoi(val, &c->log_level_max);
11,458✔
3193
                        if (r < 0)
11,458✔
3194
                                return r;
3195
                } else if ((val = startswith(l, "exec-context-log-ratelimit-interval-usec="))) {
921,667✔
UNCOV
3196
                        r = deserialize_usec(val, &c->log_ratelimit.interval);
×
UNCOV
3197
                        if (r < 0)
×
3198
                                return r;
3199
                } else if ((val = startswith(l, "exec-context-log-ratelimit-burst="))) {
921,667✔
3200
                        r = safe_atou(val, &c->log_ratelimit.burst);
×
3201
                        if (r < 0)
×
3202
                                return r;
3203
                } else if ((val = startswith(l, "exec-context-log-filter-allowed-patterns="))) {
921,667✔
3204
                        r = set_put_strdup(&c->log_filter_allowed_patterns, val);
9✔
3205
                        if (r < 0)
9✔
3206
                                return r;
3207
                } else if ((val = startswith(l, "exec-context-log-filter-denied-patterns="))) {
921,658✔
3208
                        r = set_put_strdup(&c->log_filter_denied_patterns, val);
5✔
3209
                        if (r < 0)
5✔
3210
                                return r;
3211
                } else if ((val = startswith(l, "exec-context-log-extra-fields="))) {
921,653✔
3212
                        if (!GREEDY_REALLOC(c->log_extra_fields, c->n_log_extra_fields + 1))
523✔
UNCOV
3213
                                return log_oom_debug();
×
3214

3215
                        c->log_extra_fields[c->n_log_extra_fields++].iov_base = strdup(val);
523✔
3216
                        if (!c->log_extra_fields[c->n_log_extra_fields-1].iov_base)
523✔
3217
                                return log_oom_debug();
×
3218
                } else if ((val = startswith(l, "exec-context-log-namespace="))) {
921,130✔
3219
                        r = free_and_strdup(&c->log_namespace, val);
2✔
3220
                        if (r < 0)
2✔
3221
                                return r;
3222
                } else if ((val = startswith(l, "exec-context-secure-bits="))) {
921,128✔
UNCOV
3223
                        r = safe_atoi(val, &c->secure_bits);
×
UNCOV
3224
                        if (r < 0)
×
3225
                                return r;
3226
                } else if ((val = startswith(l, "exec-context-capability-bounding-set="))) {
921,128✔
3227
                        r = safe_atou64(val, &c->capability_bounding_set);
2,328✔
3228
                        if (r < 0)
2,328✔
3229
                                return r;
3230
                } else if ((val = startswith(l, "exec-context-capability-ambient-set="))) {
918,800✔
3231
                        r = safe_atou64(val, &c->capability_ambient_set);
1,269✔
3232
                        if (r < 0)
1,269✔
3233
                                return r;
3234
                } else if ((val = startswith(l, "exec-context-user="))) {
917,531✔
3235
                        r = free_and_strdup(&c->user, val);
2,554✔
3236
                        if (r < 0)
2,554✔
3237
                                return r;
3238
                } else if ((val = startswith(l, "exec-context-group="))) {
914,977✔
3239
                        r = free_and_strdup(&c->group, val);
73✔
3240
                        if (r < 0)
73✔
3241
                                return r;
3242
                } else if ((val = startswith(l, "exec-context-dynamic-user="))) {
914,904✔
3243
                        r = parse_boolean(val);
62✔
3244
                        if (r < 0)
62✔
3245
                                return r;
3246
                        c->dynamic_user = r;
62✔
3247
                } else if ((val = startswith(l, "exec-context-supplementary-groups="))) {
914,842✔
3248
                        r = deserialize_strv(val, &c->supplementary_groups);
9✔
3249
                        if (r < 0)
9✔
3250
                                return r;
3251
                } else if ((val = startswith(l, "exec-context-set-login-environment="))) {
914,833✔
UNCOV
3252
                        r = safe_atoi(val, &c->set_login_environment);
×
UNCOV
3253
                        if (r < 0)
×
3254
                                return r;
3255
                } else if ((val = startswith(l, "exec-context-pam-name="))) {
914,833✔
3256
                        r = free_and_strdup(&c->pam_name, val);
412✔
3257
                        if (r < 0)
412✔
3258
                                return r;
3259
                } else if ((val = startswith(l, "exec-context-read-write-paths="))) {
914,421✔
3260
                        r = deserialize_strv(val, &c->read_write_paths);
806✔
3261
                        if (r < 0)
806✔
3262
                                return r;
3263
                } else if ((val = startswith(l, "exec-context-read-only-paths="))) {
913,615✔
3264
                        r = deserialize_strv(val, &c->read_only_paths);
2✔
3265
                        if (r < 0)
2✔
3266
                                return r;
3267
                } else if ((val = startswith(l, "exec-context-inaccessible-paths="))) {
913,613✔
3268
                        r = deserialize_strv(val, &c->inaccessible_paths);
5✔
3269
                        if (r < 0)
5✔
3270
                                return r;
3271
                } else if ((val = startswith(l, "exec-context-exec-paths="))) {
913,608✔
3272
                        r = deserialize_strv(val, &c->exec_paths);
1✔
3273
                        if (r < 0)
1✔
3274
                                return r;
3275
                } else if ((val = startswith(l, "exec-context-no-exec-paths="))) {
913,607✔
3276
                        r = deserialize_strv(val, &c->no_exec_paths);
1✔
3277
                        if (r < 0)
1✔
3278
                                return r;
3279
                } else if ((val = startswith(l, "exec-context-exec-search-path="))) {
913,606✔
UNCOV
3280
                        r = deserialize_strv(val, &c->exec_search_path);
×
UNCOV
3281
                        if (r < 0)
×
3282
                                return r;
3283
                } else if ((val = startswith(l, "exec-context-mount-propagation-flag="))) {
913,606✔
3284
                        r = safe_atolu(val, &c->mount_propagation_flag);
11,458✔
3285
                        if (r < 0)
11,458✔
3286
                                return r;
3287
                } else if ((val = startswith(l, "exec-context-bind-read-only-path="))) {
902,148✔
3288
                        _cleanup_free_ char *source = NULL, *destination = NULL;
7✔
3289
                        bool rbind = true, ignore_enoent = false;
7✔
3290
                        char *s = NULL, *d = NULL;
7✔
3291

3292
                        r = extract_first_word(&val,
7✔
3293
                                               &source,
3294
                                               ":" WHITESPACE,
3295
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3296
                        if (r < 0)
7✔
3297
                                return r;
3298
                        if (r == 0)
7✔
3299
                                return -EINVAL;
3300

3301
                        s = source;
7✔
3302
                        if (s[0] == '-') {
7✔
3303
                                ignore_enoent = true;
1✔
3304
                                s++;
1✔
3305
                        }
3306

3307
                        if (val && val[-1] == ':') {
7✔
3308
                                r = extract_first_word(&val,
7✔
3309
                                                       &destination,
3310
                                                       ":" WHITESPACE,
3311
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3312
                                if (r < 0)
7✔
3313
                                        return r;
3314
                                if (r == 0)
7✔
UNCOV
3315
                                        continue;
×
3316

3317
                                d = destination;
7✔
3318

3319
                                if (val && val[-1] == ':') {
7✔
3320
                                        _cleanup_free_ char *options = NULL;
7✔
3321

3322
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
7✔
3323
                                        if (r < 0)
7✔
UNCOV
3324
                                                return -r;
×
3325

3326
                                        if (isempty(options) || streq(options, "rbind"))
15✔
3327
                                                rbind = true;
3328
                                        else if (streq(options, "norbind"))
1✔
3329
                                                rbind = false;
3330
                                        else
UNCOV
3331
                                                continue;
×
3332
                                }
3333
                        } else
3334
                                d = s;
3335

3336
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
14✔
3337
                                        &(BindMount) {
7✔
3338
                                                .source = s,
3339
                                                .destination = d,
3340
                                                .read_only = true,
3341
                                                .recursive = rbind,
3342
                                                .ignore_enoent = ignore_enoent,
3343
                                        });
3344
                        if (r < 0)
7✔
UNCOV
3345
                                return log_oom_debug();
×
3346
                } else if ((val = startswith(l, "exec-context-bind-path="))) {
902,141✔
3347
                        _cleanup_free_ char *source = NULL, *destination = NULL;
16✔
3348
                        bool rbind = true, ignore_enoent = false;
16✔
3349
                        char *s = NULL, *d = NULL;
16✔
3350

3351
                        r = extract_first_word(&val,
16✔
3352
                                               &source,
3353
                                               ":" WHITESPACE,
3354
                                               EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3355
                        if (r < 0)
16✔
3356
                                return r;
3357
                        if (r == 0)
16✔
3358
                                return -EINVAL;
3359

3360
                        s = source;
16✔
3361
                        if (s[0] == '-') {
16✔
3362
                                ignore_enoent = true;
1✔
3363
                                s++;
1✔
3364
                        }
3365

3366
                        if (val && val[-1] == ':') {
16✔
3367
                                r = extract_first_word(&val,
16✔
3368
                                                       &destination,
3369
                                                       ":" WHITESPACE,
3370
                                                       EXTRACT_UNQUOTE|EXTRACT_DONT_COALESCE_SEPARATORS|EXTRACT_UNESCAPE_SEPARATORS);
3371
                                if (r < 0)
16✔
3372
                                        return r;
3373
                                if (r == 0)
16✔
UNCOV
3374
                                        continue;
×
3375

3376
                                d = destination;
16✔
3377

3378
                                if (val && val[-1] == ':') {
16✔
3379
                                        _cleanup_free_ char *options = NULL;
16✔
3380

3381
                                        r = extract_first_word(&val, &options, NULL, EXTRACT_UNQUOTE);
16✔
3382
                                        if (r < 0)
16✔
UNCOV
3383
                                                return -r;
×
3384

3385
                                        if (isempty(options) || streq(options, "rbind"))
35✔
3386
                                                rbind = true;
3387
                                        else if (streq(options, "norbind"))
3✔
3388
                                                rbind = false;
3389
                                        else
UNCOV
3390
                                                continue;
×
3391
                                }
3392
                        } else
3393
                                d = s;
3394

3395
                        r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
32✔
3396
                                        &(BindMount) {
16✔
3397
                                                .source = s,
3398
                                                .destination = d,
3399
                                                .read_only = false,
3400
                                                .recursive = rbind,
3401
                                                .ignore_enoent = ignore_enoent,
3402
                                        });
3403
                        if (r < 0)
16✔
UNCOV
3404
                                return log_oom_debug();
×
3405
                } else if ((val = startswith(l, "exec-context-temporary-filesystems="))) {
902,125✔
3406
                        _cleanup_free_ char *path = NULL, *options = NULL;
61✔
3407

3408
                        r = extract_many_words(&val, ":", EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS, &path, &options);
61✔
3409
                        if (r < 0)
61✔
3410
                                return r;
3411
                        if (r < 1)
61✔
UNCOV
3412
                                continue;
×
3413

3414
                        r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
61✔
3415
                        if (r < 0)
61✔
3416
                                return log_oom_debug();
×
3417
                } else if ((val = startswith(l, "exec-context-utmp-id="))) {
902,064✔
3418
                        r = free_and_strdup(&c->utmp_id, val);
153✔
3419
                        if (r < 0)
153✔
3420
                                return r;
3421
                } else if ((val = startswith(l, "exec-context-utmp-mode="))) {
901,911✔
3422
                        c->utmp_mode = exec_utmp_mode_from_string(val);
11,458✔
3423
                        if (c->utmp_mode < 0)
11,458✔
3424
                                return c->utmp_mode;
3425
                } else if ((val = startswith(l, "exec-context-no-new-privileges="))) {
890,453✔
3426
                        r = parse_boolean(val);
2,143✔
3427
                        if (r < 0)
2,143✔
3428
                                return r;
3429
                        c->no_new_privileges = r;
2,143✔
3430
                } else if ((val = startswith(l, "exec-context-selinux-context="))) {
888,310✔
UNCOV
3431
                        if (val[0] == '-') {
×
UNCOV
3432
                                c->selinux_context_ignore = true;
×
UNCOV
3433
                                val++;
×
3434
                        } else
3435
                                c->selinux_context_ignore = false;
×
3436

3437
                        r = free_and_strdup(&c->selinux_context, val);
×
UNCOV
3438
                        if (r < 0)
×
3439
                                return r;
3440
                } else if ((val = startswith(l, "exec-context-apparmor-profile="))) {
888,310✔
3441
                        if (val[0] == '-') {
×
3442
                                c->apparmor_profile_ignore = true;
×
UNCOV
3443
                                val++;
×
3444
                        } else
3445
                                c->apparmor_profile_ignore = false;
×
3446

3447
                        r = free_and_strdup(&c->apparmor_profile, val);
×
UNCOV
3448
                        if (r < 0)
×
3449
                                return r;
3450
                } else if ((val = startswith(l, "exec-context-smack-process-label="))) {
888,310✔
3451
                        if (val[0] == '-') {
×
3452
                                c->smack_process_label_ignore = true;
×
UNCOV
3453
                                val++;
×
3454
                        } else
3455
                                c->smack_process_label_ignore = false;
×
3456

3457
                        r = free_and_strdup(&c->smack_process_label, val);
×
UNCOV
3458
                        if (r < 0)
×
3459
                                return r;
3460
                } else if ((val = startswith(l, "exec-context-personality="))) {
888,310✔
3461
                        c->personality = personality_from_string(val);
×
3462
                        if (c->personality == PERSONALITY_INVALID)
×
3463
                                return -EINVAL;
3464
                } else if ((val = startswith(l, "exec-context-lock-personality="))) {
888,310✔
3465
                        r = parse_boolean(val);
2,200✔
3466
                        if (r < 0)
2,200✔
3467
                                return r;
3468
                        c->lock_personality = r;
2,200✔
3469
#if HAVE_SECCOMP
3470
                } else if ((val = startswith(l, "exec-context-syscall-filter="))) {
886,110✔
3471
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
849,521✔
3472
                        int id, errno_num;
849,521✔
3473

3474
                        r = extract_many_words(&val, NULL, 0, &s_id, &s_errno_num);
849,521✔
3475
                        if (r < 0)
849,521✔
3476
                                return r;
3477
                        if (r != 2)
849,521✔
UNCOV
3478
                                continue;
×
3479

3480
                        r = safe_atoi(s_id, &id);
849,521✔
3481
                        if (r < 0)
849,521✔
3482
                                return r;
3483

3484
                        r = safe_atoi(s_errno_num, &errno_num);
849,521✔
3485
                        if (r < 0)
849,521✔
3486
                                return r;
3487

3488
                        r = hashmap_ensure_put(&c->syscall_filter, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
849,521✔
3489
                        if (r < 0)
849,521✔
3490
                                return r;
3491
                } else if ((val = startswith(l, "exec-context-syscall-archs="))) {
36,589✔
3492
                        unsigned id;
2,199✔
3493

3494
                        r = safe_atou(val, &id);
2,199✔
3495
                        if (r < 0)
2,199✔
UNCOV
3496
                                return r;
×
3497

3498
                        r = set_ensure_put(&c->syscall_archs, NULL, UINT_TO_PTR(id + 1));
2,199✔
3499
                        if (r < 0)
2,199✔
3500
                                return r;
3501
                } else if ((val = startswith(l, "exec-context-syscall-errno="))) {
34,390✔
3502
                        r = safe_atoi(val, &c->syscall_errno);
11,458✔
3503
                        if (r < 0)
11,458✔
3504
                                return r;
3505
                } else if ((val = startswith(l, "exec-context-syscall-allow-list="))) {
22,932✔
3506
                        r = parse_boolean(val);
2,182✔
3507
                        if (r < 0)
2,182✔
3508
                                return r;
3509
                        c->syscall_allow_list = r;
2,182✔
3510
                } else if ((val = startswith(l, "exec-context-syscall-log="))) {
20,750✔
UNCOV
3511
                        _cleanup_free_ char *s_id = NULL, *s_errno_num = NULL;
×
UNCOV
3512
                        int id, errno_num;
×
3513

UNCOV
3514
                        r = extract_many_words(&val, " ", 0, &s_id, &s_errno_num);
×
3515
                        if (r < 0)
×
3516
                                return r;
UNCOV
3517
                        if (r != 2)
×
3518
                                continue;
×
3519

UNCOV
3520
                        r = safe_atoi(s_id, &id);
×
3521
                        if (r < 0)
×
3522
                                return r;
3523

3524
                        r = safe_atoi(s_errno_num, &errno_num);
×
3525
                        if (r < 0)
×
3526
                                return r;
3527

3528
                        r = hashmap_ensure_put(&c->syscall_log, NULL, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
×
3529
                        if (r < 0)
×
3530
                                return r;
3531
                } else if ((val = startswith(l, "exec-context-syscall-log-allow-list="))) {
20,750✔
3532
                        r = parse_boolean(val);
×
3533
                        if (r < 0)
×
3534
                                return r;
UNCOV
3535
                        c->syscall_log_allow_list = r;
×
3536
#endif
3537
                } else if ((val = startswith(l, "exec-context-restrict-namespaces="))) {
20,750✔
3538
                        r = safe_atolu(val, &c->restrict_namespaces);
1,944✔
3539
                        if (r < 0)
1,944✔
3540
                                return r;
3541
                } else if ((val = startswith(l, "exec-context-delegate-namespaces="))) {
18,806✔
3542
                        r = safe_atolu(val, &c->delegate_namespaces);
10✔
3543
                        if (r < 0)
10✔
3544
                                return r;
3545
                } else if ((val = startswith(l, "exec-context-restrict-filesystems="))) {
18,796✔
UNCOV
3546
                        r = set_put_strdup(&c->restrict_filesystems, val);
×
UNCOV
3547
                        if (r < 0)
×
3548
                                return r;
3549
                } else if ((val = startswith(l, "exec-context-restrict-filesystems-allow-list="))) {
18,796✔
3550
                        r = parse_boolean(val);
×
3551
                        if (r < 0)
×
3552
                                return r;
UNCOV
3553
                        c->restrict_filesystems_allow_list = r;
×
3554
                } else if ((val = startswith(l, "exec-context-address-families="))) {
18,796✔
3555
                        int af;
9,166✔
3556

3557
                        r = safe_atoi(val, &af);
9,166✔
3558
                        if (r < 0)
9,166✔
3559
                                return r;
×
3560

3561
                        r = set_ensure_put(&c->address_families, NULL, INT_TO_PTR(af));
9,166✔
3562
                        if (r < 0)
9,166✔
3563
                                return r;
3564
                } else if ((val = startswith(l, "exec-context-address-families-allow-list="))) {
9,630✔
3565
                        r = parse_boolean(val);
2,197✔
3566
                        if (r < 0)
2,197✔
3567
                                return r;
3568
                        c->address_families_allow_list = r;
2,197✔
3569
                } else if ((val = startswith(l, "exec-context-network-namespace-path="))) {
7,433✔
UNCOV
3570
                        r = free_and_strdup(&c->network_namespace_path, val);
×
UNCOV
3571
                        if (r < 0)
×
3572
                                return r;
3573
                } else if ((val = startswith(l, "exec-context-ipc-namespace-path="))) {
7,433✔
UNCOV
3574
                        r = free_and_strdup(&c->ipc_namespace_path, val);
×
UNCOV
3575
                        if (r < 0)
×
3576
                                return r;
3577
                } else if ((val = startswith(l, "exec-context-mount-image="))) {
7,433✔
3578
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3579
                        _cleanup_free_ char *source = NULL, *destination = NULL;
60✔
3580
                        bool permissive = false;
60✔
3581
                        char *s;
60✔
3582

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

3593
                        s = source;
60✔
3594
                        if (s[0] == '-') {
60✔
UNCOV
3595
                                permissive = true;
×
UNCOV
3596
                                s++;
×
3597
                        }
3598

3599
                        if (isempty(destination))
60✔
UNCOV
3600
                                continue;
×
3601

3602
                        for (;;) {
65✔
3603
                                _cleanup_free_ char *tuple = NULL, *partition = NULL, *opts = NULL;
5✔
3604
                                PartitionDesignator partition_designator;
65✔
3605
                                MountOptions *o = NULL;
65✔
3606
                                const char *p;
65✔
3607

3608
                                r = extract_first_word(&val, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
65✔
3609
                                if (r < 0)
65✔
3610
                                        return r;
3611
                                if (r == 0)
65✔
3612
                                        break;
3613

3614
                                p = tuple;
5✔
3615
                                r = extract_many_words(&p,
5✔
3616
                                                       ":",
3617
                                                       EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3618
                                                       &partition,
3619
                                                       &opts);
3620
                                if (r < 0)
5✔
3621
                                        return r;
3622
                                if (r == 0)
5✔
UNCOV
3623
                                        continue;
×
3624
                                if (r == 1) {
5✔
UNCOV
3625
                                        o = new(MountOptions, 1);
×
UNCOV
3626
                                        if (!o)
×
UNCOV
3627
                                                return log_oom_debug();
×
UNCOV
3628
                                        *o = (MountOptions) {
×
3629
                                                .partition_designator = PARTITION_ROOT,
UNCOV
3630
                                                .options = TAKE_PTR(partition),
×
3631
                                        };
UNCOV
3632
                                        LIST_APPEND(mount_options, options, o);
×
3633

3634
                                        continue;
×
3635
                                }
3636

3637
                                partition_designator = partition_designator_from_string(partition);
5✔
3638
                                if (partition_designator < 0)
5✔
UNCOV
3639
                                        continue;
×
3640

3641
                                o = new(MountOptions, 1);
5✔
3642
                                if (!o)
5✔
UNCOV
3643
                                        return log_oom_debug();
×
3644
                                *o = (MountOptions) {
5✔
3645
                                        .partition_designator = partition_designator,
3646
                                        .options = TAKE_PTR(opts),
5✔
3647
                                };
3648
                                LIST_APPEND(mount_options, options, o);
5✔
3649
                        }
3650

3651
                        r = mount_image_add(&c->mount_images, &c->n_mount_images,
120✔
3652
                                        &(MountImage) {
60✔
3653
                                                .source = s,
3654
                                                .destination = destination,
3655
                                                .mount_options = options,
3656
                                                .ignore_enoent = permissive,
3657
                                                .type = MOUNT_IMAGE_DISCRETE,
3658
                                        });
3659
                        if (r < 0)
60✔
UNCOV
3660
                                return log_oom_debug();
×
3661
                } else if ((val = startswith(l, "exec-context-extension-image="))) {
7,373✔
UNCOV
3662
                        _cleanup_(mount_options_free_allp) MountOptions *options = NULL;
×
3663
                        _cleanup_free_ char *source = NULL;
8✔
3664
                        bool permissive = false;
8✔
3665
                        char *s;
8✔
3666

3667
                        r = extract_first_word(&val,
8✔
3668
                                               &source,
3669
                                               NULL,
3670
                                               EXTRACT_UNQUOTE|EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS);
3671
                        if (r < 0)
8✔
3672
                                return r;
3673
                        if (r == 0)
8✔
3674
                                return -EINVAL;
3675

3676
                        s = source;
8✔
3677
                        if (s[0] == '-') {
8✔
3678
                                permissive = true;
2✔
3679
                                s++;
2✔
3680
                        }
3681

3682
                        for (;;) {
8✔
UNCOV
3683
                                _cleanup_free_ char *tuple = NULL, *partition = NULL, *opts = NULL;
×
3684
                                PartitionDesignator partition_designator;
8✔
3685
                                MountOptions *o = NULL;
8✔
3686
                                const char *p;
8✔
3687

3688
                                r = extract_first_word(&val, &tuple, NULL, EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
8✔
3689
                                if (r < 0)
8✔
3690
                                        return r;
3691
                                if (r == 0)
8✔
3692
                                        break;
3693

UNCOV
3694
                                p = tuple;
×
UNCOV
3695
                                r = extract_many_words(&p,
×
3696
                                                       ":",
3697
                                                       EXTRACT_CUNESCAPE|EXTRACT_UNESCAPE_SEPARATORS,
3698
                                                       &partition,
3699
                                                       &opts);
UNCOV
3700
                                if (r < 0)
×
3701
                                        return r;
3702
                                if (r == 0)
×
3703
                                        continue;
×
UNCOV
3704
                                if (r == 1) {
×
UNCOV
3705
                                        o = new(MountOptions, 1);
×
UNCOV
3706
                                        if (!o)
×
UNCOV
3707
                                                return log_oom_debug();
×
3708
                                        *o = (MountOptions) {
×
3709
                                                .partition_designator = PARTITION_ROOT,
3710
                                                .options = TAKE_PTR(partition),
×
3711
                                        };
3712
                                        LIST_APPEND(mount_options, options, o);
×
3713

3714
                                        continue;
×
3715
                                }
3716

UNCOV
3717
                                partition_designator = partition_designator_from_string(partition);
×
3718
                                if (partition_designator < 0)
×
UNCOV
3719
                                        continue;
×
3720

UNCOV
3721
                                o = new(MountOptions, 1);
×
3722
                                if (!o)
×
UNCOV
3723
                                        return log_oom_debug();
×
UNCOV
3724
                                *o = (MountOptions) {
×
3725
                                        .partition_designator = partition_designator,
3726
                                        .options = TAKE_PTR(opts),
×
3727
                                };
UNCOV
3728
                                LIST_APPEND(mount_options, options, o);
×
3729
                        }
3730

3731
                        r = mount_image_add(&c->extension_images, &c->n_extension_images,
16✔
3732
                                        &(MountImage) {
8✔
3733
                                                .source = s,
3734
                                                .mount_options = options,
3735
                                                .ignore_enoent = permissive,
3736
                                                .type = MOUNT_IMAGE_EXTENSION,
3737
                                        });
3738
                        if (r < 0)
8✔
UNCOV
3739
                                return log_oom_debug();
×
3740
                } else if ((val = startswith(l, "exec-context-extension-directories="))) {
7,365✔
3741
                        r = deserialize_strv(val, &c->extension_directories);
7✔
3742
                        if (r < 0)
7✔
3743
                                return r;
3744
                } else if ((val = startswith(l, "exec-context-set-credentials="))) {
7,358✔
UNCOV
3745
                        _cleanup_free_ char *id = NULL, *data = NULL, *encrypted = NULL;
×
3746

3747
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &data, &encrypted);
162✔
3748
                        if (r < 0)
162✔
3749
                                return r;
3750
                        if (r != 3)
162✔
3751
                                return -EINVAL;
3752

3753
                        r = parse_boolean(encrypted);
162✔
3754
                        if (r < 0)
162✔
3755
                                return r;
3756
                        bool e = r;
162✔
3757

3758
                        _cleanup_free_ void *d = NULL;
162✔
3759
                        size_t size;
162✔
3760

3761
                        r = unbase64mem_full(data, SIZE_MAX, /* secure = */ true, &d, &size);
162✔
3762
                        if (r < 0)
162✔
3763
                                return r;
3764

3765
                        r = exec_context_put_set_credential(c, id, TAKE_PTR(d), size, e);
162✔
3766
                        if (r < 0)
162✔
3767
                                return r;
3768
                } else if ((val = startswith(l, "exec-context-load-credentials="))) {
7,196✔
3769
                        _cleanup_free_ char *id = NULL, *path = NULL, *encrypted = NULL;
71✔
3770

3771
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &id, &path, &encrypted);
71✔
3772
                        if (r < 0)
71✔
3773
                                return r;
3774
                        if (r != 3)
71✔
3775
                                return -EINVAL;
3776

3777
                        r = parse_boolean(encrypted);
71✔
3778
                        if (r < 0)
71✔
3779
                                return r;
3780

3781
                        r = exec_context_put_load_credential(c, id, path, r > 0);
71✔
3782
                        if (r < 0)
71✔
3783
                                return r;
3784
                } else if ((val = startswith(l, "exec-context-import-credentials="))) {
7,125✔
3785
                        _cleanup_free_ char *glob = NULL, *rename = NULL;
7,121✔
3786

3787
                        r = extract_many_words(&val, " ", EXTRACT_DONT_COALESCE_SEPARATORS, &glob, &rename);
7,121✔
3788
                        if (r < 0)
7,121✔
3789
                                return r;
3790
                        if (r == 0)
7,121✔
3791
                                return -EINVAL;
3792

3793
                        r = exec_context_put_import_credential(c, glob, rename);
7,121✔
3794
                        if (r < 0)
7,121✔
3795
                                return r;
3796
                } else if ((val = startswith(l, "exec-context-root-image-policy="))) {
4✔
3797
                        if (c->root_image_policy)
4✔
3798
                                return -EINVAL; /* duplicated */
3799

3800
                        r = image_policy_from_string(val, &c->root_image_policy);
4✔
3801
                        if (r < 0)
4✔
3802
                                return r;
UNCOV
3803
                } else if ((val = startswith(l, "exec-context-mount-image-policy="))) {
×
UNCOV
3804
                        if (c->mount_image_policy)
×
3805
                                return -EINVAL; /* duplicated */
3806

UNCOV
3807
                        r = image_policy_from_string(val, &c->mount_image_policy);
×
UNCOV
3808
                        if (r < 0)
×
3809
                                return r;
UNCOV
3810
                } else if ((val = startswith(l, "exec-context-extension-image-policy="))) {
×
3811
                        if (c->extension_image_policy)
×
3812
                                return -EINVAL; /* duplicated */
3813

UNCOV
3814
                        r = image_policy_from_string(val, &c->extension_image_policy);
×
3815
                        if (r < 0)
×
3816
                                return r;
3817
                } else
3818
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
1,266,566✔
3819
        }
3820

3821
        return 0;
11,458✔
3822
}
3823

3824
static int exec_command_serialize(const ExecCommand *c, FILE *f) {
2,187✔
3825
        int r;
2,187✔
3826

3827
        assert(c);
2,187✔
3828
        assert(f);
2,187✔
3829

3830
        r = serialize_item(f, "exec-command-path", c->path);
2,187✔
3831
        if (r < 0)
2,187✔
3832
                return r;
3833

3834
        r = serialize_strv(f, "exec-command-argv", c->argv);
2,187✔
3835
        if (r < 0)
2,187✔
3836
                return r;
3837

3838
        r = serialize_item_format(f, "exec-command-flags", "%d", (int) c->flags);
2,187✔
3839
        if (r < 0)
2,187✔
3840
                return r;
3841

3842
        fputc('\n', f); /* End marker */
2,187✔
3843

3844
        return 0;
2,187✔
3845
}
3846

3847
static int exec_command_deserialize(ExecCommand *c, FILE *f) {
11,458✔
3848
        int r;
11,458✔
3849

3850
        assert(c);
11,458✔
3851
        assert(f);
11,458✔
3852

3853
        for (;;) {
122,486✔
3854
                _cleanup_free_ char *l = NULL;
55,514✔
3855
                const char *val;
66,972✔
3856

3857
                r = deserialize_read_line(f, &l);
66,972✔
3858
                if (r < 0)
66,972✔
3859
                        return r;
3860
                if (r == 0) /* eof or end marker */
66,972✔
3861
                        break;
3862

3863
                if ((val = startswith(l, "exec-command-path="))) {
55,514✔
3864
                        r = free_and_strdup(&c->path, val);
11,458✔
3865
                        if (r < 0)
11,458✔
3866
                                return r;
3867
                } else if ((val = startswith(l, "exec-command-argv="))) {
44,056✔
3868
                        r = deserialize_strv(val, &c->argv);
32,598✔
3869
                        if (r < 0)
32,598✔
3870
                                return r;
3871
                } else if ((val = startswith(l, "exec-command-flags="))) {
11,458✔
3872
                        r = safe_atoi(val, &c->flags);
11,458✔
3873
                        if (r < 0)
11,458✔
3874
                                return r;
3875
                } else
3876
                        log_warning("Failed to parse serialized line, ignoring: %s", l);
55,514✔
3877

3878
        }
3879

3880
        return 0;
11,458✔
3881
}
3882

3883
int exec_serialize_invocation(
2,187✔
3884
                FILE *f,
3885
                FDSet *fds,
3886
                const ExecContext *ctx,
3887
                const ExecCommand *cmd,
3888
                const ExecParameters *p,
3889
                const ExecRuntime *rt,
3890
                const CGroupContext *cg) {
3891

3892
        int r;
2,187✔
3893

3894
        assert(f);
2,187✔
3895
        assert(fds);
2,187✔
3896

3897
        r = exec_context_serialize(ctx, f);
2,187✔
3898
        if (r < 0)
2,187✔
UNCOV
3899
                return log_debug_errno(r, "Failed to serialize context: %m");
×
3900

3901
        r = exec_command_serialize(cmd, f);
2,187✔
3902
        if (r < 0)
2,187✔
UNCOV
3903
                return log_debug_errno(r, "Failed to serialize command: %m");
×
3904

3905
        r = exec_parameters_serialize(p, ctx, f, fds);
2,187✔
3906
        if (r < 0)
2,187✔
3907
                return log_debug_errno(r, "Failed to serialize parameters: %m");
×
3908

3909
        r = exec_runtime_serialize(rt, f, fds);
2,187✔
3910
        if (r < 0)
2,187✔
3911
                return log_debug_errno(r, "Failed to serialize runtime: %m");
×
3912

3913
        r = exec_cgroup_context_serialize(cg, f);
2,187✔
3914
        if (r < 0)
2,187✔
3915
                return log_debug_errno(r, "Failed to serialize cgroup context: %m");
×
3916

3917
        return 0;
3918
}
3919

3920
int exec_deserialize_invocation(
11,458✔
3921
                FILE *f,
3922
                FDSet *fds,
3923
                ExecContext *ctx,
3924
                ExecCommand *cmd,
3925
                ExecParameters *p,
3926
                ExecRuntime *rt,
3927
                CGroupContext *cg) {
3928

3929
        int r;
11,458✔
3930

3931
        assert(f);
11,458✔
3932
        assert(fds);
11,458✔
3933

3934
        r = exec_context_deserialize(ctx, f);
11,458✔
3935
        if (r < 0)
11,458✔
UNCOV
3936
                return log_debug_errno(r, "Failed to deserialize context: %m");
×
3937

3938
        r = exec_command_deserialize(cmd, f);
11,458✔
3939
        if (r < 0)
11,458✔
UNCOV
3940
                return log_debug_errno(r, "Failed to deserialize command: %m");
×
3941

3942
        r = exec_parameters_deserialize(p, f, fds);
11,458✔
3943
        if (r < 0)
11,458✔
3944
                return log_debug_errno(r, "Failed to deserialize parameters: %m");
×
3945

3946
        r = exec_runtime_deserialize(rt, f, fds);
11,458✔
3947
        if (r < 0)
11,458✔
3948
                return log_debug_errno(r, "Failed to deserialize runtime: %m");
×
3949

3950
        r = exec_cgroup_context_deserialize(cg, f);
11,458✔
3951
        if (r < 0)
11,458✔
3952
                return log_debug_errno(r, "Failed to deserialize cgroup context: %m");
×
3953

3954
        return 0;
3955
}
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