FAILED: patch "[PATCH] net: tap: set skb->dev before parsing virtio net header in" failed to apply to 6.12-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x 3874892dd27d5387aa9a06f58d9060f18f351d24
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026081349-dropout-afoot-d502@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 3874892dd27d5387aa9a06f58d9060f18f351d24 Mon Sep 17 00:00:00 2001
From: Dongli Zhang <[email protected]>
Date: Sun, 2 Aug 2026 15:46:12 -0700
Subject: [PATCH] net: tap: set skb->dev before parsing virtio net header in
tap_get_user_xdp()
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().
drivers/net/tap.c +14 -10
@@ -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 ;
Sasha Levin
maintainerPATCH 1/1 net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp()
From: Dongli Zhang <[email protected]>
[ Upstream commit 3874892dd27d5387aa9a06f58d9060f18f351d24 ]
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().
--- drivers/net/tap.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
drivers/net/tap.c +14 -10
@@ -1199,10 +1199,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 =virtio_net_hdr_to_skb (skb, gso,tap_is_little_endian (q)); -if (err) +if (err) { +rcu_read_unlock (); goto err_kfree; + } }/* Move network header to the right position for VLAN tagged packets */
@@ -1210,15 +1221,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 ;
Signature · 1 line
2.53.0
Re: [PATCH 6.12.y] net: tap: set skb->dev before parsing virtio net header in tap_get_user_xdp()
Hey Sasha,
Can you post this backport for the remaining stable too? It seems you missed the other FAILED emails.
git am works without any conflict.
Thanks,
Siddh