Netdev List
 help / color / mirror / Atom feed
From: netdev-bot+sashiko@kernel.org
To: edumazet@kernel.org
Cc: netdev@vger.kernel.org, davem@davemloft.net, kuba@kernel.org,
	pabeni@redhat.com, horms@kernel.org, willemb@google.com,
	mst@redhat.com, jasowangio@gmail.com, eperezma@redhat.com,
	hassansultan@google.com, virtualization@lists.linux.dev
Subject: Re: [PATCH net v3 3/8] tun: clear stale skb->protocol of NAPI frags skbs
Date: Sun, 08 Nov 2026 23:01:59 +0000	[thread overview]
Message-ID: <179417891984.994134.14397350053196333026@kernel.org> (raw)
In-Reply-To: <20261105115715.1466924-4-edumazet@kernel.org>

Thank you for your contribution! Sashiko AI review found more severe
issue(s) in other patches of this series. This mail is only an FYI, in case
you want to address the nit picks below when you respin.

Low priority / nit picks for your consideration:

- [Low] The commit message understates what a stale skb->protocol does in
  the non-tunnel path.
- [Low] The first symptom in the commit message ("the outer protocol
  check of UDP tunnel GSO packets rejects a valid frame when the two…

--

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

This patch clears skb->protocol for IFF_TAP frames in tun_get_user()
before tun_vnet_hdr_tnl_to_skb() runs. With IFF_NAPI_FRAGS, an skb
recycled by napi_reuse_skb() keeps the protocol that napi_frags_skb() set
for the previous frame. Without this patch, the virtio header checks see
that stale value.

Closes: https://lore.kernel.org/netdev/179386753589.488856.11455181721004759454@kernel.org/

[ ... ]

> On the IFF_TAP path, 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: the outer protocol check of UDP tunnel GSO
> packets rejects a valid frame when the two ethertypes differ, and

[Severity: Low]
Does this symptom really come from 90e33d459407? The outer protocol check
that compares against skb->protocol seems to have been added earlier in
this series, by "net: virtio: validate outer protocol of UDP tunnel GSO
packets":

include/linux/virtio_net.h:virtio_net_l3_start() {
    ...
		h_proto = eth_hdr(skb)->h_proto;
		...
		if (skb->protocol && skb->protocol != h_proto)
			return false;
    ...
}

At the baseline, the tunnel path in virtio_net_hdr_tnl_to_skb() never
read skb->protocol. A stale value could not cause a tunnel rejection
there.

With the current ordering, the two intermediate commits ("net: virtio:
validate outer protocol of UDP tunnel GSO packets" and "net: virtio: do
not use dev->type to find the outer L3 header") would drop a valid UDP
tunnel GSO frame with -EINVAL. This happens on an IFF_TAP |
IFF_NAPI_FRAGS device when GRO holds packets and the outer ethertype
differs from the one in the previous merged frame, for example an IPv4
outer after an IPv6 frame:

tun_get_user()
  tun_vnet_hdr_tnl_to_skb()
    virtio_net_hdr_tnl_to_skb()
      virtio_net_tnl_offsets_ok()
        virtio_net_l3_start()   <- stale skb->protocol != h_proto

Could this patch move ahead of "net: virtio: validate outer protocol of
UDP tunnel GSO packets" so the series stays bisectable? If not, could
the commit message at least mention the dependency on that commit?

> GSO packets without VIRTIO_NET_HDR_F_NEEDS_CSUM are dissected with
> the wrong protocol.

[Severity: Low]
Is "dissected with the wrong protocol" too mild for what happens here?
In __virtio_net_hdr_to_skb(), a stale non-zero skb->protocol means
dev_parse_header_protocol() never reads the real h_proto of the frame:

include/linux/virtio_net.h:__virtio_net_hdr_to_skb() {
    ...
	} else if (gso_type) {
		...
		if (!skb->protocol) {
			skb->protocol = dev_parse_header_protocol(skb);
			if (!skb->protocol)
				virtio_net_hdr_set_proto(skb, hdr);
		}
retry:
		if (!skb_flow_dissect_flow_keys_basic(NULL, skb, &keys,
						      NULL, 0, 0, 0,
						      0)) {
		...
		if (!pskb_may_pull(skb, p_off) ||
		    keys.basic.ip_proto != ip_proto ||
		    !virtio_net_hdr_match_proto(keys.basic.n_proto,
						hdr_gso_type))
			return -EINVAL;
    ...
}

When data is NULL, the dissector starts from skb->protocol at
skb_network_offset(), which tun_get_user() sets to ETH_HLEN. So
virtio_net_hdr_match_proto() checks the protocol of the previous frame,
not the ethertype of this one.

A writer could then send a VIRTIO_NET_HDR_GSO_TCPV4 frame whose h_proto
is something else, such as MPLS or NSH, with what looks like an
IPv4/TCP payload at offset 14. That frame would pass validation and get
SKB_GSO_TCPV4 | SKB_GSO_DODGY. eth_type_trans() would then set
skb->protocol to the h_proto that was never checked.

The code change closes this. Could the commit message describe it as a
bypass of the check that the ethertype matches the gso_type, rather than
just a misparse?

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261105115715.1466924-1-edumazet%40kernel.org

  parent reply	other threads:[~2026-11-08 23:02 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 11:57 [PATCH net v3 0/8] net: virtio: validate outer protocol of UDP tunnel GSO packets Eric Dumazet
2026-11-05 11:57 ` [PATCH net v3 1/8] " Eric Dumazet
2026-11-08 23:01   ` netdev-bot+sashiko
2026-11-05 11:57 ` [PATCH net v3 2/8] net: virtio: do not use dev->type to find the outer L3 header Eric Dumazet
2026-11-06  4:18   ` Willem de Bruijn
2026-11-06  8:48     ` Eric Dumazet
2026-11-06  9:27   ` Michael S. Tsirkin
2026-11-06  9:55     ` Eric Dumazet
2026-11-08 23:01   ` netdev-bot+sashiko
2026-11-05 11:57 ` [PATCH net v3 3/8] tun: clear stale skb->protocol of NAPI frags skbs Eric Dumazet
2026-11-06  4:21   ` Willem de Bruijn
2026-11-06  8:49     ` Eric Dumazet
2026-11-08 23:01   ` netdev-bot+sashiko [this message]
2026-11-05 11:57 ` [PATCH net v3 4/8] selftests: net: tuntap: fix UDP checksum length in build_udp_packet_csum() Eric Dumazet
2026-11-05 11:57 ` [PATCH net v3 5/8] selftests: net: tun: test outer protocol of UDP tunnel GSO packets Eric Dumazet
2026-11-05 11:57 ` [PATCH net v3 6/8] selftests: net: tun: test UDP tunnel GSO on retyped devices Eric Dumazet
2026-11-06  4:25   ` Willem de Bruijn
2026-11-08 23:02   ` netdev-bot+sashiko
2026-11-05 11:57 ` [PATCH net v3 7/8] selftests: net: tun: test more outer header mismatches of UDP tunnel GSO Eric Dumazet
2026-11-08 23:02   ` netdev-bot+sashiko
2026-11-05 11:57 ` [PATCH net v3 8/8] selftests: net: tuntap: write UDP tunnel offsets in little endian Eric Dumazet
2026-11-08 23:02   ` netdev-bot+sashiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=179417891984.994134.14397350053196333026@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=eperezma@redhat.com \
    --cc=hassansultan@google.com \
    --cc=horms@kernel.org \
    --cc=jasowangio@gmail.com \
    --cc=kuba@kernel.org \
    --cc=mst@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=virtualization@lists.linux.dev \
    --cc=willemb@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox