From: Dan Carpenter <dan.carpen...@oracle.com>

[ Upstream commit e152d8af4220a05c9797591609151d404866beaa ]

The "vq" struct is added to the "vdev->vqs" list prematurely.  If we
encounter an error later in the function then the "vq" is freed, but
since it is still on the list that could lead to a use after free bug.

Fixes: cbeedb72b97a ("virtio_ring: allocate desc state for split ring 
separately")
Reported-by: Robert Buhren <robert.buh...@sect.tu-berlin.de>
Reported-by: Felicitas Hetzelt <f...@sect.tu-berlin.de>
Signed-off-by: Dan Carpenter <dan.carpen...@oracle.com>
Link: https://lore.kernel.org/r/X8pGaG/zkI3jk8mk@mwanda
Signed-off-by: Michael S. Tsirkin <m...@redhat.com>
Acked-by: Jason Wang <jasow...@redhat.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/virtio/virtio_ring.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 924b6b85376bd..71e16b53e9c18 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -1608,7 +1608,6 @@ static struct virtqueue *vring_create_virtqueue_packed(
        vq->num_added = 0;
        vq->packed_ring = true;
        vq->use_dma_api = vring_use_dma_api(vdev);
-       list_add_tail(&vq->vq.list, &vdev->vqs);
 #ifdef DEBUG
        vq->in_use = false;
        vq->last_add_time_valid = false;
@@ -1669,6 +1668,7 @@ static struct virtqueue *vring_create_virtqueue_packed(
                        cpu_to_le16(vq->packed.event_flags_shadow);
        }
 
+       list_add_tail(&vq->vq.list, &vdev->vqs);
        return &vq->vq;
 
 err_desc_extra:
@@ -2085,7 +2085,6 @@ struct virtqueue *__vring_new_virtqueue(unsigned int 
index,
        vq->last_used_idx = 0;
        vq->num_added = 0;
        vq->use_dma_api = vring_use_dma_api(vdev);
-       list_add_tail(&vq->vq.list, &vdev->vqs);
 #ifdef DEBUG
        vq->in_use = false;
        vq->last_add_time_valid = false;
@@ -2127,6 +2126,7 @@ struct virtqueue *__vring_new_virtqueue(unsigned int 
index,
        memset(vq->split.desc_state, 0, vring.num *
                        sizeof(struct vring_desc_state_split));
 
+       list_add_tail(&vq->vq.list, &vdev->vqs);
        return &vq->vq;
 }
 EXPORT_SYMBOL_GPL(__vring_new_virtqueue);
-- 
2.27.0



Reply via email to