Author: mav
Date: Thu Aug  2 21:25:32 2018
New Revision: 337185
URL: https://svnweb.freebsd.org/changeset/base/337185

Log:
  MFV r337184: 9457 libzfs_import.c:add_config() has a memory leak
  
  A memory leak occurs on lines 209 and 213 because the config is not freed
  in the error case.  The interface to add_config() seems less than ideal -
  it would be better if it copied any data necessary from the config and the
  caller freed it.
  
  illumos/illumos-gate@ddfe901b12348d31c500fb57f9174e88860a4061
  
  Reviewed by: Matt Ahrens <[email protected]>
  Reviewed by: Serapheim Dimitropoulos <[email protected]>
  Approved by: Robert Mustacchi <[email protected]>
  Author:     sara hartse <[email protected]>

Modified:
  head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
Directory Properties:
  head/cddl/contrib/opensolaris/   (props changed)

Modified: head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c
==============================================================================
--- head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c     Thu Aug 
 2 21:24:04 2018        (r337184)
+++ head/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c     Thu Aug 
 2 21:25:32 2018        (r337185)
@@ -33,7 +33,7 @@
  * ZFS label of each device.  If we successfully read the label, then we
  * organize the configuration information in the following hierarchy:
  *
- *     pool guid -> toplevel vdev guid -> label txg
+ *     pool guid -> toplevel vdev guid -> label txg
  *
  * Duplicate entries matching this same tuple will be discarded.  Once we have
  * examined every device, we pick the best label txg config for each toplevel
@@ -245,7 +245,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, cons
                ne->ne_next = pl->names;
                pl->names = ne;
 
-               nvlist_free(config);
                return (0);
        }
 
@@ -265,7 +264,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, cons
            &top_guid) != 0 ||
            nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG,
            &txg) != 0 || txg == 0) {
-               nvlist_free(config);
                return (0);
        }
 
@@ -280,7 +278,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, cons
 
        if (pe == NULL) {
                if ((pe = zfs_alloc(hdl, sizeof (pool_entry_t))) == NULL) {
-                       nvlist_free(config);
                        return (-1);
                }
                pe->pe_guid = pool_guid;
@@ -299,7 +296,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, cons
 
        if (ve == NULL) {
                if ((ve = zfs_alloc(hdl, sizeof (vdev_entry_t))) == NULL) {
-                       nvlist_free(config);
                        return (-1);
                }
                ve->ve_guid = top_guid;
@@ -319,15 +315,12 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, cons
 
        if (ce == NULL) {
                if ((ce = zfs_alloc(hdl, sizeof (config_entry_t))) == NULL) {
-                       nvlist_free(config);
                        return (-1);
                }
                ce->ce_txg = txg;
-               ce->ce_config = config;
+               ce->ce_config = fnvlist_dup(config);
                ce->ce_next = ve->ve_configs;
                ve->ve_configs = ce;
-       } else {
-               nvlist_free(config);
        }
 
        /*
@@ -1396,9 +1389,7 @@ skipdir:
                                            &this_guid) == 0 &&
                                            iarg->guid == this_guid;
                                }
-                               if (!matched) {
-                                       nvlist_free(config);
-                               } else {
+                               if (matched) {
                                        /*
                                         * use the non-raw path for the config
                                         */
@@ -1408,6 +1399,7 @@ skipdir:
                                            config) != 0)
                                                config_failed = B_TRUE;
                                }
+                               nvlist_free(config);
                        }
                        free(slice->rn_name);
                        free(slice);
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to