diff options
author | Greg Kurz <gkurz@linux.vnet.ibm.com> | 2016-02-16 17:54:28 +0300 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2016-03-02 18:01:49 +0300 |
commit | e1f33be9186363da7955bcb5f0b03e6685544c50 (patch) | |
tree | 351ee45f7f1e591fd755b38355a945e11547dd04 /drivers/vhost/vhost.c | |
parent | 4e94ebdd06d5dc72b7a40fc12fc496d601fb7bbc (diff) | |
download | linux-e1f33be9186363da7955bcb5f0b03e6685544c50.tar.xz |
vhost: fix error path in vhost_init_used()
We don't want side effects. If something fails, we rollback vq->is_le to
its previous value.
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'drivers/vhost/vhost.c')
-rw-r--r-- | drivers/vhost/vhost.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index ad2146a9ab2d..236553e81027 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -1156,6 +1156,8 @@ int vhost_init_used(struct vhost_virtqueue *vq) { __virtio16 last_used_idx; int r; + bool is_le = vq->is_le; + if (!vq->private_data) { vq->is_le = virtio_legacy_is_little_endian(); return 0; @@ -1165,15 +1167,20 @@ int vhost_init_used(struct vhost_virtqueue *vq) r = vhost_update_used_flags(vq); if (r) - return r; + goto err; vq->signalled_used_valid = false; - if (!access_ok(VERIFY_READ, &vq->used->idx, sizeof vq->used->idx)) - return -EFAULT; + if (!access_ok(VERIFY_READ, &vq->used->idx, sizeof vq->used->idx)) { + r = -EFAULT; + goto err; + } r = __get_user(last_used_idx, &vq->used->idx); if (r) - return r; + goto err; vq->last_used_idx = vhost16_to_cpu(vq, last_used_idx); return 0; +err: + vq->is_le = is_le; + return r; } EXPORT_SYMBOL_GPL(vhost_init_used); |