Commit 771b6ed3 authored by Jason Wang's avatar Jason Wang Committed by Peter Maydell
Browse files

virtio-net: fix unmap leak



virtio_net_handle_ctrl() and other functions that process control vq
request call iov_discard_front() which will shorten the iov. This will
lead unmapping in virtqueue_push() leaks mapping.

Fixes this by keeping the original iov untouched and using a temp variable
in those functions.

Cc: Wen Congyang <wency@cn.fujitsu.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: qemu-stable@nongnu.org
Signed-off-by: default avatarJason Wang <jasowang@redhat.com>
Reviewed-by: default avatarStefano Stabellini <stefano.stabellini@eu.citrix.com>
Reviewed-by: default avatarFam Zheng <famz@redhat.com>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Message-id: 1417082643-23907-1-git-send-email-jasowang@redhat.com
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 4cae4d5a
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -798,7 +798,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
    virtio_net_ctrl_ack status = VIRTIO_NET_ERR;
    VirtQueueElement elem;
    size_t s;
    struct iovec *iov;
    struct iovec *iov, *iov2;
    unsigned int iov_cnt;

    while (virtqueue_pop(vq, &elem)) {
@@ -808,8 +808,8 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
            exit(1);
        }

        iov = elem.out_sg;
        iov_cnt = elem.out_num;
        iov2 = iov = g_memdup(elem.out_sg, sizeof(struct iovec) * elem.out_num);
        s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
        iov_discard_front(&iov, &iov_cnt, sizeof(ctrl));
        if (s != sizeof(ctrl)) {
@@ -833,6 +833,7 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)

        virtqueue_push(vq, &elem, sizeof(status));
        virtio_notify(vdev, vq);
        g_free(iov2);
    }
}