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

systemd / systemd / 19315930715

12 Nov 2025 11:39PM UTC coverage: 72.251% (-0.2%) from 72.412%
19315930715

push

github

bluca
mkosi: update debian commit reference to efdd7a637

* efdd7a6377 Install new file for upstream build
* 9ebdc6099e d/rules: enable 10-systemd-logind-root-ignore-inhibitors.rules.example on Ubuntu
* 1255cc7663 initramfs-tools: only skip chzdev rules if zdev_early=0
* 4675b281ee d/t/boot-and-services: skip apparmor test on armhf
* 214d6e37b2 d/t/boot-and-services: run transient unit to check syslog messages
* f4e196aa26 d/t/boot-and-services: tweak test_rsyslog regex
* dbd366a43e Install new files for upstream build
* bb7f8ef532 Install new files for upstream build
* efa7cee8a7 Install new file for upstream build
* 95aa1d1685 Install new file for upstream build
* b770f0f01b kernel-install: skip 55-initrd.install when an initrd generator is configured
* af8d1e3134 Update changelog for 258.1-2 release
* 2d0e73cd14 d/libnss-systemd.postinst: Ensure module is enabled for all four databases

306471 of 424176 relevant lines covered (72.25%)

1239443.53 hits per line

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

77.89
/src/basic/capability-util.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <stdatomic.h>
4
#include <stdio.h>
5
#include <sys/prctl.h>
6
#include <sys/syscall.h>
7
#include <unistd.h>
8

9
#include "alloc-util.h"
10
#include "bitfield.h"
11
#include "capability-list.h"
12
#include "capability-util.h"
13
#include "errno-util.h"
14
#include "fd-util.h"
15
#include "fileio.h"
16
#include "log.h"
17
#include "parse-util.h"
18
#include "pidref.h"
19
#include "process-util.h"
20
#include "stat-util.h"
21
#include "user-util.h"
22

23
int capability_get(CapabilityQuintet *ret) {
208,424✔
24
        assert(ret);
208,424✔
25

26
        struct __user_cap_header_struct hdr = {
416,848✔
27
                .version = _LINUX_CAPABILITY_VERSION_3,
28
                .pid = getpid_cached(),
208,424✔
29
        };
30

31
        assert_cc(_LINUX_CAPABILITY_U32S_3 == 2);
208,424✔
32
        struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3];
208,424✔
33
        if (syscall(SYS_capget, &hdr, data) < 0)
208,424✔
34
                return -errno;
×
35

36
        *ret = (CapabilityQuintet) {
208,424✔
37
                .effective = (uint64_t) data[0].effective | ((uint64_t) data[1].effective << 32),
208,424✔
38
                .bounding = UINT64_MAX,
39
                .inheritable = (uint64_t) data[0].inheritable | ((uint64_t) data[1].inheritable << 32),
208,424✔
40
                .permitted = (uint64_t) data[0].permitted | ((uint64_t) data[1].permitted << 32),
208,424✔
41
                .ambient = UINT64_MAX,
42
        };
43
        return 0;
208,424✔
44
}
45

46
static int capability_apply(const CapabilityQuintet *q) {
6,957✔
47
        assert(q);
6,957✔
48

49
        struct __user_cap_header_struct hdr = {
13,914✔
50
                .version = _LINUX_CAPABILITY_VERSION_3,
51
                .pid = getpid_cached(),
6,957✔
52
        };
53

54
        struct __user_cap_data_struct data[_LINUX_CAPABILITY_U32S_3] = {
6,957✔
55
                {
56
                        .effective = (uint32_t) (q->effective & UINT32_MAX),
6,957✔
57
                        .inheritable = (uint32_t) (q->inheritable & UINT32_MAX),
6,957✔
58
                        .permitted = (uint32_t) (q->permitted & UINT32_MAX),
6,957✔
59
                },
60
                {
61
                        .effective = (uint32_t) (q->effective >> 32),
6,957✔
62
                        .inheritable = (uint32_t) (q->inheritable >> 32),
6,957✔
63
                        .permitted = (uint32_t) (q->permitted >> 32),
6,957✔
64
                },
65
        };
66
        return RET_NERRNO(syscall(SYS_capset, &hdr, data));
6,957✔
67
}
68

