Skip to content

Commit 75d6ad3

Browse files
kdavemasoncl
authored andcommitted
btrfs: more superblock checks, lower bounds on devices and sectorsize/nodesize
I received a few crafted images from Jiri, all got through the recently added superblock checks. The lower bounds checks for num_devices and sector/node -sizes were missing and caused a crash during mount. Tools for symbolic code execution were used to prepare the images contents. Reported-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <clm@fb.com>
1 parent 9cc97d6 commit 75d6ad3

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

fs/btrfs/disk-io.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3871,6 +3871,21 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
38713871
printk(KERN_WARNING "BTRFS: log_root block unaligned: %llu\n",
38723872
btrfs_super_log_root(sb));
38733873

3874+
/*
3875+
* Check the lower bound, the alignment and other constraints are
3876+
* checked later.
3877+
*/
3878+
if (btrfs_super_nodesize(sb) < 4096) {
3879+
printk(KERN_ERR "BTRFS: nodesize too small: %u < 4096\n",
3880+
btrfs_super_nodesize(sb));
3881+
ret = -EINVAL;
3882+
}
3883+
if (btrfs_super_sectorsize(sb) < 4096) {
3884+
printk(KERN_ERR "BTRFS: sectorsize too small: %u < 4096\n",
3885+
btrfs_super_sectorsize(sb));
3886+
ret = -EINVAL;
3887+
}
3888+
38743889
if (memcmp(fs_info->fsid, sb->dev_item.fsid, BTRFS_UUID_SIZE) != 0) {
38753890
printk(KERN_ERR "BTRFS: dev_item UUID does not match fsid: %pU != %pU\n",
38763891
fs_info->fsid, sb->dev_item.fsid);
@@ -3884,6 +3899,10 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
38843899
if (btrfs_super_num_devices(sb) > (1UL << 31))
38853900
printk(KERN_WARNING "BTRFS: suspicious number of devices: %llu\n",
38863901
btrfs_super_num_devices(sb));
3902+
if (btrfs_super_num_devices(sb) == 0) {
3903+
printk(KERN_ERR "BTRFS: number of devices is 0\n");
3904+
ret = -EINVAL;
3905+
}
38873906

38883907
if (btrfs_super_bytenr(sb) != BTRFS_SUPER_INFO_OFFSET) {
38893908
printk(KERN_ERR "BTRFS: super offset mismatch %llu != %u\n",

0 commit comments

Comments
 (0)