Skip to content

Commit

Permalink
fs/minix: reject too-large maximum file size
Browse files Browse the repository at this point in the history
If the minix filesystem tries to map a very large logical block number to
its on-disk location, block_to_path() can return offsets that are too
large, causing out-of-bounds memory accesses when accessing indirect index
blocks.  This should be prevented by the check against the maximum file
size, but this doesn't work because the maximum file size is read directly
from the on-disk superblock and isn't validated itself.

Fix this by validating the maximum file size at mount time.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: [email protected]
Reported-by: [email protected]
Reported-by: [email protected]
Signed-off-by: Eric Biggers <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Cc: Alexander Viro <[email protected]>
Cc: Qiujun Huang <[email protected]>
Cc: <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
ebiggers authored and torvalds committed Aug 12, 2020
1 parent facb03d commit 270ef41
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions fs/minix/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,23 @@ static int minix_remount (struct super_block * sb, int * flags, char * data)
return 0;
}

static bool minix_check_superblock(struct minix_sb_info *sbi)
{
if (sbi->s_imap_blocks == 0 || sbi->s_zmap_blocks == 0)
return false;

/*
* s_max_size must not exceed the block mapping limitation. This check
* is only needed for V1 filesystems, since V2/V3 support an extra level
* of indirect blocks which places the limit well above U32_MAX.
*/
if (sbi->s_version == MINIX_V1 &&
sbi->s_max_size > (7 + 512 + 512*512) * BLOCK_SIZE)
return false;

return true;
}

static int minix_fill_super(struct super_block *s, void *data, int silent)
{
struct buffer_head *bh;
Expand Down Expand Up @@ -228,11 +245,12 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
} else
goto out_no_fs;

if (!minix_check_superblock(sbi))
goto out_illegal_sb;

/*
* Allocate the buffer map to keep the superblock small.
*/
if (sbi->s_imap_blocks == 0 || sbi->s_zmap_blocks == 0)
goto out_illegal_sb;
i = (sbi->s_imap_blocks + sbi->s_zmap_blocks) * sizeof(bh);
map = kzalloc(i, GFP_KERNEL);
if (!map)
Expand Down

0 comments on commit 270ef41

Please sign in to comment.