69
unsigned cap_last_cap(void) {
1,525,632✔
70
        static atomic_int saved = INT_MAX;
1,525,632✔
71
        int r, c;
1,525,632✔
72

73
        c = saved;
1,525,632✔
74
        if (c != INT_MAX)
1,525,632✔
75
                return c;
1,525,632✔
76

77
        /* Available since linux-3.2 */
78
        _cleanup_free_ char *content = NULL;
10,423✔
79
        r = read_one_line_file("/proc/sys/kernel/cap_last_cap", &content);
10,423✔
80
        if (r < 0)
10,423✔
81
                log_debug_errno(r, "Failed to read /proc/sys/kernel/cap_last_cap, ignoring: %m");
×
82
        else {
83
                r = safe_atoi(content, &c);
10,423✔
84
                if (r < 0)
10,423✔
85
                        log_debug_errno(r, "Failed to parse /proc/sys/kernel/cap_last_cap, ignoring: %m");
×
86
                else {
87
                        if (c > CAP_LIMIT) /* Safety for the future: if one day the kernel learns more than
10,423✔
88
                                            * 64 caps, then we are in trouble (since we, as much userspace
89
                                            * and kernel space store capability masks in uint64_t types). We
90
                                            * also want to use UINT64_MAX as marker for "unset". Hence let's
91
                                            * hence protect ourselves against that and always cap at 62 for
92
                                            * now. */
93
                                c = CAP_LIMIT;
×
94

95
                        saved = c;
10,423✔
96
                        return c;
10,423✔
97
                }
98
        }
99

100
        /* Fall back to syscall-probing for pre linux-3.2, or where /proc/ is not mounted */
101
        unsigned long p = (unsigned long) MIN(CAP_LAST_CAP, CAP_LIMIT);
×
102

103
        if (prctl(PR_CAPBSET_READ, p) < 0) {
×
104

105
                /* Hmm, look downwards, until we find one that works */
106
                for (p--; p > 0; p--)
×
107
                        if (prctl(PR_CAPBSET_READ, p) >= 0)
×
108
                                break;
109

110
        } else {
111

112
                /* Hmm, look upwards, until we find one that doesn't work */
113
                for (; p < CAP_LIMIT; p++)
×
114
                        if (prctl(PR_CAPBSET_READ, p+1) < 0)
×
115
                                break;
116
        }
117

118
        c = (int) p;
×
119
        saved = c;
×
120
        return c;
×
121
}
122

123
int have_effective_cap(unsigned cap) {
198,389✔
124
        CapabilityQuintet q;
198,389✔
125
        int r;
198,389✔
126

127
        assert(cap <= CAP_LIMIT);
198,389✔
128

129
        r = capability_get(&q);
198,389✔
130
        if (r < 0)
198,389✔
131
                return r;
198,389✔
132

133
        return BIT_SET(q.effective, cap);
198,389✔
134
}
135

136
int have_inheritable_cap(unsigned cap) {
2✔
137
        CapabilityQuintet q;
2✔
138
        int r;
2✔
139

140
        assert(cap <= CAP_LIMIT);
2✔
141

142
        r = capability_get(&q);
2✔
143
        if (r < 0)
2✔
144
                return r;
2✔
145

146
        return BIT_SET(q.inheritable, cap);
2✔
147
}
148

149
int capability_ambient_set_apply(uint64_t set, bool also_inherit) {
15,984✔
150
        int r;
15,984✔
151

152
        /* Remove capabilities requested in ambient set, but not in the bounding set */
153
        for (unsigned i = 0; i <= cap_last_cap(); i++) {
671,328✔
154
                if (!BIT_SET(set, i))
655,344✔
155
                        continue;
648,428✔
156

157
                if (prctl(PR_CAPBSET_READ, (unsigned long) i) != 1) {
6,916✔
158
                        log_debug("Ambient capability %s requested but missing from bounding set, suppressing automatically.",
53✔
159
                                  capability_to_name(i));
160
                        CLEAR_BIT(set, i);
53✔
161
                }
162
        }
163

164
        /* Add the capabilities to the ambient set (an possibly also the inheritable set) */
165

166
        if (also_inherit) {
15,984✔
167
                CapabilityQuintet q;
700✔
168

169
                r = capability_get(&q);
700✔
170
                if (r < 0)
700✔
171
                        return r;
×
172

173
                q.inheritable = set;
700✔
174

175
                r = capability_apply(&q);
700✔
176
                if (r < 0)
700✔
177
                        return r;
178
        }
179

180
        for (unsigned i = 0; i <= cap_last_cap(); i++)
671,328✔
181
                if (BIT_SET(set, i)) {
655,344✔
182
                        /* Add the capability to the ambient set. */
183
                        if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0) < 0)
