]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/capability-util.c
Merge pull request #14853 from floppym/issue9806
[thirdparty/systemd.git] / src / basic / capability-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <errno.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <sys/prctl.h>
7 #include <unistd.h>
8
9 #include "alloc-util.h"
10 #include "capability-util.h"
11 #include "cap-list.h"
12 #include "fileio.h"
13 #include "log.h"
14 #include "macro.h"
15 #include "missing_prctl.h"
16 #include "parse-util.h"
17 #include "user-util.h"
18 #include "util.h"
19
20 int have_effective_cap(int value) {
21 _cleanup_cap_free_ cap_t cap;
22 cap_flag_value_t fv;
23
24 cap = cap_get_proc();
25 if (!cap)
26 return -errno;
27
28 if (cap_get_flag(cap, value, CAP_EFFECTIVE, &fv) < 0)
29 return -errno;
30
31 return fv == CAP_SET;
32 }
33
34 unsigned long cap_last_cap(void) {
35 static thread_local unsigned long saved;
36 static thread_local bool valid = false;
37 _cleanup_free_ char *content = NULL;
38 unsigned long p = 0;
39 int r;
40
41 if (valid)
42 return saved;
43
44 /* available since linux-3.2 */
45 r = read_one_line_file("/proc/sys/kernel/cap_last_cap", &content);
46 if (r >= 0) {
47 r = safe_atolu(content, &p);
48 if (r >= 0) {
49
50 if (p > 63) /* Safety for the future: if one day the kernel learns more than 64 caps,
51 * then we are in trouble (since we, as much userspace and kernel space
52 * store capability masks in uint64_t types). Let's hence protect
53 * ourselves against that and always cap at 63 for now. */
54 p = 63;
55
56 saved = p;
57 valid = true;
58 return p;
59 }
60 }
61
62 /* fall back to syscall-probing for pre linux-3.2 */
63 p = MIN((unsigned long) CAP_LAST_CAP, 63U);
64
65 if (prctl(PR_CAPBSET_READ, p) < 0) {
66
67 /* Hmm, look downwards, until we find one that works */
68 for (p--; p > 0; p --)
69 if (prctl(PR_CAPBSET_READ, p) >= 0)
70 break;
71
72 } else {
73
74 /* Hmm, look upwards, until we find one that doesn't work */
75 for (; p < 63; p++)
76 if (prctl(PR_CAPBSET_READ, p+1) < 0)
77 break;
78 }
79
80 saved = p;
81 valid = true;
82
83 return p;
84 }
85
86 int capability_update_inherited_set(cap_t caps, uint64_t set) {
87 unsigned long i;
88
89 /* Add capabilities in the set to the inherited caps, drops capabilities not in the set.
90 * Do not apply them yet. */
91
92 for (i = 0; i <= cap_last_cap(); i++) {
93 cap_flag_value_t flag = set & (UINT64_C(1) << i) ? CAP_SET : CAP_CLEAR;
94 cap_value_t v;
95
96 v = (cap_value_t) i;
97
98 if (cap_set_flag(caps, CAP_INHERITABLE, 1, &v, flag) < 0)
99 return -errno;
100 }
101
102 return 0;
103 }
104
105 int capability_ambient_set_apply(uint64_t set, bool also_inherit) {
106 _cleanup_cap_free_ cap_t caps = NULL;
107 unsigned long i;
108 int r;
109
110 /* Check that we can use PR_CAP_AMBIENT or quit early. */
111 if (!ambient_capabilities_supported())
112 return 0;
113
114 /* Add the capabilities to the ambient set. */
115
116 if (also_inherit) {
117 caps = cap_get_proc();
118 if (!caps)
119 return -errno;
120
121 r = capability_update_inherited_set(caps, set);
122 if (r < 0)
123 return -errno;
124
125 if (cap_set_proc(caps) < 0)
126 return -errno;
127 }
128
129 for (i = 0; i <= cap_last_cap(); i++) {
130
131 if (set & (UINT64_C(1) << i)) {
132
133 /* Add the capability to the ambient set. */
134 if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, i, 0, 0) < 0)
135 return -errno;
136 } else {
137
138 /* Drop the capability so we don't inherit capabilities we didn't ask for. */
139 r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, i, 0, 0);
140 if (r < 0)
141 return -errno;
142
143 if (r)
144 if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_LOWER, i, 0, 0) < 0)
145 return -errno;
146
147 }
148 }
149
150 return 0;
151 }
152
153 int capability_bounding_set_drop(uint64_t keep, bool right_now) {
154 _cleanup_cap_free_ cap_t before_cap = NULL, after_cap = NULL;
155 cap_flag_value_t fv;
156 unsigned long i;
157 int r;
158
159 /* If we are run as PID 1 we will lack CAP_SETPCAP by default
160 * in the effective set (yes, the kernel drops that when
161 * executing init!), so get it back temporarily so that we can
162 * call PR_CAPBSET_DROP. */
163
164 before_cap = cap_get_proc();
165 if (!before_cap)
166 return -errno;
167
168 if (cap_get_flag(before_cap, CAP_SETPCAP, CAP_EFFECTIVE, &fv) < 0)
169 return -errno;
170
171 if (fv != CAP_SET) {
172 _cleanup_cap_free_ cap_t temp_cap = NULL;
173 static const cap_value_t v = CAP_SETPCAP;
174
175 temp_cap = cap_dup(before_cap);
176 if (!temp_cap)
177 return -errno;
178
179 if (cap_set_flag(temp_cap, CAP_EFFECTIVE, 1, &v, CAP_SET) < 0)
180 return -errno;
181
182 if (cap_set_proc(temp_cap) < 0)
183 log_debug_errno(errno, "Can't acquire effective CAP_SETPCAP bit, ignoring: %m");
184
185 /* If we didn't manage to acquire the CAP_SETPCAP bit, we continue anyway, after all this just means
186 * we'll fail later, when we actually intend to drop some capabilities. */
187 }
188
189 after_cap = cap_dup(before_cap);
190 if (!after_cap)
191 return -errno;
192
193 for (i = 0; i <= cap_last_cap(); i++) {
194 cap_value_t v;
195
196 if ((keep & (UINT64_C(1) << i)))
197 continue;
198
199 /* Drop it from the bounding set */
200 if (prctl(PR_CAPBSET_DROP, i) < 0) {
201 r = -errno;
202
203 /* If dropping the capability failed, let's see if we didn't have it in the first place. If so,
204 * continue anyway, as dropping a capability we didn't have in the first place doesn't really
205 * matter anyway. */
206 if (prctl(PR_CAPBSET_READ, i) != 0)
207 goto finish;
208 }
209 v = (cap_value_t) i;
210
211 /* Also drop it from the inheritable set, so
212 * that anything we exec() loses the
213 * capability for good. */
214 if (cap_set_flag(after_cap, CAP_INHERITABLE, 1, &v, CAP_CLEAR) < 0) {
215 r = -errno;
216 goto finish;
217 }
218
219 /* If we shall apply this right now drop it
220 * also from our own capability sets. */
221 if (right_now) {
222 if (cap_set_flag(after_cap, CAP_PERMITTED, 1, &v, CAP_CLEAR) < 0 ||
223 cap_set_flag(after_cap, CAP_EFFECTIVE, 1, &v, CAP_CLEAR) < 0) {
224 r = -errno;
225 goto finish;
226 }
227 }
228 }
229
230 r = 0;
231
232 finish:
233 if (cap_set_proc(after_cap) < 0) {
234 /* If there are no actual changes anyway then let's ignore this error. */
235 if (cap_compare(before_cap, after_cap) != 0)
236 r = -errno;
237 }
238
239 return r;
240 }
241
242 static int drop_from_file(const char *fn, uint64_t keep) {
243 _cleanup_free_ char *p = NULL;
244 uint64_t current, after;
245 uint32_t hi, lo;
246 int r, k;
247
248 r = read_one_line_file(fn, &p);
249 if (r < 0)
250 return r;
251
252 k = sscanf(p, "%" PRIu32 " %" PRIu32, &lo, &hi);
253 if (k != 2)
254 return -EIO;
255
256 current = (uint64_t) lo | ((uint64_t) hi << 32);
257 after = current & keep;
258
259 if (current == after)
260 return 0;
261
262 lo = after & UINT32_C(0xFFFFFFFF);
263 hi = (after >> 32) & UINT32_C(0xFFFFFFFF);
264
265 return write_string_filef(fn, 0, "%" PRIu32 " %" PRIu32, lo, hi);
266 }
267
268 int capability_bounding_set_drop_usermode(uint64_t keep) {
269 int r;
270
271 r = drop_from_file("/proc/sys/kernel/usermodehelper/inheritable", keep);
272 if (r < 0)
273 return r;
274
275 r = drop_from_file("/proc/sys/kernel/usermodehelper/bset", keep);
276 if (r < 0)
277 return r;
278
279 return r;
280 }
281
282 int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) {
283 int r;
284
285 /* Unfortunately we cannot leave privilege dropping to PID 1 here, since we want to run as user but
286 * want to keep some capabilities. Since file capabilities have been introduced this cannot be done
287 * across exec() anymore, unless our binary has the capability configured in the file system, which
288 * we want to avoid. */
289
290 if (setresgid(gid, gid, gid) < 0)
291 return log_error_errno(errno, "Failed to change group ID: %m");
292
293 r = maybe_setgroups(0, NULL);
294 if (r < 0)
295 return log_error_errno(r, "Failed to drop auxiliary groups list: %m");
296
297 /* Ensure we keep the permitted caps across the setresuid(). Note that we do this even if we actually
298 * don't want to keep any capabilities, since we want to be able to drop them from the bounding set
299 * too, and we can only do that if we have capabilities. */
300 if (prctl(PR_SET_KEEPCAPS, 1) < 0)
301 return log_error_errno(errno, "Failed to enable keep capabilities flag: %m");
302
303 if (setresuid(uid, uid, uid) < 0)
304 return log_error_errno(errno, "Failed to change user ID: %m");
305
306 if (prctl(PR_SET_KEEPCAPS, 0) < 0)
307 return log_error_errno(errno, "Failed to disable keep capabilities flag: %m");
308
309 /* Drop all caps from the bounding set (as well as the inheritable/permitted/effective sets), except
310 * the ones we want to keep */
311 r = capability_bounding_set_drop(keep_capabilities, true);
312 if (r < 0)
313 return log_error_errno(r, "Failed to drop capabilities: %m");
314
315 /* Now upgrade the permitted caps we still kept to effective caps */
316 if (keep_capabilities != 0) {
317 cap_value_t bits[u64log2(keep_capabilities) + 1];
318 _cleanup_cap_free_ cap_t d = NULL;
319 unsigned i, j = 0;
320
321 d = cap_init();
322 if (!d)
323 return log_oom();
324
325 for (i = 0; i < ELEMENTSOF(bits); i++)
326 if (keep_capabilities & (1ULL << i))
327 bits[j++] = i;
328
329 /* use enough bits */
330 assert(i == 64 || (keep_capabilities >> i) == 0);
331 /* don't use too many bits */
332 assert(keep_capabilities & (UINT64_C(1) << (i - 1)));
333
334 if (cap_set_flag(d, CAP_EFFECTIVE, j, bits, CAP_SET) < 0 ||
335 cap_set_flag(d, CAP_PERMITTED, j, bits, CAP_SET) < 0)
336 return log_error_errno(errno, "Failed to enable capabilities bits: %m");
337
338 if (cap_set_proc(d) < 0)
339 return log_error_errno(errno, "Failed to increase capabilities: %m");
340 }
341
342 return 0;
343 }
344
345 int drop_capability(cap_value_t cv) {
346 _cleanup_cap_free_ cap_t tmp_cap = NULL;
347
348 tmp_cap = cap_get_proc();
349 if (!tmp_cap)
350 return -errno;
351
352 if ((cap_set_flag(tmp_cap, CAP_INHERITABLE, 1, &cv, CAP_CLEAR) < 0) ||
353 (cap_set_flag(tmp_cap, CAP_PERMITTED, 1, &cv, CAP_CLEAR) < 0) ||
354 (cap_set_flag(tmp_cap, CAP_EFFECTIVE, 1, &cv, CAP_CLEAR) < 0))
355 return -errno;
356
357 if (cap_set_proc(tmp_cap) < 0)
358 return -errno;
359
360 return 0;
361 }
362
363 bool ambient_capabilities_supported(void) {
364 static int cache = -1;
365
366 if (cache >= 0)
367 return cache;
368
369 /* If PR_CAP_AMBIENT returns something valid, or an unexpected error code we assume that ambient caps are
370 * available. */
371
372 cache = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET, CAP_KILL, 0, 0) >= 0 ||
373 !IN_SET(errno, EINVAL, EOPNOTSUPP, ENOSYS);
374
375 return cache;
376 }
377
378 bool capability_quintet_mangle(CapabilityQuintet *q) {
379 unsigned long i;
380 uint64_t combined, drop = 0;
381 bool ambient_supported;
382
383 assert(q);
384
385 combined = q->effective | q->bounding | q->inheritable | q->permitted;
386
387 ambient_supported = q->ambient != (uint64_t) -1;
388 if (ambient_supported)
389 combined |= q->ambient;
390
391 for (i = 0; i <= cap_last_cap(); i++) {
392 unsigned long bit = UINT64_C(1) << i;
393 if (!FLAGS_SET(combined, bit))
394 continue;
395
396 if (prctl(PR_CAPBSET_READ, i) > 0)
397 continue;
398
399 drop |= bit;
400
401 log_debug("Not in the current bounding set: %s", capability_to_name(i));
402 }
403
404 q->effective &= ~drop;
405 q->bounding &= ~drop;
406 q->inheritable &= ~drop;
407 q->permitted &= ~drop;
408
409 if (ambient_supported)
410 q->ambient &= ~drop;
411
412 return drop != 0; /* Let the caller know we changed something */
413 }
414
415 int capability_quintet_enforce(const CapabilityQuintet *q) {
416 _cleanup_cap_free_ cap_t c = NULL, modified = NULL;
417 int r;
418
419 if (q->ambient != (uint64_t) -1) {
420 unsigned long i;
421 bool changed = false;
422
423 c = cap_get_proc();
424 if (!c)
425 return -errno;
426
427 /* In order to raise the ambient caps set we first need to raise the matching inheritable + permitted
428 * cap */
429 for (i = 0; i <= cap_last_cap(); i++) {
430 uint64_t m = UINT64_C(1) << i;
431 cap_value_t cv = (cap_value_t) i;
432 cap_flag_value_t old_value_inheritable, old_value_permitted;
433
434 if ((q->ambient & m) == 0)
435 continue;
436
437 if (cap_get_flag(c, cv, CAP_INHERITABLE, &old_value_inheritable) < 0)
438 return -errno;
439 if (cap_get_flag(c, cv, CAP_PERMITTED, &old_value_permitted) < 0)
440 return -errno;
441
442 if (old_value_inheritable == CAP_SET && old_value_permitted == CAP_SET)
443 continue;
444
445 if (cap_set_flag(c, CAP_INHERITABLE, 1, &cv, CAP_SET) < 0)
446 return -errno;
447 if (cap_set_flag(c, CAP_PERMITTED, 1, &cv, CAP_SET) < 0)
448 return -errno;
449
450 changed = true;
451 }
452
453 if (changed)
454 if (cap_set_proc(c) < 0)
455 return -errno;
456
457 r = capability_ambient_set_apply(q->ambient, false);
458 if (r < 0)
459 return r;
460 }
461
462 if (q->inheritable != (uint64_t) -1 || q->permitted != (uint64_t) -1 || q->effective != (uint64_t) -1) {
463 bool changed = false;
464 unsigned long i;
465
466 if (!c) {
467 c = cap_get_proc();
468 if (!c)
469 return -errno;
470 }
471
472 for (i = 0; i <= cap_last_cap(); i++) {
473 uint64_t m = UINT64_C(1) << i;
474 cap_value_t cv = (cap_value_t) i;
475
476 if (q->inheritable != (uint64_t) -1) {
477 cap_flag_value_t old_value, new_value;
478
479 if (cap_get_flag(c, cv, CAP_INHERITABLE, &old_value) < 0) {
480 if (errno == EINVAL) /* If the kernel knows more caps than this
481 * version of libcap, then this will return
482 * EINVAL. In that case, simply ignore it,
483 * pretend it doesn't exist. */
484 continue;
485
486 return -errno;
487 }
488
489 new_value = (q->inheritable & m) ? CAP_SET : CAP_CLEAR;
490
491 if (old_value != new_value) {
492 changed = true;
493
494 if (cap_set_flag(c, CAP_INHERITABLE, 1, &cv, new_value) < 0)
495 return -errno;
496 }
497 }
498
499 if (q->permitted != (uint64_t) -1) {
500 cap_flag_value_t old_value, new_value;
501
502 if (cap_get_flag(c, cv, CAP_PERMITTED, &old_value) < 0) {
503 if (errno == EINVAL)
504 continue;
505
506 return -errno;
507 }
508
509 new_value = (q->permitted & m) ? CAP_SET : CAP_CLEAR;
510
511 if (old_value != new_value) {
512 changed = true;
513
514 if (cap_set_flag(c, CAP_PERMITTED, 1, &cv, new_value) < 0)
515 return -errno;
516 }
517 }
518
519 if (q->effective != (uint64_t) -1) {
520 cap_flag_value_t old_value, new_value;
521
522 if (cap_get_flag(c, cv, CAP_EFFECTIVE, &old_value) < 0) {
523 if (errno == EINVAL)
524 continue;
525
526 return -errno;
527 }
528
529 new_value = (q->effective & m) ? CAP_SET : CAP_CLEAR;
530
531 if (old_value != new_value) {
532 changed = true;
533
534 if (cap_set_flag(c, CAP_EFFECTIVE, 1, &cv, new_value) < 0)
535 return -errno;
536 }
537 }
538 }
539
540 if (changed) {
541 /* In order to change the bounding caps, we need to keep CAP_SETPCAP for a bit
542 * longer. Let's add it to our list hence for now. */
543 if (q->bounding != (uint64_t) -1) {
544 cap_value_t cv = CAP_SETPCAP;
545
546 modified = cap_dup(c);
547 if (!modified)
548 return -ENOMEM;
549
550 if (cap_set_flag(modified, CAP_PERMITTED, 1, &cv, CAP_SET) < 0)
551 return -errno;
552 if (cap_set_flag(modified, CAP_EFFECTIVE, 1, &cv, CAP_SET) < 0)
553 return -errno;
554
555 if (cap_compare(modified, c) == 0) {
556 /* No change? then drop this nonsense again */
557 cap_free(modified);
558 modified = NULL;
559 }
560 }
561
562 /* Now, let's enforce the caps for the first time. Note that this is where we acquire
563 * caps in any of the sets we currently don't have. We have to do this before
564 * dropping the bounding caps below, since at that point we can never acquire new
565 * caps in inherited/permitted/effective anymore, but only lose them. */
566 if (cap_set_proc(modified ?: c) < 0)
567 return -errno;
568 }
569 }
570
571 if (q->bounding != (uint64_t) -1) {
572 r = capability_bounding_set_drop(q->bounding, false);
573 if (r < 0)
574 return r;
575 }
576
577 /* If needed, let's now set the caps again, this time in the final version, which differs from what
578 * we have already set only in the CAP_SETPCAP bit, which we needed for dropping the bounding
579 * bits. This call only undoes bits and doesn't acquire any which means the bounding caps don't
580 * matter. */
581 if (modified)
582 if (cap_set_proc(c) < 0)
583 return -errno;
584
585 return 0;
586 }