]> granicus.if.org Git - zfs/commitdiff
Double-free of encryption wrapping key due to invalid pool properties
authorloli10K <loli10K@users.noreply.github.com>
Tue, 28 May 2019 22:19:50 +0000 (00:19 +0200)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 7 Jun 2019 19:45:40 +0000 (12:45 -0700)
This commits fixes a double-free in zfs_ioc_pool_create() triggered by
specifying an unsupported combination of properties when creating a pool
with encryption enabled.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Tom Caputi <tcaputi@datto.com>
Signed-off-by: loli10K <ezomori.nozomu@gmail.com>
Closes #8791

module/zfs/zfs_ioctl.c
tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh

index debe733dab7ca672be1be721080d3d114455260e..f30d0a89441496020001e91be5083d022c9b9c5e 100644 (file)
@@ -1514,6 +1514,7 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
        nvlist_t *zplprops = NULL;
        dsl_crypto_params_t *dcp = NULL;
        char *spa_name = zc->zc_name;
+       boolean_t unload_wkey = B_TRUE;
 
        if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
            zc->zc_iflags, &config)))
@@ -1541,11 +1542,8 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
                (void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl);
                if (nvl) {
                        error = nvlist_dup(nvl, &rootprops, KM_SLEEP);
-                       if (error != 0) {
-                               nvlist_free(config);
-                               nvlist_free(props);
-                               return (error);
-                       }
+                       if (error != 0)
+                               goto pool_props_bad;
                        (void) nvlist_remove_all(props, ZPOOL_ROOTFS_PROPS);
                }
 
@@ -1553,11 +1551,8 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
                    &hidden_args);
                error = dsl_crypto_params_create_nvlist(DCP_CMD_NONE,
                    rootprops, hidden_args, &dcp);
-               if (error != 0) {
-                       nvlist_free(config);
-                       nvlist_free(props);
-                       return (error);
-               }
+               if (error != 0)
+                       goto pool_props_bad;
                (void) nvlist_remove_all(props, ZPOOL_HIDDEN_ARGS);
 
                VERIFY(nvlist_alloc(&zplprops, NV_UNIQUE_NAME, KM_SLEEP) == 0);
@@ -1577,15 +1572,17 @@ zfs_ioc_pool_create(zfs_cmd_t *zc)
         * Set the remaining root properties
         */
        if (!error && (error = zfs_set_prop_nvlist(spa_name,
-           ZPROP_SRC_LOCAL, rootprops, NULL)) != 0)
+           ZPROP_SRC_LOCAL, rootprops, NULL)) != 0) {
                (void) spa_destroy(spa_name);
+               unload_wkey = B_FALSE; /* spa_destroy() unloads wrapping keys */
+       }
 
 pool_props_bad:
        nvlist_free(rootprops);
        nvlist_free(zplprops);
        nvlist_free(config);
        nvlist_free(props);
-       dsl_crypto_params_free(dcp, !!error);
+       dsl_crypto_params_free(dcp, unload_wkey && !!error);
 
        return (error);
 }
index aa154d5c65ccb4fde6798b0beae2d744e4af7b73..e521d8f1cff027a45514fb757dcd3920affba7ad 100755 (executable)
@@ -45,6 +45,7 @@
 # N    1       1       no      keyformat given, but crypt off
 # Y    0       0       no      no keyformat specified for new key
 # Y    0       1       no      no keyformat specified for new key
+# Y    1       1       no      unsupported combination of non-encryption props
 # Y    1       0       yes     new encryption root
 # Y    1       1       yes     new encryption root
 #
@@ -83,6 +84,10 @@ log_mustnot zpool create -O encryption=on $TESTPOOL $DISKS
 log_mustnot zpool create -O encryption=on -O keylocation=prompt \
        $TESTPOOL $DISKS
 
+log_mustnot eval "echo $PASSPHRASE | zpool create -O encryption=on" \
+       "-O keyformat=passphrase -O keylocation=prompt" \
+       "-o feature@lz4_compress=disabled -O compression=lz4 $TESTPOOL $DISKS"
+
 log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \
        "-O keyformat=passphrase $TESTPOOL $DISKS"
 log_must zpool destroy $TESTPOOL