From 92368f4fb8ff40b87faa4acf1775720ffaf5749d Mon Sep 17 00:00:00 2001 From: zhang jiao Date: Thu, 29 Oct 2026 15:25:10 +0800 Subject: [PATCH] virtio_ring: Initialize id field in packed indirect descriptors The virtqueue_add_indirect_packed() function fills an indirect descriptor table with addr, len, and flags for each entry, but does not initialize the id field of struct vring_packed_desc. The table is allocated via kmalloc() (not kzalloc) and then DMA-mapped with DMA_TO_DEVICE, making the uninitialized 2-byte id field of each descriptor readable by the device. This leaks kernel heap memory to the device for every packed indirect descriptor entry. A malicious or compromised device could extract heap contents by reading the id fields from the DMA-mapped indirect descriptor tables. This affects all virtio devices that use packed virtqueues with indirect descriptors, which is the common configuration for modern virtio devices. Fix this by explicitly initializing desc[i].id to zero in the descriptor filling loop. The id field is unused in indirect descriptor table entries per the virtio specification (only the head descriptor in the main ring uses id for buffer identification), so setting it to zero is semantically correct. This matches the split ring path where all four fields of struct vring_desc (addr, len, flags, next) are explicitly written in virtqueue_add_desc_split(). Signed-off-by: zhang jiao Signed-off-by: Michael S. Tsirkin Message-ID: <20261029072511.851-1-zhangjiao2@cmss.chinamobile.com> --- drivers/virtio/virtio_ring.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index bec008123ce8..f683a2d6a200 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -1575,6 +1575,11 @@ static int virtqueue_add_indirect_packed(struct vring_virtqueue *vq, 0 : VRING_DESC_F_WRITE); desc[i].addr = cpu_to_le64(addr); desc[i].len = cpu_to_le32(len); + /* The id field is unused in indirect descriptors but + * must be initialized to prevent leaking kernel heap + * memory to the device through the DMA-mapped table. + */ + desc[i].id = 0; if (unlikely(vq->use_map_api)) { extra[i].addr = premapped ? DMA_MAPPING_ERROR : addr;