caps/
ambient.rs

1//! Implementation of Ambient set.
2
3use crate::errors::CapsError;
4use crate::nr;
5use crate::runtime;
6use crate::{Capability, CapsHashSet};
7use std::io::Error;
8
9pub fn clear() -> Result<(), CapsError> {
10    let ret = unsafe { libc::prctl(nr::PR_CAP_AMBIENT, nr::PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0) };
11    match ret {
12        0 => Ok(()),
13        _ => Err(format!(
14            "PR_CAP_AMBIENT_CLEAR_ALL failure: {}",
15            Error::last_os_error()
16        )
17        .into()),
18    }
19}
20
21pub fn drop(cap: Capability) -> Result<(), CapsError> {
22    let ret = unsafe {
23        libc::prctl(
24            nr::PR_CAP_AMBIENT,
25            nr::PR_CAP_AMBIENT_LOWER,
26            libc::c_uint::from(cap.index()),
27            0,
28            0,
29        )
30    };
31    match ret {
32        0 => Ok(()),
33        _ => Err(format!("PR_CAP_AMBIENT_LOWER failure: {}", Error::last_os_error()).into()),
34    }
35}
36
37pub fn has_cap(cap: Capability) -> Result<bool, CapsError> {
38    let ret = unsafe {
39        libc::prctl(
40            nr::PR_CAP_AMBIENT,
41            nr::PR_CAP_AMBIENT_IS_SET,
42            libc::c_uint::from(cap.index()),
43            0,
44            0,
45        )
46    };
47    match ret {
48        0 => Ok(false),
49        1 => Ok(true),
50        _ => Err(format!("PR_CAP_AMBIENT_IS_SET failure: {}", Error::last_os_error()).into()),
51    }
52}
53
54pub fn raise(cap: Capability) -> Result<(), CapsError> {
55    let ret = unsafe {
56        libc::prctl(
57            nr::PR_CAP_AMBIENT,
58            nr::PR_CAP_AMBIENT_RAISE,
59            libc::c_uint::from(cap.index()),
60            0,
61            0,
62        )
63    };
64    match ret {
65        0 => Ok(()),
66        _ => Err(format!("PR_CAP_AMBIENT_RAISE failure: {}", Error::last_os_error()).into()),
67    }
68}
69
70pub fn read() -> Result<CapsHashSet, CapsError> {
71    let mut res = super::CapsHashSet::new();
72    for c in runtime::thread_all_supported() {
73        if has_cap(c)? {
74            res.insert(c);
75        }
76    }
77    Ok(res)
78}
79
80pub fn set(value: &super::CapsHashSet) -> Result<(), CapsError> {
81    for c in runtime::thread_all_supported() {
82        if value.contains(&c) {
83            raise(c)?;
84        } else {
85            drop(c)?;
86        };
87    }
88    Ok(())
89}