2019-07-15 10:05:58 +03:00
use std ::io ;
2019-10-21 15:04:50 +03:00
use std ::os ::raw ::{ c_int , c_ulong } ;
2019-07-15 10:05:58 +03:00
bitflags ::bitflags! {
pub struct SecureBits : c_ulong {
2019-09-03 13:45:29 +03:00
const NOROOT = 0b0_0000_0001 ;
const NOROOT_LOCKED = 0b0_0000_0010 ;
const NO_SETUID_FIXUP = 0b0_0000_0100 ;
const NO_SETUID_FIXUP_LOCKED = 0b0_0000_1000 ;
const KEEP_CAPS = 0b0_0001_0000 ;
const KEEP_CAPS_LOCKED = 0b0_0010_0000 ;
const NO_CAP_AMBIENT_RAISE = 0b0_0100_0000 ;
const NO_CAP_AMBIENT_RAISE_LOCKED = 0b0_1000_0000 ;
2019-07-15 10:05:58 +03:00
2019-09-03 13:45:29 +03:00
const ALL_BITS = 0b0_0101_0101 ;
const ALL_LOCKS = 0b0_1010_1010 ;
2019-07-15 10:05:58 +03:00
}
}
impl SecureBits {
2019-09-04 10:46:31 +03:00
pub fn apply ( self ) -> io ::Result < ( ) > {
2019-10-30 13:16:53 +03:00
c_result! ( unsafe { libc ::prctl ( libc ::PR_SET_SECUREBITS , self . bits ( ) ) } ) ? ;
2019-07-15 10:05:58 +03:00
Ok ( ( ) )
}
pub fn get_current ( ) -> io ::Result < Self > {
2019-10-30 13:16:53 +03:00
let bits = c_result! ( unsafe { libc ::prctl ( libc ::PR_GET_SECUREBITS ) } ) ? ;
2019-07-15 10:05:58 +03:00
Self ::from_bits ( bits as _ )
. ok_or_else ( | | io_format_err! ( " prctl() returned unknown securebits " ) )
}
}
2019-10-21 15:04:50 +03:00
#[ derive(Clone, Default) ]
pub struct Capabilities {
pub inheritable : u64 ,
pub permitted : u64 ,
pub effective : u64 ,
//bounding: u64, // we don't care currently
}
// Too lazy to bindgen libcap stuff...
const CAPABILITY_VERSION_3 : u32 = 0x2008_0522 ;
/// Represents process capabilities.
///
/// This can be used to change the process' capability sets (if permitted by the kernel).
impl Capabilities {
// We currently don't implement capget as it takes a pid which is racy on kernels without pidfd
// support. Later on we might support a `capget(&PidFd)` method?
/// Change our process capabilities. This does not include the bounding set.
pub fn capset ( & self ) -> io ::Result < ( ) > {
// kernel abi:
2020-01-21 13:12:50 +03:00
#[ allow(dead_code) ]
2019-10-21 15:04:50 +03:00
struct Header {
version : u32 ,
pid : c_int ,
}
2020-01-21 13:12:50 +03:00
#[ allow(dead_code) ]
2019-10-21 15:04:50 +03:00
struct Data {
effective : u32 ,
permitted : u32 ,
inheritable : u32 ,
}
let header = Header {
version : CAPABILITY_VERSION_3 ,
pid : 0 , // equivalent to gettid(),
} ;
let data = [
Data {
effective : self . effective as u32 ,
permitted : self . permitted as u32 ,
inheritable : self . inheritable as u32 ,
} ,
Data {
effective : ( self . effective > > 32 ) as u32 ,
permitted : ( self . permitted > > 32 ) as u32 ,
inheritable : ( self . inheritable > > 32 ) as u32 ,
} ,
] ;
c_try! ( unsafe { libc ::syscall ( libc ::SYS_capset , & header , & data ) } ) ;
Ok ( ( ) )
}
}