1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#[allow(missing_docs)]
#[repr(u8)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Capability
{
AuditControl = capability::CAP_AUDIT_CONTROL as u8,
AuditRead = capability::CAP_AUDIT_READ as u8,
AuditWrite = capability::CAP_AUDIT_WRITE as u8,
BlockSuspend = capability::CAP_BLOCK_SUSPEND as u8,
Chown = capability::CAP_CHOWN as u8,
DiscretionaryAccessControlBypass = capability::CAP_DAC_OVERRIDE as u8,
DiscretionaryAccessControlFileReadBypass = capability::CAP_DAC_READ_SEARCH as u8,
FileOwnerBypass = capability::CAP_FOWNER as u8,
FileSetId = capability::CAP_FSETID as u8,
LockMemory = capability::CAP_IPC_LOCK as u8,
IpcOwner = capability::CAP_IPC_OWNER as u8,
Kill = capability::CAP_KILL as u8,
Lease = capability::CAP_LEASE as u8,
Immutable = capability::CAP_LINUX_IMMUTABLE as u8,
MandatoryAccessControlBypass = capability::CAP_MAC_ADMIN as u8,
MandatoryAccessControlOverride = capability::CAP_MAC_OVERRIDE as u8,
MakeNodes = capability::CAP_MKNOD as u8,
SystemAdministration = capability::CAP_SYS_ADMIN as u8,
NetworkAdministration = capability::CAP_NET_ADMIN as u8,
BindPortsBelow1024 = capability::CAP_NET_BIND_SERVICE as u8,
NetRaw = capability::CAP_NET_RAW as u8,
SetUid = capability::CAP_SETUID as u8,
SetGid = capability::CAP_SETGID as u8,
SetFileCapabilities = capability::CAP_SETFCAP as u8,
SetProcessCapabilities = capability::CAP_SETPCAP as u8,
RebootAndKexecLoad = capability::CAP_SYS_BOOT as u8,
Chroot = capability::CAP_SYS_CHROOT as u8,
KernelModule = capability::CAP_SYS_MODULE as u8,
Nice = capability::CAP_SYS_NICE as u8,
ProcessAccounting = capability::CAP_SYS_PACCT as u8,
PTrace = capability::CAP_SYS_PTRACE as u8,
RawIO = capability::CAP_SYS_RAWIO as u8,
Resource = capability::CAP_SYS_RESOURCE as u8,
Time = capability::CAP_SYS_TIME as u8,
TtyConfig = capability::CAP_SYS_TTY_CONFIG as u8,
Syslog = capability::CAP_SYSLOG as u8,
WakeAlarm = capability::CAP_WAKE_ALARM as u8,
}
impl Capability
{
pub fn clear_all_ambient_capabilities()
{
unsafe { prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0) };
}
pub fn ensure_capabilities_dropped(drop_these_capabilities_if_current_process_has_them: &[Capability])
{
for capability_to_drop in drop_these_capabilities_if_current_process_has_them
{
if capability_to_drop.current_process_has().unwrap_or(false)
{
capability_to_drop.drop_from_current_process().unwrap_or(());
}
}
}
pub fn current_process_has(&self) -> Option<bool>
{
match unsafe { prctl(PR_CAPBSET_READ, *self as c_ulong) }
{
1 => Some(true),
0 => Some(false),
-1 => match errno().0
{
E::EINVAL => None,
illegal @ _ => panic!("Illegal error code '{}' from prctl()", illegal),
},
illegal @ _ => panic!("prctl() returned illegal result '{}'", illegal),
}
}
pub fn drop_from_current_process(&self) -> Result<(), ()>
{
match unsafe { prctl(PR_CAPBSET_DROP, *self as c_ulong) }
{
0 => Ok(()),
-1 => match errno().0
{
E::EPERM => Err(()),
E::EINVAL => panic!("Kernel does not support 'file' capabilities"),
illegal @ _ => panic!("Illegal error code '{}' from prctl()", illegal),
},
illegal @ _ => panic!("prctl() returned illegal result '{}'", illegal),
}
}
}