Skip to content

ban_raw_subprocess dylint: enforce wrapper for all subprocess spawns #264

Description

@zackees

Follow-up to #261 / PR #262.

Goal

Land the custom ban_raw_subprocess dylint that forbids direct std::process::Command::{spawn,output,status} and tokio::process::Command::{spawn,output,status} outside an allowlist, so all subprocess spawns are forced through fbuild_core::subprocess::run_command (NativeProcess wrapper) or fbuild_core::containment::{spawn_contained, spawn_detached, tokio_spawn::spawn_contained} (containment wrappers).

This was prototyped in #262 (commit 634e9e5) and reverted before merge.

Why it was deferred

PR #262 attempted to land the dylint alongside the LTO fix, but ran into three CR blockers:

  1. CI integration is non-trivial. Published dylint_driver 5.0.0 doesnt build against the nightly-2026-03-26 toolchain that dylint_linting 5.0.0 wants. zccache solves this with ci/build_dylint_driver.py which clones dylints git rev and builds a matching driver. fbuild needs the same script (or to find a published combo that works without it).

  2. Scope filter too loose. SOURCE_PREFIX = "crates/" matched crates/*/tests/, crates/*/examples/, crates/*/benches/ etc. Either tighten to crates/*/src/ or broaden the allowlist to cover all test/example/bench files using Command::* directly.

  3. Missing qpath handling. The check_expr arm only handles ExprKind::MethodCall. Qualified-path calls (<Command>::spawn(&mut cmd), tokio::process::Command::spawn(&mut cmd)) also need to be caught via ExprKind::Call + qpath_res.

Acceptance criteria

  • Port ci/build_dylint_driver.py from zccache so CI can run cargo dylint --all.
  • Tighten or broaden the source-file scope per (2); allowlist any remaining legitimate raw-spawn test files.
  • Extend the lint to handle ExprKind::Call qualified-path syntax (mirror zccache's pattern for both call shapes).
  • CI step on check-ubuntu.yml runs the dylint with -D warnings and passes.

Reference

  • zccache pattern: ~/dev/zccache/dylints/ban_raw_subprocess_in_daemon/, ci/build_dylint_driver.py, .github/workflows/ci.yml::dylint job.
  • Prototype on the reverted PR fix(linker): redirect GCC LTO temp dir (#261) #262 commit 634e9e5: dylints/ban_raw_subprocess/{Cargo.toml,Cargo.lock,README.md,rust-toolchain.toml,src/lib.rs,src/allowlist.txt}.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions