aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorGreg Kurz <groug@kaod.org>2020-07-09 15:50:45 +0200
committerKevin Wolf <kwolf@redhat.com>2020-07-14 15:24:15 +0200
commite6cada9231af022ffc2e351c70dfaea8530496e1 (patch)
tree3773d5b1da5ad61af2558fdad1982e859e583062 /tests
parentd9f059aa6cfccefaffa3532556e966df4a99ece2 (diff)
downloadqemu-e6cada9231af022ffc2e351c70dfaea8530496e1.zip
qemu-e6cada9231af022ffc2e351c70dfaea8530496e1.tar.gz
qemu-e6cada9231af022ffc2e351c70dfaea8530496e1.tar.bz2
block: Avoid stale pointer dereference in blk_get_aio_context()
It is possible for blk_remove_bs() to race with blk_drain_all(), causing the latter to dereference a stale blk->root pointer: blk_remove_bs(blk) bdrv_root_unref_child(blk->root) child_bs = blk->root->bs bdrv_detach_child(blk->root) ... g_free(blk->root) <============== blk->root becomes stale bdrv_unref(child_bs) <============ yield at some point A blk_drain_all() can be triggered by some guest action in the meantime, eg. on POWER, SLOF might disable bus mastering on a virtio-scsi-pci device: virtio_write_config() virtio_pci_stop_ioeventfd() virtio_bus_stop_ioeventfd() virtio_scsi_dataplane_stop() blk_drain_all() blk_get_aio_context() bs = blk->root ? blk->root->bs : NULL ^^^^^^^^^ stale Then, depending on one's luck, QEMU either crashes with SEGV or hits the assertion in blk_get_aio_context(). blk->root is set by blk_insert_bs() which calls bdrv_root_attach_child() first. The blk_remove_bs() function should rollback the changes made by blk_insert_bs() in the opposite order (or it should be documented somewhere why this isn't the case). Clear blk->root before calling bdrv_root_unref_child() in blk_remove_bs(). Signed-off-by: Greg Kurz <groug@kaod.org> Message-Id: <159430264541.389456.11925072456012783045.stgit@bahia.lan> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'tests')
0 files changed, 0 insertions, 0 deletions