2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <sys/capability.h>
25 #include <sys/prctl.h>
28 #include "alloc-util.h"
29 #include "capability-util.h"
33 #include "parse-util.h"
34 #include "user-util.h"
37 int have_effective_cap(int value
) {
38 _cleanup_cap_free_ cap_t cap
;
45 if (cap_get_flag(cap
, value
, CAP_EFFECTIVE
, &fv
) < 0)
51 unsigned long cap_last_cap(void) {
52 static thread_local
unsigned long saved
;
53 static thread_local
bool valid
= false;
54 _cleanup_free_
char *content
= NULL
;
61 /* available since linux-3.2 */
62 r
= read_one_line_file("/proc/sys/kernel/cap_last_cap", &content
);
64 r
= safe_atolu(content
, &p
);
72 /* fall back to syscall-probing for pre linux-3.2 */
73 p
= (unsigned long) CAP_LAST_CAP
;
75 if (prctl(PR_CAPBSET_READ
, p
) < 0) {
77 /* Hmm, look downwards, until we find one that
79 for (p
--; p
> 0; p
--)
80 if (prctl(PR_CAPBSET_READ
, p
) >= 0)
85 /* Hmm, look upwards, until we find one that doesn't
88 if (prctl(PR_CAPBSET_READ
, p
+1) < 0)
98 int capability_update_inherited_set(cap_t caps
, uint64_t set
) {
101 /* Add capabilities in the set to the inherited caps. Do not apply
104 for (i
= 0; i
< cap_last_cap(); i
++) {
106 if (set
& (UINT64_C(1) << i
)) {
111 /* Make the capability inheritable. */
112 if (cap_set_flag(caps
, CAP_INHERITABLE
, 1, &v
, CAP_SET
) < 0)
120 int capability_ambient_set_apply(uint64_t set
, bool also_inherit
) {
122 _cleanup_cap_free_ cap_t caps
= NULL
;
124 /* Add the capabilities to the ambient set. */
128 caps
= cap_get_proc();
132 r
= capability_update_inherited_set(caps
, set
);
136 if (cap_set_proc(caps
) < 0)
140 for (i
= 0; i
< cap_last_cap(); i
++) {
142 if (set
& (UINT64_C(1) << i
)) {
144 /* Add the capability to the ambient set. */
145 if (prctl(PR_CAP_AMBIENT
, PR_CAP_AMBIENT_RAISE
, i
, 0, 0) < 0)
153 int capability_bounding_set_drop(uint64_t keep
, bool right_now
) {
154 _cleanup_cap_free_ cap_t before_cap
= NULL
, after_cap
= NULL
;
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. */
164 before_cap
= cap_get_proc();
168 if (cap_get_flag(before_cap
, CAP_SETPCAP
, CAP_EFFECTIVE
, &fv
) < 0)
172 _cleanup_cap_free_ cap_t temp_cap
= NULL
;
173 static const cap_value_t v
= CAP_SETPCAP
;
175 temp_cap
= cap_dup(before_cap
);
179 if (cap_set_flag(temp_cap
, CAP_EFFECTIVE
, 1, &v
, CAP_SET
) < 0)
182 if (cap_set_proc(temp_cap
) < 0)
183 log_debug_errno(errno
, "Can't acquire effective CAP_SETPCAP bit, ignoring: %m");
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. */
189 after_cap
= cap_dup(before_cap
);
193 for (i
= 0; i
<= cap_last_cap(); i
++) {
196 if ((keep
& (UINT64_C(1) << i
)))
199 /* Drop it from the bounding set */
200 if (prctl(PR_CAPBSET_DROP
, i
) < 0) {
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
206 if (prctl(PR_CAPBSET_READ
, i
) != 0)
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) {
219 /* If we shall apply this right now drop it
220 * also from our own capability sets. */
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) {
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)
242 static int drop_from_file(const char *fn
, uint64_t keep
) {
245 uint64_t current
, after
;
248 r
= read_one_line_file(fn
, &p
);
252 assert_cc(sizeof(hi
) == sizeof(unsigned));
253 assert_cc(sizeof(lo
) == sizeof(unsigned));
255 k
= sscanf(p
, "%u %u", &lo
, &hi
);
261 current
= (uint64_t) lo
| ((uint64_t) hi
<< 32ULL);
262 after
= current
& keep
;
264 if (current
== after
)
267 lo
= (unsigned) (after
& 0xFFFFFFFFULL
);
268 hi
= (unsigned) ((after
>> 32ULL) & 0xFFFFFFFFULL
);
270 if (asprintf(&p
, "%u %u", lo
, hi
) < 0)
273 r
= write_string_file(fn
, p
, WRITE_STRING_FILE_CREATE
);
279 int capability_bounding_set_drop_usermode(uint64_t keep
) {
282 r
= drop_from_file("/proc/sys/kernel/usermodehelper/inheritable", keep
);
286 r
= drop_from_file("/proc/sys/kernel/usermodehelper/bset", keep
);
293 int drop_privileges(uid_t uid
, gid_t gid
, uint64_t keep_capabilities
) {
294 _cleanup_cap_free_ cap_t d
= NULL
;
298 /* Unfortunately we cannot leave privilege dropping to PID 1
299 * here, since we want to run as user but want to keep some
300 * capabilities. Since file capabilities have been introduced
301 * this cannot be done across exec() anymore, unless our
302 * binary has the capability configured in the file system,
303 * which we want to avoid. */
305 if (setresgid(gid
, gid
, gid
) < 0)
306 return log_error_errno(errno
, "Failed to change group ID: %m");
308 r
= maybe_setgroups(0, NULL
);
310 return log_error_errno(r
, "Failed to drop auxiliary groups list: %m");
312 /* Ensure we keep the permitted caps across the setresuid() */
313 if (prctl(PR_SET_KEEPCAPS
, 1) < 0)
314 return log_error_errno(errno
, "Failed to enable keep capabilities flag: %m");
316 r
= setresuid(uid
, uid
, uid
);
318 return log_error_errno(errno
, "Failed to change user ID: %m");
320 if (prctl(PR_SET_KEEPCAPS
, 0) < 0)
321 return log_error_errno(errno
, "Failed to disable keep capabilities flag: %m");
323 /* Drop all caps from the bounding set, except the ones we want */
324 r
= capability_bounding_set_drop(keep_capabilities
, true);
326 return log_error_errno(r
, "Failed to drop capabilities: %m");
328 /* Now upgrade the permitted caps we still kept to effective caps */
333 if (keep_capabilities
) {
334 cap_value_t bits
[u64log2(keep_capabilities
) + 1];
336 for (i
= 0; i
< ELEMENTSOF(bits
); i
++)
337 if (keep_capabilities
& (1ULL << i
))
340 /* use enough bits */
341 assert(i
== 64 || (keep_capabilities
>> i
) == 0);
342 /* don't use too many bits */
343 assert(keep_capabilities
& (1ULL << (i
- 1)));
345 if (cap_set_flag(d
, CAP_EFFECTIVE
, j
, bits
, CAP_SET
) < 0 ||
346 cap_set_flag(d
, CAP_PERMITTED
, j
, bits
, CAP_SET
) < 0)
347 return log_error_errno(errno
, "Failed to enable capabilities bits: %m");
349 if (cap_set_proc(d
) < 0)
350 return log_error_errno(errno
, "Failed to increase capabilities: %m");
356 int drop_capability(cap_value_t cv
) {
357 _cleanup_cap_free_ cap_t tmp_cap
= NULL
;
359 tmp_cap
= cap_get_proc();
363 if ((cap_set_flag(tmp_cap
, CAP_INHERITABLE
, 1, &cv
, CAP_CLEAR
) < 0) ||
364 (cap_set_flag(tmp_cap
, CAP_PERMITTED
, 1, &cv
, CAP_CLEAR
) < 0) ||
365 (cap_set_flag(tmp_cap
, CAP_EFFECTIVE
, 1, &cv
, CAP_CLEAR
) < 0))
368 if (cap_set_proc(tmp_cap
) < 0)
374 bool ambient_capabilities_supported(void) {
375 static int cache
= -1;
380 /* If PR_CAP_AMBIENT returns something valid, or an unexpected error code we assume that ambient caps are
383 cache
= prctl(PR_CAP_AMBIENT
, PR_CAP_AMBIENT_IS_SET
, CAP_KILL
, 0, 0) >= 0 ||
384 !IN_SET(errno
, EINVAL
, EOPNOTSUPP
, ENOSYS
);