Skip to content

print_linux_report reads the default stance unguarded, and no test would catch its removal #19

Description

@ghostpsalm

Summary

main.rs::print_linux_report (the --no-ui path) calls linux::default_policy::read(backend)
itself. Nothing executes that line under test, so deleting it would leave the gate green while
every headless report silently lost its default-inbound line.

This is the same defect PR #18 closed inside linux::bridge — it just closed it in one of the two
places the pattern occurs.

Where

  • src/main.rs:655print_linux_report, the fourth stance read.
  • Related residue from the same PR: nothing asserts that the 4-arg linux::bridge::to_result names
    default_policy::Sources::system(). PR linux/bridge: inject the default-inbound stance into to_result #18 shrank that hole from three call sites to one line but
    did not close it, and said so.

Detail

Found by a red-team pass on PR #18, which demonstrated the original hole empirically: it replaced
all three default_policy::read(backend) arguments in src/linux/bridge.rs with None and the
full gate still reported 224 passed; 0 failed. The same mutation now fails, because the bridge
reads the stance through one seam that a test can point at a temp file
(linux::default_policy::Sources / read_from, added in PR #18).

print_linux_report was named as out of scope in that plan rather than discovered afterwards.

Per CLAUDE.md ("The default-inbound row"), the verdict in the gaps between rules is what decides
whether a listening socket with no rule is exposed. Losing it from a headless report — the mode a
reviewer on someone else's host actually uses — is a correctness failure, not a cosmetic one.

Fix

Route print_linux_report through the same Sources/read_from seam and add a test that points it
at a temp defaults file, matching the_ufw_default_stance_is_read_through_the_supplied_sources in
src/linux/bridge.rs. Then consider whether the one remaining unpinned line — Sources::system()
inside to_result — is worth a seam of its own or is honestly irreducible.

Status: Confirmed

Reproduced by mutation on the pre-PR-#18 code. The main.rs site is unchanged and still has the hole.

Severity: Medium · Confirmed · from the PR #18 run record,
factory/runs/20260906-112236-bridge-totals-flake.json

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    accuracyCorrectness of counts/attributionbugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions