Skip to content

Commit e3540ea

Browse files
kdavemasoncl
authored andcommitted
btrfs: add more checks to btrfs_read_sys_array
Verify that the sys_array has enough bytes to read the next item. Signed-off-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <clm@fb.com>
1 parent 1ffb22c commit e3540ea

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

fs/btrfs/volumes.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6296,20 +6296,34 @@ int btrfs_read_sys_array(struct btrfs_root *root)
62966296

62976297
while (cur_offset < array_size) {
62986298
disk_key = (struct btrfs_disk_key *)array_ptr;
6299+
len = sizeof(*disk_key);
6300+
if (cur_offset + len > array_size)
6301+
goto out_short_read;
6302+
62996303
btrfs_disk_key_to_cpu(&key, disk_key);
63006304

6301-
len = sizeof(*disk_key);
63026305
array_ptr += len;
63036306
sb_array_offset += len;
63046307
cur_offset += len;
63056308

63066309
if (key.type == BTRFS_CHUNK_ITEM_KEY) {
63076310
chunk = (struct btrfs_chunk *)sb_array_offset;
6311+
/*
6312+
* At least one btrfs_chunk with one stripe must be
6313+
* present, exact stripe count check comes afterwards
6314+
*/
6315+
len = btrfs_chunk_item_size(1);
6316+
if (cur_offset + len > array_size)
6317+
goto out_short_read;
6318+
6319+
num_stripes = btrfs_chunk_num_stripes(sb, chunk);
6320+
len = btrfs_chunk_item_size(num_stripes);
6321+
if (cur_offset + len > array_size)
6322+
goto out_short_read;
6323+
63086324
ret = read_one_chunk(root, &key, sb, chunk);
63096325
if (ret)
63106326
break;
6311-
num_stripes = btrfs_chunk_num_stripes(sb, chunk);
6312-
len = btrfs_chunk_item_size(num_stripes);
63136327
} else {
63146328
ret = -EIO;
63156329
break;
@@ -6320,6 +6334,12 @@ int btrfs_read_sys_array(struct btrfs_root *root)
63206334
}
63216335
free_extent_buffer(sb);
63226336
return ret;
6337+
6338+
out_short_read:
6339+
printk(KERN_ERR "BTRFS: sys_array too short to read %u bytes at offset %u\n",
6340+
len, cur_offset);
6341+
free_extent_buffer(sb);
6342+
return -EIO;
63236343
}
63246344

63256345
int btrfs_read_chunk_tree(struct btrfs_root *root)

0 commit comments

Comments
 (0)