[PATCH AUTOSEL 6.18-5.10] netfilter: nf_conntrack: use get_unaligned_be32() in tcp_sack()

Sasha Levin <[email protected]>
Newsgroups gmane.comp.security.firewalls.netfilter.devel,gmane.linux.kernel.stable,gmane.linux.network,gmane.linux.kernel
Message-ID <[email protected]>
From: Rosen Penev <[email protected]>

[ Upstream commit d3bf9eae486490832bd08fd62ab0ac601f346bd4 ]

The timestamp-only fast path dereferences the option stream as
*(__be32 *)ptr, which assumes 4-byte alignment that the TCP option
stream does not guarantee. Use get_unaligned_be32() instead, which
reads the value safely and already returns host byte order, so the
htonl() on the comparison constant can be dropped.

This matches the existing get_unaligned_be32() use later in the same
function.

Assisted-by: Claude:Opus-4.7
Signed-off-by: Rosen Penev <[email protected]>
Reviewed-by: Fernando Fernandez Mancera <[email protected]>
Signed-off-by: Pablo Neira Ayuso <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit Message Forensics

**Step 1.1 — Subject line**
- Record: `[netfilter: nf_conntrack]` `[use]` — replace unsafe aligned
  32-bit dereference in `tcp_sack()` timestamp fast path with
  `get_unaligned_be32()`.

**Step 1.2 — Tags**
- Record:
  - `Assisted-by: Claude:Opus-4.7`
  - `Signed-off-by: Rosen Penev <[email protected]>`
  - `Reviewed-by: Fernando Fernandez Mancera <[email protected]>`
  - `Signed-off-by: Pablo Neira Ayuso <[email protected]>` (subsystem
    maintainer)
  - No `Fixes:`, `Reported-by:`, `Cc: [email protected]`, or
    `Link:` tags
  - Notable: maintainer review and commit; reviewer independently
    spotted the same issue

**Step 1.3 — Body**
- Record:
  - **Bug:** `*(__be32 *)ptr` in the timestamp-only fast path assumes
    4-byte alignment of the TCP option stream
  - **Symptom:** Unaligned memory access on architectures that require
    alignment (kernel trap/oops); undefined behavior elsewhere
  - **Root cause:** TCP options are not guaranteed 4-byte aligned;
    `skb_header_pointer()` often returns a pointer directly into skb
    linear data at a misaligned offset
  - **Fix:** Use `get_unaligned_be32()`, matching the existing SACK
    parsing code in the same function

**Step 1.4 — Hidden bug fix?**
- Record: Yes — despite not using "fix" in the subject, this is a
  correctness/memory-safety bug fix, not cleanup or optimization.

---

## Phase 2: Diff Analysis

**Step 2.1 — Inventory**
- Record:
  - 1 file: `net/netfilter/nf_conntrack_proto_tcp.c` (+5/-5 lines)
  - Function: `tcp_sack()`
  - Scope: Single-file, surgical fix

**Step 2.2 — Code flow**
- Record:
  - **Before:** Fast path for timestamp-only TCP options used `*(__be32
    *)ptr == htonl(...)` — aligned 32-bit read
  - **After:** Uses `get_unaligned_be32(ptr) == (...)` — safe unaligned
    read; `htonl()` dropped because `get_unaligned_be32()` returns host
    byte order
  - **Path:** Hot path in `tcp_sack()` when `length ==
    TCPOLEN_TSTAMP_ALIGNED` (12 bytes = NOP/NOP/TIMESTAMP option only)

**Step 2.3 — Bug mechanism**
- Record:
  - **Category:** Memory safety / unaligned access (same class as commit
    `534f81a506879` from 2009 in the same function)
  - **Mechanism:** `ptr` from `skb_header_pointer()` points at
    `skb->data + dataoff + sizeof(tcphdr)`. For typical Ethernet+IPv4,
    options start at offset 54 (54 % 4 = 2), so `*(__be32 *)ptr` is an
    unaligned access when skb data is linear

