devices/virtio/fs/
caps.rs

1// Copyright 2021 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
5use std::ffi::c_void;
6use std::io;
7use std::os::raw::c_int;
8
9#[allow(non_camel_case_types)]
10type cap_t = *mut c_void;
11
12#[allow(non_camel_case_types)]
13pub type cap_value_t = u32;
14
15#[allow(non_camel_case_types)]
16type cap_flag_t = u32;
17
18#[allow(non_camel_case_types)]
19type cap_flag_value_t = i32;
20
21#[link(name = "cap")]
22extern "C" {
23    fn cap_free(ptr: *mut c_void) -> c_int;
24
25    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
33    fn cap_get_proc() -> cap_t;
34    fn cap_set_proc(cap: cap_t) -> c_int;
35}
36
37#[repr(u32)]
38pub 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
80impl From<Capability> for cap_value_t {
81    fn from(c: Capability) -> cap_value_t {
82        c as cap_value_t
83    }
84}
85
86#[repr(u32)]
87pub enum Set {
88    Effective = 0,
89    Permitted = 1,
90    Inheritable = 2,
91}
92
93impl From<Set> for cap_flag_t {
94    fn from(s: Set) -> cap_flag_t {
95        s as cap_flag_t
96    }
97}
98
99#[repr(i32)]
100pub enum Value {
101    Clear = 0,
102    Set = 1,
103}
104
105impl From<Value> for cap_flag_value_t {
106    fn from(v: Value) -> cap_flag_value_t {
107        v as cap_flag_value_t
108    }
109}
110
111pub struct Caps(cap_t);
112
113impl Caps {
114    /// Get the capabilities for the current thread.
115    pub fn for_current_thread() -> io::Result<Caps> {
116        // SAFETY:
117        // Safe because this doesn't modify any memory and we check the return value.
118        let caps = unsafe { cap_get_proc() };
119        if caps.is_null() {
120            Err(io::Error::last_os_error())
121        } else {
122            Ok(Caps(caps))
123        }
124    }
125
126    /// Update the capabilities described by `self` by setting or clearing `caps` in `set`.
127    pub fn update(&mut self, caps: &[Capability], set: Set, value: Value) -> io::Result<()> {
128        // SAFETY:
129        // Safe because this only modifies the memory pointed to by `self.0` and we check the return
130        // value.
131        let ret = unsafe {
132            cap_set_flag(
133                self.0,
134                set.into(),
135                caps.len() as c_int,
136                // It's safe to cast this pointer because `Capability` is #[repr(u32)]
137                caps.as_ptr() as *const cap_value_t,
138                value.into(),
139            )
140        };
141
142        if ret == 0 {
143            Ok(())
144        } else {
145            Err(io::Error::last_os_error())
146        }
147    }
148
149    /// Apply the capabilities described by `self` to the current thread.
150    pub fn apply(&self) -> io::Result<()> {
151        // SAFETY: trivially safe
152        if unsafe { cap_set_proc(self.0) } == 0 {
153            Ok(())
154        } else {
155            Err(io::Error::last_os_error())
156        }
157    }
158}
159
160impl Drop for Caps {
161    fn drop(&mut self) {
162        // SAFETY: cap_t is allocated from `Self`
163        unsafe {
164            cap_free(self.0);
165        }
166    }
167}