[libvirt] [PATCH v2 3/4] secret: Properly handle @def after virSecretObjAdd in driver

Pavel Hrdina phrdina at redhat.com
Tue Jul 25 12:54:00 UTC 2017


On Tue, Jul 25, 2017 at 08:37:23AM -0400, John Ferlan wrote:
> 
> 
> On 07/25/2017 08:21 AM, Pavel Hrdina wrote:
> > On Tue, Jul 25, 2017 at 01:36:20PM +0200, Pavel Hrdina wrote:
> >> On Fri, Jul 14, 2017 at 10:04:41AM -0400, John Ferlan wrote:
> >>> Since the virSecretObjListAdd technically consumes @def on success,
> >>> the secretDefineXML should set @def = NULL immediately and process
> >>> the remaining calls using a new @objdef variable. We can use use
> >>> VIR_STEAL_PTR since we know the Add function just stores @def in
> >>> obj->def.
> >>>
> >>> This fixes a possible double free of @def if the code jumps to
> >>> restore_backup: and calls virSecretObjListRemove without setting
> >>> def = NULL. In this case, the subsequent call to DefFree would
> >>> succeed and free @def; however, the call to EndAPI would also
> >>> call DefFree because the Unref done would be the last one for
> >>> the @obj meaning the obj->def would be used to call DefFree,
> >>> but it's already been free'd because @def wasn't managed right
> >>> within this error path.
> >>>
> >>> Signed-off-by: John Ferlan <jferlan at redhat.com>
> >>> ---
> >>>  src/secret/secret_driver.c | 19 ++++++++++---------
> >>>  1 file changed, 10 insertions(+), 9 deletions(-)
> >>>
> >>> diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
> >>> index 30124b4..77351d8 100644
> >>> --- a/src/secret/secret_driver.c
> >>> +++ b/src/secret/secret_driver.c
> >>> @@ -210,6 +210,7 @@ secretDefineXML(virConnectPtr conn,
> >>>  {
> >>>      virSecretPtr ret = NULL;
> >>>      virSecretObjPtr obj = NULL;
> >>> +    virSecretDefPtr objdef;
> >>
> >> s/objdef/objDef/
> >>
> >> Reviewed-by: Pavel Hrdina <phrdina at redhat.com>
> > 
> > Actually this patch introduces a memory leak in case we restore the
> > @backup definition.
> > 
> > virSecretObjListAdd() adds the @def into @obj and sets the old def
> > into @backup, so far good.
> > 
> > VIR_STEAL_PTR(objdef, def) leaves the @def == NULL, still good
> > 
> > But if we in any point jump to "restore_backup" after the VIR_STEAL_PTR
> > and the @backup != NULL we simply changes the @obj->def back to @backup
> > and the new def is only in @objdef which is not freed anywhere.
> 
> I went through this in the previous review, but for the opposite
> condition where backup == NULL (repeated for ease)
> 
> Without the stealing of objdef, when return from the Add function we
> have "refcnt=2" and "lock=true".
> 
> For some reason we jump to restore_backup and call ObjListRemove which
> returns and the object refcnt=1 and lock=false.
> 
> We fall into cleanup:
> 
> Call virSecretDefFree(def) where @def != NULL, so it free's it
> Call virSecretObjEndAPI(&obj) which calls Unref, setting R=0 and calling
> virSecretDefFree(obj->def)... But wait, we already did that because we
> allowed the DefFree(def) to free something it didn't own.
> 
> 
> > 
> > Possible fix is to set @def = NULL after the virSecretObjListRemove()
> > in restore_backup:
> > 
> >     ...
> >     } else {
> >         virSecretObjListRemove(driver->secrets, obj);
> >         virObjectUnref(obj);
> >         obj = NULL;
> >         def = NULL;
> >     }
> >     ...
> > 
> 
> The other fix to the leak you point out is:
> 
>     if (backup) {
>         virSecretObjSetDef(obj, backup);
>         def = objdef;
>     } else {
>         virSecretObjListRemove(driver->secrets, obj);
>     }

That works for me, but still I would like to use objDef.

Pavel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20170725/6579ebaa/attachment-0001.sig>


More information about the libvir-list mailing list