Commit 3287cd714a85 for kernel

commit 3287cd714a853d9443c4a743eca010aedcfbbcdd
Author: Eric Dumazet <edumazet@kernel.org>
Date:   Tue Nov 10 22:36:27 2026 +0100

    tun: clear stale skb->protocol of NAPI frags skbs

    With IFF_NAPI_FRAGS, tun_napi_alloc_frags() gets its skb from
    napi_get_frags(). If GRO merged the previous frame with
    GRO_MERGED_FREE, that skb was recycled by napi_reuse_skb(), which does
    not reset skb->protocol set by napi_frags_skb() for the previous frame.

    tun_get_user() calls tun_vnet_hdr_tnl_to_skb() before eth_type_trans(),
    so the virtio header checks see the protocol of the previous frame:
    GSO packets without VIRTIO_NET_HDR_F_NEEDS_CSUM are dissected with the
    wrong protocol. A following change checks the outer protocol of UDP
    tunnel GSO packets, which would then reject a valid frame when the two
    ethertypes differ.

    This needs GRO to hold packets across writes, and IFF_NAPI_FRAGS needs
    CAP_NET_ADMIN.

    Clear skb->protocol in tun_napi_alloc_frags(), like skbs allocated
    by tun_alloc_skb() or build_skb(). eth_type_trans() sets it later.

    Fixes: 90e33d459407 ("tun: enable napi_gro_frags() for TUN/TAP driver")
    Reported-by: Sashiko <sashiko-bot@kernel.org>
    Closes: https://lore.kernel.org/netdev/179386753589.488856.11455181721004759454@kernel.org/
    Suggested-by: Willem de Bruijn <willemb@google.com>
    Reviewed-by: Willem de Bruijn <willemb@google.com>
    Signed-off-by: Eric Dumazet <edumazet@kernel.org>
    Link: https://patch.msgid.link/20261110213628.3476051-3-edumazet@kernel.org
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index ab1b91a9a99e..4ab7a4f7fc4e 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1500,6 +1500,12 @@ static struct sk_buff *tun_napi_alloc_frags(struct tun_file *tfile,
 	if (!skb)
 		return ERR_PTR(-ENOMEM);

+	/* An skb recycled by napi_reuse_skb() keeps the protocol of a
+	 * previous frame. eth_type_trans() sets it after the virtio
+	 * header checks, which must not see a stale one.
+	 */
+	skb->protocol = 0;
+
 	linear = iov_iter_single_seg_count(it);
 	err = __skb_grow(skb, linear);
 	if (err)