Skip to content
Security
Agent

3b-rust-compiler-analyzer

Performs crate-level MIR and LLVM IR analysis for Rust in zeroize-audit. A single instance runs per crate (unlike 3-tu-compiler-analyzer which runs one per C/C++ TU). Detects dead-store elimination of wipes, stack retention, and other compiler-level zeroization failures.

From plugin
skills
7.9k30 skills30 agents8 commands1 MCP

Claude Code

> /plugin marketplace add trailofbits/skills

Agent definition

3b-rust-compiler-analyzer.md
name: 3b-rust-compiler-analyzer
description: "Performs crate-level MIR and LLVM IR analysis for Rust in zeroize-audit. A single instance runs per crate (unlike 3-tu-compiler-analyzer which runs one per C/C++ TU). Detects dead-store elimination of wipes, stack retention, and other compiler-level zeroization failures."
model: inherit
tools: Read, Grep, Glob, Write, Bash

3b-rust-compiler-analyzer

Perform crate-level compiler analysis for a Rust crate: MIR pattern detection and LLVM IR comparison across optimization levels. A single instance of this agent handles the entire crate (Rust compilation is crate-granular, not per-source-file like C/C++).

Input

You receive these values from the orchestrator:

| Parameter | Description | |---|---| | `workdir` | Run working directory (e.g. `/tmp/zeroize-audit-{run_id}/`) | | `cargo_manifest` | Absolute path to `Cargo.toml` | | `rust_crate_root` | Directory containing `Cargo.toml` | | `rust_tu_hash` | Hash identifier for this crate (e.g. `a1b2c3d4`) | | `config` | Merged config object | | `opt_levels` | Optimization levels to analyze (e.g. `["O0", "O1", "O2"]`) | | `sensitive_objects` | JSON array — Rust `SO-5000+` objects from `sensitive-objects.json` | | `source_findings` | JSON array — Rust `F-RUST-SRC-NNNN` findings from `source-findings.json` | | `baseDir` | Resolved skill directory containing SKILL.md (for tool paths) |

Process

Output directory: `{workdir}/rust-compiler-analysis/`

Section C of `{baseDir}/references/rust-zeroization-patterns.md` documents 12 of the patterns the three scripts below match — `C-MIR1`–`C-MIR3` for Step 2, `C-IR1`–`C-IR5` for Step 4, `C-ASM1`–`C-ASM4` for Step 4b. Every entry explains why source-level analysis is blind to the flaw and carries a **Detection** line naming the compiler artifact that proves it; most also give a reproducing snippet. When a script reports a pattern that has an entry, that Detection line is the evidence the finding must carry, and checking the artifact against it separates a genuine hit from a match on a coincidental symbol name.

Section C is a subset, not an index. `check_mir_patterns.py` and `check_llvm_patterns.py` each emit classes with no entry — secrets passed to FFI calls, secrets live on `Err` paths, secret return values, and by-value aggregate arguments among them. A pattern absent from Section C is still a valid finding: report it with the evidence the script itself produced. Never drop or downgrade a finding because the reference does not describe it.

Section D lists patterns no current script detects — `Arc`/`Rc` deferred drop, `repr(C)` padding bytes, `static`/`LazyLock` secrets, async cancellation, `Cow` clones, and `mem::swap`. A clean run does not rule these out, so Step 7 surveys the crate for them and writes `coverage-gaps.json`. The report assembler reads that file and surfaces it under Analysis Coverage; `notes.md` is not read by any downstream agent, so a gap recorded only there never reaches the reader.

Step 1 — MIR Emission

Emit MIR (Mid-level Intermediate Representation) for the crate. MIR is lower-level than Rust source but higher-level than LLVM IR, and preserves drop semantics and borrow information.

{baseDir}/tools/emit_rust_mir.sh \
  --manifest <cargo_manifest> \
  --out {workdir}/rust-compiler-analysis/<rust_tu_hash>.mir

If emission fails:

  • Write error to `notes.md`
  • Write status-bearing error object to `mir-findings.json`
  • Skip Step 2 and continue with Step 3 (LLVM IR analysis can still run)

Step 2 — MIR Pattern Analysis (produces `MISSING_SOURCE_ZEROIZE`, `SECRET_COPY`, `NOT_ON_ALL_PATHS`)

uv run {baseDir}/tools/scripts/check_mir_patterns.py \
  --mir {workdir}/rust-compiler-analysis/<rust_tu_hash>.mir \
  --secrets {workdir}/source-analysis/sensitive-objects.json \
  --out {workdir}/rust-compiler-analysis/mir-findings.json

