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

nordisk/holger

server/lib/src/sandbox/media.rs

//! **The sandbox laid from the medium** (lane HOLGER-MEDIA, 2026-10-23): the
//! box's half of `holger_sandbox::media`.
//!
//! Before the server serves, every entry the medium carries beside the app
//! (the manifest, crun, the worker's rootfs, ClamAV's rootfs) is fetched out of
//! the running slot's signed archive, checked against the manifest's sha256 and
//! laid under `<data_root>/sandbox` ([`Layout`]). A record of what was laid
//! (`laid.toml`: entry → sha256) makes the next boot of the same medium lay
//! nothing again, but EVERY boot re-hashes (NCSC P1, lane HOL-NCSC): the
//! medium's entries against the manifest, and what is laid against them (every
//! file's sha256, mode, owner and link); a laid tree that differs is laid again
//! from the medium and said by name (`holger-sandbox-14`), and one that still
//! differs refuses the scans. A new release (a keep medium, a live update)
//! carries new entries and lays them over. One entry that is missing, short or wrong refuses
//! the lay by name and NOTHING of it is kept: the scans stay refused
//! (`holger-sandbox-1`).
//!
//! `fetch` is the one seam: on the appliance it reads an entry out of the
//! running slot's archive (server-cli `sandbox_boot`); a test, a container or a
//! developer's box names a directory of entries (`HOLGER_SANDBOX_MEDIA_DIR`,
//! the shape `cargo xtask scan-worker stage` writes).

use std::collections::BTreeMap;
use std::path::{Path, PathBuf};

use holger_sandbox::media::{self as m, Kind, Layout, Manifest};
use holger_sandbox::Refusal;
use serde::{Deserialize, Serialize};

/// A directory of entries instead of the running slot's archive.
pub const MEDIA_DIR_ENV: &str = "HOLGER_SANDBOX_MEDIA_DIR";

/// clamd's config inside its container (`clamd.conf` beside this file, the one
/// `scripts/clamd-sandbox.sh` mounts), laid beside its socket. It lives inside the crate so
/// the published crate carries it (it was `distribution/scan-worker/clamd.conf` until
/// PUB-HOLGER, 2026-10-28).
pub const CLAMD_CONF: &str = include_str!("clamd.conf");

/// What one lay did.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Laid {
    pub entries: Vec<LaidEntry>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LaidEntry {
    pub name: String,
    pub sha256: String,
    /// Already laid by an earlier boot of the same medium, and re-hashed equal to it this
    /// start: nothing written.
    pub kept: bool,
    /// Laid by an earlier boot, but what is on the disk no longer is what the medium says
    /// (`holger-sandbox-14`): laid again from the medium this start.
    pub drifted: bool,
}

impl Laid {
    /// One line for the boot log.
    pub fn words(&self) -> String {
        self.entries
            .iter()
            .map(|e| {
                let how = match (e.kept, e.drifted) {
                    (true, _) => " (kept, re-hashed)",
                    (false, true) => {
                        " (laid again: it differed from the medium, holger-sandbox-14)"
                    }
                    (false, false) => "",
                };
                format!("{} {}{how}", e.name, &e.sha256[..12])
            })
            .collect::<Vec<_>>()
            .join(", ")
    }
}

/// The record on disk: entry → sha256 of what was laid.
#[derive(Debug, Default, Serialize, Deserialize)]
struct Record {
    #[serde(default)]
    laid: BTreeMap<String, String>,
}

fn read_record(at: &Path) -> Record {
    std::fs::read_to_string(at)
        .ok()
        .and_then(|t| toml::from_str(&t).ok())
        .unwrap_or_default()
}

fn write_record(at: &Path, r: &Record) -> Result<(), Refusal> {
    let text = toml::to_string(r).map_err(|e| Refusal::Io(format!("the laid record: {e}")))?;
    std::fs::write(at, text).map_err(|e| Refusal::Io(format!("{}: {e}", at.display())))
}

/// Where an entry lands.
fn target_of(layout: &Layout, e: &m::Entry) -> PathBuf {
    match e.name.as_str() {
        m::CRUN => layout.crun(),
        m::WORKER_ROOTFS => layout.worker_rootfs(),
        m::CLAMAV_ROOTFS => layout.clamav_rootfs(),
        other => match e.kind {
            Kind::Program => layout.dir.join(other),
            Kind::Guest => layout.heimdall_guests().join(other),
            Kind::Rootfs => layout
                .dir
                .join(other.trim_end_matches(".tar"))
                .join("rootfs"),
        },
    }
}