**Step 2.4 — Fix quality**
- Record:
  - Obviously correct: mirrors the existing `get_unaligned_be32()` use
    at line 442 in the same function
  - Minimal, no unrelated changes
  - Low regression risk: `get_unaligned_be32()` is already included via
    `<linux/unaligned.h>` and used in this file
  - Byte-order handling is correct (constant built in host order,
    compared to host-order return value)

---

## Phase 3: Git History Investigation

**Step 3.1 — Blame**
- Record:
  - Fast path introduced in `9fb9cbb1082d6` (Nov 2005, nf_conntrack
    subsystem creation)
  - Aligned dereference `*(__be32 *)ptr` from `8f05ce91c8b801` (Mar
    2007)
  - Bug has been present since 2007 in this code path

**Step 3.2 — Fixes: tag**
- Record: N/A — no `Fixes:` tag in commit message

**Step 3.3 — Related file history**
- Record:
  - `534f81a506879` (Mar 2009): fixed unaligned access in SACK option
    parsing loop in the same `tcp_sack()` function (SPARC64 kernel
    unaligned access reports) — fast path was missed
  - `bb9fc37358ffa` (Aug 2011): fixed `TCPOLEN_TSTAMP_ALIGNED*4` typo so
    the fast path actually runs
  - Standalone single-patch series (v1 only); no prerequisites

**Step 3.4 — Author context**
- Record: Rosen Penev is a regular netfilter contributor; patch
  committed by Pablo Neira Ayuso (netfilter maintainer)

**Step 3.5 — Dependencies**
- Record: None. `get_unaligned_be32()` and `<linux/unaligned.h>` already
  present in this tree's version of the file.

---

## Phase 4: Mailing List and External Research

**Step 4.1 — Original discussion**
- Record:
  - Lore URL:
    https://patch.msgid.link/[email protected]
  - Single v1 patch, no revisions
  - Fernando Fernandez Mancera: independently spotted the same issue; "I
    think this is for correctness too"; `Reviewed-by`
  - Pablo Neira Ayuso: committed with humorous "Missing
    put_unaligned_be32(), BTW." (read path only)
  - No NAKs or objections

**Step 4.2 — Reviewers**
- Record: CC'd to netfilter-devel, netdev, Pablo Neira, Florian
  Westphal, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni —
  appropriate maintainers included

**Step 4.3 — Bug report**
- Record: No syzbot or user bug report for this specific fast-path
  issue. Historical precedent: `534f81a506879` documented real SPARC64
  unaligned-access kernel messages from the same function's SACK path.

**Step 4.4 — Related patches**
- Record: Reviewer noted more unaligned-access audits may be needed
  elsewhere; this patch is self-contained

**Step 4.5 — Stable list**
- Record: Could not search lore stable archive (bot protection). No
  stable nomination found in the patch thread.

---

## Phase 5: Code Semantic Analysis

**Step 5.1 — Key functions**
- Record: `tcp_sack()` modified; callers unchanged

**Step 5.2 — Callers**
- Record:
  - `tcp_sack()` called from `tcp_in_window()` when `receiver->flags &
    IP_CT_TCP_FLAG_SACK_PERM`
  - `tcp_in_window()` called from `nf_conntrack_tcp_packet()` (line
    1254)
  - `nf_conntrack_tcp_packet()` is the main TCP conntrack packet handler
    — invoked on every tracked TCP packet through netfilter hooks

**Step 5.3 — Callees**
- Record: `skb_header_pointer()`, `get_unaligned_be32()` — standard
  skb/conntrack helpers

**Step 5.4 — Reachability**
- Record:
  - Reachable from all netfilter conntrack TCP traffic (routers,
    firewalls, NAT gateways, any `CONFIG_NF_CONNTRACK` system)
  - Fast path triggers on timestamp-only TCP options (`length == 12`) —
    very common on modern TCP stacks
  - Requires SACK negotiation (`IP_CT_TCP_FLAG_SACK_PERM`) — also common
  - Userspace can trigger via normal TCP connections through conntrack-
    enabled systems

