* [PATCH for-7.2] block-backend: avoid bdrv_unregister_buf() NULL pointer deref
@ 2022-11-21 21:19 Stefan Hajnoczi
2022-11-21 22:22 ` Philippe Mathieu-Daudé
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2022-11-21 21:19 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-block, Hanna Reitz, Kevin Wolf, Stefan Hajnoczi,
Jonathan Cameron
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: baf422684d73 ("virtio-blk: use BDRV_REQ_REGISTERED_BUF optimization hint")
Co-authored-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/block-backend.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index b48c91f4e1..d98a96ff37 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -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,
--
2.38.1
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH for-7.2] block-backend: avoid bdrv_unregister_buf() NULL pointer deref
2022-11-21 21:19 [PATCH for-7.2] block-backend: avoid bdrv_unregister_buf() NULL pointer deref Stefan Hajnoczi
@ 2022-11-21 22:22 ` Philippe Mathieu-Daudé
2022-11-22 8:21 ` Kevin Wolf
2022-11-30 19:47 ` Stefan Hajnoczi
2 siblings, 0 replies; 5+ messages in thread
From: Philippe Mathieu-Daudé @ 2022-11-21 22:22 UTC (permalink / raw)
To: Stefan Hajnoczi, qemu-devel
Cc: qemu-block, Hanna Reitz, Kevin Wolf, Jonathan Cameron
On 21/11/22 22:19, Stefan Hajnoczi wrote:
> 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: baf422684d73 ("virtio-blk: use BDRV_REQ_REGISTERED_BUF optimization hint")
> Co-authored-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
> block/block-backend.c | 15 +++++++++++++--
> 1 file changed, 13 insertions(+), 2 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH for-7.2] block-backend: avoid bdrv_unregister_buf() NULL pointer deref
2022-11-21 21:19 [PATCH for-7.2] block-backend: avoid bdrv_unregister_buf() NULL pointer deref Stefan Hajnoczi
2022-11-21 22:22 ` Philippe Mathieu-Daudé
@ 2022-11-22 8:21 ` Kevin Wolf
2022-11-29 20:53 ` Stefan Hajnoczi
2022-11-30 19:47 ` Stefan Hajnoczi
2 siblings, 1 reply; 5+ messages in thread
From: Kevin Wolf @ 2022-11-22 8:21 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: qemu-devel, qemu-block, Hanna Reitz, Jonathan Cameron
Am 21.11.2022 um 22:19 hat Stefan Hajnoczi geschrieben:
> 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: baf422684d73 ("virtio-blk: use BDRV_REQ_REGISTERED_BUF optimization hint")
> Co-authored-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
This raises some questions, though. What happens if the graph isn't
static between creation and deletion of the device? Do we need to do
something with registered buffers when a node is attached to or detached
from an existing device?
Kevin
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH for-7.2] block-backend: avoid bdrv_unregister_buf() NULL pointer deref
2022-11-22 8:21 ` Kevin Wolf
@ 2022-11-29 20:53 ` Stefan Hajnoczi
0 siblings, 0 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2022-11-29 20:53 UTC (permalink / raw)
To: Kevin Wolf
Cc: Stefan Hajnoczi, qemu-devel, qemu-block, Hanna Reitz,
Jonathan Cameron
On Tue, 22 Nov 2022 at 03:22, Kevin Wolf <kwolf@redhat.com> wrote:
>
> Am 21.11.2022 um 22:19 hat Stefan Hajnoczi geschrieben:
> > 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: baf422684d73 ("virtio-blk: use BDRV_REQ_REGISTERED_BUF optimization hint")
> > Co-authored-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
>
> Reviewed-by: Kevin Wolf <kwolf@redhat.com>
>
> This raises some questions, though. What happens if the graph isn't
> static between creation and deletion of the device? Do we need to do
> something with registered buffers when a node is attached to or detached
> from an existing device?
I think you are right. Graph changes need to be handled. Right now they aren't.
Stefan
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH for-7.2] block-backend: avoid bdrv_unregister_buf() NULL pointer deref
2022-11-21 21:19 [PATCH for-7.2] block-backend: avoid bdrv_unregister_buf() NULL pointer deref Stefan Hajnoczi
2022-11-21 22:22 ` Philippe Mathieu-Daudé
2022-11-22 8:21 ` Kevin Wolf
@ 2022-11-30 19:47 ` Stefan Hajnoczi
2 siblings, 0 replies; 5+ messages in thread
From: Stefan Hajnoczi @ 2022-11-30 19:47 UTC (permalink / raw)
To: Stefan Hajnoczi
Cc: qemu-devel, qemu-block, Hanna Reitz, Kevin Wolf, Jonathan Cameron
Merged. I will work on supporting graph changes.
Stefan
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-11-30 19:48 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-11-21 21:19 [PATCH for-7.2] block-backend: avoid bdrv_unregister_buf() NULL pointer deref Stefan Hajnoczi
2022-11-21 22:22 ` Philippe Mathieu-Daudé
2022-11-22 8:21 ` Kevin Wolf
2022-11-29 20:53 ` Stefan Hajnoczi
2022-11-30 19:47 ` Stefan Hajnoczi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).