[libvirt] [PATCH 2/4] nwfilter: Fix potential locking problems on ObjLoad failure

John Ferlan jferlan at redhat.com
Fri Apr 29 21:32:40 UTC 2016



On 04/24/2016 07:22 PM, Cole Robinson wrote:
> In virNWFilterObjLoad we can still fail after virNWFilterObjAssignDef,
> but we don't unlock and free the created virNWFilterObjPtr in the
> cleanup path.
> 
> The bit we are trying to do after AssignDef is just STRDUP in the
> configFile path. However caching the configFile in the NWFilterObj
> is largely redundant and doesn't follow the same pattern we use
> for domain and network objects.
> 
> So just remove all the configFile caching which fixes the latent
> bug as a side effect.
> ---
>  src/conf/nwfilter_conf.c       | 62 ++++++++++++++++++++----------------------
>  src/conf/nwfilter_conf.h       |  5 ++--
>  src/nwfilter/nwfilter_driver.c |  6 ++--
>  3 files changed, 34 insertions(+), 39 deletions(-)
> 

Fine with the concept - seems as though there's still some streamlining
that can be done - possibly as a followup sometime.  Seeing as
virNWFilterConfigFile essentially does the same thing as virFileBuildPath.

Trying to compare with network (and domain) would then just be easier.
Those are the models I used for secrets.

ACK to what's here (extra credit saved for the future).

John

> diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
> index ced8eb8..d02bbff 100644
> --- a/src/conf/nwfilter_conf.c
> +++ b/src/conf/nwfilter_conf.c
> @@ -353,8 +353,6 @@ virNWFilterObjFree(virNWFilterObjPtr obj)
>      virNWFilterDefFree(obj->def);
>      virNWFilterDefFree(obj->newDef);
>  
> -    VIR_FREE(obj->configFile);
> -
>      virMutexDestroy(&obj->lock);
>  
>      VIR_FREE(obj);
> @@ -3181,12 +3179,6 @@ virNWFilterObjLoad(virNWFilterObjListPtr nwfilters,
>          return NULL;
>      }
>  
> -    VIR_FREE(nwfilter->configFile); /* for driver reload */
> -    if (VIR_STRDUP(nwfilter->configFile, path) < 0) {
> -        virNWFilterDefFree(def);
> -        return NULL;
> -    }
> -
>      return nwfilter;
>  }
>  
> @@ -3234,60 +3226,66 @@ virNWFilterLoadAllConfigs(virNWFilterObjListPtr nwfilters,
>  
>  int
>  virNWFilterObjSaveDef(virNWFilterDriverStatePtr driver,
> -                      virNWFilterObjPtr nwfilter,
>                        virNWFilterDefPtr def)
>  {
>      char uuidstr[VIR_UUID_STRING_BUFLEN];
>      char *xml;
> -    int ret;
> -
> -    if (!nwfilter->configFile) {
> -        if (virFileMakePath(driver->configDir) < 0) {
> -            virReportSystemError(errno,
> -                                 _("cannot create config directory %s"),
> -                                 driver->configDir);
> -            return -1;
> -        }
> +    int ret = -1;
> +    char *configFile = NULL;
>  
> -        if (!(nwfilter->configFile = virFileBuildPath(driver->configDir,
> -                                                      def->name, ".xml"))) {
> -            return -1;
> -        }
> +    if (virFileMakePath(driver->configDir) < 0) {
> +        virReportSystemError(errno,
> +                             _("cannot create config directory %s"),
> +                             driver->configDir);
> +        goto error;
> +    }
> +
> +    if (!(configFile = virFileBuildPath(driver->configDir,
> +                                        def->name, ".xml"))) {
> +        goto error;
>      }
>  
>      if (!(xml = virNWFilterDefFormat(def))) {
>          virReportError(VIR_ERR_INTERNAL_ERROR,
>                         "%s", _("failed to generate XML"));
> -        return -1;
> +        goto error;
>      }
>  
>      virUUIDFormat(def->uuid, uuidstr);
> -    ret = virXMLSaveFile(nwfilter->configFile,
> +    ret = virXMLSaveFile(configFile,
>                           virXMLPickShellSafeComment(def->name, uuidstr),
>                           "nwfilter-edit", xml);
>      VIR_FREE(xml);
>  
> + error:
> +    VIR_FREE(configFile);
>      return ret;
>  }
>  
>  
>  int
> -virNWFilterObjDeleteDef(virNWFilterObjPtr nwfilter)
> +virNWFilterObjDeleteDef(const char *configDir,
> +                        virNWFilterObjPtr nwfilter)
>  {
> -    if (!nwfilter->configFile) {
> -        virReportError(VIR_ERR_INTERNAL_ERROR,
> -                       _("no config file for %s"), nwfilter->def->name);
> -        return -1;
> +    int ret = -1;
> +    char *configFile = NULL;
> +
> +    if (!(configFile = virFileBuildPath(configDir,
> +                                        nwfilter->def->name, ".xml"))) {
> +        goto error;
>      }
>  
> -    if (unlink(nwfilter->configFile) < 0) {
> +    if (unlink(configFile) < 0) {
>          virReportError(VIR_ERR_INTERNAL_ERROR,
>                         _("cannot remove config for %s"),
>                         nwfilter->def->name);
> -        return -1;
> +        goto error;
>      }
>  
> -    return 0;
> +    ret = 0;
> + error:
> +    VIR_FREE(configFile);
> +    return ret;
>  }
>  
>  
> diff --git a/src/conf/nwfilter_conf.h b/src/conf/nwfilter_conf.h
> index 0211861..823cfa4 100644
> --- a/src/conf/nwfilter_conf.h
> +++ b/src/conf/nwfilter_conf.h
> @@ -551,7 +551,6 @@ typedef virNWFilterObj *virNWFilterObjPtr;
>  struct _virNWFilterObj {
>      virMutex lock;
>  
> -    char *configFile;
>      int active;
>      int wantRemoved;
>  
> @@ -612,10 +611,10 @@ virNWFilterObjPtr virNWFilterObjFindByName(virNWFilterObjListPtr nwfilters,
>  
>  
>  int virNWFilterObjSaveDef(virNWFilterDriverStatePtr driver,
> -                          virNWFilterObjPtr nwfilter,
>                            virNWFilterDefPtr def);
>  
> -int virNWFilterObjDeleteDef(virNWFilterObjPtr nwfilter);
> +int virNWFilterObjDeleteDef(const char *configDir,
> +                            virNWFilterObjPtr nwfilter);
>  
>  virNWFilterObjPtr virNWFilterObjAssignDef(virNWFilterObjListPtr nwfilters,
>                                            virNWFilterDefPtr def);
> diff --git a/src/nwfilter/nwfilter_driver.c b/src/nwfilter/nwfilter_driver.c
> index 1a868b6..2828b28 100644
> --- a/src/nwfilter/nwfilter_driver.c
> +++ b/src/nwfilter/nwfilter_driver.c
> @@ -554,7 +554,7 @@ nwfilterDefineXML(virConnectPtr conn,
>      if (!(nwfilter = virNWFilterObjAssignDef(&driver->nwfilters, def)))
>          goto cleanup;
>  
> -    if (virNWFilterObjSaveDef(driver, nwfilter, def) < 0) {
> +    if (virNWFilterObjSaveDef(driver, def) < 0) {
>          virNWFilterObjRemove(&driver->nwfilters, nwfilter);
>          def = NULL;
>          goto cleanup;
> @@ -602,11 +602,9 @@ nwfilterUndefine(virNWFilterPtr obj)
>          goto cleanup;
>      }
>  
> -    if (virNWFilterObjDeleteDef(nwfilter) < 0)
> +    if (virNWFilterObjDeleteDef(driver->configDir, nwfilter) < 0)
>          goto cleanup;
>  
> -    VIR_FREE(nwfilter->configFile);
> -
>      virNWFilterObjRemove(&driver->nwfilters, nwfilter);
>      nwfilter = NULL;
>      ret = 0;
> 




More information about the libvir-list mailing list