Skip to content

Commit cf8f169

Browse files
icedielermstsirkin
authored andcommitted
virtio_ring: fix unmap of indirect descriptors
The function virtqueue_add_split() DMA-maps the scatterlist buffers. In case a mapping error occurs the already mapped buffers must be unmapped. This happens by jumping to the 'unmap_release' label. In case of indirect descriptors the release is wrong and may leak kernel memory. Because the implementation assumes that the head descriptor is already mapped it starts iterating over the descriptor list starting from the head descriptor. However for indirect descriptors the head descriptor is never mapped in case of an error. The fix is to initialize the start index with zero in case of indirect descriptors and use the 'desc' pointer directly for iterating over the descriptor chain. Signed-off-by: Matthias Lange <[email protected]> Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent 02fa5d7 commit cf8f169

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

drivers/virtio/virtio_ring.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,13 +566,17 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
566566

567567
unmap_release:
568568
err_idx = i;
569-
i = head;
569+
570+
if (indirect)
571+
i = 0;
572+
else
573+
i = head;
570574

571575
for (n = 0; n < total_sg; n++) {
572576
if (i == err_idx)
573577
break;
574578
vring_unmap_one_split(vq, &desc[i]);
575-
i = virtio16_to_cpu(_vq->vdev, vq->split.vring.desc[i].next);
579+
i = virtio16_to_cpu(_vq->vdev, desc[i].next);
576580
}
577581

578582
if (indirect)

0 commit comments

Comments
 (0)