* [PATCH net v1 1/3] virtio-net: fix incorrect flags recording in big mode
2025-10-11 9:41 [PATCH net v1 0/3] fixes two virtio-net related bugs Xuan Zhuo
@ 2025-10-11 9:41 ` Xuan Zhuo
2025-10-11 9:41 ` [PATCH net v1 2/3] virtio-net: correct hdr_len handling for VIRTIO_NET_F_GUEST_HDRLEN Xuan Zhuo
` (2 subsequent siblings)
3 siblings, 0 replies; 7+ messages in thread
From: Xuan Zhuo @ 2025-10-11 9:41 UTC (permalink / raw)
To: netdev
Cc: Michael S. Tsirkin, Jason Wang, Xuan Zhuo, Eugenio Pérez,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Willem de Bruijn, Jiri Pirko, Alvaro Karsz, Heng Qi,
virtualization
The purpose of commit 703eec1b2422 ("virtio_net: fixing XDP for fully
checksummed packets handling") is to record the flags in advance, as
their value may be overwritten in the XDP case. However, the flags
recorded under big mode are incorrect, because in big mode, the passed
buf does not point to the rx buffer, but rather to the page of the
submitted buffer. This commit fixes this issue.
For the small mode, the commit c11a49d58ad2 ("virtio_net: Fix mismatched
buf address when unmapping for small packets") fixed it.
Fixes: 703eec1b2422 ("virtio_net: fixing XDP for fully checksummed packets handling")
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
Acked-by: Jason Wang <jasowang@redhat.com>
---
drivers/net/virtio_net.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7da5a37917e9..22f7725798e3 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -2620,22 +2620,28 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
return;
}
- /* 1. Save the flags early, as the XDP program might overwrite them.
+ /* About the flags below:
+ * 1. Save the flags early, as the XDP program might overwrite them.
* These flags ensure packets marked as VIRTIO_NET_HDR_F_DATA_VALID
* stay valid after XDP processing.
* 2. XDP doesn't work with partially checksummed packets (refer to
* virtnet_xdp_set()), so packets marked as
* VIRTIO_NET_HDR_F_NEEDS_CSUM get dropped during XDP processing.
*/
- flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
- if (vi->mergeable_rx_bufs)
+ if (vi->mergeable_rx_bufs) {
+ flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
skb = receive_mergeable(dev, vi, rq, buf, ctx, len, xdp_xmit,
stats);
- else if (vi->big_packets)
+ } else if (vi->big_packets) {
+ void *p = page_address((struct page *)buf);
+
+ flags = ((struct virtio_net_common_hdr *)p)->hdr.flags;
skb = receive_big(dev, vi, rq, buf, len, stats);
- else
+ } else {
+ flags = ((struct virtio_net_common_hdr *)buf)->hdr.flags;
skb = receive_small(dev, vi, rq, buf, ctx, len, xdp_xmit, stats);
+ }
if (unlikely(!skb))
return;
--
2.32.0.3.g01195cf9f
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH net v1 2/3] virtio-net: correct hdr_len handling for VIRTIO_NET_F_GUEST_HDRLEN
2025-10-11 9:41 [PATCH net v1 0/3] fixes two virtio-net related bugs Xuan Zhuo
2025-10-11 9:41 ` [PATCH net v1 1/3] virtio-net: fix incorrect flags recording in big mode Xuan Zhuo
@ 2025-10-11 9:41 ` Xuan Zhuo
2025-10-11 9:41 ` [PATCH net v1 3/3] virtio-net: correct hdr_len handling for tunnel gso Xuan Zhuo
2025-10-11 14:13 ` [syzbot ci] Re: fixes two virtio-net related bugs syzbot ci
3 siblings, 0 replies; 7+ messages in thread
From: Xuan Zhuo @ 2025-10-11 9:41 UTC (permalink / raw)
To: netdev
Cc: Michael S. Tsirkin, Jason Wang, Xuan Zhuo, Eugenio Pérez,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Willem de Bruijn, Jiri Pirko, Alvaro Karsz, Heng Qi,
virtualization
The commit be50da3e9d4a ("net: virtio_net: implement exact header length
guest feature") introduces support for the VIRTIO_NET_F_GUEST_HDRLEN
feature in virtio-net.
This feature requires virtio-net to set hdr_len to the actual header
length of the packet when transmitting, the number of
bytes from the start of the packet to the beginning of the
transport-layer payload.
However, in practice, hdr_len was being set using skb_headlen(skb),
which is clearly incorrect. This commit fixes that issue.
Fixes: be50da3e9d4a ("net: virtio_net: implement exact header length guest feature")
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
include/linux/virtio_net.h | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index 20e0584db1dd..10ca53b3a399 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -217,20 +217,34 @@ static inline int virtio_net_hdr_from_skb(const struct sk_buff *skb,
if (skb_is_gso(skb)) {
struct skb_shared_info *sinfo = skb_shinfo(skb);
+ u16 hdr_len;
- /* This is a hint as to how much should be linear. */
- hdr->hdr_len = __cpu_to_virtio16(little_endian,
- skb_headlen(skb));
hdr->gso_size = __cpu_to_virtio16(little_endian,
sinfo->gso_size);
- if (sinfo->gso_type & SKB_GSO_TCPV4)
+ if (sinfo->gso_type & SKB_GSO_TCPV4) {
hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
- else if (sinfo->gso_type & SKB_GSO_TCPV6)
+ hdr_len = tcp_hdrlen(skb);
+ } else if (sinfo->gso_type & SKB_GSO_TCPV6) {
hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
- else if (sinfo->gso_type & SKB_GSO_UDP_L4)
+ hdr_len = tcp_hdrlen(skb);
+ } else if (sinfo->gso_type & SKB_GSO_UDP_L4) {
hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP_L4;
- else
+ hdr_len = sizeof(struct udphdr);
+ } else {
return -EINVAL;
+ }
+
+ /* In certain code paths (such as the TUN receive path), this
+ * function may be called without a transport header.
+ */
+ if (skb_transport_header_was_set(skb)) {
+ hdr_len += skb_transport_offset(skb);
+ hdr->hdr_len = __cpu_to_virtio16(little_endian,
+ hdr_len);
+ } else {
+ hdr->hdr_len = 0;
+ }
+
if (sinfo->gso_type & SKB_GSO_TCP_ECN)
hdr->gso_type |= VIRTIO_NET_HDR_GSO_ECN;
} else
--
2.32.0.3.g01195cf9f
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH net v1 3/3] virtio-net: correct hdr_len handling for tunnel gso
2025-10-11 9:41 [PATCH net v1 0/3] fixes two virtio-net related bugs Xuan Zhuo
2025-10-11 9:41 ` [PATCH net v1 1/3] virtio-net: fix incorrect flags recording in big mode Xuan Zhuo
2025-10-11 9:41 ` [PATCH net v1 2/3] virtio-net: correct hdr_len handling for VIRTIO_NET_F_GUEST_HDRLEN Xuan Zhuo
@ 2025-10-11 9:41 ` Xuan Zhuo
2025-10-11 14:13 ` [syzbot ci] Re: fixes two virtio-net related bugs syzbot ci
3 siblings, 0 replies; 7+ messages in thread
From: Xuan Zhuo @ 2025-10-11 9:41 UTC (permalink / raw)
To: netdev
Cc: Michael S. Tsirkin, Jason Wang, Xuan Zhuo, Eugenio Pérez,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Willem de Bruijn, Jiri Pirko, Alvaro Karsz, Heng Qi,
virtualization
The commit a2fb4bc4e2a6a03 ("net: implement virtio helpers to handle UDP
GSO tunneling.") introduces support for the UDP GSO tunnel feature in
virtio-net.
The virtio spec says:
If the \field{gso_type} has the VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV4 bit or
VIRTIO_NET_HDR_GSO_UDP_TUNNEL_IPV6 bit set, \field{hdr_len} accounts for
all the headers up to and including the inner transport.
The commit did not update the hdr_len to include the inner transport.
Fixes: a2fb4bc4e2a6a03 ("net: implement virtio helpers to handle UDP GSO tunneling.")
Signed-off-by: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
---
include/linux/virtio_net.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/include/linux/virtio_net.h b/include/linux/virtio_net.h
index 10ca53b3a399..742cce34a24e 100644
--- a/include/linux/virtio_net.h
+++ b/include/linux/virtio_net.h
@@ -403,6 +403,7 @@ virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb,
struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)vhdr;
unsigned int inner_nh, outer_th;
int tnl_gso_type;
+ u16 hdr_len;
int ret;
tnl_gso_type = skb_shinfo(skb)->gso_type & (SKB_GSO_UDP_TUNNEL |
@@ -434,6 +435,23 @@ virtio_net_hdr_tnl_from_skb(const struct sk_buff *skb,
outer_th = skb->transport_header - skb_headroom(skb);
vhdr->inner_nh_offset = cpu_to_le16(inner_nh);
vhdr->outer_th_offset = cpu_to_le16(outer_th);
+
+ switch (skb->inner_ipproto) {
+ case IPPROTO_TCP:
+ hdr_len = inner_tcp_hdrlen(skb);
+ break;
+
+ case IPPROTO_UDP:
+ hdr_len = sizeof(struct udphdr);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ hdr_len += skb_inner_transport_offset(skb);
+ hdr->hdr_len = __cpu_to_virtio16(little_endian, hdr_len);
+
return 0;
}
--
2.32.0.3.g01195cf9f
^ permalink raw reply related [flat|nested] 7+ messages in thread* [syzbot ci] Re: fixes two virtio-net related bugs.
2025-10-11 9:41 [PATCH net v1 0/3] fixes two virtio-net related bugs Xuan Zhuo
` (2 preceding siblings ...)
2025-10-11 9:41 ` [PATCH net v1 3/3] virtio-net: correct hdr_len handling for tunnel gso Xuan Zhuo
@ 2025-10-11 14:13 ` syzbot ci
3 siblings, 0 replies; 7+ messages in thread
From: syzbot ci @ 2025-10-11 14:13 UTC (permalink / raw)
To: alvaro.karsz, andrew, davem, edumazet, eperezma, hengqi, jasowang,
jiri, kuba, mst, netdev, pabeni, virtualization, willemb,
xuanzhuo
Cc: syzbot, syzkaller-bugs
syzbot ci has tested the following series
[v1] fixes two virtio-net related bugs.
https://lore.kernel.org/all/20251011094107.16439-1-xuanzhuo@linux.alibaba.com
* [PATCH net v1 1/3] virtio-net: fix incorrect flags recording in big mode
* [PATCH net v1 2/3] virtio-net: correct hdr_len handling for VIRTIO_NET_F_GUEST_HDRLEN
* [PATCH net v1 3/3] virtio-net: correct hdr_len handling for tunnel gso
and found the following issue:
WARNING in virtio_net_hdr_from_skb
Full report is available here:
https://ci.syzbot.org/series/694015b3-a5d7-400b-a7c2-c9ee69c35027
***
WARNING in virtio_net_hdr_from_skb
tree: net
URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/netdev/net.git
base: 2c95a756e0cfc19af6d0b32b0c6cf3bada334998
arch: amd64
compiler: Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
config: https://ci.syzbot.org/builds/5e67ae6c-bfc6-42cc-ab94-ff0cde528221/config
C repro: https://ci.syzbot.org/findings/39fb9135-9abf-418b-82a0-6478c7642a48/c_repro
syz repro: https://ci.syzbot.org/findings/39fb9135-9abf-418b-82a0-6478c7642a48/syz_repro
syz.0.17 uses obsolete (PF_INET,SOCK_PACKET)
------------[ cut here ]------------
WARNING: CPU: 1 PID: 5956 at ./include/linux/skbuff.h:3071 skb_transport_header include/linux/skbuff.h:3071 [inline]
WARNING: CPU: 1 PID: 5956 at ./include/linux/skbuff.h:3071 tcp_hdr include/linux/tcp.h:26 [inline]
WARNING: CPU: 1 PID: 5956 at ./include/linux/skbuff.h:3071 tcp_hdrlen include/linux/tcp.h:36 [inline]
WARNING: CPU: 1 PID: 5956 at ./include/linux/skbuff.h:3071 virtio_net_hdr_from_skb+0x5e6/0x8d0 include/linux/virtio_net.h:226
Modules linked in:
CPU: 1 UID: 0 PID: 5956 Comm: syz.0.17 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_transport_header include/linux/skbuff.h:3071 [inline]
RIP: 0010:tcp_hdr include/linux/tcp.h:26 [inline]
RIP: 0010:tcp_hdrlen include/linux/tcp.h:36 [inline]
RIP: 0010:virtio_net_hdr_from_skb+0x5e6/0x8d0 include/linux/virtio_net.h:226
Code: 6f 01 4c 89 e8 48 c1 e8 03 0f b6 04 28 84 c0 0f 85 d8 02 00 00 41 c6 45 00 05 66 41 bf 08 00 e9 2c fd ff ff e8 2b 33 a8 f7 90 <0f> 0b 90 e9 f4 fb ff ff e8 1d 33 a8 f7 90 0f 0b 90 e9 b7 fc ff ff
RSP: 0018:ffffc90003777228 EFLAGS: 00010293
RAX: ffffffff8a16e845 RBX: ffff8881763f4fd0 RCX: ffff888106388000
RDX: 0000000000000000 RSI: 000000000000ffff RDI: 000000000000ffff
RBP: 000000000000ffff R08: ffff88817517f059 R09: 0000000000000000
R10: ffff88817517f050 R11: ffffed102ea2fe0c R12: ffff88816a55a498
R13: ffff8881763f4fb6 R14: ffff8881763f4f00 R15: 1ffff1102ec7e9f6
FS: 0000555585886500(0000) GS:ffff8882a9d3b000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000010000 CR3: 00000001128ba000 CR4: 00000000000006f0
Call Trace:
<TASK>
tpacket_rcv+0x1527/0x31c0 net/packet/af_packet.c:2362
deliver_skb net/core/dev.c:2472 [inline]
deliver_ptype_list_skb net/core/dev.c:2487 [inline]
__netif_receive_skb_core+0x3465/0x4380 net/core/dev.c:6023
__netif_receive_skb_one_core net/core/dev.c:6077 [inline]
__netif_receive_skb+0x72/0x380 net/core/dev.c:6192
netif_receive_skb_internal net/core/dev.c:6278 [inline]
netif_receive_skb+0x1cb/0x790 net/core/dev.c:6337
tun_rx_batched+0x1b9/0x730 drivers/net/tun.c:1485
tun_get_user+0x2b65/0x3e90 drivers/net/tun.c:1953
tun_chr_write_iter+0x113/0x200 drivers/net/tun.c:1999
new_sync_write fs/read_write.c:593 [inline]
vfs_write+0x5c9/0xb30 fs/read_write.c:686
ksys_write+0x145/0x250 fs/read_write.c:738
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xfa/0xfa0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fd130b8eec9
Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 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 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffcdba8f558 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00007fd130de5fa0 RCX: 00007fd130b8eec9
RDX: 000000000000fdef RSI: 00002000000002c0 RDI: 0000000000000003
RBP: 00007fd130c11f91 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fd130de5fa0 R14: 00007fd130de5fa0 R15: 0000000000000003
</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.
^ permalink raw reply [flat|nested] 7+ messages in thread