* [PATCH 1/1] net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp()
@ 2026-08-02 22:46 Dongli Zhang
2026-08-03 16:33 ` Willem de Bruijn
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Dongli Zhang @ 2026-08-02 22:46 UTC (permalink / raw)
To: netdev
Cc: willemdebruijn.kernel, jasowangio, andrew+netdev, davem, edumazet,
kuba, pabeni, mst, denis.pilipchuk, joe.jin
The commit 4f61f133f354 ("net: tap: NULL pointer derefence in
dev_parse_header_protocol when skb->dev is null") fixed a crash in
tap_get_user() by assigning skb->dev before calling tun_vnet_hdr_to_skb().
This is required because virtio_net_hdr_to_skb() may invoke
dev_parse_header_protocol(), which dereferences skb->dev. Without the
assignment, a NULL pointer dereference can occur.
However, tap_get_user_xdp() still parses the virtio-net header before
assigning skb->dev. When the vhost TX path passes an XDP buffer containing
a GSO virtio-net header but the protocol is set to zero on purpose,
tun_vnet_hdr_to_skb() can reach dev_parse_header_protocol() while skb->dev
is still NULL, resulting in a crash.
Fix this by looking up the tap device and assigning skb->dev before calling
tun_vnet_hdr_to_skb(), matching the ordering already used in
tap_get_user(). Preserve the existing RCU read-side critical section across
dev_queue_xmit().
Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5.5
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
---
drivers/net/tap.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/drivers/net/tap.c b/drivers/net/tap.c
index fae115915c8e..5d2d34d24ce8 100644
--- a/drivers/net/tap.c
+++ b/drivers/net/tap.c
@@ -1074,10 +1074,21 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
skb_reset_mac_header(skb);
skb->protocol = eth_hdr(skb)->h_proto;
+ rcu_read_lock();
+ tap = rcu_dereference(q->tap);
+ if (!tap) {
+ kfree_skb(skb);
+ rcu_read_unlock();
+ return 0;
+ }
+ skb->dev = tap->dev;
+
if (vnet_hdr_len) {
err = tun_vnet_hdr_to_skb(q->flags, skb, gso);
- if (err)
+ if (err) {
+ rcu_read_unlock();
goto err_kfree;
+ }
}
/* Move network header to the right position for VLAN tagged packets */
@@ -1085,15 +1096,8 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0)
skb_set_network_header(skb, depth);
- rcu_read_lock();
- tap = rcu_dereference(q->tap);
- if (tap) {
- skb->dev = tap->dev;
- skb_probe_transport_header(skb);
- dev_queue_xmit(skb);
- } else {
- kfree_skb(skb);
- }
+ skb_probe_transport_header(skb);
+ dev_queue_xmit(skb);
rcu_read_unlock();
return 0;
--
2.43.5
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH 1/1] net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp()
2026-08-02 22:46 [PATCH 1/1] net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp() Dongli Zhang
@ 2026-08-03 16:33 ` Willem de Bruijn
2026-08-03 16:38 ` Michael S. Tsirkin
2026-08-06 0:40 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: Willem de Bruijn @ 2026-08-03 16:33 UTC (permalink / raw)
To: Dongli Zhang, netdev
Cc: willemdebruijn.kernel, jasowangio, andrew+netdev, davem, edumazet,
kuba, pabeni, mst, denis.pilipchuk, joe.jin
Dongli Zhang wrote:
> The commit 4f61f133f354 ("net: tap: NULL pointer derefence in
> dev_parse_header_protocol when skb->dev is null") fixed a crash in
> tap_get_user() by assigning skb->dev before calling tun_vnet_hdr_to_skb().
> This is required because virtio_net_hdr_to_skb() may invoke
> dev_parse_header_protocol(), which dereferences skb->dev. Without the
> assignment, a NULL pointer dereference can occur.
>
> However, tap_get_user_xdp() still parses the virtio-net header before
> assigning skb->dev. When the vhost TX path passes an XDP buffer containing
> a GSO virtio-net header but the protocol is set to zero on purpose,
> tun_vnet_hdr_to_skb() can reach dev_parse_header_protocol() while skb->dev
> is still NULL, resulting in a crash.
>
> Fix this by looking up the tap device and assigning skb->dev before calling
> tun_vnet_hdr_to_skb(), matching the ordering already used in
> tap_get_user(). Preserve the existing RCU read-side critical section across
> dev_queue_xmit().
>
> Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
> Cc: stable@vger.kernel.org
> Assisted-by: Codex:GPT-5.5
> Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH 1/1] net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp()
2026-08-02 22:46 [PATCH 1/1] net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp() Dongli Zhang
2026-08-03 16:33 ` Willem de Bruijn
@ 2026-08-03 16:38 ` Michael S. Tsirkin
2026-08-06 0:40 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: Michael S. Tsirkin @ 2026-08-03 16:38 UTC (permalink / raw)
To: Dongli Zhang
Cc: netdev, willemdebruijn.kernel, jasowangio, andrew+netdev, davem,
edumazet, kuba, pabeni, denis.pilipchuk, joe.jin
On Sun, Aug 02, 2026 at 03:46:12PM -0700, Dongli Zhang wrote:
> The commit 4f61f133f354 ("net: tap: NULL pointer derefence in
> dev_parse_header_protocol when skb->dev is null") fixed a crash in
> tap_get_user() by assigning skb->dev before calling tun_vnet_hdr_to_skb().
> This is required because virtio_net_hdr_to_skb() may invoke
> dev_parse_header_protocol(), which dereferences skb->dev. Without the
> assignment, a NULL pointer dereference can occur.
>
> However, tap_get_user_xdp() still parses the virtio-net header before
> assigning skb->dev. When the vhost TX path passes an XDP buffer containing
> a GSO virtio-net header but the protocol is set to zero on purpose,
> tun_vnet_hdr_to_skb() can reach dev_parse_header_protocol() while skb->dev
> is still NULL, resulting in a crash.
>
> Fix this by looking up the tap device and assigning skb->dev before calling
> tun_vnet_hdr_to_skb(), matching the ordering already used in
> tap_get_user(). Preserve the existing RCU read-side critical section across
> dev_queue_xmit().
>
> Fixes: 924a9bc362a5 ("net: check if protocol extracted by virtio_net_hdr_set_proto is correct")
> Cc: stable@vger.kernel.org
> Assisted-by: Codex:GPT-5.5
> Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
> ---
> drivers/net/tap.c | 24 ++++++++++++++----------
> 1 file changed, 14 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/tap.c b/drivers/net/tap.c
> index fae115915c8e..5d2d34d24ce8 100644
> --- a/drivers/net/tap.c
> +++ b/drivers/net/tap.c
> @@ -1074,10 +1074,21 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
> skb_reset_mac_header(skb);
> skb->protocol = eth_hdr(skb)->h_proto;
>
> + rcu_read_lock();
> + tap = rcu_dereference(q->tap);
> + if (!tap) {
> + kfree_skb(skb);
> + rcu_read_unlock();
> + return 0;
> + }
> + skb->dev = tap->dev;
> +
> if (vnet_hdr_len) {
> err = tun_vnet_hdr_to_skb(q->flags, skb, gso);
> - if (err)
> + if (err) {
> + rcu_read_unlock();
> goto err_kfree;
> + }
> }
>
> /* Move network header to the right position for VLAN tagged packets */
> @@ -1085,15 +1096,8 @@ static int tap_get_user_xdp(struct tap_queue *q, struct xdp_buff *xdp)
> vlan_get_protocol_and_depth(skb, skb->protocol, &depth) != 0)
> skb_set_network_header(skb, depth);
>
> - rcu_read_lock();
> - tap = rcu_dereference(q->tap);
> - if (tap) {
> - skb->dev = tap->dev;
> - skb_probe_transport_header(skb);
> - dev_queue_xmit(skb);
> - } else {
> - kfree_skb(skb);
> - }
> + skb_probe_transport_header(skb);
> + dev_queue_xmit(skb);
> rcu_read_unlock();
>
> return 0;
> --
> 2.43.5
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH 1/1] net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp()
2026-08-02 22:46 [PATCH 1/1] net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp() Dongli Zhang
2026-08-03 16:33 ` Willem de Bruijn
2026-08-03 16:38 ` Michael S. Tsirkin
@ 2026-08-06 0:40 ` patchwork-bot+netdevbpf
2 siblings, 0 replies; 4+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-08-06 0:40 UTC (permalink / raw)
To: Dongli Zhang
Cc: netdev, willemdebruijn.kernel, jasowangio, andrew+netdev, davem,
edumazet, kuba, pabeni, mst, denis.pilipchuk, joe.jin
Hello:
This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Sun, 2 Aug 2026 15:46:12 -0700 you wrote:
> The commit 4f61f133f354 ("net: tap: NULL pointer derefence in
> dev_parse_header_protocol when skb->dev is null") fixed a crash in
> tap_get_user() by assigning skb->dev before calling tun_vnet_hdr_to_skb().
> This is required because virtio_net_hdr_to_skb() may invoke
> dev_parse_header_protocol(), which dereferences skb->dev. Without the
> assignment, a NULL pointer dereference can occur.
>
> [...]
Here is the summary with links:
- [1/1] net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp()
https://git.kernel.org/netdev/net/c/3874892dd27d
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-06 0:40 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-02 22:46 [PATCH 1/1] net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp() Dongli Zhang
2026-08-03 16:33 ` Willem de Bruijn
2026-08-03 16:38 ` Michael S. Tsirkin
2026-08-06 0:40 ` patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox