提交 a626117f 编写于 作者: M Michael S. Tsirkin 提交者: Michael Roth

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: NPaolo Bonzini <pbonzini@redhat.com>
Fixes: 3724650d ("virtio: introduce virtqueue_alloc_element")
Signed-off-by: NMichael S. Tsirkin <mst@redhat.com>
Reviewed-by: NCornelia Huck <cornelia.huck@de.ibm.com>
(cherry picked from commit 6bdc21c0)
* dropped context dep on 8607f5c3Signed-off-by: NMichael Roth <mdroth@linux.vnet.ibm.com>
上级 3b33cba6
...@@ -592,24 +592,12 @@ static void virtqueue_undo_map_desc(unsigned int out_num, unsigned int in_num, ...@@ -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, 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) int is_write)
{ {
unsigned int i; unsigned int i;
hwaddr len; 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++) { for (i = 0; i < *num_sg; i++) {
len = sg[i].iov_len; len = sg[i].iov_len;
sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write); 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, ...@@ -626,10 +614,8 @@ static void virtqueue_map_iovec(struct iovec *sg, hwaddr *addr,
void virtqueue_map(VirtQueueElement *elem) void virtqueue_map(VirtQueueElement *elem)
{ {
virtqueue_map_iovec(elem->in_sg, elem->in_addr, &elem->in_num, virtqueue_map_iovec(elem->in_sg, elem->in_addr, &elem->in_num, 1);
VIRTQUEUE_MAX_SIZE, 1); virtqueue_map_iovec(elem->out_sg, elem->out_addr, &elem->out_num, 0);
virtqueue_map_iovec(elem->out_sg, elem->out_addr, &elem->out_num,
VIRTQUEUE_MAX_SIZE, 0);
} }
static void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_num) 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) ...@@ -790,6 +776,16 @@ void *qemu_get_virtqueue_element(QEMUFile *f, size_t sz)
qemu_get_buffer(f, (uint8_t *)&data, sizeof(VirtQueueElementOld)); 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 = virtqueue_alloc_element(sz, data.out_num, data.in_num);
elem->index = data.index; elem->index = data.index;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册