Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/virtio/fs/caps.rs
5394 views
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
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" {
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)]
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 {
81
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 {
94
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 {
106
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.
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
160
impl 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
}
168
169