diff options
| author | Xiang Mei <xmei5@asu.edu> | 2026-06-06 22:44:28 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-06-09 18:33:18 -0700 |
| commit | 7f2fcff15e99bb852f6967396ed12b38376e2c8d (patch) | |
| tree | 9e55df43af361295d6b49d09c03eed3bba79fab5 | |
| parent | 34080db3e70ddf94c38512ad2331e3c3afca6cc1 (diff) | |
tun: zero the whole vnet header in tun_put_user()
tun_put_user() declares an on-stack struct virtio_net_hdr_v1_hash_tunnel
without zeroing it. For a non-tunnel skb, virtio_net_hdr_tnl_from_skb()
only initializes the first 10 bytes (sizeof(struct virtio_net_hdr)),
leaving bytes 10..23 (num_buffers and the hash/tunnel fields) as stack
garbage.
An unprivileged user can set the vnet header size to 24 with
TUNSETVNETHDRSZ, so __tun_vnet_hdr_put() copies all 24 bytes of the
partially-initialized struct to userspace, leaking 14 bytes of kernel
stack on every read of a non-tunnel packet.
Fix it the same way tun_get_user() already does by zeroing the whole
header right after declaration.
Fixes: 288f30435132 ("tun: enable gso over UDP tunnel support.")
Reported-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Xiang Mei <xmei5@asu.edu>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260607054428.3050243-1-xmei5@asu.edu
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/tun.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 9e7744eb57a3..fed9dfdfcc3b 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -2070,6 +2070,7 @@ static ssize_t tun_put_user(struct tun_struct *tun, struct virtio_net_hdr_v1_hash_tunnel hdr; struct virtio_net_hdr *gso; + memset(&hdr, 0, sizeof(hdr)); ret = tun_vnet_hdr_tnl_from_skb(tun->flags, tun->dev, skb, &hdr); if (ret) |
