Skip to content

Appendix A-Production Hardening Reference

This appendix consolidates the hardening slices distributed throughout the curriculum. By week 24 the reader's hardening/ workspace should contain working examples of every section below.


A.1 Compiler-Driven Optimization

  • What it is: LLVM optimizes across crate boundaries at link time, enabling cross-crate inlining, dead-code elimination on monomorphized paths, and devirtualization.
  • Modes:
  • lto = false (default debug): per-codegen-unit only.
  • lto = "thin": ThinLTO. Parallel, fast, ~95% of fat-LTO's wins. Default for new release builds.
  • lto = "fat": full LTO. Single-threaded, slow, but produces the smallest/fastest binaries. Use for shipped binaries.
  • lto = "off": explicit opt-out (rare).
  • Combine with codegen-units = 1 for maximum cross-function optimization. The cost is parallelism: a single codegen unit cannot be compiled in parallel.
  • Cargo profile snippet:
    [profile.release]
    lto = "fat"
    codegen-units = 1
    panic = "abort"
    strip = "symbols"
    

A.1.2 Profile-Guided Optimization (PGO)

PGO uses runtime profiles to guide layout, inlining, and branch-prediction hints.

Workflow: 1. Instrument:

RUSTFLAGS="-Cprofile-generate=/tmp/pgo" \
  cargo build --release --target=x86_64-unknown-linux-gnu
2. Run a representative workload with the instrumented binary. The "representative" qualifier is the entire challenge of PGO; a synthetic benchmark gives you a binary tuned for synthetic benchmarks. 3. Merge profiles:
llvm-profdata merge -o /tmp/pgo/merged.profdata /tmp/pgo
4. Re-build with the profile:
RUSTFLAGS="-Cprofile-use=/tmp/pgo/merged.profdata" \
  cargo build --release --target=x86_64-unknown-linux-gnu

Expect ~5–15% throughput wins on hot paths. Do not enable PGO on first-shipping binaries; it adds build complexity for a marginal win. Enable once the workload is well-characterized.

A.1.3 BOLT (Binary Optimization and Layout Tool)

  • BOLT is a post-link optimizer that rewrites the binary based on perf record data. Stacks on top of PGO.
  • Workflow: build with - Wl,-qto keep relocations, runperf recordon a representative workload, runllvm-bolt` with the perf data.
  • Used in production by Meta and the rustc team itself (rustc's own binary is BOLTed).

A.1.4 target-cpu=native and feature gating

  • RUSTFLAGS="-C target-cpu=native" enables every ISA extension the build host supports-not portable. Use only for self-hosted services where the deployment hardware is known.
  • For portable binaries with runtime feature dispatch: is_x86_feature_detected!("avx2") plus multiversion macro for compile-time fan-out. Pattern from simd-json, rav1e.

A.2 Cross-Compilation

A.2.1 Targets to know

Triple Use case
x86_64-unknown-linux-musl Statically linked Linux server binaries; no glibc dependency.
aarch64-unknown-linux-gnu Graviton, Ampere, Apple Silicon Linux VMs.
aarch64-apple-darwin Apple Silicon native.
x86_64-pc-windows-msvc Windows native (preferred over gnu).
wasm32-unknown-unknown Browser/runtime-less WASM.
wasm32-wasip2 Server-side WASM with WASI.
thumbv7em-none-eabihf Cortex-M4F (no_std, embedded).
riscv64gc-unknown-linux-gnu RISC-V Linux.

A.2.2 Toolchain mechanics

  • rustup target add <triple> adds prebuilt std for the target.
  • For native deps (C libraries), use cross (cross build --target=...) which uses Docker images with the right toolchains pre-installed.
  • For pure-Rust crates, cargo zigbuild (using Zig as the C linker) is a popular zero-config alternative.

A.2.3 Static linking

  • musl + - C target-feature=+crt-static` produces a fully static binary. Ideal for distroless containers.
  • Beware: musl's allocator is slow; for performance-critical static binaries, use mimalloc or jemalloc as the global allocator.

A.3 Supply-Chain & Soundness Auditing

A.3.1 cargo-deny

  • License allowlist ([licenses]).
  • Banned crates ([bans])-used in Month 5 to enforce hexagonal layering.
  • Advisory database integration ([advisories]) for known CVEs.
  • Source allowlist ([sources])-only crates.io and your private registry.

