|
@@ -1038,6 +1038,7 @@ static int vhost_update_avail_event(struct vhost_virtqueue *vq, u16 avail_event)
|
|
|
|
|
|
int vhost_init_used(struct vhost_virtqueue *vq)
|
|
|
{
|
|
|
+ u16 last_used_idx;
|
|
|
int r;
|
|
|
if (!vq->private_data)
|
|
|
return 0;
|
|
@@ -1046,7 +1047,13 @@ int vhost_init_used(struct vhost_virtqueue *vq)
|
|
|
if (r)
|
|
|
return r;
|
|
|
vq->signalled_used_valid = false;
|
|
|
- return get_user(vq->last_used_idx, &vq->used->idx);
|
|
|
+ if (!access_ok(VERIFY_READ, &vq->used->idx, sizeof vq->used->idx))
|
|
|
+ return -EFAULT;
|
|
|
+ r = __get_user(last_used_idx, &vq->used->idx);
|
|
|
+ if (r)
|
|
|
+ return r;
|
|
|
+ vq->last_used_idx = last_used_idx;
|
|
|
+ return 0;
|
|
|
}
|
|
|
EXPORT_SYMBOL_GPL(vhost_init_used);
|
|
|
|
|
@@ -1404,7 +1411,7 @@ int vhost_add_used_n(struct vhost_virtqueue *vq, struct vring_used_elem *heads,
|
|
|
|
|
|
/* Make sure buffer is written before we update index. */
|
|
|
smp_wmb();
|
|
|
- if (put_user(vq->last_used_idx, &vq->used->idx)) {
|
|
|
+ if (__put_user(vq->last_used_idx, &vq->used->idx)) {
|
|
|
vq_err(vq, "Failed to increment used idx");
|
|
|
return -EFAULT;
|
|
|
}
|
|
@@ -1449,7 +1456,7 @@ static bool vhost_notify(struct vhost_dev *dev, struct vhost_virtqueue *vq)
|
|
|
if (unlikely(!v))
|
|
|
return true;
|
|
|
|
|
|
- if (get_user(event, vhost_used_event(vq))) {
|
|
|
+ if (__get_user(event, vhost_used_event(vq))) {
|
|
|
vq_err(vq, "Failed to get used event idx");
|
|
|
return true;
|
|
|
}
|