]> granicus.if.org Git - zfs/commitdiff
Fix memleak in zfs_do_* and zpool_do_*
authorluozhengzheng <luo.zhengzheng@zte.com.cn>
Thu, 1 Sep 2016 02:23:10 +0000 (10:23 +0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 12 Sep 2016 20:02:47 +0000 (13:02 -0700)
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: luozhengzheng <luo.zhengzheng@zte.com.cn>
Closes #5056

cmd/zfs/zfs_main.c
cmd/zpool/zpool_main.c

index 8a8f56af9928639d63b4a5e983199526ee6d08f0..063ee7c54b51589f9ce32a308436bd70bb3042f4 100644 (file)
@@ -659,8 +659,10 @@ zfs_do_clone(int argc, char **argv)
        while ((c = getopt(argc, argv, "o:p")) != -1) {
                switch (c) {
                case 'o':
-                       if (parseprop(props, optarg) != 0)
+                       if (parseprop(props, optarg) != 0) {
+                               nvlist_free(props);
                                return (1);
+                       }
                        break;
                case 'p':
                        parents = B_TRUE;
@@ -692,8 +694,10 @@ zfs_do_clone(int argc, char **argv)
        }
 
        /* open the source dataset */
-       if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_SNAPSHOT)) == NULL)
+       if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_SNAPSHOT)) == NULL) {
+               nvlist_free(props);
                return (1);
+       }
 
        if (parents && zfs_name_valid(argv[1], ZFS_TYPE_FILESYSTEM |
            ZFS_TYPE_VOLUME)) {
@@ -703,10 +707,16 @@ zfs_do_clone(int argc, char **argv)
                 * complain.
                 */
                if (zfs_dataset_exists(g_zfs, argv[1], ZFS_TYPE_FILESYSTEM |
-                   ZFS_TYPE_VOLUME))
+                   ZFS_TYPE_VOLUME)) {
+                       zfs_close(zhp);
+                       nvlist_free(props);
                        return (0);
-               if (zfs_create_ancestors(g_zfs, argv[1]) != 0)
+               }
+               if (zfs_create_ancestors(g_zfs, argv[1]) != 0) {
+                       zfs_close(zhp);
+                       nvlist_free(props);
                        return (1);
+               }
        }
 
        /* pass to libzfs */
@@ -1280,8 +1290,10 @@ zfs_do_destroy(int argc, char **argv)
                *at = '\0';
                zhp = zfs_open(g_zfs, argv[0],
                    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
-               if (zhp == NULL)
+               if (zhp == NULL) {
+                       nvlist_free(cb.cb_nvl);
                        return (1);
+               }
 
                cb.cb_snapspec = at + 1;
                if (gather_snapshots(zfs_handle_dup(zhp), &cb) != 0 ||
@@ -1370,7 +1382,7 @@ zfs_do_destroy(int argc, char **argv)
                            "cannot destroy bookmark");
                }
 
-               nvlist_free(cb.cb_nvl);
+               nvlist_free(nvl);
 
                return (err);
        } else {
@@ -3645,8 +3657,11 @@ zfs_do_snapshot(int argc, char **argv)
        while ((c = getopt(argc, argv, "ro:")) != -1) {
                switch (c) {
                case 'o':
-                       if (parseprop(props, optarg) != 0)
+                       if (parseprop(props, optarg) != 0) {
+                               nvlist_free(sd.sd_nvl);
+                               nvlist_free(props);
                                return (1);
+                       }
                        break;
                case 'r':
                        sd.sd_recursive = B_TRUE;
@@ -3937,8 +3952,10 @@ zfs_do_receive(int argc, char **argv)
        while ((c = getopt(argc, argv, ":o:denuvFsA")) != -1) {
                switch (c) {
                case 'o':
-                       if (parseprop(props, optarg) != 0)
+                       if (parseprop(props, optarg) != 0) {
+                               nvlist_free(props);
                                return (1);
+                       }
                        break;
                case 'd':
                        flags.isprefix = B_TRUE;
@@ -4012,9 +4029,12 @@ zfs_do_receive(int argc, char **argv)
                    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) {
                        zfs_handle_t *zhp = zfs_open(g_zfs,
                            namebuf, ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
-                       if (zhp == NULL)
+                       if (zhp == NULL) {
+                               nvlist_free(props);
                                return (1);
+                       }
                        err = zfs_destroy(zhp, B_FALSE);
+                       zfs_close(zhp);
                } else {
                        zfs_handle_t *zhp = zfs_open(g_zfs,
                            argv[0], ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME);
@@ -4027,11 +4047,14 @@ zfs_do_receive(int argc, char **argv)
                                    gettext("'%s' does not have any "
                                    "resumable receive state to abort\n"),
                                    argv[0]);
+                               nvlist_free(props);
+                               zfs_close(zhp);
                                return (1);
                        }
                        err = zfs_destroy(zhp, B_FALSE);
+                       zfs_close(zhp);
                }
-
+               nvlist_free(props);
                return (err != 0);
        }
 
@@ -4040,9 +4063,11 @@ zfs_do_receive(int argc, char **argv)
                    gettext("Error: Backup stream can not be read "
                    "from a terminal.\n"
                    "You must redirect standard input.\n"));
+               nvlist_free(props);
                return (1);
        }
        err = zfs_receive(g_zfs, argv[0], props, &flags, STDIN_FILENO, NULL);
