* [PATCH net 1/1] net: nsh: handle nested NSH headers during GSO [not found] <cover.1776597597.git.caoruide123@gmail.com> @ 2026-04-20 3:31 ` Ren Wei 2026-04-20 8:12 ` [syzbot ci] " syzbot ci 0 siblings, 1 reply; 2+ messages in thread From: Ren Wei @ 2026-04-20 3:31 UTC (permalink / raw) To: netdev Cc: davem, edumazet, kuba, pabeni, horms, jbenc, yuantan098, yifanwucs, tomapufckgml, bird, lx24, caoruide123, n05ec From: Ruide Cao <caoruide123@gmail.com> nsh_gso_segment() currently redispatches the inner payload through skb_mac_gso_segment() after stripping one NSH header. For nested NSH payloads, including Ethernet-encapsulated NSH payloads, this can cause repeated re-entry into nsh_gso_segment(). The existing validation added by commit af50e4ba34f4 ("nsh: fix infinite loop") only covers invalid header lengths and does not address repeated self-dispatch across nested NSH payload chains. Handle nested NSH headers iteratively in a single nsh_gso_segment() invocation. Unwrap consecutive NSH headers until the first non-NSH payload is reached, including the case where the next redispatch target is reached through ETH_P_TEB, segment that payload once, and then restore the full outer encapsulation on each output segment. Also route validation failures through the same unwind path so the skb state is restored after any partial unwrap. This keeps nested NSH GSO handling correct while avoiding recursive redispatch. Fixes: c411ed854584 ("nsh: add GSO support") Cc: stable@kernel.org Reported-by: Yuan Tan <yuantan098@gmail.com> Reported-by: Yifan Wu <yifanwucs@gmail.com> Reported-by: Juefei Pu <tomapufckgml@gmail.com> Reported-by: Xin Liu <bird@lzu.edu.cn> Co-developed-by: Xiao Liu <lx24@stu.ynu.edu.cn> Signed-off-by: Xiao Liu <lx24@stu.ynu.edu.cn> Signed-off-by: Ruide Cao <caoruide123@gmail.com> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn> --- net/nsh/nsh.c | 75 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/net/nsh/nsh.c b/net/nsh/nsh.c index bfb7758063f3..89c240c2ed7c 100644 --- a/net/nsh/nsh.c +++ b/net/nsh/nsh.c @@ -77,7 +77,7 @@ EXPORT_SYMBOL_GPL(nsh_pop); static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, netdev_features_t features) { - unsigned int outer_hlen, mac_len, nsh_len; + unsigned int outer_hlen, mac_len, nsh_len, total_pull_len = 0; struct sk_buff *segs = ERR_PTR(-EINVAL); u16 mac_offset = skb->mac_header; __be16 outer_proto, proto; @@ -88,40 +88,73 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb, outer_hlen = skb_mac_header_len(skb); mac_len = skb->mac_len; - if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN))) - goto out; - nsh_len = nsh_hdr_len(nsh_hdr(skb)); - if (nsh_len < NSH_BASE_HDR_LEN) - goto out; - if (unlikely(!pskb_may_pull(skb, nsh_len))) - goto out; + while (true) { + if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN))) + goto err; + nsh_len = nsh_hdr_len(nsh_hdr(skb)); + if (nsh_len < NSH_BASE_HDR_LEN) + goto err; + if (unlikely(!pskb_may_pull(skb, nsh_len))) + goto err; - proto = tun_p_to_eth_p(nsh_hdr(skb)->np); - if (!proto) - goto out; + proto = tun_p_to_eth_p(nsh_hdr(skb)->np); + if (!proto) + goto err; - __skb_pull(skb, nsh_len); + __skb_pull(skb, nsh_len); + total_pull_len += nsh_len; - skb_reset_mac_header(skb); - skb->mac_len = proto == htons(ETH_P_TEB) ? ETH_HLEN : 0; - skb->protocol = proto; + skb_reset_mac_header(skb); + skb->mac_len = proto == htons(ETH_P_TEB) ? ETH_HLEN : 0; + skb->protocol = proto; + + /* Keep unwrapping any payload that would redispatch back into + * nsh_gso_segment(), including Ethernet-encapsulated NSH. + */ + if (proto == htons(ETH_P_NSH)) + continue; + + if (proto == htons(ETH_P_TEB)) { + int depth = skb->mac_len; + + proto = skb_network_protocol(skb, &depth); + if (!proto) + goto err; + + if (proto == htons(ETH_P_NSH)) { + __skb_pull(skb, depth); + total_pull_len += depth; + + skb_reset_mac_header(skb); + skb->mac_len = 0; + skb->protocol = proto; + continue; + } + } + + break; + } features &= NETIF_F_SG; segs = skb_mac_gso_segment(skb, features); - if (IS_ERR_OR_NULL(segs)) { - skb_gso_error_unwind(skb, htons(ETH_P_NSH), nsh_len, - mac_offset, mac_len); - goto out; - } + if (IS_ERR_OR_NULL(segs)) + goto err; for (skb = segs; skb; skb = skb->next) { skb->protocol = outer_proto; - __skb_push(skb, nsh_len + outer_hlen); + __skb_push(skb, total_pull_len + outer_hlen); skb_reset_mac_header(skb); skb_set_network_header(skb, outer_hlen); skb->mac_len = mac_len; } + goto out; + +err: + if (total_pull_len) + skb_gso_error_unwind(skb, outer_proto, total_pull_len, + mac_offset, mac_len); + out: return segs; } -- 2.34.1 ^ permalink raw reply related [flat|nested] 2+ messages in thread
* [syzbot ci] Re: net: nsh: handle nested NSH headers during GSO 2026-04-20 3:31 ` [PATCH net 1/1] net: nsh: handle nested NSH headers during GSO Ren Wei @ 2026-04-20 8:12 ` syzbot ci 0 siblings, 0 replies; 2+ messages in thread From: syzbot ci @ 2026-04-20 8:12 UTC (permalink / raw) To: bird, caoruide123, davem, edumazet, horms, jbenc, kuba, lx24, n05ec, netdev, pabeni, tomapufckgml, yifanwucs, yuantan098 Cc: syzbot, syzkaller-bugs syzbot ci has tested the following series [v1] net: nsh: handle nested NSH headers during GSO https://lore.kernel.org/all/6112cce99b4e3571444a616d0fb19e91e2fcca72.1776597598.git.caoruide123@gmail.com * [PATCH net 1/1] net: nsh: handle nested NSH headers during GSO and found the following issue: WARNING in nsh_gso_segment Full report is available here: https://ci.syzbot.org/series/13f77bac-014d-4059-9187-fbdbcb6a6540 *** WARNING in nsh_gso_segment tree: net URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/netdev/net.git base: 0cf004ffb61cd32d140531c3a84afe975f9fc7ea arch: amd64 compiler: Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8 config: https://ci.syzbot.org/builds/193058cd-cd88-4bb0-a6e6-b43b6179fcd9/config syz repro: https://ci.syzbot.org/findings/446db72d-a630-471c-b369-2ef1f7b3b6ed/syz_repro ------------[ cut here ]------------ offset != (typeof(skb->mac_header))offset WARNING: ./include/linux/skbuff.h:3173 at skb_reset_mac_header include/linux/skbuff.h:3173 [inline], CPU#1: syz.1.20/5978 WARNING: ./include/linux/skbuff.h:3173 at nsh_gso_segment+0x833/0x12d0 net/nsh/nsh.c:107, CPU#1: syz.1.20/5978 Modules linked in: CPU: 1 UID: 0 PID: 5978 Comm: syz.1.20 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 RIP: 0010:skb_reset_mac_header include/linux/skbuff.h:3173 [inline] RIP: 0010:nsh_gso_segment+0x833/0x12d0 net/nsh/nsh.c:107 Code: 2f 08 00 00 48 8b 7c 24 60 44 89 f6 e8 46 83 e4 fd 48 85 c0 0f 84 20 08 00 00 e8 48 af 31 f6 e9 ab fb ff ff e8 3e af 31 f6 90 <0f> 0b 90 e9 43 fd ff ff e8 30 af 31 f6 90 0f 0b 90 e9 39 fe ff ff RSP: 0018:ffffc90004847220 EFLAGS: 00010293 RAX: ffffffff8b93aeb2 RBX: ffff88817362a6d8 RCX: ffff88810f088000 RDX: 0000000000000000 RSI: 0000000000010040 RDI: 0000000000010000 RBP: ffffc90004847390 R08: ffff88810f088000 R09: 0000000000000005 R10: 0000000000000005 R11: 0000000000000000 R12: 0000000000000000 R13: 0000000000010040 R14: dffffc0000000000 R15: 0000000000000074 FS: 00007f28e9ed36c0(0000) GS:ffff8882a9245000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000200000010000 CR3: 0000000170f06000 CR4: 00000000000006f0 Call Trace: <TASK> skb_mac_gso_segment+0x31c/0x690 net/core/gso.c:53 __skb_gso_segment+0x376/0x540 net/core/gso.c:124 skb_gso_segment include/net/gso.h:83 [inline] validate_xmit_skb+0xa21/0x14a0 net/core/dev.c:4039 validate_xmit_skb_list+0x84/0x120 net/core/dev.c:4089 sch_direct_xmit+0xdf/0x4c0 net/sched/sch_generic.c:357 __dev_xmit_skb net/core/dev.c:4209 [inline] __dev_queue_xmit+0x180f/0x3950 net/core/dev.c:4831 packet_snd net/packet/af_packet.c:3077 [inline] packet_sendmsg+0x3ebc/0x50f0 net/packet/af_packet.c:3109 sock_sendmsg_nosec net/socket.c:787 [inline] __sock_sendmsg net/socket.c:802 [inline] __sys_sendto+0x672/0x710 net/socket.c:2265 __do_sys_sendto net/socket.c:2272 [inline] __se_sys_sendto net/socket.c:2268 [inline] __x64_sys_sendto+0xde/0x100 net/socket.c:2268 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0x15f/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f28e8f9c819 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f28e9ed3028 EFLAGS: 00000246 ORIG_RAX: 000000000000002c RAX: ffffffffffffffda RBX: 00007f28e9216090 RCX: 00007f28e8f9c819 RDX: 00000000000100a6 RSI: 0000200000000180 RDI: 0000000000000005 RBP: 00007f28e9032c91 R08: 0000200000000140 R09: 0000000000000014 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f28e9216128 R14: 00007f28e9216090 R15: 00007ffd50249d78 </TASK> *** If these findings have caused you to resend the series or submit a separate fix, please add the following tag to your commit message: Tested-by: syzbot@syzkaller.appspotmail.com --- This report is generated by a bot. It may contain errors. syzbot ci engineers can be reached at syzkaller@googlegroups.com. To test a patch for this bug, please reply with `#syz test` (should be on a separate line). The patch should be attached to the email. Note: arguments like custom git repos and branches are not supported. ^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-04-20 8:12 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <cover.1776597597.git.caoruide123@gmail.com>
2026-04-20 3:31 ` [PATCH net 1/1] net: nsh: handle nested NSH headers during GSO Ren Wei
2026-04-20 8:12 ` [syzbot ci] " syzbot ci
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox