summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kurz <gkurz@linux.vnet.ibm.com>2016-02-16 15:54:28 +0100
committerMichael S. Tsirkin <mst@redhat.com>2016-03-02 17:01:49 +0200
commite1f33be9186363da7955bcb5f0b03e6685544c50 (patch)
tree351ee45f7f1e591fd755b38355a945e11547dd04
parent4e94ebdd06d5dc72b7a40fc12fc496d601fb7bbc (diff)
downloadlinux-e1f33be9186363da7955bcb5f0b03e6685544c50.tar.gz
linux-e1f33be9186363da7955bcb5f0b03e6685544c50.tar.bz2
linux-e1f33be9186363da7955bcb5f0b03e6685544c50.zip
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>
-rw-r--r--drivers/vhost/vhost.c15
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);