qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-block] [PATCH] block: fix bs->file leak in bdrv_new_open_drive


From: Kevin Wolf
Subject: Re: [Qemu-block] [PATCH] block: fix bs->file leak in bdrv_new_open_driver()
Date: Fri, 7 Jul 2017 11:28:15 +0200
User-agent: Mutt/1.5.21 (2010-09-15)

Am 29.06.2017 um 22:06 hat Manos Pitsidianakis geschrieben:
> On Thu, Jun 29, 2017 at 03:57:49PM +0200, Kevin Wolf wrote:
> >Am 29.06.2017 um 14:07 hat Manos Pitsidianakis geschrieben:
> >>On Thu, Jun 29, 2017 at 01:18:24PM +0200, Kevin Wolf wrote:
> >>>Am 29.06.2017 um 08:03 hat Manos Pitsidianakis geschrieben:
> >>>>bdrv_open_driver() is called in two places, bdrv_new_open_driver() and
> >>>>bdrv_open_common(). In the latter, failure cleanup in is in its caller,
> >>>>bdrv_open_inherit(), which unrefs the bs->file of the failed driver open
> >>>>if it exists. Let's check for this in bdrv_new_open_driver() as well.
> >>>>
> >>>>Signed-off-by: Manos Pitsidianakis <address@hidden>
> >>>>---
> >>>> block.c | 3 +++
> >>>> 1 file changed, 3 insertions(+)
> >>>>
> >>>>diff --git a/block.c b/block.c
> >>>>index 694396281b..aeacd520e0 100644
> >>>>--- a/block.c
> >>>>+++ b/block.c
> >>>>@@ -1165,6 +1165,9 @@ BlockDriverState *bdrv_new_open_driver(BlockDriver 
> >>>>*drv, const char *node_name,
> >>>>
> >>>>     ret = bdrv_open_driver(bs, drv, node_name, bs->options, flags, errp);
> >>>>     if (ret < 0) {
> >>>>+        if (bs->file != NULL) {
> >>>>+            bdrv_unref_child(bs, bs->file);
> >>>>+        }
> >>>>         QDECREF(bs->explicit_options);
> >>>>         QDECREF(bs->options);
> >>>>         bdrv_unref(bs);
> >>>
> >>>I think we should set bs->file = NULL here to remove the dangling
> >>>pointer. I think it is never accessed anyway because of the
> >>>bs->drv = NULL in the error path of bdrv_open_driver(), but better safe
> >>>than sorry.
> >>
> >>You can't see it in the diff but after bdrv_unref(bs),
> >>bdrv_new_open_driver returns NULL so there won't be any access to bs
> >>anyway. And since bs is destroyed by bdrv_unref (its refcount is 1),
> >>there's not really a point in setting bs->file = NULL.
> >
> >Yes, but bdrv_unref() doesn't have to expect inconsistent BDSes. It
> >doesn't access bs->file currently when bs->drv == NULL, but that's more
> >by luck than by design.
> >
> >>>But what would you think about avoiding the code duplication and just
> >>>moving the bdrv_unref_child() call from bdrv_open_inherit() down to
> >>>bdrv_open_driver(), so that bdrv_new_open_driver() is automatically
> >>>covered?
> >>
> >>The result would be the same, but this will cover future callers of
> >>bdrv_open_driver. Should I submit a v2?
> >
> >I would prefer this, yes.
> 
> Perhaps it would be better to destroy bs at failure in
> bdrv_open_driver and not leave it to the caller which takes care of
> bdrv_close and unrefing bs->file anyway (Also bs->children). Setting
> bs->drv to NULL at failure in bdrv_open_driver means some things
> won't be executed in bdrv_close when the bs is destroyed eventually
> as well, so that fixes another mistake.

Oh, didn't I reply here yet? Your suggestion sounds good to me.

Kevin

Attachment: pgpPO4OX7yGEG.pgp
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]