6,863✔
184
                                return -errno;
×
185
                } else {
186
                        /* Drop the capability so we don't inherit capabilities we didn't ask for. */
187
                        r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0);
648,481✔
188
                        if (r < 0)
648,481✔
189
                                return -errno;
×
190
                        if (r > 0)
648,481✔
191
                                if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, i, 0, 0) < 0)
449✔
192
                                        return -errno;
×
193
                }
194

195
        return 0;
196
}
197

198
int capability_gain_cap_setpcap(void) {
3,163✔
199
        CapabilityQuintet q;
3,163✔
200
        int r;
3,163✔
201

202
        r = capability_get(&q);
3,163✔
203
        if (r < 0)
3,163✔
204
                return r;
3,163✔
205

206
        if (BIT_SET(q.effective, CAP_SETPCAP))
3,163✔
207
                return 1; /* We already have capability. */
208

209
        SET_BIT(q.effective, CAP_SETPCAP);
89✔
210

211
        r = capability_apply(&q);
89✔
212
        if (r < 0) {
89✔
213
                /* If we didn't manage to acquire the CAP_SETPCAP bit, we continue anyway, after all this
214
                 * just means we'll fail later, when we actually intend to drop some capabilities or try to
215
                 * set securebits. */
216
                log_debug_errno(r, "Can't acquire effective CAP_SETPCAP bit, ignoring: %m");
×
217
                return 0;
×
218
        }
219

220
        return 1; /* acquired */
221
}
222

223
int capability_bounding_set_drop(uint64_t keep, bool right_now) {
2,409✔
224
        int k, r;
2,409✔
225

226
        /* If we are run as PID 1 we will lack CAP_SETPCAP by default in the effective set (yes, the kernel
227
         * drops that when executing init!), so get it back temporarily so that we can call PR_CAPBSET_DROP. */
228

229
        CapabilityQuintet q;
2,409✔
230
        r = capability_get(&q);
2,409✔
231
        if (r < 0)
2,409✔
232
                return r;
2,409✔
233
        CapabilityQuintet saved = q;
2,409✔
234

235
        r = capability_gain_cap_setpcap();
2,409✔
236
        if (r < 0)
2,409✔
237
                return r;
238

239
        for (unsigned i = 0; i <= cap_last_cap(); i++) {
101,178✔
240
                if (BIT_SET(keep, i))
98,769✔
241
                        continue;
26,669✔
242

243
                /* Drop it from the bounding set */
244
                if (prctl(PR_CAPBSET_DROP, i) < 0) {
72,100✔
245
                        r = -errno;
×
246

247
                        /* If dropping the capability failed, let's see if we didn't have it in the first
248
                         * place. If so, continue anyway, as dropping a capability we didn't have in the
249
                         * first place doesn't really matter anyway. */
250
                        if (prctl(PR_CAPBSET_READ, i) != 0)
×
251
                                goto finish;
×
252
                }
253

254
                /* Also drop it from the inheritable set, so that anything we exec() loses the capability for
255
                 * good. */
256
                CLEAR_BIT(q.inheritable, i);
72,100✔
257

258
                /* If we shall apply this right now drop it also from our own capability sets. */
259
                if (right_now) {
72,100✔
260
                        CLEAR_BIT(q.effective, i);
2,114✔
261
                        CLEAR_BIT(q.permitted, i);
2,114✔
262
                }
263
        }
264

265
        r = 0;
266

267
finish:
2,409✔
268
        k = capability_apply(&q);
2,409✔
269
        if (k < 0)
2,409✔
270
                /* If there are no actual changes anyway then let's ignore this error. */
271
                if (!capability_quintet_equal(&q, &saved))
×
272
                        return k;
×
273

274
        return r;
275
}
276

