diff options
author | Alexander Motin <mav@FreeBSD.org> | 2018-08-02 21:24:04 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2018-08-02 21:24:04 +0000 |
commit | 732d23f312ac102fb9b1e6a5564a11d2e1bdbf25 (patch) | |
tree | d7136572a1a4ff878e898f0abd0c07844da63be3 /lib | |
parent | cb97edbcd01e21cb237997ffade4cdcae29f34da (diff) | |
download | src-732d23f312ac102fb9b1e6a5564a11d2e1bdbf25.tar.gz src-732d23f312ac102fb9b1e6a5564a11d2e1bdbf25.zip |
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 <matt@delphix.com>
Reviewed by: Serapheim Dimitropoulos <serapheim.dimitro@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Author: sara hartse <sara.hartse@delphix.com>
Notes
Notes:
svn path=/vendor/illumos/dist/; revision=337184
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libzfs/common/libzfs_import.c | 16 |
1 files changed, 4 insertions, 12 deletions
diff --git a/lib/libzfs/common/libzfs_import.c b/lib/libzfs/common/libzfs_import.c index d28e852ef69b..5bd900ad0040 100644 --- a/lib/libzfs/common/libzfs_import.c +++ b/lib/libzfs/common/libzfs_import.c @@ -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 @@ -217,7 +217,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path, ne->ne_next = pl->names; pl->names = ne; - nvlist_free(config); return (0); } @@ -237,7 +236,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path, &top_guid) != 0 || nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_TXG, &txg) != 0 || txg == 0) { - nvlist_free(config); return (0); } @@ -252,7 +250,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path, if (pe == NULL) { if ((pe = zfs_alloc(hdl, sizeof (pool_entry_t))) == NULL) { - nvlist_free(config); return (-1); } pe->pe_guid = pool_guid; @@ -271,7 +268,6 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path, if (ve == NULL) { if ((ve = zfs_alloc(hdl, sizeof (vdev_entry_t))) == NULL) { - nvlist_free(config); return (-1); } ve->ve_guid = top_guid; @@ -291,15 +287,12 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path, 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); } /* @@ -1235,9 +1228,7 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) &this_guid) == 0 && iarg->guid == this_guid; } - if (!matched) { - nvlist_free(config); - } else { + if (matched) { /* * use the non-raw path for the config */ @@ -1247,6 +1238,7 @@ zpool_find_import_impl(libzfs_handle_t *hdl, importargs_t *iarg) config) != 0) config_failed = B_TRUE; } + nvlist_free(config); } free(slice->rn_name); free(slice); |