From: Michael S. Tsirkin Date: Wed, 18 Jan 2017 19:32:22 +0000 (+0200) Subject: virtio: fix up max size checks X-Git-Tag: v2.8.1~55 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a626117f6ae0dfe8089c7fa263c56b105f9fd47d;p=thirdparty%2Fqemu.git virtio: fix up max size checks Coverity reports that ARRAY_SIZE(elem->out_sg) (and all the others too) is wrong because elem->out_sg is a pointer. However, the check is not in the right place and the max_size argument of virtqueue_map_iovec can be removed. The check on in_num/out_num should be moved to qemu_get_virtqueue_element instead, before the call to virtqueue_alloc_element. Cc: qemu-stable@nongnu.org Reported-by: Paolo Bonzini Fixes: 3724650db07057333879484c8bc7d900b5c1bf8e ("virtio: introduce virtqueue_alloc_element") Signed-off-by: Michael S. Tsirkin Reviewed-by: Cornelia Huck (cherry picked from commit 6bdc21c050a2a7b92cbbd0b2a1f8934e9b5f896f) * dropped context dep on 8607f5c30 Signed-off-by: Michael Roth --- diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index e37641a9c95..6dfc92f2308 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -592,24 +592,12 @@ static void virtqueue_undo_map_desc(unsigned int out_num, unsigned int in_num, } static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr, - unsigned int *num_sg, unsigned int max_size, + unsigned int *num_sg, int is_write) { unsigned int i; hwaddr len; - /* Note: this function MUST validate input, some callers - * are passing in num_sg values received over the network. - */ - /* TODO: teach all callers that this can fail, and return failure instead - * of asserting here. - * When we do, we might be able to re-enable NDEBUG below. - */ -#ifdef NDEBUG -#error building with NDEBUG is not supported -#endif - assert(*num_sg <= max_size); - for (i = 0; i < *num_sg; i++) { len = sg[i].iov_len; sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write); @@ -626,10 +614,8 @@ static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr, void virtqueue_map(VirtQueueElement *elem) { - virtqueue_map_iovec(elem->in_sg, elem->in_addr, &elem->in_num, - VIRTQUEUE_MAX_SIZE, 1); - virtqueue_map_iovec(elem->out_sg, elem->out_addr, &elem->out_num, - VIRTQUEUE_MAX_SIZE, 0); + virtqueue_map_iovec(elem->in_sg, elem->in_addr, &elem->in_num, 1); + virtqueue_map_iovec(elem->out_sg, elem->out_addr, &elem->out_num, 0); } static void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_num) @@ -790,6 +776,16 @@ void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz) qemu_get_buffer(f, (uint8_t *)&data, sizeof(VirtQueueElementOld)); + /* TODO: teach all callers that this can fail, and return failure instead + * of asserting here. + * When we do, we might be able to re-enable NDEBUG below. + */ +#ifdef NDEBUG +#error building with NDEBUG is not supported +#endif + assert(ARRAY_SIZE(data.in_addr) >= data.in_num); + assert(ARRAY_SIZE(data.out_addr) >= data.out_num); + elem = virtqueue_alloc_element(sz, data.out_num, data.in_num); elem->index = data.index;