xref: /aosp_15_r20/external/crosvm/base/src/sys/linux/capabilities.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1 // Copyright 2019 The ChromiumOS Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 use libc::c_int;
6 use libc::c_void;
7 
8 use super::errno_result;
9 use super::Result;
10 
11 #[allow(non_camel_case_types)]
12 type cap_t = *mut c_void;
13 
14 #[link(name = "cap")]
15 extern "C" {
cap_init() -> cap_t16     fn cap_init() -> cap_t;
cap_free(ptr: *mut c_void) -> c_int17     fn cap_free(ptr: *mut c_void) -> c_int;
cap_set_proc(cap: cap_t) -> c_int18     fn cap_set_proc(cap: cap_t) -> c_int;
19 }
20 
21 /// Drops all capabilities (permitted, inheritable, and effective) from the current process.
drop_capabilities() -> Result<()>22 pub fn drop_capabilities() -> Result<()> {
23     // SAFETY:
24     // Safe because we do not actually manipulate any memory handled by libcap
25     // and we check errors.
26     unsafe {
27         let caps = cap_init();
28         if caps.is_null() {
29             return errno_result();
30         }
31 
32         // Freshly initialized capabilities do not have any bits set, so applying them
33         // will drop all capabilities from the process.
34         // Safe because we will check the result and otherwise do not touch the memory.
35         let ret = cap_set_proc(caps);
36         // We need to free capabilities regardless of success of the operation above.
37         cap_free(caps);
38         // Now check if we managed to apply (drop) capabilities.
39         if ret < 0 {
40             return errno_result();
41         }
42     }
43     Ok(())
44 }
45