• Eryu Guan's avatar
    ext4: validate s_first_meta_bg at mount time · 3a4b77cd
    Eryu Guan authored
    Ralf Spenneberg reported that he hit a kernel crash when mounting a
    modified ext4 image. And it turns out that kernel crashed when
    calculating fs overhead (ext4_calculate_overhead()), this is because
    the image has very large s_first_meta_bg (debug code shows it's
    842150400), and ext4 overruns the memory in count_overhead() when
    setting bitmap buffer, which is PAGE_SIZE.
    
    ext4_calculate_overhead():
      buf = get_zeroed_page(GFP_NOFS);  <=== PAGE_SIZE buffer
      blks = count_overhead(sb, i, buf);
    
    count_overhead():
      for (j = ext4_bg_num_gdb(sb, grp); j > 0; j--) { <=== j = 842150400
              ext4_set_bit(EXT4_B2C(sbi, s++), buf);   <=== buffer overrun
              count++;
      }
    
    This can be reproduced easily for me by this script:
    
      #!/bin/bash
      rm -f fs.img
      mkdir -p /mnt/ext4
      fallocate -l 16M fs.img
      mke2fs -t ext4 -O bigalloc,meta_bg,^resize_inode -F fs.img
      debugfs -w -R "ssv first_meta_bg 842150400" fs.img
      mount -o loop fs.img /mnt/ext4
    
    Fix it by validating s_first_meta_bg first at mount time, and
    refusing to mount if its value exceeds the largest possible meta_bg
    number.
    Reported-by: default avatarRalf Spenneberg <ralf@os-t.de>
    Signed-off-by: default avatarEryu Guan <guaneryu@gmail.com>
    Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    Reviewed-by: default avatarAndreas Dilger <adilger@dilger.ca>
    3a4b77cd
super.c 161 KB