**Step 5.5 — Similar patterns**
- Record: Same function already uses `get_unaligned_be32()` at line 442
  for SACK blocks (fixed in 2009). The fast path was the remaining
  unaligned dereference.

---

## Phase 6: Cross-Reference Against Local Tree

**Step 6.1 — Buggy code in tree**
- Record:
  - Local tree: **v6.18.44** (`git describe HEAD`)
  - Buggy code **present** at lines 408–412 of
    `net/netfilter/nf_conntrack_proto_tcp.c`
  - Bug present since 2007; not introduced after 6.18 branch point

**Step 6.2 — Backport complications**
- Record: `git apply --check` and `git cherry-pick --no-commit` both
  succeed — clean apply expected

**Step 6.3 — Related fixes already present**
- Record:
  - 2009 SACK-path unaligned fix (`534f81a506879`) is in tree
  - This specific fast-path fix (`d3bf9eae48649`) is **not** in tree
    (only on master)

---

## Phase 7: Subsystem Context

**Step 7.1 — Subsystem**
- Record: `net/netfilter` — nf_conntrack TCP tracker. Criticality:
  **CORE/IMPORTANT** (widely deployed on servers, routers, embedded
  systems with `CONFIG_NF_CONNTRACK`)

**Step 7.2 — Activity**
- Record: Actively maintained subsystem with frequent stable fixes in
  this tree

---

## Phase 8: Impact and Risk Assessment

**Step 8.1 — Who is affected**
- Record: Systems with `CONFIG_NF_CONNTRACK` processing TCP traffic —
  routers, firewalls, NAT, containers/VMs using conntrack. Not universal
  (config-dependent), but very common in production networking.

**Step 8.2 — Trigger conditions**
- Record:
  - Linear skb (common) where TCP options start at non-4-byte-aligned
    offset
  - Typical Ethernet+IPv4: options at offset 54 (mod 4 = 2) — verified
    by calculation
  - Timestamp-only option layout (length 12)
  - SACK negotiated on connection
  - **Likelihood:** High on affected architectures for normal TCP
    traffic

**Step 8.3 — Failure mode**
- Record:
  - Strict-alignment architectures (SPARC, some ARM/MIPS): kernel
    unaligned-access trap — severity **CRITICAL** (documented precedent
    in same function, 2009)
  - x86: usually tolerates unaligned access but technically undefined
    behavior
  - No data corruption path identified; primarily crash/trap risk

**Step 8.4 — Risk-benefit**
- Record:
  - **Benefit:** HIGH — prevents kernel faults on common TCP fast path
    in widely deployed code
  - **Risk:** VERY LOW — 5-line change, matches existing pattern in same
    function, reviewed by subsystem developer and maintainer
  - **Ratio:** Strong benefit, minimal risk

---

## Phase 9: Final Synthesis

**Step 9.1 — Evidence summary**

FOR backport:
- Real unaligned memory access bug in hot conntrack path
- Present since 2007; same function had identical-class fix in 2009 for
  SACK path
- Typical packet layouts place TCP options at 2-mod-4 offsets (verified)
- Small, surgical, obviously correct fix
- Reviewed by Fernando Fernandez Mancera; committed by netfilter
  maintainer Pablo Neira
- Applies cleanly to v6.18.44
- No new APIs or features

AGAINST backport:
- No syzbot report or user crash report for this specific fast path
- Only affects `CONFIG_NF_CONNTRACK` systems
- Most severe on strict-alignment architectures (smaller user base than
  x86)
- Impact on x86 is lower (unaligned access usually works)

UNRESOLVED:
- No explicit stable nomination in mailing list thread
- Lore stable archive search blocked

