Skip to content

Commit

Permalink
virtio_ring: fix unmap of indirect descriptors
Browse files Browse the repository at this point in the history
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 <matthias.lange@kernkonzept.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
  • Loading branch information
Matthias Lange authored and Michael S. Tsirkin committed Sep 9, 2019
1 parent 02fa5d7 commit cf8f169
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions drivers/virtio/virtio_ring.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,13 +566,17 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,

unmap_release:
err_idx = i;
i = head;

if (indirect)
i = 0;
else
i = head;

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

if (indirect)
Expand Down

0 comments on commit cf8f169

Please sign in to comment.