mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	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 <behlendorf1@llnl.gov> Reviewed-by: Tom Caputi <tcaputi@datto.com> Signed-off-by: loli10K <ezomori.nozomu@gmail.com> Closes #8791
This commit is contained in:
		
							parent
							
								
									27b446f799
								
							
						
					
					
						commit
						aaf3b30dcf
					
				| @ -1514,6 +1514,7 @@ zfs_ioc_pool_create(zfs_cmd_t *zc) | |||||||
| 	nvlist_t *zplprops = NULL; | 	nvlist_t *zplprops = NULL; | ||||||
| 	dsl_crypto_params_t *dcp = NULL; | 	dsl_crypto_params_t *dcp = NULL; | ||||||
| 	char *spa_name = zc->zc_name; | 	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, | 	if ((error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size, | ||||||
| 	    zc->zc_iflags, &config))) | 	    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); | 		(void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl); | ||||||
| 		if (nvl) { | 		if (nvl) { | ||||||
| 			error = nvlist_dup(nvl, &rootprops, KM_SLEEP); | 			error = nvlist_dup(nvl, &rootprops, KM_SLEEP); | ||||||
| 			if (error != 0) { | 			if (error != 0) | ||||||
| 				nvlist_free(config); | 				goto pool_props_bad; | ||||||
| 				nvlist_free(props); |  | ||||||
| 				return (error); |  | ||||||
| 			} |  | ||||||
| 			(void) nvlist_remove_all(props, ZPOOL_ROOTFS_PROPS); | 			(void) nvlist_remove_all(props, ZPOOL_ROOTFS_PROPS); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -1553,11 +1551,8 @@ zfs_ioc_pool_create(zfs_cmd_t *zc) | |||||||
| 		    &hidden_args); | 		    &hidden_args); | ||||||
| 		error = dsl_crypto_params_create_nvlist(DCP_CMD_NONE, | 		error = dsl_crypto_params_create_nvlist(DCP_CMD_NONE, | ||||||
| 		    rootprops, hidden_args, &dcp); | 		    rootprops, hidden_args, &dcp); | ||||||
| 		if (error != 0) { | 		if (error != 0) | ||||||
| 			nvlist_free(config); | 			goto pool_props_bad; | ||||||
| 			nvlist_free(props); |  | ||||||
| 			return (error); |  | ||||||
| 		} |  | ||||||
| 		(void) nvlist_remove_all(props, ZPOOL_HIDDEN_ARGS); | 		(void) nvlist_remove_all(props, ZPOOL_HIDDEN_ARGS); | ||||||
| 
 | 
 | ||||||
| 		VERIFY(nvlist_alloc(&zplprops, NV_UNIQUE_NAME, KM_SLEEP) == 0); | 		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 | 	 * Set the remaining root properties | ||||||
| 	 */ | 	 */ | ||||||
| 	if (!error && (error = zfs_set_prop_nvlist(spa_name, | 	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); | 		(void) spa_destroy(spa_name); | ||||||
|  | 		unload_wkey = B_FALSE; /* spa_destroy() unloads wrapping keys */ | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| pool_props_bad: | pool_props_bad: | ||||||
| 	nvlist_free(rootprops); | 	nvlist_free(rootprops); | ||||||
| 	nvlist_free(zplprops); | 	nvlist_free(zplprops); | ||||||
| 	nvlist_free(config); | 	nvlist_free(config); | ||||||
| 	nvlist_free(props); | 	nvlist_free(props); | ||||||
| 	dsl_crypto_params_free(dcp, !!error); | 	dsl_crypto_params_free(dcp, unload_wkey && !!error); | ||||||
| 
 | 
 | ||||||
| 	return (error); | 	return (error); | ||||||
| } | } | ||||||
|  | |||||||
| @ -45,6 +45,7 @@ | |||||||
| # N	1	1	no	keyformat given, but crypt off | # N	1	1	no	keyformat given, but crypt off | ||||||
| # Y	0	0	no	no keyformat specified for new key | # Y	0	0	no	no keyformat specified for new key | ||||||
| # Y	0	1	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	0	yes	new encryption root | ||||||
| # Y	1	1	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 \ | log_mustnot zpool create -O encryption=on -O keylocation=prompt \ | ||||||
| 	$TESTPOOL $DISKS | 	$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" \ | log_must eval "echo $PASSPHRASE | zpool create -O encryption=on" \ | ||||||
| 	"-O keyformat=passphrase $TESTPOOL $DISKS" | 	"-O keyformat=passphrase $TESTPOOL $DISKS" | ||||||
| log_must zpool destroy $TESTPOOL | log_must zpool destroy $TESTPOOL | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 loli10K
						loli10K