**Step 9.2 — Stable rules checklist**
1. Obviously correct and tested? **PASS** — matches existing in-function
   pattern; reviewed and committed by maintainers
2. Fixes a real bug? **PASS** — unaligned dereference on non-guaranteed-
   aligned data
3. Important issue? **PASS** — kernel trap/oops on strict-alignment
   arch; hot networking path
4. Small and contained? **PASS** — 1 file, ~5 lines changed
5. No new features/APIs? **PASS** — correctness fix only
6. Can apply to local tree? **PASS** — verified clean apply to v6.18.44

**Step 9.3 — Exception category**
- Record: Not a device-ID/quirk/DT/docs exception; qualifies as a core
  correctness/memory-safety fix

**Step 9.4 — Decision rationale**

This commit completes the unaligned-access fix started in 2009 for
`tcp_sack()`. The timestamp-only fast path — hit on very common TCP
packets — still uses an aligned `*(__be32 *)` dereference on data that
is typically 2-byte-aligned in standard Ethernet+IPv4 layouts. On
strict-alignment architectures this can cause kernel faults; the same
failure mode was already documented and fixed for the SACK parsing loop
in this exact function. The fix is minimal, follows an established
pattern already in the file, applies cleanly to the v6.18.44 tree, and
has maintainer review.

---

## Verification

- [Phase 1] Parsed commit message and tags from `git show d3bf9eae48649`
- [Phase 2] Diff analysis: 5-line change in `tcp_sack()` fast path
- [Phase 3] `git blame -L 407,413`: aligned dereference from 2007
  (`8f05ce91c8b801`)
- [Phase 3] `git show 534f81a506879`: prior SACK-path unaligned fix in
  same function (SPARC64)
- [Phase 3] `git show bb9fc37358ffa`: fast path length fix (2011)
- [Phase 3] `git log --grep`: no duplicate fix for this fast path in
  stable tree
- [Phase 4] `b4 dig -c d3bf9eae48649`: lore thread found
- [Phase 4] `b4 dig -w`: netdev/netfilter maintainers CC'd
- [Phase 4] `b4 dig -a`: single v1 patch
- [Phase 4] Mbox review: Reviewed-by from Fernando Fernandez Mancera;
  maintainer commit
- [Phase 5] `grep tcp_sack`: called from `tcp_in_window()` →
  `nf_conntrack_tcp_packet()`
- [Phase 5] Read `skb_header_pointer()` in `include/linux/skbuff.h`:
  returns direct skb pointer when linear
- [Phase 5] Python alignment calc: eth+ipv4 opts at offset 54 (mod 4 =
  2)
- [Phase 6] `git describe HEAD`: v6.18.44
- [Phase 6] Read current file lines 408–412: buggy code still present
- [Phase 6] `git apply --check` on patch: applies cleanly
- [Phase 6] `git cherry-pick --no-commit d3bf9eae48649`: auto-merge
  succeeds
- [Phase 6] `get_unaligned_be32` already at line 442; `#include
  <linux/unaligned.h>` at line 17
- [Phase 8] Failure mode: unaligned access trap on strict-alignment arch
  — CRITICAL severity class

**YES**

 net/netfilter/nf_conntrack_proto_tcp.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index e99ab1e88e9f8..4a23edf7107a5 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -405,11 +405,11 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
 		return;
 
 	/* Fast path for timestamp-only option */
-	if (length == TCPOLEN_TSTAMP_ALIGNED
-	    && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
-				       | (TCPOPT_NOP << 16)
-				       | (TCPOPT_TIMESTAMP << 8)
-				       | TCPOLEN_TIMESTAMP))
+	if (length == TCPOLEN_TSTAMP_ALIGNED &&
+	    get_unaligned_be32(ptr) == ((TCPOPT_NOP << 24) |
+					(TCPOPT_NOP << 16) |
+					(TCPOPT_TIMESTAMP << 8) |
+					TCPOLEN_TIMESTAMP))
 		return;
 
 	while (length > 0) {
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.