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
#[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 clearAllAmbientCapabilities()
{
unsafe { prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0) };
}
pub fn ensureDropped(dropTheseCapabilitiesIfEnabled: &[Capability])
{
for capabilityToDrop in dropTheseCapabilitiesIfEnabled
{
if capabilityToDrop.processHas().unwrap_or(false)
{
capabilityToDrop.dropFromProcess().unwrap_or(());
}
}
}
pub fn processHas(&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 dropFromProcess(&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),
}
}
}