277
static int drop_from_file(const char *fn, uint64_t keep) {
×
278
        _cleanup_free_ char *p = NULL;
×
279
        uint64_t current, after;
×
280
        uint32_t hi, lo;
×
281
        int r, k;
×
282

283
        r = read_one_line_file(fn, &p);
×
284
        if (r < 0)
×
285
                return r;
286

287
        k = sscanf(p, "%" PRIu32 " %" PRIu32, &lo, &hi);
×
288
        if (k != 2)
×
289
                return -EIO;
290

291
        current = (uint64_t) lo | ((uint64_t) hi << 32);
×
292
        after = current & keep;
×
293

294
        if (current == after)
×
295
                return 0;
296

297
        lo = after & UINT32_MAX;
×
298
        hi = (after >> 32) & UINT32_MAX;
×
299

300
        return write_string_filef(fn, 0, "%" PRIu32 " %" PRIu32, lo, hi);
×
301
}
302

303
int capability_bounding_set_drop_usermode(uint64_t keep) {
×
304
        int r;
×
305

306
        r = drop_from_file("/proc/sys/kernel/usermodehelper/inheritable", keep);
×
307
        if (r < 0)
×
308
                return r;
309

310
        r = drop_from_file("/proc/sys/kernel/usermodehelper/bset", keep);
×
311
        if (r < 0)
×
312
                return r;
×
313

314
        return r;
315
}
316

317
int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) {
30✔
318
        int r;
30✔
319

320
        /* Unfortunately we cannot leave privilege dropping to PID 1 here, since we want to run as user but
321
         * want to keep some capabilities. Since file capabilities have been introduced this cannot be done
322
         * across exec() anymore, unless our binary has the capability configured in the file system, which
323
         * we want to avoid. */
324

325
        if (setresgid(gid, gid, gid) < 0)
30✔
326
                return log_error_errno(errno, "Failed to change group ID: %m");
1✔
327

328
        r = maybe_setgroups(/* size= */ 0, /* list= */ NULL);
29✔
329
        if (r < 0)
29✔
330
                return log_error_errno(r, "Failed to drop auxiliary groups list: %m");
1✔
331

332
        /* Ensure we keep the permitted caps across the setresuid(). Note that we do this even if we actually
333
         * don't want to keep any capabilities, since we want to be able to drop them from the bounding set
334
         * too, and we can only do that if we have capabilities. */
335
        if (prctl(PR_SET_KEEPCAPS, 1) < 0)
28✔
336
                return log_error_errno(errno, "Failed to enable keep capabilities flag: %m");
×
337

338
        if (setresuid(uid, uid, uid) < 0)
28✔
339
                return log_error_errno(errno, "Failed to change user ID: %m");
×
340

341
        if (prctl(PR_SET_KEEPCAPS, 0) < 0)
28✔
342
                return log_error_errno(errno, "Failed to disable keep capabilities flag: %m");
×
343

344
        /* Drop all caps from the bounding set (as well as the inheritable/permitted/effective sets), except
345
         * the ones we want to keep */
346
        r = capability_bounding_set_drop(keep_capabilities, /* right_now= */ true);
28✔
347
        if (r < 0)
28✔
348
                return log_error_errno(r, "Failed to drop capabilities: %m");
×
349

350
        /* Now upgrade the permitted caps we still kept to effective caps */
351
        if (keep_capabilities != 0) {
28✔
352
                CapabilityQuintet q = {
4✔
353
                        .effective = keep_capabilities,
354
                        .permitted = keep_capabilities,
355
                };
356

357
                r = capability_apply(&q);
4✔
358
                if (r < 0)
4✔
359
                        return log_error_errno(r, "Failed to increase capabilities: %m");
×
360
        }
361

362
        return 0;
363
}
364

365
static int change_capability(unsigned cap, bool b) {
3,637✔
366
        CapabilityQuintet q;
3,637✔
367
        int r;
3,637✔
368

369
        assert(cap <= CAP_LIMIT);
3,637✔
370

371
        r = capability_get(&q);
3,637✔
372
        if (r < 0)
3,637✔
373
                return r;
3,637✔
374

375
        if (b) {
3,637✔
376
                SET_BIT(q.effective, cap);
1,394✔
377
                SET_BIT(q.permitted, cap);
1,394✔
378
                SET_BIT(q.inheritable, cap);
1,394✔
379
        } else {
380
                CLEAR_BIT(q.effective, cap);
2,243✔
381
                CLEAR_BIT(q.permitted, cap);
2,243✔
382
                CLEAR_BIT(q.inheritable, cap);
2,243✔
383
        }
384

385
        return capability_apply(&q);
3,637✔
386
}
387

