aboutsummaryrefslogtreecommitdiffstats
path: root/module/zfs
diff options
context:
space:
mode:
authorloli10K <[email protected]>2019-05-29 00:19:50 +0200
committerBrian Behlendorf <[email protected]>2019-05-28 15:19:50 -0700
commitab1a9705f8021fbbb816d6042b8b8f40f1bb3aaf (patch)
treed221df7416661476b15882374f3fba7afdfda597 /module/zfs
parent227d37938553c3c774f127a6354cad57b6bfa12c (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
Diffstat (limited to 'module/zfs')
-rw-r--r--module/zfs/zfs_ioctl.c21
1 files changed, 9 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);
}