A.3.2 cargo-audit

  • RustSec advisory database. Run on every CI build.
  • cargo audit fix for trivial yanks; for non-trivial CVEs, document the response in SECURITY.md.

A.3.3 cargo-geiger

  • Counts unsafe usage in your dependency tree. Outputs a "radioactivity score."
  • Use as a signal, not a gate: unsafe per se is not bad. A high score in a leaf crate (e.g., a serializer) is normal; a high score in a domain crate is a smell.
  • Track the score over time; sudden increases indicate a dependency added unsafe code in a minor bump.

A.3.4 cargo-vet

  • Mozilla's supply-chain audit tool. Lets your team certify specific crate-version pairs as audited; CI fails if an unaudited dep enters the graph.
  • Heavyweight; appropriate for high-assurance teams (browsers, kernels, payment systems).

A.3.5 cargo-semver-checks

  • Semantic-versioning lint. Catches API breakage that would require a major bump.
  • Run on every PR that touches a public crate.

A.3.6 cargo-machete and cargo-udeps

  • Detect unused dependencies. Each unused dep is a supply-chain liability.

A.4 Soundness Validation

A.4.1 Miri

  • Interpreter for MIR. Detects undefined behavior: dangling pointers, OOB access, type confusion, data races (with - Zmiri-many-seeds`).
  • cargo +nightly miri test. ~50–100× slower than native. Used in CI as a separate job.
  • Strict-provenance mode catches a class of bugs the default mode misses: - Zmiri-strict-provenance`.

A.4.2 Loom

  • Permutation-checker for concurrent code. Replace std::sync::* and std::thread::* with loom::sync::* and loom::thread::* under a feature gate; loom::model(|| ...) exhausts interleavings.
  • Used by tokio, crossbeam, parking_lot. Use it for any data structure with hand-written atomics.

A.4.3 ThreadSanitizer / AddressSanitizer / MemorySanitizer / LeakSanitizer

  • Nightly-only via - Z sanitizer=thread|address|memory|leak. Requires - Z build-std.
  • Catches dynamic UB at runtime. Stack on top of fuzzing for maximum coverage.

A.4.4 KANI

  • Bounded model checker for Rust (formal verification). Annotate functions with #[kani::proof], write harnesses, run cargo kani.
  • Ideal for cryptographic primitives, parsers, and unsafe invariants.

A.5 Reproducibility and Distribution

A.5.1 Reproducible builds

  • Pin rust-toolchain.toml.
  • Set SOURCE_DATE_EPOCH and avoid build.rs non-determinism (no system-time stamps, no environment leaks).
  • Build inside a deterministic container image (Nix, Bazel, or a pinned Docker tag with content hash).

A.5.2 cargo-dist

  • Generates GitHub Actions to build cross-platform release artifacts and installers (shell installer, Homebrew formula, MSI).
  • The recommended baseline distribution path for a CLI or daemon.

A.5.3 Signing and SBOM

  • cosign for artifact signatures (Sigstore).
  • cargo cyclonedx or cargo sbom for CycloneDX/SPDX SBOM generation.
  • Both are now compliance prerequisites in regulated environments.

A.6 The Hardening Workspace Structure

By week 24, the hardening/ workspace should contain:

hardening/
  .cargo/config.toml          # global RUSTFLAGS, target dirs
  rust-toolchain.toml         # pinned channel
  deny.toml                   # cargo-deny rules
  cargo-vet/                  # vet store
  ci/
    lint.yml                  # fmt + clippy
    test.yml                  # test + miri + loom + sanitizers
    cross.yml                 # cross-compilation matrix
    audit.yml                 # cargo audit + deny + geiger
    fuzz.yml                  # scheduled continuous fuzzing
    pgo.yml                   # PGO build pipeline
  scripts/
    pgo.sh                    # instrument-run-rebuild script
    bolt.sh                   # post-link BOLT pass
    bench-baseline.sh         # criterion baseline comparison
  RELEASE_CHECKLIST.md
  SECURITY.md
  THREAT_MODEL.md

This is the artifact that should accompany every Rust project you ship after week 24. It is the "boring" half of professional Rust.

Comments