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
use crate::errors::*;
#[cfg(target_os = "linux")]
use caps::{self, CapSet};
#[cfg(target_os = "linux")]
use nix;

#[cfg(target_os = "openbsd")]
use pledge::pledge;
#[cfg(target_os = "openbsd")]
use unveil::unveil;

#[cfg(target_os = "linux")]
pub mod seccomp;

#[cfg(target_os = "linux")]
static CHROOT: &str = "/var/empty";


#[cfg(target_os = "linux")]
/// Drop all privileges that are only needed to setup the sandbox
pub fn fasten_seatbelt() -> Result<()> {
    info!("Dropping all capabilities");
    caps::clear(None, CapSet::Effective)
        .map_err(|_| format_err!("Failed to clear effective capability set"))?;
    caps::clear(None, CapSet::Permitted)
        .map_err(|_| format_err!("Failed to clear permitted capability set"))?;
    Ok(())
}

#[cfg(not(target_os = "linux"))]
pub fn fasten_seatbelt() -> Result<()> {
    Ok(())
}

pub fn init() -> Result<()> {
    #[cfg(target_os = "linux")]
    init_linux()?;

    #[cfg(target_os = "openbsd")]
    init_openbsd()?;

    Ok(())
}

#[cfg(target_os = "linux")]
pub fn init_linux() -> Result<()> {
    if let Err(err) = nix::unistd::chroot(CHROOT) {
        // TODO: add setting to make this a hard fail
        warn!("Failed to chroot: {:?}", err);
    } else {
        nix::unistd::chdir("/")?;
        info!("Successful chroot to {:?}", CHROOT);
    }

    fasten_seatbelt()?;

    #[cfg(target_os = "linux")]
    seccomp::init()?;

    Ok(())
}

#[cfg(target_os = "openbsd")]
pub fn init_openbsd() -> Result<()> {
    unveil("/etc/resolv.conf", "r")
        .map_err(|_| format_err!("Failed to call unveil"))?;

    unveil("/dev/urandom", "r")
        .map_err(|_| format_err!("Failed to call unveil"))?;

    // disable further unveil calls
    unveil("", "")
        .map_err(|_| format_err!("Failed to call unveil"))?;

    pledge![Stdio Rpath Dns Inet,]?;

    Ok(())
}