[stable request] Backport b2870fc21601 to 6.1.y, 6.6.y, 6.12.y, 6.18.y
Smit Patel <[email protected]> Fri, 31 Jul 2026 09:18:37 -0400
| Newsgroups | gmane.linux.kernel.stable,gmane.comp.security.firewalls.netfilter.devel,gmane.linux.network |
|---|---|
| Message-ID | <CAM5kW9DyDSJz+W70HhzQL4TeY28GTcOxDvkPHnFBh7TotqiEVg@mail.gmail.com> |
Hi, Please consider picking up the following mainline commit for the stable trees listed below: commit b2870fc21601db9133bc70c48c603b487614fa3b "netfilter: br_netfilter: Reallocate headroom if necessary in neigh_hh_bridge()" Author: Lorenzo Bianconi <[email protected]>, 2026-05-14 Fixes: e179e6322ac33 ("netfilter: bridge-netfilter: Fix MAC header handling with IP DNAT") Requested trees: 6.1.y, 6.6.y, 6.12.y, 6.18.y neigh_hh_bridge() copies the aligned L2 header to skb->data - HH_DATA_ALIGN(ETH_HLEN), i.e. skb->data - 16, without checking that the skb has that much headroom. build_skb()-based receive paths leave skb->data only ETH_HLEN above skb->head, so the 8-byte copy starts two bytes below skb->head on every bridged packet that reaches the DNAT neighbour fast path - an oops or silent corruption of the adjacent page, depending on where the buffer falls. The commit carries a Fixes: tag but no Cc: stable, so it was never queued. It is in mainline from v7.1 onwards. I have verified it is present in 7.1.y and absent from 6.18.y, 6.12.y, 6.6.y and 6.1.y, so backporting to the trees above does not leave a gap for users moving to a newer series. This is not a theoretical concern. In addition to the report in the commit message (Airoha AN7581, 6.12.57), I hit it independently on unrelated hardware: a FriendlyElec NanoPi R76S (Rockchip RK3576, arm64) running 6.1.141 with Realtek's out-of-tree r8125 driver, which as of 9.016.01 uses a page-reuse build_skb() receive path. With br_netfilter loaded, bridge-nf-call-iptables=1 and NAT reflection rules able to match bridged traffic, the machine took 7 unclean reboots in 2.5 hours, with uptimes of 59, 3, 89, 22, 2, 27 and 4 minutes. Excerpt from the ramoops dump; the full dump is available on request: Unable to handle kernel write to read-only memory at virtual address ffff0000c213fffe ESR = 0x000000009600004f FSC = 0x0f: level 3 permission fault Internal error: Oops: 000000009600004f [#1] SMP CPU: 2 PID: 0 Comm: swapper/2 Tainted: G O 6.1.141 #1 Hardware name: FriendlyElec NanoPi R76S (DT) pc : br_nf_pre_routing_finish_bridge+0xd0/0x270 [br_netfilter] x2 : ffff0000c214000e x1 : 0000000000000000 x0 : ffff0000cf600000 Call trace: br_nf_pre_routing_finish_bridge+0xd0/0x270 [br_netfilter] br_nf_hook_thresh+0x124/0x140 [br_netfilter] br_nf_pre_routing_finish+0x180/0x490 [br_netfilter] br_nf_pre_routing+0x1d0/0x484 [br_netfilter] br_handle_frame+0x270/0x42c [bridge] __netif_receive_skb_core.constprop.0+0x274/0xed4 __netif_receive_skb_one_core+0x40/0x84 __netif_receive_skb+0x1c/0x6c process_backlog+0xcc/0x190 __napi_poll+0x3c/0x1e0 net_rx_action+0x350/0x3e0 handle_softirqs+0x110/0x2f0 x2 is skb->data, 14 bytes above the page at ffff0000c2140000, and the faulting address ffff0000c213fffe is exactly x2 - 0x10: 14 bytes of headroom where 16 are required. Keeping br_netfilter unloaded has kept the machine stable since - 15 hours and counting, against a pre-fix maximum of 89 minutes. These branches are where the affected configuration lives: OpenWrt 24.10 builds 6.6, current OpenWrt carries 6.12 and 6.18, and vendor BSPs are commonly on 6.1. The patch applies cleanly to all four requested trees (verified with both git apply and patch -F0). It does not apply to 5.15.y, which would need an adjusted patch; I am not requesting that here. Happy to test the resulting queue on the R76S. Disclosure per Documentation/process/generated-content.rst: the upstream branch survey and the apply-testing above were carried out with AI assistance. The hardware, the crash, the ramoops dumps and the workaround testing are my own. Assisted-by: Claude Code:claude-opus-5 Thanks, Smit