• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2021 The Chromium OS Authors. All rights reserved.
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 std::ffi::c_void;
6 use std::io;
7 use std::os::raw::c_int;
8 
9 #[allow(non_camel_case_types)]
10 type cap_t = *mut c_void;
11 
12 #[allow(non_camel_case_types)]
13 pub type cap_value_t = u32;
14 
15 #[allow(non_camel_case_types)]
16 type cap_flag_t = u32;
17 
18 #[allow(non_camel_case_types)]
19 type cap_flag_value_t = i32;
20 
21 #[link(name = "cap")]
22 extern "C" {
cap_free(ptr: *mut c_void) -> c_int23     fn cap_free(ptr: *mut c_void) -> c_int;
24 
cap_set_flag( c: cap_t, f: cap_flag_t, ncap: c_int, caps: *const cap_value_t, val: cap_flag_value_t, ) -> c_int25     fn cap_set_flag(
26         c: cap_t,
27         f: cap_flag_t,
28         ncap: c_int,
29         caps: *const cap_value_t,
30         val: cap_flag_value_t,
31     ) -> c_int;
32 
cap_get_proc() -> cap_t33     fn cap_get_proc() -> cap_t;
cap_set_proc(cap: cap_t) -> c_int34     fn cap_set_proc(cap: cap_t) -> c_int;
35 }
36 
37 #[repr(u32)]
38 pub enum Capability {
39     Chown = 0,
40     DacOverride = 1,
41     DacReadSearch = 2,
42     Fowner = 3,
43     Fsetid = 4,
44     Kill = 5,
45     Setgid = 6,
46     Setuid = 7,
47     Setpcap = 8,
48     LinuxImmutable = 9,
49     NetBindService = 10,
50     NetBroadcast = 11,
51     NetAdmin = 12,
52     NetRaw = 13,
53     IpcLock = 14,
54     IpcOwner = 15,
55     SysModule = 16,
56     SysRawio = 17,
57     SysChroot = 18,
58     SysPtrace = 19,
59     SysPacct = 20,
60     SysAdmin = 21,
61     SysBoot = 22,
62     SysNice = 23,
63     SysResource = 24,
64     SysTime = 25,
65     SysTtyConfig = 26,
66     Mknod = 27,
67     Lease = 28,
68     AuditWrite = 29,
69     AuditControl = 30,
70     Setfcap = 31,
71     MacOverride = 32,
72     MacAdmin = 33,
73     Syslog = 34,
74     WakeAlarm = 35,
75     BlockSuspend = 36,
76     AuditRead = 37,
77     Last,
78 }
79 
80 impl From<Capability> for cap_value_t {
from(c: Capability) -> cap_value_t81     fn from(c: Capability) -> cap_value_t {
82         c as cap_value_t
83     }
84 }
85 
86 #[repr(u32)]
87 pub enum Set {
88     Effective = 0,
89     Permitted = 1,
90     Inheritable = 2,
91 }
92 
93 impl From<Set> for cap_flag_t {
from(s: Set) -> cap_flag_t94     fn from(s: Set) -> cap_flag_t {
95         s as cap_flag_t
96     }
97 }
98 
99 #[repr(i32)]
100 pub enum Value {
101     Clear = 0,
102     Set = 1,
103 }
104 
105 impl From<Value> for cap_flag_value_t {
from(v: Value) -> cap_flag_value_t106     fn from(v: Value) -> cap_flag_value_t {
107         v as cap_flag_value_t
108     }
109 }
110 
111 pub struct Caps(cap_t);
112 
113 impl Caps {
114     /// Get the capabilities for the current thread.
for_current_thread() -> io::Result<Caps>115     pub fn for_current_thread() -> io::Result<Caps> {
116         // Safe because this doesn't modify any memory and we check the return value.
117         let caps = unsafe { cap_get_proc() };
118         if caps.is_null() {
119             Err(io::Error::last_os_error())
120         } else {
121             Ok(Caps(caps))
122         }
123     }
124 
125     /// Update the capabilities described by `self` by setting or clearing `caps` in `set`.
update(&mut self, caps: &[Capability], set: Set, value: Value) -> io::Result<()>126     pub fn update(&mut self, caps: &[Capability], set: Set, value: Value) -> io::Result<()> {
127         // Safe because this only modifies the memory pointed to by `self.0` and we check the return
128         // value.
129         let ret = unsafe {
130             cap_set_flag(
131                 self.0,
132                 set.into(),
133                 caps.len() as c_int,
134                 // It's safe to cast this pointer because `Capability` is #[repr(u32)]
135                 caps.as_ptr() as *const cap_value_t,
136                 value.into(),
137             )
138         };
139 
140         if ret == 0 {
141             Ok(())
142         } else {
143             Err(io::Error::last_os_error())
144         }
145     }
146 
147     /// Apply the capabilities described by `self` to the current thread.
apply(&self) -> io::Result<()>148     pub fn apply(&self) -> io::Result<()> {
149         if unsafe { cap_set_proc(self.0) } == 0 {
150             Ok(())
151         } else {
152             Err(io::Error::last_os_error())
153         }
154     }
155 }
156 
157 impl Drop for Caps {
drop(&mut self)158     fn drop(&mut self) {
159         unsafe {
160             cap_free(self.0);
161         }
162     }
163 }
164