main
Drew Owens 0.11.2 source 784acbf 5d ago
//! ADVERSARIAL REVIEW OF 0.6.4 — pass seventeen.
//!
//! `possiblyOurs` is sound. A launcher that appeared after an unattributable
//! invoke is recorded as unattributed and excluded from the foreign set, and it
//! never reaches the kill path: cleanup is seeded from `attributed_chain`, which
//! needs a root an unattributable route does not have. "Possibly ours" is a
//! reason not to kill and not to accuse, and those are the same answer here.
//!
//! The pin below is the behavioural half of that claim: a chain the USER starts
//! during our unattributable route is neither terminated nor adopted.

mod common;

use common::{Bridge, TempDir};
use serde_json::{json, Value};

fn s(v: &Value) -> String {
    serde_json::to_string_pretty(v).unwrap_or_default()
}

/// The user clicks their Start Menu while our `explorer` route — which cannot
/// name what it started — is running. Their chain is classed `possiblyOurs`, so
/// it is not accused; the question this pins is that being un-accused does not
/// make it killable, and that the session it produces is not later adopted.
///
/// Re-attribution cannot reach it for a structural reason worth stating:
/// `our_identities` is built from `a.chain` and `a.attribution`, both of which
/// are per-route and both of which are EMPTY for an unattributable route. With
/// no identity to descend from, `descends_from_our_chain` returns before it
/// looks at anything.
#[test]
fn a_user_chain_during_an_unattributable_route_is_neither_killed_nor_adopted() {
    let dir = TempDir::new("adv16-possibly");
    std::fs::write(
        dir.join("routes.json"),
        json!({"shellExecute": {"chain": true},
               "powershell": {"chain": true},
               "explorer": {"chain": true},
               "cmdStart": {"chain": true}})
        .to_string(),
    )
    .unwrap();
    // The user's own launcher chain, reported as created "now" on every census —
    // i.e. after our invoke, which is what puts it in `possiblyOurs`.
    std::fs::write(
        dir.join("preexisting.json"),
        json!([{"pid": 70003, "image": "CATSTART.exe", "ageSeconds": 0},
               {"pid": 70004, "image": "SWXDesktopLauncher.exe", "ageSeconds": 0, "ppid": 70003}])
        .to_string(),
    )
    .unwrap();
    let lnk = format!("{}/SOLIDWORKS Design.lnk", dir.path());
    std::fs::write(&lnk, "x").unwrap();

    let b = Bridge::start_in(
        TempDir::new("adv16-scratch"),
        &[
            ("SWX_SOLIDWORKS_SHORTCUT", &lnk),
            ("SWX_LAUNCH_FAKE_DIR", &dir.path()),
            ("SWX_LAUNCH_RUN_BEGIN_SECS", "1"),
            ("SWX_LAUNCH_SLDWORKS_SECS", "2"),
            ("SWX_LAUNCH_ATTACH_SECS", "3"),
            ("SWX_LAUNCH_POLL_MS", "100"),
            ("SWX_LAUNCH_RETRY_SETTLE_MS", "400"),
            ("SWX_LAUNCH_BACKOFF_SECS", "0"),
        ],
    );
    b.call("swx_start", json!({"reason": "starting SOLIDWORKS", "waitSeconds": 0}));
    let deadline = std::time::Instant::now() + std::time::Duration::from_secs(45);
    loop {
        let st = b.call("swx_status", json!({}));
        if st["launch"]["finished"] == true || std::time::Instant::now() > deadline {
            break;
        }
        std::thread::sleep(std::time::Duration::from_millis(200));
    }

    // NOT VACUOUS: their chain must really have been classed possibly-ours, which
    // is the state whose safety is being pinned.
    let st = b.call("swx_status", json!({}));
    let possibly: Vec<u64> = st["launch"]["possiblyOurs"]
        .as_array()
        .map(|a| a.iter().filter_map(|v| v.as_u64()).collect())
        .unwrap_or_default();
    assert!(
        !possibly.is_empty(),
        "precondition: at least one launcher was classed possiblyOurs, which is the state whose \
         safety is being pinned. (The pre-existing pair above lands in each route's BASELINE and \
         is excluded before this filter — correctly; what reaches `possiblyOurs` here is the \
         unattributable routes' own chains.): {}",
        s(&st["launch"])
    );

    // THE EFFECT, on the machine: not one of their processes was terminated.
    let killed: Vec<u64> = std::fs::read_to_string(dir.join("terminated.jsonl"))
        .unwrap_or_default()
        .lines()
        .filter_map(|l| serde_json::from_str::<Value>(l).ok())
        .filter_map(|v| v.get("pid")?.as_u64())
        .collect();
    for pid in &possibly {
        assert!(
            !killed.contains(pid),
            "pid {pid} was classed `possiblyOurs` and then TERMINATED. Possibly-ours must mean \
             'do not accuse', never 'may be killed': the kill path is seeded from the attributed \
             root, which an unattributable route does not have.\nterminated: {killed:?}\n\
             possiblyOurs: {possibly:?}\n{}",
            s(&st["launch"])
        );
    }
    // ...and the pre-existing pair — a chain that was already there — is untouched too.
    for theirs in [70003u64, 70004] {
        assert!(!killed.contains(&theirs), "pre-existing pid {theirs} was terminated: {killed:?}");
    }
    // ...and their session is not adopted as ours.
    assert_ne!(
        st["launch"]["outcome"].as_str().unwrap_or(""),
        "attachedAfterSignIn",
        "a session reached through an unattributable route was adopted as ours: {}",
        s(&st["launch"])
    );
}