Commit abd76425 authored by Stefan Hajnoczi's avatar Stefan Hajnoczi Committed by Kevin Wolf
Browse files

dataplane: do not free VirtQueueElement in vring_push()



VirtQueueElement is allocated in vring_pop() so it seems to make sense
that vring_push() should free it.  Alas, virtio-blk frees
VirtQueueElement itself in virtio_blk_free_request().

This patch solves a double-free assertion in glib's g_slice_free().

Rename vring_free_element() to vring_unmap_element() since it no longer
frees the VirtQueueElement.

Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Tested-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 0a21ea32
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -272,7 +272,7 @@ static int get_indirect(Vring *vring, VirtQueueElement *elem,
    return 0;
}

void vring_free_element(VirtQueueElement *elem)
static void vring_unmap_element(VirtQueueElement *elem)
{
    int i;

@@ -287,8 +287,6 @@ void vring_free_element(VirtQueueElement *elem)
    for (i = 0; i < elem->in_num; i++) {
        vring_unmap(elem->in_sg[i].iov_base, true);
    }

    g_slice_free(VirtQueueElement, elem);
}

/* This looks in the virtqueue and for the first available buffer, and converts
@@ -402,7 +400,8 @@ out:
        vring->broken = true;
    }
    if (elem) {
        vring_free_element(elem);
        vring_unmap_element(elem);
        g_slice_free(VirtQueueElement, elem);
    }
    *p_elem = NULL;
    return ret;
@@ -418,7 +417,7 @@ void vring_push(Vring *vring, VirtQueueElement *elem, int len)
    unsigned int head = elem->index;
    uint16_t new;

    vring_free_element(elem);
    vring_unmap_element(elem);

    /* Don't touch vring if a fatal error occurred */
    if (vring->broken) {
+0 −1
Original line number Diff line number Diff line
@@ -55,6 +55,5 @@ bool vring_enable_notification(VirtIODevice *vdev, Vring *vring);
bool vring_should_notify(VirtIODevice *vdev, Vring *vring);
int vring_pop(VirtIODevice *vdev, Vring *vring, VirtQueueElement **elem);
void vring_push(Vring *vring, VirtQueueElement *elem, int len);
void vring_free_element(VirtQueueElement *elem);

#endif /* VRING_H */