mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	Fix potential NULL pointer dereference in dsl_dataset_promote_check()
If the `list_head()` returns NULL, we dereference it, right before we check to see if it returned NULL. We have defined two different pointers that both point to the same thing, which are `origin_head` and `origin_ds`. Almost everything uses `origin_ds`, so we switch them to use `origin_ds`. We also promote `origin_ds` to a const pointer so that the compiler verifies that nothing modifies it. Coverity complained about this. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Neal Gompa <ngompa@datto.com> Signed-off-by: Richard Yao <richard.yao@alumni.stonybrook.edu> Closes #13967
This commit is contained in:
		
							parent
							
								
									a2d5643f88
								
							
						
					
					
						commit
						a36b37d4de
					
				| @ -3285,7 +3285,6 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) | |||||||
| 	dsl_pool_t *dp = dmu_tx_pool(tx); | 	dsl_pool_t *dp = dmu_tx_pool(tx); | ||||||
| 	dsl_dataset_t *hds; | 	dsl_dataset_t *hds; | ||||||
| 	struct promotenode *snap; | 	struct promotenode *snap; | ||||||
| 	dsl_dataset_t *origin_ds, *origin_head; |  | ||||||
| 	int err; | 	int err; | ||||||
| 	uint64_t unused; | 	uint64_t unused; | ||||||
| 	uint64_t ss_mv_cnt; | 	uint64_t ss_mv_cnt; | ||||||
| @ -3305,12 +3304,11 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	snap = list_head(&ddpa->shared_snaps); | 	snap = list_head(&ddpa->shared_snaps); | ||||||
| 	origin_head = snap->ds; |  | ||||||
| 	if (snap == NULL) { | 	if (snap == NULL) { | ||||||
| 		err = SET_ERROR(ENOENT); | 		err = SET_ERROR(ENOENT); | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
| 	origin_ds = snap->ds; | 	dsl_dataset_t *const origin_ds = snap->ds; | ||||||
| 
 | 
 | ||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Encrypted clones share a DSL Crypto Key with their origin's dsl dir. | 	 * Encrypted clones share a DSL Crypto Key with their origin's dsl dir. | ||||||
| @ -3406,10 +3404,10 @@ dsl_dataset_promote_check(void *arg, dmu_tx_t *tx) | |||||||
| 	 * Check that bookmarks that are being transferred don't have | 	 * Check that bookmarks that are being transferred don't have | ||||||
| 	 * name conflicts. | 	 * name conflicts. | ||||||
| 	 */ | 	 */ | ||||||
| 	for (dsl_bookmark_node_t *dbn = avl_first(&origin_head->ds_bookmarks); | 	for (dsl_bookmark_node_t *dbn = avl_first(&origin_ds->ds_bookmarks); | ||||||
| 	    dbn != NULL && dbn->dbn_phys.zbm_creation_txg <= | 	    dbn != NULL && dbn->dbn_phys.zbm_creation_txg <= | ||||||
| 	    dsl_dataset_phys(origin_ds)->ds_creation_txg; | 	    dsl_dataset_phys(origin_ds)->ds_creation_txg; | ||||||
| 	    dbn = AVL_NEXT(&origin_head->ds_bookmarks, dbn)) { | 	    dbn = AVL_NEXT(&origin_ds->ds_bookmarks, dbn)) { | ||||||
| 		if (strlen(dbn->dbn_name) >= max_snap_len) { | 		if (strlen(dbn->dbn_name) >= max_snap_len) { | ||||||
| 			err = SET_ERROR(ENAMETOOLONG); | 			err = SET_ERROR(ENAMETOOLONG); | ||||||
| 			goto out; | 			goto out; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Richard Yao
						Richard Yao