Re: [syzbot] [net?] WARNING in gre_tap_xmit (2)

From: Kuniyuki Iwashima
Date: Mon Apr 22 2024 - 12:11:36 EST


From: syzbot <syzbot+c298c9f0e46a3c86332b@xxxxxxxxxxxxxxxxxxxxxxxxx>
Date: Sat, 20 Apr 2024 11:35:04 -0700
> syzbot has bisected this issue to:
>
> commit 219eee9c0d16f1b754a8b85275854ab17df0850a
> Author: Florian Westphal <fw@xxxxxxxxx>
> Date: Fri Feb 16 11:36:57 2024 +0000
>
> net: skbuff: add overflow debug check to pull/push helpers
>
> bisection log: https://syzkaller.appspot.com/x/bisect.txt?x=167a954f180000
> start commit: 443574b03387 riscv, bpf: Fix kfunc parameters incompatibil..
> git tree: bpf
> final oops: https://syzkaller.appspot.com/x/report.txt?x=157a954f180000
> console output: https://syzkaller.appspot.com/x/log.txt?x=117a954f180000
> kernel config: https://syzkaller.appspot.com/x/.config?x=6fb1be60a193d440
> dashboard link: https://syzkaller.appspot.com/bug?extid=c298c9f0e46a3c86332b
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=14a94f00980000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=15bce6ab180000
>
> Reported-by: syzbot+c298c9f0e46a3c86332b@xxxxxxxxxxxxxxxxxxxxxxxxx
> Fixes: 219eee9c0d16 ("net: skbuff: add overflow debug check to pull/push helpers")

Testing same patch for this

#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 219eee9c0d16

diff --git a/net/nsh/nsh.c b/net/nsh/nsh.c
index f4a38bd6a7e0..1344653916c4 100644
--- a/net/nsh/nsh.c
+++ b/net/nsh/nsh.c
@@ -77,13 +77,15 @@ EXPORT_SYMBOL_GPL(nsh_pop);
static struct sk_buff *nsh_gso_segment(struct sk_buff *skb,
netdev_features_t features)
{
+ unsigned int tnl_hlen, mac_len, nsh_len;
struct sk_buff *segs = ERR_PTR(-EINVAL);
u16 mac_offset = skb->mac_header;
- unsigned int nsh_len, mac_len;
- __be16 proto;
+ __be16 tnl_proto, proto;

skb_reset_network_header(skb);

+ tnl_proto = skb->protocol;
+ tnl_hlen = skb->network_header - skb->mac_header;
mac_len = skb->mac_len;

if (unlikely(!pskb_may_pull(skb, NSH_BASE_HDR_LEN)))
@@ -113,11 +115,11 @@ static struct sk_buff *nsh_gso_segment(struct sk_buff *skb,
}

for (skb = segs; skb; skb = skb->next) {
- skb->protocol = htons(ETH_P_NSH);
- __skb_push(skb, nsh_len);
- skb->mac_header = mac_offset;
- skb->network_header = skb->mac_header + mac_len;
+ __skb_push(skb, nsh_len + tnl_hlen);
+ skb_reset_mac_header(skb);
+ skb->network_header = skb->mac_header + tnl_hlen;
skb->mac_len = mac_len;
+ skb->protocol = tnl_proto;
}

out: