Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/heimdall

profiles/tests/in_sync.rs

// SPDX-License-Identifier: AGPL-3.0-only
//! Every checked-in profile: the compiled `.rs` equals its `.json`, both
//! regenerate byte-identically, and it builds an enforcing filter. Heimdall
//! is a defensive sandbox; nothing here is installed.

use heimdall_probe::codegen::files;
use heimdall_probe::Generated;
use heimdall_profiles::ALL;
use heimdall_seccomp::bpf::{build, Mode};
use heimdall_seccomp::{Action, Profile};

#[test]
fn every_compiled_profile_equals_its_json_and_regenerates_byte_identically() {
    assert!(!ALL.is_empty());
    for e in ALL {
        let g = Generated::from_json(e.json).unwrap();
        let compiled = Profile::from(e.profile);
        assert_eq!(
            compiled, g.profile,
            "{} {} {}",
            e.profile.workload, e.profile.arch, e.profile.libc
        );
        let (_, json, oci) = files(&g);
        assert_eq!(
            json, e.json,
            "{}: .json is not what gen writes",
            e.profile.workload
        );
        assert_eq!(
            oci, e.oci_json,
            "{}: .oci.json is stale",
            e.profile.workload
        );
    }
}

#[test]
fn every_profile_builds_an_enforcing_filter_without_wx_or_bare_exec() {
    for e in ALL {
        let p = Profile::from(e.profile);
        build(&p, &Mode::Enforce).unwrap();
        for s in [
            "execve",
            "execveat",
            "ptrace",
            "bpf",
            "mount",
            "init_module",
            "kexec_load",
        ] {
            assert!(!p.syscalls().contains(&s), "{} allows {s}", p.workload);
        }
        let g = Generated::from_json(e.json).unwrap();
        assert!(
            g.review.wx.is_empty(),
            "{}: W|X mappings: {:?}",
            p.workload,
            g.review.wx
        );
        let mprotect = p.arch.syscall_nr("mprotect").unwrap();
        let wx = (libc_prot_rwx()) as u64;
        assert_eq!(
            p.evaluate(mprotect, &[0, 0, wx, 0, 0, 0], Action::KillProcess),
            Action::KillProcess
        );
    }
}

fn libc_prot_rwx() -> i32 {
    // PROT_READ | PROT_WRITE | PROT_EXEC
    0x1 | 0x2 | 0x4
}

/// heimdall-wasm keeps a guest's memory out of memfds (`memory_init_cow(false)`,
/// `force_memory_init_memfd(false)`; Holger's split verify-bundle guest trapped on it in a
/// HeimdallRunner job), so the wasm host's profile, measured again over the same corpus,
/// does not allow `memfd_create`: one fewer kernel entry point for a hostile guest.
#[test]
fn the_wasm_host_profile_does_not_allow_memfd_create() {
    for e in ALL {
        let p = Profile::from(e.profile);
        if p.workload == "heimdall-wasm-host" {
            assert!(
                !p.syscalls().contains(&"memfd_create"),
                "{} {} {} allows memfd_create",
                p.workload,
                p.arch,
                p.libc
            );
        }
    }
}