test(m8a): harden cutover artifacts for M9 (guard table_down, apply/rollback trap, idempotent handover drop)#164
Merged
Conversation
…ollback trap, idempotent handover drop)
Fixes the 3 MAJOR + 1 MINOR artifact-safety findings from the independent
M8a review (Part B) before M9 runs these on tron's host:
(a) cutover_table_down is GUARDED — it now deletes only a table THIS tool
created: a protected-name denylist (voicefw + system tables) AND an
ownership sentinel chain that cutover_table_up installs. A stray
NFT_TABLE=voicefw can no longer wipe the live firewall (trusted-source
allowlist, SIP 45070 drop, RTP 20000-20100 drop). README M9 example now
uses the default SEPARATE cutover table (coexists with voicefw at
priority -10) instead of NFT_TABLE=voicefw.
(b) apply-fs-to-rustisk.sh + rollback-rustisk-to-fs.sh add an EXIT trap that
idempotently runs handover_drop_off on ANY failure path, so a
mid-sequence abort under set -euo pipefail never leaves the blanket
'udp dport <PORT> drop' stuck ON (phone outage).
(c) handover_drop_on is idempotent (a second call is a no-op, no duplicate
rule); handover_drop_off removes ALL handover rules (was head -n1 = one).
(d) RESULTS.md rollback mechanism-floor window widened to ~38-52 ms to match
the reproduced band.
Adds red-capable regression tests (safety-tests.sh + run-safety-tests.sh)
run in an ISOLATED container netns (--privileged --network none, synthetic
ports 55071/55072, never 45070/RTP/host): each proves the pre-fix bug (RED)
and the fix (GREEN) — guard refuses foreign voicefw + owner-less table,
mid-sequence failure leaves 0 lingering drops, double-on+one-off leaves 0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
M8a cutover-artifact hardening (task #40, review Part B)
Fixes the 3 MAJOR + 1 MINOR artifact-safety findings from the independent
M8a review before M9 invokes these scripts LIVE on tron's host. Scope is
confined to
tests/m8a-cutover/(shell + docs + new isolated tests); no Rusttouched, so the Rust CI is unaffected.
Fixes
(a) MAJOR —
cutover_table_downcould delete the live firewall. The READMEM9 example set
NFT_TABLE=voicefw;cutover_table_downdid an unconditionalnft delete table inet voicefw, which wipes the entire live firewall (trustedallowlist, SIP 45070 drop, RTP 20000-20100 drop, v6 drops). Now:
cutover_table_downdeletes only a table this tool created — two gatesmust both pass: (1) a protected-name denylist (
voicefw filter nat mangle raw security), and (2) an ownership sentinel chain (m8a_cutover_owner,a never-hooked regular chain that
cutover_table_upinstalls). Either gatefailing => it refuses (returns 3) instead of deleting.
cutovertable(coexists with
voicefwat input-hook priority -10, both policy accept);NFT_TABLE=voicefwremoved.(b) MAJOR — no error trap => stuck handover drop.
apply-fs-to-rustisk.shand
rollback-rustisk-to-fs.sh(set -euo pipefail, no trap) left the blanketudp dport <PORT> dropON if any mid-sequence step failed (phone outage untilmanually cleared). Added an EXIT trap that idempotently runs
handover_drop_offon every exit path and preserves the original exit code.(c) MAJOR/MINOR — non-idempotent drop rules.
handover_drop_onstacked aduplicate on a second call;
handover_drop_offusedhead -n1(removed one).Now
drop_onis idempotent (second call = no-op) anddrop_offremoves ALLhandover rules.
(d) MINOR — window band.
RESULTS.mdrollback mechanism-floor windowwidened
~49–52 ms→~38–52 msto match the reproduced band.Red-capable tests (container-isolated)
New
safety-tests.sh+run-safety-tests.sh, run inside ONE isolated containernetns (
--privileged --network none, onlylo, host LAN NO ROUTE, own emptynft ruleset, synthetic ports 55071/55072 — never 45070 / RTP 20000-20100 /
the host firewall / live stack). Each test reproduces the pre-fix bug (RED) and
proves the fix (GREEN). Actual run transcript:
Regression: original proof still green
Re-ran
run-proof.shwith the guarded/idempotent/trap changes — the listener-swapproof still passes end-to-end (
M8a RESULT: PASS, RED teeth confirmed, detectorself-test all OK, source-drops 0/0, clean FS→RUSTISK→FS boundaries). All testing
was container-isolated; the host nftables, live
voicefwfirewall, port 45070,and RTP 20000-20100 were never touched.