diff --git a/.cargo/audit.toml b/.cargo/audit.toml new file mode 100644 index 0000000..d0852f4 --- /dev/null +++ b/.cargo/audit.toml @@ -0,0 +1,56 @@ +# cargo-audit configuration — supply-chain CVE scanning policy. +# +# cargo-audit auto-reads this file from `.cargo/audit.toml`. Run it locally +# with `just audit`, which uses the exact same flags as the CI `cargo-audit` +# job so local and CI results match. +# +# Failure policy (set via CLI flags in `just audit` and CI, NOT here, because +# cargo-audit's `[output]` config table requires a complete field set): +# +# cargo audit --deny unmaintained --deny unsound +# +# That fails the build on any vulnerability (always denied by default), any +# unmaintained advisory, or any unsound advisory that is NOT explicitly listed +# in `[advisories] ignore` below. A new advisory of these kinds fails CI until +# it is either fixed (bump the offending dependency) or triaged into the ignore +# list with a justification. This is what keeps the policy from being +# "warnings-only". +# +# Yanked crates are reported as informational warnings only, not build +# failures: a plain yanked crate carries no RustSec advisory ID, so it cannot +# be individually justified/ignored here (ignores are keyed by advisory ID). +# Anything genuinely dangerous about a yanked crate surfaces as a separate +# vulnerability / unmaintained / unsound advisory, which IS denied. Currently +# yanked (informational only): core2 0.4.0 (also covered by RUSTSEC-2026-0105 +# below) and uds_windows 1.2.0 (Windows-only zbus transport, `cfg(windows)`, +# never compiled on facelock's Linux targets). +# +# Every ignore entry MUST carry an inline justification. Do not blanket-ignore. +# When a fix ships (a dependency bump that drops the advisory), delete the +# ignore rather than leaving it to rot. + +[advisories] +ignore = [ + # quick-xml 0.39.x — quadratic parse time / unbounded namespace allocation + # DoS. Fixed in >=0.41.0, but our only path to quick-xml is the build-time + # proc-macro `wayland-scanner` (v0.31.10 pins quick-xml ^0.39, so + # `cargo update` cannot lift it). wayland-scanner parses the trusted Wayland + # protocol XML shipped inside the wayland-* crates at compile time; it never + # sees attacker-controlled runtime input, and no quick-xml code runs in the + # auth path or any shipped binary. Revisit when smithay-client-toolkit / + # wayland-scanner ship a release built on quick-xml >=0.41. + "RUSTSEC-2026-0194", + "RUSTSEC-2026-0195", + + # core2 0.4.0 — unmaintained (all versions yanked). Transitive via + # image -> ravif -> rav1e -> bitstream-io, i.e. the AVIF *encoder*. facelock + # only decodes camera frames; the AVIF encode path is never exercised at + # runtime. No maintained successor is wired up upstream. Revisit when + # image / rav1e drop the core2 dependency. + "RUSTSEC-2026-0105", + + # paste 1.0.15 — unmaintained proc-macro (build-time only). Transitive via + # rav1e. Runs only at compile time and ships no runtime code; rav1e has not + # migrated to a maintained replacement yet. Revisit when rav1e drops paste. + "RUSTSEC-2024-0436", +] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30de1b8..b6cd61a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,6 +65,37 @@ jobs: target/release/libpam_facelock.so retention-days: 1 + cargo-audit: + name: Supply-chain Audit (cargo-audit) + runs-on: ubuntu-latest + container: archlinux:base-devel + # Override the workflow-level -Dwarnings: this job compiles cargo-audit's + # own third-party dependency tree, which we don't control. A future + # warning upstream shouldn't fail this job for reasons unrelated to the + # audit itself. The real build/test/clippy jobs above keep -Dwarnings. + env: + RUSTFLAGS: "" + steps: + - name: Install system dependencies + run: | + pacman -Syu --noconfirm \ + git \ + rust + + - uses: actions/checkout@v6 + + - name: Cache cargo registry and cargo-audit build + uses: Swatinem/rust-cache@v2 + + - name: Install cargo-audit + run: cargo install cargo-audit --locked + + # Ignore policy (with justifications) lives in .cargo/audit.toml. + # Deny policy matches `just audit`: fail on any vulnerability (default), + # unmaintained, or unsound advisory that is not explicitly ignored. + - name: Run cargo audit + run: cargo audit --deny unmaintained --deny unsound + tpm-tests: name: TPM Tests (swtpm) runs-on: ubuntu-latest diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ba425f6..b80dd47 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,6 +47,19 @@ The PAM module (`pam-facelock`) must stay lightweight: **libc, toml, serde, zbus Each crate has a defined dependency boundary. See `AGENTS.md` for the full table. +### Supply-chain auditing + +```bash +just audit # cargo audit --deny unmaintained --deny unsound +``` + +`just audit` scans the full `Cargo.lock` for RustSec advisories and mirrors the +CI `cargo-audit` job. It fails on any vulnerability, unmaintained, or unsound +advisory that is not explicitly ignored. The ignore list, with a justification +per entry, lives in `.cargo/audit.toml`; add a new entry (with a reason) only +when an advisory is genuinely non-exploitable here and cannot yet be fixed by a +dependency bump. Requires `cargo install cargo-audit --locked`. + ## Testing ### Tier 1: Unit tests (no hardware) @@ -88,7 +101,7 @@ Only after tiers 3--4 pass. Always keep a root shell open. Start with `sudo` onl ### All checks at once ```bash -just check # runs test + clippy + fmt +just check # runs test + clippy + fmt + audit ``` ## Security considerations diff --git a/Cargo.lock b/Cargo.lock index ccd9127..4ad8d84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -131,9 +131,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" [[package]] name = "arbitrary" @@ -1062,7 +1062,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -2217,9 +2217,9 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] @@ -2686,9 +2686,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" -version = "0.39.2" +version = "0.39.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" +checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" dependencies = [ "memchr", ] @@ -2715,15 +2715,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" dependencies = [ "aws-lc-rs", "bytes", "getrandom 0.3.4", "lru-slab", - "rand 0.9.2", + "rand 0.9.4", "ring", "rustc-hash 2.1.2", "rustls", @@ -2772,9 +2772,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" dependencies = [ "rand_chacha", "rand_core 0.9.5", @@ -2852,7 +2852,7 @@ dependencies = [ "num-traits", "paste", "profiling", - "rand 0.9.2", + "rand 0.9.4", "rand_chacha", "simd_helpers", "thiserror", @@ -3059,14 +3059,14 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.37" +version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ "aws-lc-rs", "once_cell", @@ -3116,7 +3116,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -3127,9 +3127,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ "aws-lc-rs", "ring", @@ -3520,7 +3520,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -4315,7 +4315,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] diff --git a/justfile b/justfile index 40ca5cf..d2b61d5 100644 --- a/justfile +++ b/justfile @@ -30,8 +30,14 @@ fmt-check: fmt: cargo fmt --all -# Run all checks (test + lint + format) -check: test lint fmt-check +# Scan the dependency tree for RustSec advisories (mirrors the CI cargo-audit job). +# Ignore policy lives in .cargo/audit.toml; deny policy is set here so CI matches. +# Requires cargo-audit: cargo install cargo-audit --locked +audit: + cargo audit --deny unmaintained --deny unsound + +# Run all checks (test + lint + format + audit) +check: test lint fmt-check audit # Build the PAM test container image (uses host-built release binaries) _build-test-container: build-release