From: Matthew Ahrens Date: Wed, 23 Dec 2020 17:52:24 +0000 (-0800) Subject: nvlist leaked in zpool_find_config() X-Git-Tag: zfs-2.0.1~7 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=a296875da080a93aa1aef7cea0aace4f6e867cab;p=mirror_zfs.git nvlist leaked in zpool_find_config() In `zpool_find_config()`, the `pools` nvlist is leaked. Part of it (a sub-nvlist) is returned in `*configp`, but the callers also leak that. Additionally, in `zdb.c:main()`, the `searchdirs` is leaked. The leaks were detected by ASAN (`configure --enable-asan`). This commit resolves the leaks. Reviewed-by: Igor Kozhukhov Reviewed-by: Ryan Moeller Reviewed-by: Brian Behlendorf Signed-off-by: Matthew Ahrens Closes #11396 --- diff --git a/cmd/zdb/zdb.c b/cmd/zdb/zdb.c index 376b24db1..c16492c53 100644 --- a/cmd/zdb/zdb.c +++ b/cmd/zdb/zdb.c @@ -8429,6 +8429,11 @@ main(int argc, char **argv) } } + if (searchdirs != NULL) { + umem_free(searchdirs, nsearch * sizeof (char *)); + searchdirs = NULL; + } + /* * import_checkpointed_state makes the assumption that the * target pool that we pass it is already part of the spa @@ -8447,6 +8452,11 @@ main(int argc, char **argv) target = checkpoint_target; } + if (cfg != NULL) { + nvlist_free(cfg); + cfg = NULL; + } + if (target_pool != target) free(target_pool); diff --git a/cmd/zhack/zhack.c b/cmd/zhack/zhack.c index 4d958fe43..08263120c 100644 --- a/cmd/zhack/zhack.c +++ b/cmd/zhack/zhack.c @@ -150,6 +150,7 @@ zhack_import(char *target, boolean_t readonly) zfeature_checks_disable = B_TRUE; error = spa_import(target, config, props, (readonly ? ZFS_IMPORT_SKIP_MMP : ZFS_IMPORT_NORMAL)); + fnvlist_free(config); zfeature_checks_disable = B_FALSE; if (error == EEXIST) error = 0; diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c index 31205a5bf..4e1be4dd7 100644 --- a/cmd/ztest/ztest.c +++ b/cmd/ztest/ztest.c @@ -7016,6 +7016,7 @@ ztest_import_impl(ztest_shared_t *zs) VERIFY0(zpool_find_config(NULL, ztest_opts.zo_pool, &cfg, &args, &libzpool_config_ops)); VERIFY0(spa_import(ztest_opts.zo_pool, cfg, NULL, flags)); + fnvlist_free(cfg); } /* diff --git a/lib/libzutil/zutil_import.c b/lib/libzutil/zutil_import.c index b8cdc118b..3a1827294 100644 --- a/lib/libzutil/zutil_import.c +++ b/lib/libzutil/zutil_import.c @@ -1539,7 +1539,7 @@ zpool_find_config(void *hdl, const char *target, nvlist_t **configp, nvlist_t *pools; nvlist_t *match = NULL; nvlist_t *config = NULL; - char *name = NULL, *sepp = NULL; + char *sepp = NULL; char sep = '\0'; int count = 0; char *targetdup = strdup(target); @@ -1563,11 +1563,11 @@ zpool_find_config(void *hdl, const char *target, nvlist_t **configp, /* multiple matches found */ continue; } else { - match = config; - name = nvpair_name(elem); + match = fnvlist_dup(config); } } } + fnvlist_free(pools); } if (count == 0) { @@ -1577,6 +1577,7 @@ zpool_find_config(void *hdl, const char *target, nvlist_t **configp, if (count > 1) { free(targetdup); + fnvlist_free(match); return (EINVAL); }