mirror of
				https://git.proxmox.com/git/mirror_zfs
				synced 2025-11-03 23:46:39 +00:00 
			
		
		
		
	Fix possible bad bit shift in dnode_next_offset_level()
031d7c2fe6 did not handle reverse
iteration, such that the original issue theoretically could still occur.
Note that contrary to the claim in the ZFS disk format specification
that a maximum of 6 levels are possible, 9 levels are possible with
recordsize=512 and and indirect block size of 16KB. In this unusual
configuration, span will be 65. The maximum size of span at 70 can be
reached at recordsize=16K and an indirect blocksize of 16KB.
When we are at this indirection level and are traversing backward, the
minimum value is start, but we cannot calculate that with 64-bit
arithmetic, so we avoid the calculation and instead rely on the earlier
statement that did `*offset = start;`.
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Richard Yao <richard.yao@alumni.stonybrook.edu>
Reported-by: Coverity (CID-1466214)
Closes #14618
			
			
This commit is contained in:
		
							parent
							
								
									60cfd3bbc2
								
							
						
					
					
						commit
						fa46802585
					
				@ -2597,8 +2597,9 @@ dnode_next_offset_level(dnode_t *dn, int flags, uint64_t *offset,
 | 
			
		||||
 | 
			
		||||
		if (inc < 0) {
 | 
			
		||||
			/* traversing backwards; position offset at the end */
 | 
			
		||||
			ASSERT3U(*offset, <=, start);
 | 
			
		||||
			*offset = MIN(*offset + (1ULL << span) - 1, start);
 | 
			
		||||
			if (span < 8 * sizeof (*offset))
 | 
			
		||||
				*offset = MIN(*offset + (1ULL << span) - 1,
 | 
			
		||||
				    start);
 | 
			
		||||
		} else if (*offset < start) {
 | 
			
		||||
			*offset = start;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user