+       nvlist_free(props);
 
        return (err != 0);
 }
index 09531b21dfb6e835f208ca28df104c2b3e63ea35..e512688b77e65a7e64da5683f5de4f3a97d70179 100644 (file)
@@ -1296,6 +1296,7 @@ zpool_do_destroy(int argc, char **argv)
        if (zpool_disable_datasets(zhp, force) != 0) {
                (void) fprintf(stderr, gettext("could not destroy '%s': "
                    "could not unmount datasets\n"), zpool_get_name(zhp));
+               zpool_close(zhp);
                return (1);
        }
 
@@ -2343,6 +2344,7 @@ zpool_do_import(int argc, char **argv)
                if (searchdirs != NULL)
                        free(searchdirs);
 
+               nvlist_free(props);
                nvlist_free(policy);
                return (1);
        }
@@ -2449,6 +2451,8 @@ zpool_do_import(int argc, char **argv)
                if (envdup != NULL)
                        free(envdup);
                nvlist_free(policy);
+               nvlist_free(pools);
+               nvlist_free(props);
                return (1);
        }
 
@@ -4749,13 +4753,16 @@ zpool_do_attach_or_replace(int argc, char **argv, int replacing)
                usage(B_FALSE);
        }
 
-       if ((zhp = zpool_open(g_zfs, poolname)) == NULL)
+       if ((zhp = zpool_open(g_zfs, poolname)) == NULL) {
+               nvlist_free(props);
                return (1);
+       }
 
        if (zpool_get_config(zhp, NULL) == NULL) {
                (void) fprintf(stderr, gettext("pool '%s' is unavailable\n"),
                    poolname);
                zpool_close(zhp);
+               nvlist_free(props);
                return (1);
        }
 
@@ -4763,11 +4770,13 @@ zpool_do_attach_or_replace(int argc, char **argv, int replacing)
            argc, argv);
        if (nvroot == NULL) {
                zpool_close(zhp);
+               nvlist_free(props);
                return (1);
        }
 
        ret = zpool_vdev_attach(zhp, old_disk, new_disk, nvroot, replacing);
 
+       nvlist_free(props);
        nvlist_free(nvroot);
        zpool_close(zhp);
 
@@ -4973,8 +4982,10 @@ zpool_do_split(int argc, char **argv)
        argc -= 2;
        argv += 2;
 
-       if ((zhp = zpool_open(g_zfs, srcpool)) == NULL)
+       if ((zhp = zpool_open(g_zfs, srcpool)) == NULL) {
+               nvlist_free(props);
                return (1);
+       }
 
        config = split_mirror_vdev(zhp, newpool, props, flags, argc, argv);
        if (config == NULL) {
@@ -4986,20 +4997,25 @@ zpool_do_split(int argc, char **argv)
                        print_vdev_tree(NULL, newpool, config, 0, B_FALSE,
                            flags.name_flags);
                }
-               nvlist_free(config);
        }
 
        zpool_close(zhp);
 
-       if (ret != 0 || flags.dryrun || !flags.import)
+       if (ret != 0 || flags.dryrun || !flags.import) {
+               nvlist_free(config);
+               nvlist_free(props);
                return (ret);
+       }
 
        /*
         * The split was successful. Now we need to open the new
         * pool and import it.
         */
-       if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL)
+       if ((zhp = zpool_open_canfail(g_zfs, newpool)) == NULL) {
+               nvlist_free(config);
+               nvlist_free(props);
                return (1);
+       }
        if (zpool_get_state(zhp) != POOL_STATE_UNAVAIL &&
            zpool_enable_datasets(zhp, mntopts, 0) != 0) {
                ret = 1;
@@ -5009,6 +5025,8 @@ zpool_do_split(int argc, char **argv)
                    "different altroot\n"), "zpool import");
        }
        zpool_close(zhp);
+       nvlist_free(config);
+       nvlist_free(props);
 
        return (ret);
 }