aboutsummaryrefslogtreecommitdiff
path: root/block/rbd.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2013-04-25 15:59:27 +0200
committerStefan Hajnoczi <stefanha@redhat.com>2013-04-26 13:26:28 +0200
commitc3ca988d2b0ee94dc8d53eff4b1c2de4ac06a270 (patch)
treed9452975ab8a2a00d27c3d61d39c3d7d6261c136 /block/rbd.c
parent8ec7d390b0d50b5e5b4b1d8dba7ba40d64a70875 (diff)
downloadqemu-c3ca988d2b0ee94dc8d53eff4b1c2de4ac06a270.zip
qemu-c3ca988d2b0ee94dc8d53eff4b1c2de4ac06a270.tar.gz
qemu-c3ca988d2b0ee94dc8d53eff4b1c2de4ac06a270.tar.bz2
rbd: Fix use after free in rbd_open()
Commit a9ccedc3 frees the QemuOpts for the driver-specific options immediately, even though it still needs the filename string that is contained there. This doesn't work. Move the deletion of the QemuOpts to the end of the function where its content isn't needed any more. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'block/rbd.c')
-rw-r--r--block/rbd.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/block/rbd.c b/block/rbd.c
index 1826411..0f2608b 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -478,20 +478,20 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags)
}
filename = qemu_opt_get(opts, "filename");
- qemu_opts_del(opts);
if (qemu_rbd_parsename(filename, pool, sizeof(pool),
snap_buf, sizeof(snap_buf),
s->name, sizeof(s->name),
conf, sizeof(conf)) < 0) {
- return -EINVAL;
+ r = -EINVAL;
+ goto failed_opts;
}
clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
r = rados_create(&s->cluster, clientname);
if (r < 0) {
error_report("error initializing");
- return r;
+ goto failed_opts;
}
s->snap = NULL;
@@ -557,6 +557,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags)
NULL, qemu_rbd_aio_flush_cb, s);
+ qemu_opts_del(opts);
return 0;
failed:
@@ -566,6 +567,8 @@ failed_open:
failed_shutdown:
rados_shutdown(s->cluster);
g_free(s->snap);
+failed_opts:
+ qemu_opts_del(opts);
return r;
}