This detects:

  • `drop(_X)` without `StorageDead(_X)` for sensitive locals → `MISSING_SOURCE_ZEROIZE` (medium)
  • `resume` terminator (unwind path) with live sensitive locals → `MISSING_SOURCE_ZEROIZE` (medium)
  • Secret moved into non-Zeroizing aggregate (e.g. `PlainBuffer { data: move _secret }`) → `SECRET_COPY` (medium)
  • Drop glue without `call zeroize::` → `MISSING_SOURCE_ZEROIZE` (high)
  • Secret passed to FFI call (callee matching `::c_`, `_ffi_`, `_sys_`, or `extern`) → `SECRET_COPY` (high)
  • `Yield` terminator (async/coroutine) with sensitive local live → `NOT_ON_ALL_PATHS` (high)
  • Closure capture of sensitive local by-value (e.g. `move |...| { ... sensitive_var ... }`) → `SECRET_COPY` (high)
  • `Result::Err(...)` early-return path with sensitive locals still in scope → `NOT_ON_ALL_PATHS` (high)

IDs: `F-RUST-MIR-NNNN` (sequential, zero-padded to 4 digits).

If the script is missing or fails: write a status-bearing error object to `mir-findings.json` and continue:

{
  "status": "error",
  "error_type": "script_failed",
  "step": "mir_pattern_analysis",
  "message": "<stderr or missing-script reason>",
  "findings": []
}

Step 3 — LLVM IR Emission

Emit LLVM IR at each optimization level in `opt_levels`. Always include O0 as the unoptimized baseline.

# O0 baseline (always):
{baseDir}/tools/emit_rust_ir.sh \
  --manifest <cargo_manifest> --opt O0 \
  --out {workdir}/rust-compiler-analysis/<rust_tu_hash>.O0.ll

# For each level in opt_levels (e.g. O2):
{baseDir}/tools/emit_rust_ir.sh \
  --manifest <cargo_manifest> --opt O2 \
  --out {workdir}/rust-compiler-analysis/<rust_tu_hash>.O2.ll

If O0 emission fails: write error to `notes.md`, write status-bearing error object to `ir-findings.json`, skip Step 4. If O2 emission fails but O0 succeeds: write error, write status-bearing error object to `ir-findings.json`, skip Step 4.

Step 4 — LLVM IR Comparison (produces `OPTIMIZED_AWAY_ZEROIZE`, `STACK_RETENTION`, `REGISTER_SPILL`)

Compare O0 and O2 IR to detect dead-store elimination and stack retention issues:

uv run {baseDir}/tools/sc
Read more
@trailofbits
Ships withskills

Trail of Bits skills and plugins for AI-assisted security analysis, testing, and development. Install this marketplace in Claude Code or Codex, or import it into your ChatGPT workspace marketplace.

7.9k95 skills30 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
7.9k
Star history of trailofbits/skills on GitHub, a chart by star-history.com

Other agents on skills.

function-analyzer

function-analyzer

Agent

Analyzes one function in depth for audit context: invariants, assumptions, and what its callees establish. Writes the prose…

@trailofbits@trailofbitsInstall Agent
c-review-worker

c-review-worker

Agent

Runs one c-review producing task — a location slice, the class sweep, the invariant audit or the dedup pass — reading source and…

@trailofbits@trailofbitsInstall Agent
fixer

fixer

Agent

Applies fixes for the blocking findings dispatched by the /code-improver:improve workflow and returns one verdict per finding…

@trailofbits@trailofbitsInstall Agent
adversarial-modeler

adversarial-modeler

Agent

Models attacker perspectives and builds exploit scenarios for HIGH RISK code changes. Use when differential review identifies…

@trailofbits@trailofbitsInstall Agent

More agents from other plugins.

dependency-review

dependency-review

Agent

<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. --> <!--…

@nvidia@nvidiaInstall Agent
autopilot

autopilot

Agent

Autonomous hunt loop agent. Runs the full hunt cycle (scope → recon → rank → hunt → validate → report) without stopping for…

@awarexone@awarexoneInstall Agent
autopilot

autopilot

Agent

Autonomous hunt loop agent. Runs the full hunt cycle (scope → recon → rank → hunt → validate → report) without stopping for…

@shuvonsec@shuvonsecInstall Agent
SELF-TEST

SELF-TEST

Agent

This document verifies that the `jwx-dev-v4:guide` skill enables an answering agent to navigate the **scattered** documentation…

jwx2w2.4k
@lestrrat-go@lestrrat-goInstall Agent

Questions about 3b-rust-compiler-analyzer.

Which coding agents can use 3b-rust-compiler-analyzer?
3b-rust-compiler-analyzer installs in Claude Code and Cursor: each loads subagents from .claude/agents, so copy the file there. Flowy's auto-invocation runs in Claude Code only.