/// The first way the laid `target` is not the entry `e` (its `bytes`), or `None`.
fn difference(
    e: &m::Entry,
    bytes: &[u8],
    target: &Path,
    userns_base: u32,
) -> Result<Option<String>, Refusal> {
    match e.kind {
        Kind::Program => m::laid_program_difference(&e.sha256, target),
        Kind::Rootfs => m::laid_rootfs_difference(bytes, target, userns_base),
        Kind::Guest => m::laid_file_difference(&e.sha256, target),
    }
}

/// **Lay the sandbox** under `layout` from `fetch`, with the containers' user
/// namespace base `userns_base` (0 on a developer's box: owners stay).
pub fn lay(
    layout: &Layout,
    fetch: &dyn Fn(&str) -> Result<Vec<u8>, Refusal>,
    userns_base: u32,
) -> Result<Laid, Refusal> {
    std::fs::create_dir_all(&layout.dir)
        .map_err(|e| Refusal::Io(format!("{}: {e}", layout.dir.display())))?;
    let text = fetch(m::MANIFEST)?;
    let manifest: Manifest = toml::from_str(&String::from_utf8_lossy(&text))
        .map_err(|e| Refusal::Config(format!("the sandbox manifest does not read: {e}")))?;
    manifest.check()?;
    let record_at = layout.laid_record();
    let mut record = read_record(&record_at);
    let mut laid = Vec::new();
    for e in &manifest.entries {
        let target = target_of(layout, e);
        // EVERY start (NCSC P1, lane HOL-NCSC): the medium's entry against the manifest, then
        // what is laid against the entry. The record only says what an earlier start laid; the
        // data disk is not trusted to have kept it.
        let bytes = fetch(&e.name)?;
        manifest.verify(&e.name, &bytes)?;
        let mut drifted = false;
        if record.laid.get(&e.name) == Some(&e.sha256) && target.exists() {
            match difference(e, &bytes, &target, userns_base)? {
                None => {
                    laid.push(LaidEntry {
                        name: e.name.clone(),
                        sha256: e.sha256.clone(),
                        kept: true,
                        drifted: false,
                    });
                    continue;
                }
                Some(why) => {
                    log::warn!(
                        "{}",
                        Refusal::RootfsDrift(format!(
                            "sandbox entry {}: {why}; laid again from the medium",
                            e.name
                        ))
                    );
                    drifted = true;
                }
            }
        }
        // Forget the stale record first: a lay that dies halfway lays again next boot.
        record.laid.remove(&e.name);
        write_record(&record_at, &record)?;
        match e.kind {
            Kind::Program => m::lay_program(&bytes, &target)?,
            Kind::Rootfs => {
                m::lay_rootfs(&bytes, &target, userns_base)?;
            }
            Kind::Guest => m::lay_file(&bytes, &target)?,
        }
        // Laid, and read back: what the scans run on is what the medium says, or nothing.
        if let Some(why) = difference(e, &bytes, &target, userns_base)? {
            return Err(Refusal::RootfsDrift(format!(
                "sandbox entry {} laid from the medium still differs from it: {why}",
                e.name
            )));
        }
        record.laid.insert(e.name.clone(), e.sha256.clone());
        write_record(&record_at, &record)?;
        laid.push(LaidEntry {
            name: e.name.clone(),
            sha256: e.sha256.clone(),
            kept: false,
            drifted,
        });
    }
    // Lane HOL-HEIMDALL-03: a medium that carries Heimdall gets the worker's rootfs tar laid
    // whole too (its bytes verified above against the manifest this start), the one
    // `engine: heimdall` mints its pinned worker image from; written again whenever it differs.
    if manifest.carries_heimdall() {
        let w = manifest
            .entry(m::WORKER_ROOTFS)
            .ok_or_else(|| Refusal::Config("the sandbox manifest names no worker rootfs".into()))?;
        let at = layout.worker_rootfs_tar();
        if !matches!(m::laid_file_difference(&w.sha256, &at), Ok(None)) {
            let bytes = fetch(m::WORKER_ROOTFS)?;
            manifest.verify(m::WORKER_ROOTFS, &bytes)?;
            m::lay_file(&bytes, &at)?;
        }
        for d in [layout.heimdall_oci(), layout.heimdall_work()] {
            std::fs::create_dir_all(&d)
                .map_err(|e| Refusal::Io(format!("{}: {e}", d.display())))?;
        }
    }
    for d in [layout.jobs(), layout.state(), layout.clamd_run()] {
        std::fs::create_dir_all(&d).map_err(|e| Refusal::Io(format!("{}: {e}", d.display())))?;
    }
    // clamd's run directory is the container's (its socket appears there): owned by
    // clamav's uid inside, which is base + 100 outside; world-writable for a base of 0.
    let run = layout.clamd_run();
    if userns_base != 0 {
        m::lchown(
            &run,
            userns_base + super::clamd::CLAMD_UID,
            userns_base + super::clamd::CLAMD_GID,
        )?;
    } else {
        use std::os::unix::fs::PermissionsExt as _;
        let _ = std::fs::set_permissions(&run, std::fs::Permissions::from_mode(0o1777));
    }
    std::fs::write(run.join("clamd.conf"), CLAMD_CONF)
        .map_err(|e| Refusal::Io(format!("clamd.conf: {e}")))?;
    Ok(Laid { entries: laid })
}

