Linux virtualization list
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Steffen Trumtrar" <s.trumtrar@pengutronix.de>
Cc: virtualization@lists.linux.dev,
	"Eugenio Perez" <eperezma@redhat.com>,
	bpf@vger.kernel.org, "Michael S. Tsirkin" <mst@redhat.com>
Subject: Re: [PATCH RFC v3 2/2] tun: support rx-tstamp
Date: Mon, 21 Sep 2026 14:57:30 +0000	[thread overview]
Message-ID: <20260921145731.1C61A1F00893@smtp.kernel.org> (raw)
In-Reply-To: <20260921-v6-7-topic-virtio-net-ptp-v3-2-3350851c4f88@pengutronix.de>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] net: info leak via out-of-bounds stack read in __tun_vnet_hdr_put()
- [High] net: truncation of extended virtio-net headers breaks offloads in __tun_vnet_hdr_get()
- [Medium] net: incorrect endianness when storing virtio-net timestamp in tun_put_user()
--

commit f6ec01e41ac769b584380d489021709a59d0a180
Author: Steffen Trumtrar <s.trumtrar@pengutronix.de>

tun: support rx-tstamp

Demonstrate support for new virtio-net features
VIRTIO_NET_HDR_F_TSTAMP

[ ... ]

> diff --git a/drivers/net/tun.c b/drivers/net/tun.c
> index 5a302709a68aa..924784771b6b7 100644
> --- a/drivers/net/tun.c
> +++ b/drivers/net/tun.c
> @@ -2157,12 +2157,23 @@ static ssize_t tun_put_user(struct tun_struct *tun,
>  	}
>  
>  	if (vnet_hdr_sz) {
> -		struct virtio_net_hdr_v1_hash_tunnel hdr;
> -		struct virtio_net_hdr *gso;
> +		struct virtio_net_common_hdr hdr;
>  
>  		memset(&hdr, 0, sizeof(hdr));
> +
> +		/* hdr has at least the size up to and including the tstamp field. */
> +		if (vnet_hdr_sz >= offsetof(struct virtio_net_common_hdr, tstamp) +
> +				   sizeof_field(struct virtio_net_common_hdr, tstamp)) {
> +			u64 tstamp = ktime_get_clocktai_ns();
> +
> +			hdr.tstamp[0] = (tstamp & 0x000000000000ffffULL) >> 0;
> +			hdr.tstamp[1] = (tstamp & 0x00000000ffff0000ULL) >> 16;
> +			hdr.tstamp[2] = (tstamp & 0x0000ffff00000000ULL) >> 32;
> +			hdr.tstamp[3] = (tstamp & 0xffff000000000000ULL) >> 48;

[Severity: Medium]
Since tstamp is defined as a __virtio16 array, does this need to use
cpu_to_tun_vnet16() for byte swapping?

Assigning a host-endian value directly using native 16-bit shifts could corrupt
the timestamp when read by the guest if the negotiated virtio endianness differs
from the host native endianness.

> +		}
> +
>  		ret = tun_vnet_hdr_tnl_from_skb(tun->flags, tun->dev, skb,

[ ... ]

> diff --git a/drivers/net/tun_vnet.h b/drivers/net/tun_vnet.h
> index f4c652b1fa44d..0a7fe1ce889b5 100644
> --- a/drivers/net/tun_vnet.h
> +++ b/drivers/net/tun_vnet.h
> @@ -122,15 +119,20 @@ static inline int __tun_vnet_hdr_get(int sz, unsigned int flags,
>  				     struct iov_iter *from,
>  				     struct virtio_net_hdr *hdr)
>  {
> -	unsigned int parsed_size = tun_vnet_parse_size(features);
> +	unsigned int parsed_size = tun_vnet_parse_size(sz);
> +	u8 tmp[sizeof(struct virtio_net_common_hdr)]; // temp buffer with known size
>  	u16 hdr_len;
>  
>  	if (iov_iter_count(from) < sz)
>  		return -EINVAL;
>  
> -	if (!copy_from_iter_full(hdr, parsed_size, from))
> +	/* copy parsed size data to the tmp buffer, otherwise compiler will complain */
> +	if (!copy_from_iter_full(tmp, parsed_size, from))
>  		return -EFAULT;
>  
> +	/* now copy the relevant data from tmp to hdr */
> +	memcpy(hdr, tmp, min(parsed_size, sizeof(*hdr)));

[Severity: High]
Does this artificially limit the copy to exactly 10 bytes?

Because hdr is passed as a pointer to struct virtio_net_hdr, sizeof(*hdr)
evaluates statically to 10 bytes.

Callers like tun_get_user() might allocate a larger structure, but they will
only receive 10 bytes, causing extended virtio-net header fields (such as hash
values or tunnel offsets) to be silently dropped.

> +
>  	hdr_len = tun_vnet16_to_cpu(flags, hdr->hdr_len);
>  
>  	if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
> @@ -155,14 +157,17 @@ static inline int tun_vnet_hdr_get(int sz, unsigned int flags,
>  
>  static inline int __tun_vnet_hdr_put(int sz, netdev_features_t features,
>  				     struct iov_iter *iter,
> -				     const struct virtio_net_hdr *hdr)
> +				     const struct virtio_net_common_hdr *hdr)
>  {
> -	unsigned int parsed_size = tun_vnet_parse_size(features);
> +	unsigned int parsed_size = tun_vnet_parse_size(sz);
> +	u8 buf[sizeof(*hdr)];
>  
>  	if (unlikely(iov_iter_count(iter) < sz))
>  		return -EINVAL;
>  
> -	if (unlikely(copy_to_iter(hdr, parsed_size, iter) != parsed_size))
> +	memcpy(buf, hdr, parsed_size);

[Severity: High]
Could this copy leak uninitialized kernel stack memory to userspace?

Callers like tap_put_user() and tun_put_user_xdp() allocate a 10-byte
struct virtio_net_hdr on the kernel stack and pass its pointer to
tun_vnet_hdr_put().

Because tun_vnet_hdr_put() casts the 10-byte pointer to the 32-byte
struct virtio_net_common_hdr:

    return __tun_vnet_hdr_put(sz, 0, iter, (struct virtio_net_common_hdr *)hdr);

and parsed_size can be up to 32 bytes (depending on vnet_hdr_sz), this
memcpy could read 22 bytes past the end of the 10-byte struct.

> +
> +	if (unlikely(copy_to_iter(buf, parsed_size, iter) != parsed_size))
>  		return -EFAULT;
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260921-v6-7-topic-virtio-net-ptp-v3-0-3350851c4f88@pengutronix.de?part=2

  reply	other threads:[~2026-09-21 14:57 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-21 14:46 [PATCH RFC v3 0/2] virtio-net: add flow filter for receive timestamps Steffen Trumtrar
2026-09-21 14:46 ` [PATCH RFC v3 1/2] virtio-net: support receive timestamp Steffen Trumtrar
2026-09-21 14:57   ` sashiko-bot
2026-09-22  1:33   ` Willem de Bruijn
2026-09-21 14:46 ` [PATCH RFC v3 2/2] tun: support rx-tstamp Steffen Trumtrar
2026-09-21 14:57   ` sashiko-bot [this message]
2026-09-22  1:31 ` [PATCH RFC v3 0/2] virtio-net: add flow filter for receive timestamps Willem de Bruijn
2026-09-22  5:28   ` Steffen Trumtrar

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=20260921145731.1C61A1F00893@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=eperezma@redhat.com \
    --cc=mst@redhat.com \
    --cc=s.trumtrar@pengutronix.de \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=virtualization@lists.linux.dev \
    /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