Skip to main content

sandlock_core/
lib.rs

1pub mod error;
2pub mod http;
3pub mod sandbox;     // formerly `policy`; contains Sandbox + SandboxBuilder + Confinement
4pub mod profile;
5pub mod result;
6pub(crate) mod arch;
7pub(crate) mod sys;
8pub mod landlock;
9pub mod protection;
10pub mod seccomp;
11pub(crate) mod resource;
12pub(crate) mod network;
13pub mod context;
14pub(crate) mod vdso;
15pub(crate) mod random;
16pub(crate) mod time;
17pub(crate) mod cow;
18pub(crate) mod checkpoint;
19pub(crate) mod freeze;
20pub mod netlink;
21pub(crate) mod procfs;
22pub(crate) mod port_remap;
23pub mod pipeline;
24pub mod policy_fn;
25pub mod image;
26pub mod fork;
27pub(crate) mod ca_inject;
28pub(crate) mod chroot;
29pub mod dry_run;
30mod transparent_proxy;
31
32pub use error::SandlockError;
33pub use sys::structs::{SeccompData, SeccompNotif};
34pub use checkpoint::Checkpoint;
35pub use protection::{Protection, ProtectionState, ProtectionPolicy, ProtectionStatus};
36pub use sandbox::{Confinement, ConfinementBuilder, Sandbox, SandboxBuilder};
37pub use result::{RunResult, ExitStatus};
38pub use pipeline::{Stage, Pipeline, Gather};
39pub use dry_run::{Change, ChangeKind, DryRunResult};
40// Sectioned-profile parsing types: ProfileInput is the top-level deserialization
41// target; ProgramSpec carries [program].exec/args (not a Sandbox field).
42pub use crate::profile::{ProfileInput, ProgramSpec};
43
44// Public extension API — see docs/extension-handlers.md.
45pub use seccomp::dispatch::{Handler, HandlerCtx, HandlerError};
46pub use seccomp::syscall::{Syscall, SyscallError};
47
48/// Query the Landlock ABI version supported by the running kernel.
49pub fn landlock_abi_version() -> Result<u32, error::ConfinementError> {
50    landlock::abi_version()
51}
52
53/// Minimum Landlock ABI version required by sandlock.
54pub const MIN_LANDLOCK_ABI: u32 = landlock::MIN_ABI;
55
56/// Confine the calling process with Landlock restrictions.
57///
58/// This applies `PR_SET_NO_NEW_PRIVS` and Landlock rules from the sandbox's
59/// filesystem fields. IPC and signal isolation are always enabled. The
60/// confinement is **irreversible**.
61///
62/// This does NOT fork or exec — it confines the current process in-place.
63pub fn confine(confinement: &Confinement) -> Result<(), SandlockError> {
64    // Set NO_NEW_PRIVS (required for Landlock)
65    if unsafe { libc::prctl(libc::PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) } != 0 {
66        return Err(SandlockError::Runtime(
67            error::SandboxRuntimeError::Confinement(
68                error::ConfinementError::Landlock(format!(
69                    "prctl(PR_SET_NO_NEW_PRIVS): {}",
70                    std::io::Error::last_os_error()
71                ))
72            )
73        ));
74    }
75
76    let mut builder = Sandbox::builder();
77    for path in &confinement.fs_readable {
78        builder = builder.fs_read(path.clone());
79    }
80    for path in &confinement.fs_writable {
81        builder = builder.fs_write(path.clone());
82    }
83    let stripped = builder.build()?;
84
85    // Apply Landlock filesystem rules.
86    landlock::confine_filesystem(&stripped)
87}