diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-12 13:07:31 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-09-12 13:07:31 +0300 |
commit | ad32b4800c2b59a303e337ec1f6c2f122418cebe (patch) | |
tree | 1f46d5c2a8a2ee947646e86e4917f239e84f311b | |
parent | 6dcf6a4eb95a8a78c181cd27132f41aca36aeb94 (diff) | |
parent | 060423bfdee3f8bc6e2c1bac97de24d5415e2bc4 (diff) | |
download | linux-ad32b4800c2b59a303e337ec1f6c2f122418cebe.tar.xz |
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio fixes from Michael Tsirkin:
"Last minute bugfixes.
A couple of security things.
And an error handling bugfix that is never encountered by most people,
but that also makes it kind of safe to push at the last minute, and it
helps push the fix to stable a bit sooner"
* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
vhost: make sure log_num < in_num
vhost: block speculation of translated descriptors
virtio_ring: fix unmap of indirect descriptors
-rw-r--r-- | drivers/vhost/vhost.c | 10 | ||||
-rw-r--r-- | drivers/virtio/virtio_ring.c | 8 |
2 files changed, 12 insertions, 6 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 5dc174ac8cac..acabf20b069e 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -2071,8 +2071,10 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len, _iov = iov + ret; size = node->size - addr + node->start; _iov->iov_len = min((u64)len - s, size); - _iov->iov_base = (void __user *)(unsigned long) - (node->userspace_addr + addr - node->start); + _iov->iov_base = (void __user *) + ((unsigned long)node->userspace_addr + + array_index_nospec((unsigned long)(addr - node->start), + node->size)); s += size; addr += size; ++ret; @@ -2178,7 +2180,7 @@ static int get_indirect(struct vhost_virtqueue *vq, /* If this is an input descriptor, increment that count. */ if (access == VHOST_ACCESS_WO) { *in_num += ret; - if (unlikely(log)) { + if (unlikely(log && ret)) { log[*log_num].addr = vhost64_to_cpu(vq, desc.addr); log[*log_num].len = vhost32_to_cpu(vq, desc.len); ++*log_num; @@ -2319,7 +2321,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq, /* If this is an input descriptor, * increment that count. */ *in_num += ret; - if (unlikely(log)) { + if (unlikely(log && ret)) { log[*log_num].addr = vhost64_to_cpu(vq, desc.addr); log[*log_num].len = vhost32_to_cpu(vq, desc.len); ++*log_num; diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index c8be1c4f5b55..bdc08244a648 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -566,13 +566,17 @@ static inline int virtqueue_add_split(struct virtqueue *_vq, unmap_release: err_idx = i; - i = head; + + if (indirect) + i = 0; + else + i = head; for (n = 0; n < total_sg; n++) { if (i == err_idx) break; vring_unmap_one_split(vq, &desc[i]); - i = virtio16_to_cpu(_vq->vdev, vq->split.vring.desc[i].next); + i = virtio16_to_cpu(_vq->vdev, desc[i].next); } if (indirect) |