Skip to content

Commit

Permalink
block-backend: avoid bdrv_unregister_buf() NULL pointer deref
Browse files Browse the repository at this point in the history
bdrv_*() APIs expect a valid BlockDriverState. Calling them with bs=NULL
leads to undefined behavior.

Jonathan Cameron reported this following NULL pointer dereference when a
VM with a virtio-blk device and a memory-backend-file object is
terminated:
1. qemu_cleanup() closes all drives, setting blk->root to NULL
2. qemu_cleanup() calls user_creatable_cleanup(), which results in a RAM
   block notifier callback because the memory-backend-file is destroyed.
3. blk_unregister_buf() is called by virtio-blk's BlockRamRegistrar
   notifier callback and undefined behavior occurs.

Fixes: baf4226 ("virtio-blk: use BDRV_REQ_REGISTERED_BUF optimization hint")
Co-authored-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-Id: <20221121211923.1993171-1-stefanha@redhat.com>
  • Loading branch information
stefanhaRH and jic23 committed Nov 29, 2022
1 parent 379541d commit ce85b16
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions block/block-backend.c
Expand Up @@ -2576,14 +2576,25 @@ static void blk_root_drained_end(BdrvChild *child, int *drained_end_counter)

bool blk_register_buf(BlockBackend *blk, void *host, size_t size, Error **errp)
{
BlockDriverState *bs = blk_bs(blk);

GLOBAL_STATE_CODE();
return bdrv_register_buf(blk_bs(blk), host, size, errp);

if (bs) {
return bdrv_register_buf(bs, host, size, errp);
}
return true;
}

void blk_unregister_buf(BlockBackend *blk, void *host, size_t size)
{
BlockDriverState *bs = blk_bs(blk);

GLOBAL_STATE_CODE();
bdrv_unregister_buf(blk_bs(blk), host, size);

if (bs) {
bdrv_unregister_buf(bs, host, size);
}
}

int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
Expand Down

0 comments on commit ce85b16

Please sign in to comment.