Commit ad32b480 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 6dcf6a4e 060423bf
...@@ -2071,8 +2071,10 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len, ...@@ -2071,8 +2071,10 @@ static int translate_desc(struct vhost_virtqueue *vq, u64 addr, u32 len,
_iov = iov + ret; _iov = iov + ret;
size = node->size - addr + node->start; size = node->size - addr + node->start;
_iov->iov_len = min((u64)len - s, size); _iov->iov_len = min((u64)len - s, size);
_iov->iov_base = (void __user *)(unsigned long) _iov->iov_base = (void __user *)
(node->userspace_addr + addr - node->start); ((unsigned long)node->userspace_addr +
array_index_nospec((unsigned long)(addr - node->start),
node->size));
s += size; s += size;
addr += size; addr += size;
++ret; ++ret;
...@@ -2178,7 +2180,7 @@ static int get_indirect(struct vhost_virtqueue *vq, ...@@ -2178,7 +2180,7 @@ static int get_indirect(struct vhost_virtqueue *vq,
/* If this is an input descriptor, increment that count. */ /* If this is an input descriptor, increment that count. */
if (access == VHOST_ACCESS_WO) { if (access == VHOST_ACCESS_WO) {
*in_num += ret; *in_num += ret;
if (unlikely(log)) { if (unlikely(log && ret)) {
log[*log_num].addr = vhost64_to_cpu(vq, desc.addr); log[*log_num].addr = vhost64_to_cpu(vq, desc.addr);
log[*log_num].len = vhost32_to_cpu(vq, desc.len); log[*log_num].len = vhost32_to_cpu(vq, desc.len);
++*log_num; ++*log_num;
...@@ -2319,7 +2321,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq, ...@@ -2319,7 +2321,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
/* If this is an input descriptor, /* If this is an input descriptor,
* increment that count. */ * increment that count. */
*in_num += ret; *in_num += ret;
if (unlikely(log)) { if (unlikely(log && ret)) {
log[*log_num].addr = vhost64_to_cpu(vq, desc.addr); log[*log_num].addr = vhost64_to_cpu(vq, desc.addr);
log[*log_num].len = vhost32_to_cpu(vq, desc.len); log[*log_num].len = vhost32_to_cpu(vq, desc.len);
++*log_num; ++*log_num;
......
...@@ -566,13 +566,17 @@ static inline int virtqueue_add_split(struct virtqueue *_vq, ...@@ -566,13 +566,17 @@ static inline int virtqueue_add_split(struct virtqueue *_vq,
unmap_release: unmap_release:
err_idx = i; err_idx = i;
if (indirect)
i = 0;
else
i = head; i = head;
for (n = 0; n < total_sg; n++) { for (n = 0; n < total_sg; n++) {
if (i == err_idx) if (i == err_idx)
break; break;
vring_unmap_one_split(vq, &desc[i]); 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) if (indirect)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment