]> git.proxmox.com Git - pve-lxc-syscalld.git/blame - src/capability.rs
refactor 'pidfd.rs' into a process module
[pve-lxc-syscalld.git] / src / capability.rs
CommitLineData
738dbfbe 1use std::io;
3bbd1db0 2use std::os::raw::{c_int, c_ulong};
738dbfbe 3
738dbfbe
WB
4bitflags::bitflags! {
5 pub struct SecureBits: c_ulong {
bd05b957
WB
6 const NOROOT = 0b0_0000_0001;
7 const NOROOT_LOCKED = 0b0_0000_0010;
8 const NO_SETUID_FIXUP = 0b0_0000_0100;
9 const NO_SETUID_FIXUP_LOCKED = 0b0_0000_1000;
10 const KEEP_CAPS = 0b0_0001_0000;
11 const KEEP_CAPS_LOCKED = 0b0_0010_0000;
12 const NO_CAP_AMBIENT_RAISE = 0b0_0100_0000;
13 const NO_CAP_AMBIENT_RAISE_LOCKED = 0b0_1000_0000;
738dbfbe 14
bd05b957
WB
15 const ALL_BITS = 0b0_0101_0101;
16 const ALL_LOCKS = 0b0_1010_1010;
738dbfbe
WB
17 }
18}
19
20impl SecureBits {
baedb4ca 21 pub fn apply(self) -> io::Result<()> {
738dbfbe
WB
22 c_call!(unsafe { libc::prctl(libc::PR_SET_SECUREBITS, self.bits()) })?;
23 Ok(())
24 }
25
26 pub fn get_current() -> io::Result<Self> {
27 let bits = c_call!(unsafe { libc::prctl(libc::PR_GET_SECUREBITS) })?;
28 Self::from_bits(bits as _)
29 .ok_or_else(|| io_format_err!("prctl() returned unknown securebits"))
30 }
31}
3bbd1db0
WB
32
33#[derive(Clone, Default)]
34pub struct Capabilities {
35 pub inheritable: u64,
36 pub permitted: u64,
37 pub effective: u64,
38 //bounding: u64, // we don't care currently
39}
40
41// Too lazy to bindgen libcap stuff...
42const CAPABILITY_VERSION_3: u32 = 0x2008_0522;
43
44/// Represents process capabilities.
45///
46/// This can be used to change the process' capability sets (if permitted by the kernel).
47impl Capabilities {
48 // We currently don't implement capget as it takes a pid which is racy on kernels without pidfd
49 // support. Later on we might support a `capget(&PidFd)` method?
50
51 /// Change our process capabilities. This does not include the bounding set.
52 pub fn capset(&self) -> io::Result<()> {
53 #![allow(dead_code)]
54 // kernel abi:
55 struct Header {
56 version: u32,
57 pid: c_int,
58 }
59
60 struct Data {
61 effective: u32,
62 permitted: u32,
63 inheritable: u32,
64 }
65
66 let header = Header {
67 version: CAPABILITY_VERSION_3,
68 pid: 0, // equivalent to gettid(),
69 };
70
71 let data = [
72 Data {
73 effective: self.effective as u32,
74 permitted: self.permitted as u32,
75 inheritable: self.inheritable as u32,
76 },
77 Data {
78 effective: (self.effective >> 32) as u32,
79 permitted: (self.permitted >> 32) as u32,
80 inheritable: (self.inheritable >> 32) as u32,
81 },
82 ];
83
84 c_try!(unsafe { libc::syscall(libc::SYS_capset, &header, &data) });
85
86 Ok(())
87 }
88}