Re: [PATCH v3] Subject: [PATCH] net: gro: fix double aggregation of flush-marked skbs
From: Shiming Cheng (成诗明) <hidden>
Date: 2026-07-03 01:27:21
Also in:
linux-arm-kernel, linux-mediatek, lkml, stable
On Thu, 2026-07-02 at 12:02 +0200, Paolo Abeni wrote:
Note: the patch subject is quite uncorrected On 6/30/26 4:35 AM, Shiming Cheng wrote:quoted
The new skb_gro_receive_list() function is missing a critical safety check present in the legacy skb_gro_receive() path. Specifically, it does not validate NAPI_GRO_CB(skb)->flush before allowing packet aggregation.skb_gro_receive_list() is not very "new" and definitely skb_gro_receive() is not legacy.
The wording here may need to be adjusted. I'm referring to the chronological order/which one came first. Updated: The skb_gro_receive_list() function is missing a critical safety check that exists in the skb_gro_receive() implementation. Specifically, it does not validate NAPI_GRO_CB(skb)->flush before allowing packet aggregation
quoted
This allows already-GRO'd packets with existing frag_list to be re-aggregated into a new GRO session, corrupting the frag_list chain structure. When skb_segment() attempts to unpack these malformed packets, it encounters invalid state and triggers a kernel panic. Scenario (Tethering/Device forwarding): 1. Driver: Generated aggregated packet P1 via LRO with frag_list 2. Dev A: Receives aggregated fraglist packet and flush flag set 3. Dev A: Re-enters GRO, skb_gro_receive_list() is called 4. Missing flush check allows re-aggregation despite flush flag 5. Frag_list chain becomes corrupted (loops or dangling refs) 6. Dev B: TX path calls skb_segment(), crashes on corrupted frag_listI can't parse the above. Is this something that can happen with in- tree drivers or do you need OoT module to trigger it? In any case please clarify the actual order and the involved driver. Possibly a stack strace leading to the critical aggregation could help.
We are hitting a GRO/LRO-related failure in a tethering scenario. On the RX path, the driver performs an LRO-style aggregation before handing packets to the stack. When `nfrags` exceeds 17, additional packets are no longer appended to the frags array, but are attached through `skb_shared_info(skb)->frag_list`. After that, the driver still passes the skb into `napi_gro_receive()`, so the same traffic goes through a second aggregation stage in GRO. In our tethering case, `NAPI_GRO_CB(skb)->is_flist = !sk`, so `is_flist` becomes `true`, and the skb follows the `SKB_GSO_FRAGLIST` path, eventually reaching `skb_gro_receive_list()`. The issue is that some later skbs may already carry their own `frag_list` as a result of the first aggregation done by the driver. When GRO links those skbs again into a new `frag_list` chain, the resulting skb layout becomes more complex than expected and eventually triggers the kernel exception. Actual skb relationships when the issue occurs is as follows. A->frag_list = B B->next = C C->frag_list = D In the observed layout, A already links `B -> C` through `frag_list`, while C itself still carries its own `frag_list -> D`. In other words, when GRO continues chaining skbs in `skb_gro_receive_list()`, the later skb is no longer a simple standalone packet, but an skb that already carries `shared_info->frag_list` from the driver-side LRO stage. This creates a nested `frag_list` layout and eventually triggers the kernel exception in our case.
quoted
Fix: Add NAPI_GRO_CB(skb)->flush validation to the early-return check in skb_gro_receive_list(), matching the defensive programming pattern of skb_gro_receive(). Fixes: 8928756d53d5 ("net: add fraglist GRO/GSO support")The fix tag is wrong, should be: Fixes: 3a1296a38d0c ('net: Support GRO/GSO fraglist chaining.')
I will update it in the next patch.
/P