/// Entries out of the app archive (`sandbox/<name>` in the `.znippy` korp-start
/// verified at boot): the running slot's archive, staged by server-cli.
#[cfg(feature = "sign")]
pub fn fetch_from_archive(archive: PathBuf) -> impl Fn(&str) -> Result<Vec<u8>, Refusal> {
    move |name: &str| {
        znippy_common::get_file(&archive, &m::entry_path(name))
            .map_err(|e| Refusal::ImageMissing(format!("sandbox entry {:?} is not in the app archive {} ({e}): this medium carries no scan sandbox", m::entry_path(name), archive.display())))
    }
}

/// **Is `path` on a mount that forbids exec?** The data volume korp lays is
/// `nosuid,nodev,noexec` (korp-installer `DATA_XFS_MOUNT_FLAGS_NAMED`), and the
/// sandbox's runtime and rootfs live under it: MEASURED on the laid box
/// (2026-10-24), `crun --version: Permission denied` with a 0755 file as root.
/// The deepest mount point that is a prefix of `path` decides; `None` when
/// `mountinfo` names no mount above it (a test, an odd namespace).
pub fn mount_noexec_for(mountinfo: &str, path: &Path) -> Option<bool> {
    let mut best: Option<(usize, bool)> = None;
    for line in mountinfo.lines() {
        // 36 35 98:0 /mnt1 /mnt2 rw,noatime master:1 - ext3 /dev/root rw,errors=continue
        let mut f = line.split_whitespace();
        let (Some(_), Some(_), Some(_), Some(_), Some(mp), Some(opts)) =
            (f.next(), f.next(), f.next(), f.next(), f.next(), f.next())
        else {
            continue;
        };
        let mp = mp.replace("\\040", " ");
        let mp_path = Path::new(&mp);
        if path.starts_with(mp_path) && best.is_none_or(|(l, _)| mp.len() > l) {
            best = Some((mp.len(), opts.split(',').any(|o| o == "noexec")));
        }
    }
    best.map(|(_, noexec)| noexec)
}

