diff options
author | loli10K <[email protected]> | 2019-05-29 00:19:50 +0200 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2019-05-28 15:19:50 -0700 |
commit | ab1a9705f8021fbbb816d6042b8b8f40f1bb3aaf (patch) | |
tree | d221df7416661476b15882374f3fba7afdfda597 | |
parent | 227d37938553c3c774f127a6354cad57b6bfa12c (diff) |
Double-free of encryption wrapping key due to invalid pool properties
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 <[email protected]>
Reviewed-by: Tom Caputi <[email protected]>
Signed-off-by: loli10K <[email protected]>
Closes #8791
-rw-r--r-- | module/zfs/zfs_ioctl.c | 21 | ||||
-rwxr-xr-x | tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh | 5 |
2 files changed, 14 insertions, 12 deletions
diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c index debe733da..f30d0a894 100644 --- a/module/zfs/zfs_ioctl.c +++ b/module/zfs/zfs_ioctl.c @@ -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); } diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh index aa154d5c6..e521d8f1c 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zpool_create/zpool_create_encrypted.ksh @@ -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 |