388
int drop_capability(unsigned cap) {
2,243✔
389
        return change_capability(cap, false);
2,243✔
390
}
391

392
int keep_capability(unsigned cap) {
1,394✔
393
        return change_capability(cap, true);
1,394✔
394
}
395

396
bool capability_quintet_mangle(CapabilityQuintet *q) {
121✔
397
        uint64_t combined, drop = 0;
121✔
398

399
        assert(q);
121✔
400

401
        combined = q->effective | q->bounding | q->inheritable | q->permitted | q->ambient;
121✔
402

403
        for (unsigned i = 0; i <= cap_last_cap(); i++) {
5,082✔
404
                if (!BIT_SET(combined, i))
4,961✔
405
                        continue;
1,785✔
406

407
                if (prctl(PR_CAPBSET_READ, (unsigned long) i) > 0)
3,176✔
408
                        continue;
3,176✔
409

410
                SET_BIT(drop, i);
×
411

412
                log_debug("Dropping capability not in the current bounding set: %s", capability_to_name(i));
×
413
        }
414

415
        q->effective &= ~drop;
121✔
416
        q->bounding &= ~drop;
121✔
417
        q->inheritable &= ~drop;
121✔
418
        q->permitted &= ~drop;
121✔
419
        q->ambient &= ~drop;
121✔
420

421
        return drop != 0; /* Let the caller know we changed something */
121✔
422
}
423

424
int capability_quintet_enforce(const CapabilityQuintet *q) {
121✔
425
        CapabilityQuintet c;
121✔
426
        bool modified = false;
121✔
427
        int r;
121✔
428

429
        if (q->ambient != CAP_MASK_UNSET ||
121✔
430
            q->inheritable != CAP_MASK_UNSET ||
×
431
            q->permitted != CAP_MASK_UNSET ||
×
432
            q->effective != CAP_MASK_UNSET) {
×
433
                r = capability_get(&c);
121✔
434
                if (r < 0)
121✔
435
                        return r;
121✔
436
        }
437

438
        if (q->ambient != CAP_MASK_UNSET) {
121✔
439
                /* In order to raise the ambient caps set we first need to raise the matching
440
                 * inheritable + permitted cap */
441
                if (!FLAGS_SET(c.permitted, q->ambient) ||
121✔
442
                    !FLAGS_SET(c.inheritable, q->ambient)) {
121✔
443

444
                        c.permitted |= q->ambient;
1✔
445
                        c.inheritable |= q->ambient;
1✔
446

447
                        r = capability_apply(&c);
1✔
448
                        if (r < 0)
1✔
449
                                return r;
450
                }
451

452
                r = capability_ambient_set_apply(q->ambient, /* also_inherit= */ false);
121✔
453
                if (r < 0)
121✔
454
                        return r;
455
        }
456

457
        if (q->inheritable != CAP_MASK_UNSET || q->permitted != CAP_MASK_UNSET || q->effective != CAP_MASK_UNSET) {
121✔
458
                if (!FLAGS_SET(c.effective, q->effective) ||
120✔
459
                    !FLAGS_SET(c.permitted, q->permitted) ||
120✔
460
                    !FLAGS_SET(c.inheritable, q->inheritable)) {
120✔
461

462
                        c.effective |= q->effective;
117✔
463
                        c.permitted |= q->permitted;
117✔
464
                        c.inheritable |= q->inheritable;
117✔
465

466
                        /* Now, let's enforce the caps for the first time. Note that this is where we acquire
467
                         * caps in any of the sets we currently don't have. We have to do this before
468
                         * dropping the bounding caps below, since at that point we can never acquire new
469
                         * caps in inherited/permitted/effective anymore, but only lose them.
470
                         *
471
                         * In order to change the bounding caps, we need to keep CAP_SETPCAP for a bit
472
                         * longer. Let's add it to our list hence for now. */
473
                        if (q->bounding != CAP_MASK_UNSET &&
117✔
474
                            (!BIT_SET(c.effective, CAP_SETPCAP) || !BIT_SET(c.permitted, CAP_SETPCAP))) {
117✔
475
                                CapabilityQuintet tmp = c;
×
476

477
                                SET_BIT(c.effective, CAP_SETPCAP);
×
478
                                SET_BIT(c.permitted, CAP_SETPCAP);
×
479

480
                                modified = true;
×
481

482
                                r = capability_apply(&tmp);
×
483
                        } else
484
                                r = capability_apply(&c);
117✔
485
                        if (r < 0)
117✔
486
                                return r;
487
                }
488
        }
489

490
        if (q->bounding != CAP_MASK_UNSET) {
121✔
491
                r = capability_bounding_set_drop(q->bounding, /* right_now= */ false);
120✔
492
                if (r < 0)
120✔
493
                        return r;
494
        }
495

496
        /* If needed, let's now set the caps again, this time in the final version, which differs from what
497
         * we have already set only in the CAP_SETPCAP bit, which we needed for dropping the bounding
498
         * bits. This call only undoes bits and doesn't acquire any which means the bounding caps don't
499
         * matter. */
500
        if (modified) {
121✔
501
                r = capability_apply(&c);
×
502
                if (r < 0)
×
503
                        return r;
×
504
        }
505

506
        return 0;
507
}
508

