1 /* SPDX-License-Identifier: LGPL-2.1+ */
7 #include <sys/capability.h>
11 #include "alloc-util.h"
12 #include "capability-util.h"
16 #include "missing_prctl.h"
17 #include "parse-util.h"
18 #include "user-util.h"
21 int have_effective_cap(int value
) {
22 _cleanup_cap_free_ cap_t cap
;
29 if (cap_get_flag(cap
, value
, CAP_EFFECTIVE
, &fv
) < 0)
35 unsigned long cap_last_cap(void) {
36 static thread_local
unsigned long saved
;
37 static thread_local
bool valid
= false;
38 _cleanup_free_
char *content
= NULL
;
45 /* available since linux-3.2 */
46 r
= read_one_line_file("/proc/sys/kernel/cap_last_cap", &content
);
48 r
= safe_atolu(content
, &p
);
56 /* fall back to syscall-probing for pre linux-3.2 */
57 p
= (unsigned long) CAP_LAST_CAP
;
59 if (prctl(PR_CAPBSET_READ
, p
) < 0) {
61 /* Hmm, look downwards, until we find one that
63 for (p
--; p
> 0; p
--)
64 if (prctl(PR_CAPBSET_READ
, p
) >= 0)
69 /* Hmm, look upwards, until we find one that doesn't
72 if (prctl(PR_CAPBSET_READ
, p
+1) < 0)
82 int capability_update_inherited_set(cap_t caps
, uint64_t set
) {
85 /* Add capabilities in the set to the inherited caps. Do not apply
88 for (i
= 0; i
< cap_last_cap(); i
++) {
90 if (set
& (UINT64_C(1) << i
)) {
95 /* Make the capability inheritable. */
96 if (cap_set_flag(caps
, CAP_INHERITABLE
, 1, &v
, CAP_SET
) < 0)
104 int capability_ambient_set_apply(uint64_t set
, bool also_inherit
) {
106 _cleanup_cap_free_ cap_t caps
= NULL
;
108 /* Add the capabilities to the ambient set. */
112 caps
= cap_get_proc();
116 r
= capability_update_inherited_set(caps
, set
);
120 if (cap_set_proc(caps
) < 0)
124 for (i
= 0; i
< cap_last_cap(); i
++) {
126 if (set
& (UINT64_C(1) << i
)) {
128 /* Add the capability to the ambient set. */
129 if (prctl(PR_CAP_AMBIENT
, PR_CAP_AMBIENT_RAISE
, i
, 0, 0) < 0)
137 int capability_bounding_set_drop(uint64_t keep
, bool right_now
) {
138 _cleanup_cap_free_ cap_t before_cap
= NULL
, after_cap
= NULL
;
143 /* If we are run as PID 1 we will lack CAP_SETPCAP by default
144 * in the effective set (yes, the kernel drops that when
145 * executing init!), so get it back temporarily so that we can
146 * call PR_CAPBSET_DROP. */
148 before_cap
= cap_get_proc();
152 if (cap_get_flag(before_cap
, CAP_SETPCAP
, CAP_EFFECTIVE
, &fv
) < 0)
156 _cleanup_cap_free_ cap_t temp_cap
= NULL
;
157 static const cap_value_t v
= CAP_SETPCAP
;
159 temp_cap
= cap_dup(before_cap
);
163 if (cap_set_flag(temp_cap
, CAP_EFFECTIVE
, 1, &v
, CAP_SET
) < 0)
166 if (cap_set_proc(temp_cap
) < 0)
167 log_debug_errno(errno
, "Can't acquire effective CAP_SETPCAP bit, ignoring: %m");
169 /* If we didn't manage to acquire the CAP_SETPCAP bit, we continue anyway, after all this just means
170 * we'll fail later, when we actually intend to drop some capabilities. */
173 after_cap
= cap_dup(before_cap
);
177 for (i
= 0; i
<= cap_last_cap(); i
++) {
180 if ((keep
& (UINT64_C(1) << i
)))
183 /* Drop it from the bounding set */
184 if (prctl(PR_CAPBSET_DROP
, i
) < 0) {
187 /* If dropping the capability failed, let's see if we didn't have it in the first place. If so,
188 * continue anyway, as dropping a capability we didn't have in the first place doesn't really
190 if (prctl(PR_CAPBSET_READ
, i
) != 0)
195 /* Also drop it from the inheritable set, so
196 * that anything we exec() loses the
197 * capability for good. */
198 if (cap_set_flag(after_cap
, CAP_INHERITABLE
, 1, &v
, CAP_CLEAR
) < 0) {
203 /* If we shall apply this right now drop it
204 * also from our own capability sets. */
206 if (cap_set_flag(after_cap
, CAP_PERMITTED
, 1, &v
, CAP_CLEAR
) < 0 ||
207 cap_set_flag(after_cap
, CAP_EFFECTIVE
, 1, &v
, CAP_CLEAR
) < 0) {
217 if (cap_set_proc(after_cap
) < 0) {
218 /* If there are no actual changes anyway then let's ignore this error. */
219 if (cap_compare(before_cap
, after_cap
) != 0)
226 static int drop_from_file(const char *fn
, uint64_t keep
) {
227 _cleanup_free_
char *p
= NULL
;
228 uint64_t current
, after
;
232 r
= read_one_line_file(fn
, &p
);
236 assert_cc(sizeof(hi
) == sizeof(unsigned));
237 assert_cc(sizeof(lo
) == sizeof(unsigned));
239 k
= sscanf(p
, "%u %u", &lo
, &hi
);
243 current
= (uint64_t) lo
| ((uint64_t) hi
<< 32ULL);
244 after
= current
& keep
;
246 if (current
== after
)
249 lo
= (unsigned) (after
& 0xFFFFFFFFULL
);
250 hi
= (unsigned) ((after
>> 32ULL) & 0xFFFFFFFFULL
);
252 return write_string_filef(fn
, WRITE_STRING_FILE_CREATE
, "%u %u", lo
, hi
);
255 int capability_bounding_set_drop_usermode(uint64_t keep
) {
258 r
= drop_from_file("/proc/sys/kernel/usermodehelper/inheritable", keep
);
262 r
= drop_from_file("/proc/sys/kernel/usermodehelper/bset", keep
);
269 int drop_privileges(uid_t uid
, gid_t gid
, uint64_t keep_capabilities
) {
270 _cleanup_cap_free_ cap_t d
= NULL
;
274 /* Unfortunately we cannot leave privilege dropping to PID 1
275 * here, since we want to run as user but want to keep some
276 * capabilities. Since file capabilities have been introduced
277 * this cannot be done across exec() anymore, unless our
278 * binary has the capability configured in the file system,
279 * which we want to avoid. */
281 if (setresgid(gid
, gid
, gid
) < 0)
282 return log_error_errno(errno
, "Failed to change group ID: %m");
284 r
= maybe_setgroups(0, NULL
);
286 return log_error_errno(r
, "Failed to drop auxiliary groups list: %m");
288 /* Ensure we keep the permitted caps across the setresuid() */
289 if (prctl(PR_SET_KEEPCAPS
, 1) < 0)
290 return log_error_errno(errno
, "Failed to enable keep capabilities flag: %m");
292 if (setresuid(uid
, uid
, uid
) < 0)
293 return log_error_errno(errno
, "Failed to change user ID: %m");
295 if (prctl(PR_SET_KEEPCAPS
, 0) < 0)
296 return log_error_errno(errno
, "Failed to disable keep capabilities flag: %m");
298 /* Drop all caps from the bounding set, except the ones we want */
299 r
= capability_bounding_set_drop(keep_capabilities
, true);
301 return log_error_errno(r
, "Failed to drop capabilities: %m");
303 /* Now upgrade the permitted caps we still kept to effective caps */
308 if (keep_capabilities
) {
309 cap_value_t bits
[u64log2(keep_capabilities
) + 1];
311 for (i
= 0; i
< ELEMENTSOF(bits
); i
++)
312 if (keep_capabilities
& (1ULL << i
))
315 /* use enough bits */
316 assert(i
== 64 || (keep_capabilities
>> i
) == 0);
317 /* don't use too many bits */
318 assert(keep_capabilities
& (1ULL << (i
- 1)));
320 if (cap_set_flag(d
, CAP_EFFECTIVE
, j
, bits
, CAP_SET
) < 0 ||
321 cap_set_flag(d
, CAP_PERMITTED
, j
, bits
, CAP_SET
) < 0)
322 return log_error_errno(errno
, "Failed to enable capabilities bits: %m");
324 if (cap_set_proc(d
) < 0)
325 return log_error_errno(errno
, "Failed to increase capabilities: %m");
331 int drop_capability(cap_value_t cv
) {
332 _cleanup_cap_free_ cap_t tmp_cap
= NULL
;
334 tmp_cap
= cap_get_proc();
338 if ((cap_set_flag(tmp_cap
, CAP_INHERITABLE
, 1, &cv
, CAP_CLEAR
) < 0) ||
339 (cap_set_flag(tmp_cap
, CAP_PERMITTED
, 1, &cv
, CAP_CLEAR
) < 0) ||
340 (cap_set_flag(tmp_cap
, CAP_EFFECTIVE
, 1, &cv
, CAP_CLEAR
) < 0))
343 if (cap_set_proc(tmp_cap
) < 0)
349 bool ambient_capabilities_supported(void) {
350 static int cache
= -1;
355 /* If PR_CAP_AMBIENT returns something valid, or an unexpected error code we assume that ambient caps are
358 cache
= prctl(PR_CAP_AMBIENT
, PR_CAP_AMBIENT_IS_SET
, CAP_KILL
, 0, 0) >= 0 ||
359 !IN_SET(errno
, EINVAL
, EOPNOTSUPP
, ENOSYS
);
364 int capability_quintet_enforce(const CapabilityQuintet
*q
) {
365 _cleanup_cap_free_ cap_t c
= NULL
;
368 if (q
->ambient
!= (uint64_t) -1) {
370 bool changed
= false;
376 /* In order to raise the ambient caps set we first need to raise the matching inheritable + permitted
378 for (i
= 0; i
<= cap_last_cap(); i
++) {
379 uint64_t m
= UINT64_C(1) << i
;
380 cap_value_t cv
= (cap_value_t
) i
;
381 cap_flag_value_t old_value_inheritable
, old_value_permitted
;
383 if ((q
->ambient
& m
) == 0)
386 if (cap_get_flag(c
, cv
, CAP_INHERITABLE
, &old_value_inheritable
) < 0)
388 if (cap_get_flag(c
, cv
, CAP_PERMITTED
, &old_value_permitted
) < 0)
391 if (old_value_inheritable
== CAP_SET
&& old_value_permitted
== CAP_SET
)
394 if (cap_set_flag(c
, CAP_INHERITABLE
, 1, &cv
, CAP_SET
) < 0)
397 if (cap_set_flag(c
, CAP_PERMITTED
, 1, &cv
, CAP_SET
) < 0)
404 if (cap_set_proc(c
) < 0)
407 r
= capability_ambient_set_apply(q
->ambient
, false);
412 if (q
->inheritable
!= (uint64_t) -1 || q
->permitted
!= (uint64_t) -1 || q
->effective
!= (uint64_t) -1) {
413 bool changed
= false;
422 for (i
= 0; i
<= cap_last_cap(); i
++) {
423 uint64_t m
= UINT64_C(1) << i
;
424 cap_value_t cv
= (cap_value_t
) i
;
426 if (q
->inheritable
!= (uint64_t) -1) {
427 cap_flag_value_t old_value
, new_value
;
429 if (cap_get_flag(c
, cv
, CAP_INHERITABLE
, &old_value
) < 0)
432 new_value
= (q
->inheritable
& m
) ? CAP_SET
: CAP_CLEAR
;
434 if (old_value
!= new_value
) {
437 if (cap_set_flag(c
, CAP_INHERITABLE
, 1, &cv
, new_value
) < 0)
442 if (q
->permitted
!= (uint64_t) -1) {
443 cap_flag_value_t old_value
, new_value
;
445 if (cap_get_flag(c
, cv
, CAP_PERMITTED
, &old_value
) < 0)
448 new_value
= (q
->permitted
& m
) ? CAP_SET
: CAP_CLEAR
;
450 if (old_value
!= new_value
) {
453 if (cap_set_flag(c
, CAP_PERMITTED
, 1, &cv
, new_value
) < 0)
458 if (q
->effective
!= (uint64_t) -1) {
459 cap_flag_value_t old_value
, new_value
;
461 if (cap_get_flag(c
, cv
, CAP_EFFECTIVE
, &old_value
) < 0)
464 new_value
= (q
->effective
& m
) ? CAP_SET
: CAP_CLEAR
;
466 if (old_value
!= new_value
) {
469 if (cap_set_flag(c
, CAP_EFFECTIVE
, 1, &cv
, new_value
) < 0)
476 if (cap_set_proc(c
) < 0)
480 if (q
->bounding
!= (uint64_t) -1) {
481 r
= capability_bounding_set_drop(q
->bounding
, false);