Message ID | 20250325095449.2594874-1-wangliang74@huawei.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net] ipv6: sit: fix skb_under_panic with overflowed needed_headroom | expand |
On Tue, 25 Mar 2025 17:54:49 +0800 Wang Liang wrote: > When create ipip6 tunnel, if tunnel->parms.link is assigned to the previous > created tunnel device, the dev->needed_headroom will increase based on the > previous one. Sorry for the inconvenience but could you repost this patch? Our CI was broken when you posted and we currently don't have a way to re-trigger it :(
在 2025/3/26 19:47, Jakub Kicinski 写道: > On Tue, 25 Mar 2025 17:54:49 +0800 Wang Liang wrote: >> When create ipip6 tunnel, if tunnel->parms.link is assigned to the previous >> created tunnel device, the dev->needed_headroom will increase based on the >> previous one. > Sorry for the inconvenience but could you repost this patch? > Our CI was broken when you posted and we currently don't have > a way to re-trigger it :( Ok, I will send this patch again.
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 39bd8951bfca..1662b735c5e3 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c @@ -1095,7 +1095,7 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb, } -static void ipip6_tunnel_bind_dev(struct net_device *dev) +static int ipip6_tunnel_bind_dev(struct net_device *dev) { struct ip_tunnel *tunnel = netdev_priv(dev); int t_hlen = tunnel->hlen + sizeof(struct iphdr); @@ -1134,7 +1134,12 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev) WRITE_ONCE(dev->mtu, mtu); hlen = tdev->hard_header_len + tdev->needed_headroom; } + + if (t_hlen + hlen > U16_MAX) + return -EOVERFLOW; + dev->needed_headroom = t_hlen + hlen; + return 0; } static void ipip6_tunnel_update(struct ip_tunnel *t, @@ -1452,7 +1457,9 @@ static int ipip6_tunnel_init(struct net_device *dev) tunnel->net = dev_net(dev); strcpy(tunnel->parms.name, dev->name); - ipip6_tunnel_bind_dev(dev); + err = ipip6_tunnel_bind_dev(dev); + if (err) + return err; err = dst_cache_init(&tunnel->dst_cache, GFP_KERNEL); if (err)
When create ipip6 tunnel, if tunnel->parms.link is assigned to the previous created tunnel device, the dev->needed_headroom will increase based on the previous one. If the number of tunnel device is sufficient, the needed_headroom can be overflowed. The overflow happens like this: ipip6_newlink ipip6_tunnel_create register_netdevice ipip6_tunnel_init ipip6_tunnel_bind_dev t_hlen = tunnel->hlen + sizeof(struct iphdr); // 40 hlen = tdev->hard_header_len + tdev->needed_headroom; // 65496 dev->needed_headroom = t_hlen + hlen; // 65536 -> 0 The value of LL_RESERVED_SPACE(rt->dst.dev) may be HH_DATA_MOD, that leads to a small skb allocated in __ip_append_data(), which triggers a skb_under_panic: ------------[ cut here ]------------ kernel BUG at net/core/skbuff.c:209! Oops: invalid opcode: 0000 [#1] PREEMPT SMP KASAN PTI CPU: 0 UID: 0 PID: 24133 Comm: test Tainted: G W 6.14.0-rc7-00067-g76b6905c11fd-dirty #1 Tainted: [W]=WARN Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.15.0-0-g2dd4b9b3f840-prebuilt.qemu.org 04/01/2014 RIP: 0010:skb_panic+0x156/0x1d0 Call Trace: <TASK> skb_push+0xc8/0xe0 fou_build_udp+0x31/0x3a0 gue_build_header+0xf7/0x150 ip_tunnel_xmit+0x684/0x3660 sit_tunnel_xmit__.isra.0+0xeb/0x150 sit_tunnel_xmit+0x2e3/0x2930 dev_hard_start_xmit+0x1a6/0x7b0 __dev_queue_xmit+0x2fa9/0x4120 neigh_connected_output+0x39e/0x590 ip_finish_output2+0x7bb/0x1f00 __ip_finish_output+0x442/0x940 ip_finish_output+0x31/0x380 ip_mc_output+0x1c4/0x6a0 ip_send_skb+0x339/0x570 udp_send_skb+0x905/0x1540 udp_sendmsg+0x17c8/0x28f0 udpv6_sendmsg+0x17f1/0x2c30 inet6_sendmsg+0x105/0x140 ____sys_sendmsg+0x801/0xc70 ___sys_sendmsg+0x110/0x1b0 __sys_sendmmsg+0x1f2/0x410 __x64_sys_sendmmsg+0x99/0x100 do_syscall_64+0x6e/0x1c0 entry_SYSCALL_64_after_hwframe+0x76/0x7e ---[ end trace 0000000000000000 ]--- Fix this by add check for needed_headroom in ipip6_tunnel_bind_dev(). Reported-by: syzbot+4c63f36709a642f801c5@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=4c63f36709a642f801c5 Fixes: c88f8d5cd95f ("sit: update dev->needed_headroom in ipip6_tunnel_bind_dev()") Signed-off-by: Wang Liang <wangliang74@huawei.com> --- net/ipv6/sit.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)