mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	Squashfs: Fix oops when reading fsfuzzer corrupted filesystems
This fixes a code regression caused by the recent mainlining changes. The recent code changes call zlib_inflate repeatedly, decompressing into separate 4K buffers, this code didn't check for the possibility that zlib_inflate might ask for too many buffers when decompressing corrupted data. Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
This commit is contained in:
		
							parent
							
								
									2450cf51a1
								
							
						
					
					
						commit
						118e1ef6fa
					
				
					 4 changed files with 15 additions and 6 deletions
				
			
		|  | @ -80,7 +80,7 @@ static struct buffer_head *get_block_length(struct super_block *sb, | |||
|  * generated a larger block - this does occasionally happen with zlib). | ||||
|  */ | ||||
| int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, | ||||
| 			int length, u64 *next_index, int srclength) | ||||
| 			int length, u64 *next_index, int srclength, int pages) | ||||
| { | ||||
| 	struct squashfs_sb_info *msblk = sb->s_fs_info; | ||||
| 	struct buffer_head **bh; | ||||
|  | @ -185,6 +185,14 @@ int squashfs_read_data(struct super_block *sb, void **buffer, u64 index, | |||
| 			} | ||||
| 
 | ||||
| 			if (msblk->stream.avail_out == 0) { | ||||
| 				if (page == pages) { | ||||
| 					ERROR("zlib_inflate tried to " | ||||
| 						"decompress too much data, " | ||||
| 						"expected %d bytes.  Zlib " | ||||
| 						"data probably corrupt\n", | ||||
| 						srclength); | ||||
| 					goto release_mutex; | ||||
| 				} | ||||
| 				msblk->stream.next_out = buffer[page++]; | ||||
| 				msblk->stream.avail_out = PAGE_CACHE_SIZE; | ||||
| 			} | ||||
|  | @ -268,7 +276,8 @@ block_release: | |||
| 		put_bh(bh[k]); | ||||
| 
 | ||||
| read_failure: | ||||
| 	ERROR("sb_bread failed reading block 0x%llx\n", cur_index); | ||||
| 	ERROR("squashfs_read_data failed to read block 0x%llx\n", | ||||
| 					(unsigned long long) index); | ||||
| 	kfree(bh); | ||||
| 	return -EIO; | ||||
| } | ||||
|  |  | |||
|  | @ -119,7 +119,7 @@ struct squashfs_cache_entry *squashfs_cache_get(struct super_block *sb, | |||
| 
 | ||||
| 			entry->length = squashfs_read_data(sb, entry->data, | ||||
| 				block, length, &entry->next_index, | ||||
| 				cache->block_size); | ||||
| 				cache->block_size, cache->pages); | ||||
| 
 | ||||
| 			spin_lock(&cache->lock); | ||||
| 
 | ||||
|  | @ -406,7 +406,7 @@ int squashfs_read_table(struct super_block *sb, void *buffer, u64 block, | |||
| 	for (i = 0; i < pages; i++, buffer += PAGE_CACHE_SIZE) | ||||
| 		data[i] = buffer; | ||||
| 	res = squashfs_read_data(sb, data, block, length | | ||||
| 		SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length); | ||||
| 		SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length, pages); | ||||
| 	kfree(data); | ||||
| 	return res; | ||||
| } | ||||
|  |  | |||
|  | @ -34,7 +34,7 @@ static inline struct squashfs_inode_info *squashfs_i(struct inode *inode) | |||
| 
 | ||||
| /* block.c */ | ||||
| extern int squashfs_read_data(struct super_block *, void **, u64, int, u64 *, | ||||
| 				int); | ||||
| 				int, int); | ||||
| 
 | ||||
| /* cache.c */ | ||||
| extern struct squashfs_cache *squashfs_cache_init(char *, int, int); | ||||
|  |  | |||
|  | @ -389,7 +389,7 @@ static int __init init_squashfs_fs(void) | |||
| 		return err; | ||||
| 	} | ||||
| 
 | ||||
| 	printk(KERN_INFO "squashfs: version 4.0 (2009/01/03) " | ||||
| 	printk(KERN_INFO "squashfs: version 4.0 (2009/01/31) " | ||||
| 		"Phillip Lougher\n"); | ||||
| 
 | ||||
| 	return 0; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Phillip Lougher
						Phillip Lougher