Message ID | ecbccca7b88acfd07164623c40f93cf0842645d3.1688716558.git.pabeni@redhat.com (mailing list archive) |
---|---|
State | Accepted |
Commit | c329b261afe71197d9da83c1f18eb45a7e97e089 |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net] net: prevent skb corruption on frag list segmentation | expand |
On Fri, Jul 7, 2023 at 10:11 AM Paolo Abeni <pabeni@redhat.com> wrote: > > Ian reported several skb corruptions triggered by rx-gro-list, > collecting different oops alike: > > Reported-by: Ian Kumlien <ian.kumlien@gmail.com> > Tested-by: Ian Kumlien <ian.kumlien@gmail.com> > Fixes: 3a1296a38d0c ("net: Support GRO/GSO fraglist chaining.") > Signed-off-by: Paolo Abeni <pabeni@redhat.com> > Reviewed-by: Eric Dumazet <edumazet@google.com>
Hello: This patch was applied to netdev/net.git (main) by David S. Miller <davem@davemloft.net>: On Fri, 7 Jul 2023 10:11:10 +0200 you wrote: > Ian reported several skb corruptions triggered by rx-gro-list, > collecting different oops alike: > > [ 62.624003] BUG: kernel NULL pointer dereference, address: 00000000000000c0 > [ 62.631083] #PF: supervisor read access in kernel mode > [ 62.636312] #PF: error_code(0x0000) - not-present page > [ 62.641541] PGD 0 P4D 0 > [ 62.644174] Oops: 0000 [#1] PREEMPT SMP NOPTI > [ 62.648629] CPU: 1 PID: 913 Comm: napi/eno2-79 Not tainted 6.4.0 #364 > [ 62.655162] Hardware name: Supermicro Super Server/A2SDi-12C-HLN4F, BIOS 1.7a 10/13/2022 > [ 62.663344] RIP: 0010:__udp_gso_segment (./include/linux/skbuff.h:2858 > ./include/linux/udp.h:23 net/ipv4/udp_offload.c:228 net/ipv4/udp_offload.c:261 > net/ipv4/udp_offload.c:277) > [ 62.687193] RSP: 0018:ffffbd3a83b4f868 EFLAGS: 00010246 > [ 62.692515] RAX: 00000000000000ce RBX: 0000000000000000 RCX: 0000000000000000 > [ 62.699743] RDX: ffffa124def8a000 RSI: 0000000000000079 RDI: ffffa125952a14d4 > [ 62.706970] RBP: ffffa124def8a000 R08: 0000000000000022 R09: 00002000001558c9 > [ 62.714199] R10: 0000000000000000 R11: 00000000be554639 R12: 00000000000000e2 > [ 62.721426] R13: ffffa125952a1400 R14: ffffa125952a1400 R15: 00002000001558c9 > [ 62.728654] FS: 0000000000000000(0000) GS:ffffa127efa40000(0000) > knlGS:0000000000000000 > [ 62.736852] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 > [ 62.742702] CR2: 00000000000000c0 CR3: 00000001034b0000 CR4: 00000000003526e0 > [ 62.749948] Call Trace: > [ 62.752498] <TASK> > [ 62.779267] inet_gso_segment (net/ipv4/af_inet.c:1398) > [ 62.787605] skb_mac_gso_segment (net/core/gro.c:141) > [ 62.791906] __skb_gso_segment (net/core/dev.c:3403 (discriminator 2)) > [ 62.800492] validate_xmit_skb (./include/linux/netdevice.h:4862 > net/core/dev.c:3659) > [ 62.804695] validate_xmit_skb_list (net/core/dev.c:3710) > [ 62.809158] sch_direct_xmit (net/sched/sch_generic.c:330) > [ 62.813198] __dev_queue_xmit (net/core/dev.c:3805 net/core/dev.c:4210) > net/netfilter/core.c:626) > [ 62.821093] br_dev_queue_push_xmit (net/bridge/br_forward.c:55) > [ 62.825652] maybe_deliver (net/bridge/br_forward.c:193) > [ 62.829420] br_flood (net/bridge/br_forward.c:233) > [ 62.832758] br_handle_frame_finish (net/bridge/br_input.c:215) > [ 62.837403] br_handle_frame (net/bridge/br_input.c:298 > net/bridge/br_input.c:416) > [ 62.851417] __netif_receive_skb_core.constprop.0 (net/core/dev.c:5387) > [ 62.866114] __netif_receive_skb_list_core (net/core/dev.c:5570) > [ 62.871367] netif_receive_skb_list_internal (net/core/dev.c:5638 > net/core/dev.c:5727) > [ 62.876795] napi_complete_done (./include/linux/list.h:37 > ./include/net/gro.h:434 ./include/net/gro.h:429 net/core/dev.c:6067) > [ 62.881004] ixgbe_poll (drivers/net/ethernet/intel/ixgbe/ixgbe_main.c:3191) > [ 62.893534] __napi_poll (net/core/dev.c:6498) > [ 62.897133] napi_threaded_poll (./include/linux/netpoll.h:89 > net/core/dev.c:6640) > [ 62.905276] kthread (kernel/kthread.c:379) > [ 62.913435] ret_from_fork (arch/x86/entry/entry_64.S:314) > [ 62.917119] </TASK> > > [...] Here is the summary with links: - [net] net: prevent skb corruption on frag list segmentation https://git.kernel.org/netdev/net/c/c329b261afe7 You are awesome, thank you!
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 6c5915efbc17..a298992060e6 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4261,6 +4261,11 @@ struct sk_buff *skb_segment_list(struct sk_buff *skb, skb_push(skb, -skb_network_offset(skb) + offset); + /* Ensure the head is writeable before touching the shared info */ + err = skb_unclone(skb, GFP_ATOMIC); + if (err) + goto err_linearize; + skb_shinfo(skb)->frag_list = NULL; while (list_skb) {