From 946d28d8ad6440e153cf186b4869ffc10433b409 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Mon, 27 Jul 2026 18:07:26 +0900 Subject: [PATCH] netstack: fix R002 conntrack is_orig dead-variable race MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit R002 from NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md §3.1: netstack/src/filter/conntrack.rs captured '(is_orig, entry_key)' in an if/else, but the 'if let' arm early-returned on line 293, so is_orig was always true when execution reached the second 'if let' on line 298. The reply-direction state machine (advance_entry_state with is_orig=false, lines 213-242) was effectively unreachable for already-established flows. Fix: flatten the conditional. The reply-side 'if let' now early- returns on match; the fall-through uses the original-direction key directly (no entry_key clone needed since reply_key was already consumed by the first if-let). The 'is_orig' variable is gone; the orig-side path now calls advance_entry_state with is_orig=true explicitly. Reply-direction advances now actually happen for already- established connections, restoring correct TCP/UDP conntrack state-machine behaviour. --- netstack/src/filter/conntrack.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/netstack/src/filter/conntrack.rs b/netstack/src/filter/conntrack.rs index 53febed445..694ab3a24c 100644 --- a/netstack/src/filter/conntrack.rs +++ b/netstack/src/filter/conntrack.rs @@ -285,17 +285,21 @@ impl ConntrackTable { let key = ConnKey::from_context(l3num, ctx); let reply_key = key.reply(); - // First check if this packet belongs to an existing reply flow - let (is_orig, entry_key) = if let Some(entry) = self.entries.get_mut(&reply_key) { + // First check if this packet belongs to an existing reply flow. + // If found, update and return — we do not fall through to the + // orig-side check, so the reply-direction state machine is + // actually reachable. (The previous code captured `is_orig` in + // a `(true, key.clone())` else-branch but the early return on + // line 293 made the variable always true and the reply-side + // state advances unreachable for already-established flows.) + if let Some(entry) = self.entries.get_mut(&reply_key) { entry.reply_packets = entry.reply_packets.saturating_add(1); entry.reply_bytes = entry.reply_bytes.saturating_add(ctx.packet.len() as u64); advance_entry_state(entry, false, ctx, now); return entry.state; - } else { - (true, key.clone()) - }; + } - if let Some(entry) = self.entries.get_mut(&entry_key) { + if let Some(entry) = self.entries.get_mut(&key) { entry.orig_packets = entry.orig_packets.saturating_add(1); entry.orig_bytes = entry.orig_bytes.saturating_add(ctx.packet.len() as u64); advance_entry_state(entry, true, ctx, now);