/// Entries from a directory (`<dir>/<name>`): the shape `cargo xtask scan-worker stage` writes.
pub fn fetch_from_dir(dir: PathBuf) -> impl Fn(&str) -> Result<Vec<u8>, Refusal> {
    move |name: &str| {
        let p = dir.join(name);
        m::read(&p).map_err(|_| {
            Refusal::ImageMissing(format!(
                "sandbox entry {name:?} is not in {} (cargo xtask scan-worker stage)",
                dir.display()
            ))
        })
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    fn staged(dir: &Path) -> Manifest {
        let worker = m::worker_rootfs_tar(b"\x7fELF-worker");
        let clam = m::worker_rootfs_tar(b"\x7fELF-clamd");
        let manifest = Manifest::of(b"#!/bin/sh\necho crun\n", &worker, &clam);
        std::fs::write(dir.join(m::MANIFEST), toml::to_string(&manifest).unwrap()).unwrap();
        std::fs::write(dir.join(m::CRUN), b"#!/bin/sh\necho crun\n").unwrap();
        std::fs::write(dir.join(m::WORKER_ROOTFS), &worker).unwrap();
        std::fs::write(dir.join(m::CLAMAV_ROOTFS), &clam).unwrap();
        manifest
    }

    #[test]
    fn the_sandbox_is_laid_from_the_entries_and_kept_on_the_next_boot() {
        let tmp = tempfile::tempdir().unwrap();
        let media = tmp.path().join("media");
        std::fs::create_dir_all(&media).unwrap();
        staged(&media);
        let layout = Layout::under(&tmp.path().join("data"));
        let fetch = fetch_from_dir(media.clone());
        let first = lay(&layout, &fetch, 0).unwrap();
        assert_eq!(first.entries.len(), 3);
        assert!(first.entries.iter().all(|e| !e.kept));
        assert!(layout.crun().is_file());
        assert!(layout.worker_rootfs().join("holger-scan-worker").is_file());
        assert!(layout.clamav_rootfs().join("holger-scan-worker").is_file());
        assert!(layout.clamd_run().join("clamd.conf").is_file());
        assert!(layout.jobs().is_dir() && layout.state().is_dir());
        let again = lay(&layout, &fetch, 0).unwrap();
        assert!(again.entries.iter().all(|e| e.kept), "{again:?}");
        assert!(
            again.words().contains("(kept, re-hashed)"),
            "{}",
            again.words()
        );
        // A new release: one entry differs, only that one is laid again.
        let worker2 = m::worker_rootfs_tar(b"\x7fELF-worker-2");
        let mut manifest = staged(&media);
        manifest.entries[1].sha256 = m::sha256_hex(&worker2);
        manifest.entries[1].bytes = worker2.len() as u64;
        std::fs::write(media.join(m::MANIFEST), toml::to_string(&manifest).unwrap()).unwrap();
        std::fs::write(media.join(m::WORKER_ROOTFS), &worker2).unwrap();
        let third = lay(&layout, &fetch, 0).unwrap();
        let kept: Vec<bool> = third.entries.iter().map(|e| e.kept).collect();
        assert_eq!(kept, [true, false, true]);
        assert_eq!(
            std::fs::read(layout.worker_rootfs().join("holger-scan-worker")).unwrap(),
            b"\x7fELF-worker-2"
        );
    }

    /// NCSC P1 (lane HOL-NCSC): every start re-hashes what was laid. A changed file, an added
    /// program or a changed runtime is found and laid again from the medium, by name.
    #[test]
    fn every_start_re_hashes_the_laid_sandbox_and_lays_a_changed_one_again() {
        use std::os::unix::fs::PermissionsExt as _;
        let tmp = tempfile::tempdir().unwrap();
        let media = tmp.path().join("media");
        std::fs::create_dir_all(&media).unwrap();
        staged(&media);
        let layout = Layout::under(&tmp.path().join("data"));
        let fetch = fetch_from_dir(media.clone());
        lay(&layout, &fetch, 0).unwrap();
        // Someone with the data disk changes the worker, adds a program and swaps the runtime.
        let worker = layout.worker_rootfs().join("holger-scan-worker");
        std::fs::set_permissions(&worker, std::fs::Permissions::from_mode(0o755)).unwrap();
        std::fs::write(&worker, b"\x7fELF-evil!").unwrap();
        std::fs::set_permissions(&worker, std::fs::Permissions::from_mode(0o555)).unwrap();
        let etc = layout.clamav_rootfs().join("etc");
        std::fs::set_permissions(&etc, std::fs::Permissions::from_mode(0o755)).unwrap();
        std::fs::write(etc.join("evil.sh"), b"#!/bin/sh\nexit 0\n").unwrap();
        std::fs::write(layout.crun(), b"#!/bin/sh\necho evil\n").unwrap();
        let again = lay(&layout, &fetch, 0).unwrap();
        let drifted: Vec<(&str, bool, bool)> = again
            .entries
            .iter()
            .map(|e| (e.name.as_str(), e.kept, e.drifted))
            .collect();
        assert_eq!(
            drifted,
            [
                (m::CRUN, false, true),
                (m::WORKER_ROOTFS, false, true),
                (m::CLAMAV_ROOTFS, false, true)
            ]
        );
        assert!(
            again.words().contains("holger-sandbox-14"),
            "{}",
            again.words()
        );
        assert_eq!(
            std::fs::read(&worker).unwrap(),
            b"\x7fELF-worker",
            "the medium's worker is back"
        );
        assert!(
            !layout.clamav_rootfs().join("etc/evil.sh").exists(),
            "the added program is gone"
        );
        assert_eq!(
            std::fs::read(layout.crun()).unwrap(),
            b"#!/bin/sh\necho crun\n"
        );
        // An empty mount point the runtime made (crun makes its bind targets) is not a change.
        std::fs::set_permissions(&etc, std::fs::Permissions::from_mode(0o755)).unwrap();
        std::fs::write(layout.clamav_rootfs().join("etc/clamd-sandbox.conf"), b"").unwrap();
        std::fs::create_dir_all(layout.clamav_rootfs().join("run/clamd")).unwrap();
        let third = lay(&layout, &fetch, 0).unwrap();
        assert!(
            third.entries.iter().all(|e| e.kept && !e.drifted),
            "{third:?}"
        );
    }

    /// The medium itself is checked at every start, not only at the first lay: an entry that
    /// changed under the manifest since is refused, though the record says it was laid.
    #[test]
    fn a_medium_entry_that_changed_since_the_first_lay_is_refused() {
        let tmp = tempfile::tempdir().unwrap();
        let media = tmp.path().join("media");
        std::fs::create_dir_all(&media).unwrap();
        staged(&media);
        let layout = Layout::under(&tmp.path().join("data"));
        lay(&layout, &fetch_from_dir(media.clone()), 0).unwrap();
        let mut w = std::fs::read(media.join(m::WORKER_ROOTFS)).unwrap();
        let at = w.len() / 3;
        w[at] ^= 0x55;
        std::fs::write(media.join(m::WORKER_ROOTFS), &w).unwrap();
        let e = lay(&layout, &fetch_from_dir(media), 0).unwrap_err();
        assert_eq!(e.code().code, "holger-sandbox-8", "{e}");
    }

    #[test]
    fn a_wrong_or_missing_entry_refuses_the_lay_by_name_and_keeps_nothing_of_it() {
        let tmp = tempfile::tempdir().unwrap();
        let media = tmp.path().join("media");
        std::fs::create_dir_all(&media).unwrap();
        staged(&media);
        // The same length, other bytes: the sha256 leg is the one that says no.
        std::fs::write(media.join(m::CRUN), b"#!/bin/sh\necho crux\n").unwrap();
        let layout = Layout::under(&tmp.path().join("data"));
        let e = lay(&layout, &fetch_from_dir(media.clone()), 0).unwrap_err();
        assert_eq!(e.code().code, "holger-sandbox-8", "{e}");
        assert!(
            e.to_string().contains("crun") && e.to_string().contains("sha256"),
            "{e}"
        );
        assert!(!layout.crun().exists(), "nothing laid for the wrong entry");
        assert!(
            !layout.worker_rootfs().exists(),
            "the lay stops at the first refusal"
        );
        std::fs::remove_file(media.join(m::CRUN)).unwrap();
        let e = lay(&layout, &fetch_from_dir(media), 0).unwrap_err();
        assert!(e.to_string().contains("scan-worker stage"), "{e}");
    }

    #[test]
    fn the_governing_mount_decides_exec() {
        let mi = "22 1 8:1 / / rw,relatime - xfs /dev/vda2 rw\n\
                  40 22 8:3 / /data rw,nosuid,nodev,noexec,relatime - xfs /dev/vdb1 rw\n\
                  41 40 0:30 / /data/holger/sandbox rw,nosuid,nodev,relatime - xfs /dev/vdb1 rw\n\
                  42 22 0:31 / /run/holger\\040x rw,noexec - tmpfs tmpfs rw\n";
        assert_eq!(
            mount_noexec_for(mi, Path::new("/data/holger/intel")),
            Some(true)
        );
        assert_eq!(
            mount_noexec_for(mi, Path::new("/data/holger/sandbox/crun")),
            Some(false),
            "the exec bind over the sandbox wins"
        );
        assert_eq!(mount_noexec_for(mi, Path::new("/etc/holger")), Some(false));
        assert_eq!(
            mount_noexec_for(mi, Path::new("/run/holger x/y")),
            Some(true),
            "an escaped mount point"
        );
        assert_eq!(mount_noexec_for("", Path::new("/x")), None);
    }

    #[test]
    fn no_manifest_is_a_refusal_by_name() {
        let tmp = tempfile::tempdir().unwrap();
        let layout = Layout::under(&tmp.path().join("data"));
        let e = lay(&layout, &fetch_from_dir(tmp.path().join("empty")), 0).unwrap_err();
        assert!(e.to_string().contains("manifest.toml"), "{e}");
    }

    /// Lane HOL-HEIMDALL-03: a medium that carries Heimdall's shim and its released guests lays
    /// the shim executable, every guest file read-only under `heimdall-guests/`, and the worker's
    /// rootfs tar whole (what `engine: heimdall` mints its image from); each re-hashed at every
    /// start, a changed one laid again. A medium without the shim lays none of it.
    #[test]
    fn a_medium_with_heimdall_lays_its_shim_its_guests_and_the_worker_tar() {
        use std::os::unix::fs::PermissionsExt as _;
        let tmp = tempfile::tempdir().unwrap();
        let media = tmp.path().join("media");
        std::fs::create_dir_all(&media).unwrap();
        let shim = b"\x7fELF-heimdall-container-shim".to_vec();
        let guest = b"\0asm-verifier".to_vec();
        let sig = b"cms".to_vec();
        let manifest = staged(&media)
            .with(
                m::HEIMDALL_SHIM,
                Kind::Program,
                &shim,
                Some("nordisk-heimdall-container 0.2.0".into()),
            )
            .with(
                "heimdall-verify-bundle-verifier.wasm",
                Kind::Guest,
                &guest,
                Some("heimdall-guests-0.2.1".into()),
            )
            .with(
                "heimdall-verify-bundle-verifier.wasm.p7s",
                Kind::Guest,
                &sig,
                Some("heimdall-guests-0.2.1".into()),
            );
        manifest.check().unwrap();
        assert!(manifest.carries_heimdall());
        std::fs::write(media.join(m::MANIFEST), toml::to_string(&manifest).unwrap()).unwrap();
        std::fs::write(media.join(m::HEIMDALL_SHIM), &shim).unwrap();
        std::fs::write(media.join("heimdall-verify-bundle-verifier.wasm"), &guest).unwrap();
        std::fs::write(media.join("heimdall-verify-bundle-verifier.wasm.p7s"), &sig).unwrap();
        let layout = Layout::under(&tmp.path().join("data"));
        let fetch = fetch_from_dir(media.clone());
        let first = lay(&layout, &fetch, 0).unwrap();
        assert_eq!(first.entries.len(), 6);
        let mode = |p: &Path| std::fs::metadata(p).unwrap().permissions().mode() & 0o7777;
        assert_eq!(std::fs::read(layout.heimdall_shim()).unwrap(), shim);
        assert_eq!(mode(&layout.heimdall_shim()), 0o755);
        let g = layout
            .heimdall_guests()
            .join("heimdall-verify-bundle-verifier.wasm");
        assert_eq!(std::fs::read(&g).unwrap(), guest);
        assert_eq!(mode(&g), 0o444);
        assert_eq!(
            std::fs::read(layout.worker_rootfs_tar()).unwrap(),
            std::fs::read(media.join(m::WORKER_ROOTFS)).unwrap(),
            "the worker's tar, whole"
        );
        assert_eq!(mode(&layout.worker_rootfs_tar()), 0o444);
        assert!(layout.heimdall_oci().is_dir() && layout.heimdall_work().is_dir());
        let again = lay(&layout, &fetch, 0).unwrap();
        assert!(again.entries.iter().all(|e| e.kept), "{again:?}");
        // A guest changed on the data disk is laid again; so is the worker tar.
        std::fs::set_permissions(&g, std::fs::Permissions::from_mode(0o644)).unwrap();
        std::fs::write(&g, b"evil").unwrap();
        std::fs::set_permissions(
            layout.worker_rootfs_tar(),
            std::fs::Permissions::from_mode(0o644),
        )
        .unwrap();
        std::fs::write(layout.worker_rootfs_tar(), b"evil").unwrap();
        let third = lay(&layout, &fetch, 0).unwrap();
        assert!(
            third
                .entries
                .iter()
                .any(|e| e.drifted && e.name.ends_with(".wasm")),
            "{third:?}"
        );
        assert_eq!(std::fs::read(&g).unwrap(), guest);
        assert_eq!(
            std::fs::read(layout.worker_rootfs_tar()).unwrap(),
            std::fs::read(media.join(m::WORKER_ROOTFS)).unwrap()
        );
        // Without the shim, nothing of Heimdall is laid.
        let plain = tempfile::tempdir().unwrap();
        let pmedia = plain.path().join("media");
        std::fs::create_dir_all(&pmedia).unwrap();
        assert!(!staged(&pmedia).carries_heimdall());
        let pl = Layout::under(&plain.path().join("data"));
        lay(&pl, &fetch_from_dir(pmedia), 0).unwrap();
        assert!(!pl.worker_rootfs_tar().exists() && !pl.heimdall_guests().exists());
    }
}