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

nordisk/heimdall

crates/heimdall-cli/tests/profile_corpus.rs

// SPDX-License-Identifier: AGPL-3.0-only
//! Writes the probe corpus of the `heimdall-wasm-host` profile
//! (profiles/heimdall-wasm-host/corpus): small WAT guests turned into
//! components, signed with a throwaway CA, their inputs and policies.
//! Heimdall is a defensive sandbox; the adversarial guests attack only
//! Heimdall's own limits.
//!
//! The real verify-bundle guest's part of the corpus (verify-bundle/ and its
//! runs in workload.toml) is guests/verify-bundle/tests/probe_corpus.rs: its
//! Holger bundles need that workspace's dev-dependencies.
//!
//! Run by hand when the corpus changes, then probe and regenerate:
//!   HEIMDALL_WRITE_CORPUS=profiles/heimdall-wasm-host/corpus \
//!     cargo test -p nordisk-heimdall-cli --test profile_corpus -- --ignored

#[path = "../../heimdall-wasm/tests/common/mod.rs"]
mod common;

use std::path::Path;

use common::{component, good_wat, sidecar, Kit, Wat};

const SPIN: &str = "(loop $l (br $l)) (i32.const 0)";

fn copy_guest(kit_module: &Path, to: &Path, name: &str) {
    for ext in ["", ".p7s", ".blake3"] {
        let from = if ext.is_empty() {
            kit_module.to_path_buf()
        } else {
            sidecar(kit_module, &ext[1..])
        };
        std::fs::copy(&from, to.join(format!("{name}.wasm{ext}"))).unwrap();
    }
}

fn input(to: &Path, dir: &str, bytes: &[u8]) {
    std::fs::create_dir_all(to.join(dir)).unwrap();
    std::fs::write(to.join(dir).join("input.bin"), bytes).unwrap();
}

#[test]
#[ignore = "writes the checked-in probe corpus; run by hand"]
fn writes_the_heimdall_wasm_host_probe_corpus() {
    let Some(out) = std::env::var_os("HEIMDALL_WRITE_CORPUS") else {
        panic!("set HEIMDALL_WRITE_CORPUS=<dir>");
    };
    let out = Path::new(&out);
    let _ = std::fs::remove_dir_all(out);
    std::fs::create_dir_all(out).unwrap();
    let kit = Kit::new("corpus");
    std::fs::copy(&kit.root, out.join("root.der")).unwrap();

    let guests: Vec<(&str, String)> = vec![
        ("good", good_wat()),
        ("spin", Wat::new(SPIN).text()),
        (
            "membomb",
            Wat::new("(loop $l (br_if $l (i32.ne (memory.grow (i32.const 16)) (i32.const -1)))) unreachable").text(),
        ),
        (
            "recurse",
            Wat::new("(drop (call $deep (i32.const 0))) (call $ok (i32.const 16) (i32.const 0))")
                .extra("(func $deep (param i32) (result i32) (call $deep (i32.add (local.get 0) (i32.const 1))))")
                .text(),
        ),
        (
            "manyfiles",
            Wat::new(
                r#"(local $i i32)
    (loop $l
      (call $hexname (local.get $i))
      (call $emit (i32.const 64) (i32.const 8) (i32.const 16) (i32.const 1))
      (local.set $i (i32.add (local.get $i) (i32.const 1)))
      (br_if $l (i32.lt_u (local.get $i) (i32.const 100000))))
    (call $ok (i32.const 16) (i32.const 0))"#,
            )
            .text(),
        ),
    ];
    for (name, wat) in &guests {
        let m = kit.place(name, &component(wat));
        copy_guest(&m, out, name);
    }
    // A guest whose signature is for another module: refused before load.
    let good = component(&good_wat());
    let other = kit.place("other", &component(&Wat::new(SPIN).text()));
    std::fs::write(out.join("badsig.wasm"), &good).unwrap();
    std::fs::copy(sidecar(&other, "p7s"), out.join("badsig.wasm.p7s")).unwrap();
    std::fs::copy(sidecar(&other, "blake3"), out.join("badsig.wasm.blake3")).unwrap();

    input(out, "in-good", b"a good input for the probe corpus\n");
    input(out, "in-tampered", b"T: tampered input\n");
    input(out, "in-malformed", b"M: malformed input\n");
    let policies = [
        (
            "policy-fuel.toml",
            "version = 1\n[limits]\nfuel = 1000000\nwall_time_ms = 60000\n",
        ),
        (
            "policy-time.toml",
            "version = 1\n[limits]\nfuel = 1000000000000\nwall_time_ms = 300\n",
        ),
        (
            "policy-mem.toml",
            "version = 1\n[limits]\nmemory_bytes = 8388608\n",
        ),
        (
            "policy-files.toml",
            "version = 1\n[limits]\nmax_output_files = 8\n",
        ),
    ];
    for (n, t) in policies {
        std::fs::write(
            out.join(n),
            format!("# Heimdall is a defensive sandbox: probe corpus policy.\n{t}"),
        )
        .unwrap();
    }
    std::fs::write(
        out.join("README.md"),
        "# heimdall-wasm-host probe corpus\n\nHeimdall is a defensive sandbox. Generated by\n`crates/heimdall-cli/tests/profile_corpus.rs` (guests signed with a throwaway\ntest CA, `root.der`); the runs are in `../workload.toml`.\n",
    )
    .unwrap();
}