509
int capability_get_ambient(uint64_t *ret) {
747✔
510
        uint64_t a = 0;
747✔
511
        int r;
747✔
512

513
        assert(ret);
747✔
514

515
        for (unsigned i = 0; i <= cap_last_cap(); i++) {
31,374✔
516
                r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0);
30,627✔
517
                if (r < 0)
30,627✔
518
                        return -errno;
×
519
                if (r > 0)
30,627✔
520
                        SET_BIT(a, i);
109✔
521
        }
522

523
        *ret = a;
747✔
524
        return 1;
747✔
525
}
526

527
int pidref_get_capability(const PidRef *pidref, CapabilityQuintet *ret) {
14,553✔
528
        int r;
14,553✔
529

530
        if (!pidref_is_set(pidref))
14,553✔
531
                return -ESRCH;
14,553✔
532
        if (pidref_is_remote(pidref))
14,553✔
533
                return -EREMOTE;
534

535
        const char *path = procfs_file_alloca(pidref->pid, "status");
14,553✔
536
        _cleanup_fclose_ FILE *f = fopen(path, "re");
29,106✔
537
        if (!f) {
14,553✔
538
                if (errno == ENOENT && proc_mounted() == 0)
4,356✔
539
                        return -ENOSYS;
540

541
                return -errno;
4,356✔
542
        }
543

544
        CapabilityQuintet q = CAPABILITY_QUINTET_NULL;
10,197✔
545
        for (;;) {
1,242,095✔
546
                _cleanup_free_ char *line = NULL;
615,952✔
547

548
                r = read_line(f, LONG_LINE_MAX, &line);
626,146✔
549
                if (r < 0)
626,146✔
550
                        return r;
551
                if (r == 0)
626,143✔
552
                        break;
553

554
                static const struct {
555
                        const char *field;
556
                        size_t offset;
557
                } fields[] = {
558
                        { "CapBnd:", offsetof(CapabilityQuintet, bounding)    },
559
                        { "CapInh:", offsetof(CapabilityQuintet, inheritable) },
560
                        { "CapPrm:", offsetof(CapabilityQuintet, permitted)   },
561
                        { "CapEff:", offsetof(CapabilityQuintet, effective)   },
562
                        { "CapAmb:", offsetof(CapabilityQuintet, ambient)     },
563
                };
564

565
                FOREACH_ELEMENT(i, fields) {
3,695,694✔
566

567
                        const char *p = first_word(line, i->field);
3,079,745✔
568
                        if (!p)
3,079,745✔
569
                                continue;
3,028,775✔
570

571
                        uint64_t *v = (uint64_t*) ((uint8_t*) &q + i->offset);
50,970✔
572

573
                        if (*v != CAP_MASK_UNSET)
50,970✔
574
                                return -EBADMSG;
575

576
                        r = safe_atoux64(p, v);
50,970✔
577
                        if (r < 0)
50,970✔
578
                                return r;
579

580
                        if (*v == CAP_MASK_UNSET)
50,970✔
581
                                return -EBADMSG;
582
                }
583
        }
584

585
        if (!capability_quintet_is_fully_set(&q))
10,194✔
586
                return -EBADMSG;
587

588
        r = pidref_verify(pidref);
10,194✔
589
        if (r < 0)
10,194✔
590
                return r;
591

592
        if (ret)
10,194✔
593
                *ret = q;
10,194✔
594

595
        return 0;
596
}
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