• Baokun Li's avatar
    ext4: fix slab-out-of-bounds in ext4_mb_find_good_group_avg_frag_lists() · 13df4d44
    Baokun Li authored
    We can trigger a slab-out-of-bounds with the following commands:
    
        mkfs.ext4 -F /dev/$disk 10G
        mount /dev/$disk /tmp/test
        echo 2147483647 > /sys/fs/ext4/$disk/mb_group_prealloc
        echo test > /tmp/test/file && sync
    
    ==================================================================
    BUG: KASAN: slab-out-of-bounds in ext4_mb_find_good_group_avg_frag_lists+0x8a/0x200 [ext4]
    Read of size 8 at addr ffff888121b9d0f0 by task kworker/u2:0/11
    CPU: 0 PID: 11 Comm: kworker/u2:0 Tainted: GL 6.7.0-next-20240118 #521
    Call Trace:
     dump_stack_lvl+0x2c/0x50
     kasan_report+0xb6/0xf0
     ext4_mb_find_good_group_avg_frag_lists+0x8a/0x200 [ext4]
     ext4_mb_regular_allocator+0x19e9/0x2370 [ext4]
     ext4_mb_new_blocks+0x88a/0x1370 [ext4]
     ext4_ext_map_blocks+0x14f7/0x2390 [ext4]
     ext4_map_blocks+0x569/0xea0 [ext4]
     ext4_do_writepages+0x10f6/0x1bc0 [ext4]
    [...]
    ==================================================================
    
    The flow of issue triggering is as follows:
    
    // Set s_mb_group_prealloc to 2147483647 via sysfs
    ext4_mb_new_blocks
      ext4_mb_normalize_request
        ext4_mb_normalize_group_request
          ac->ac_g_ex.fe_len = EXT4_SB(sb)->s_mb_group_prealloc
      ext4_mb_regular_allocator
        ext4_mb_choose_next_group
          ext4_mb_choose_next_group_best_avail
            mb_avg_fragment_size_order
              order = fls(len) - 2 = 29
            ext4_mb_find_good_group_avg_frag_lists
              frag_list = &sbi->s_mb_avg_fragment_size[order]
              if (list_empty(frag_list)) // Trigger SOOB!
    
    At 4k block size, the length of the s_mb_avg_fragment_size list is 14,
    but an oversized s_mb_group_prealloc is set, causing slab-out-of-bounds
    to be triggered by an attempt to access an element at index 29.
    
    Add a new attr_id attr_clusters_in_group with values in the range
    [0, sbi->s_clusters_per_group] and declare mb_group_prealloc as
    that type to fix the issue. In addition avoid returning an order
    from mb_avg_fragment_size_order() greater than MB_NUM_ORDERS(sb)
    and reduce some useless loops.
    
    Fixes: 7e170922 ("ext4: Add allocation criteria 1.5 (CR1_5)")
    CC: stable@vger.kernel.org
    Signed-off-by: default avatarBaokun Li <libaokun1@huawei.com>
    Reviewed-by: default avatarJan Kara <jack@suse.cz>
    Reviewed-by: default avatarOjaswin Mujoo <ojaswin@linux.ibm.com>
    Link: https://lore.kernel.org/r/20240319113325.3110393-5-libaokun1@huawei.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
    13df4d44
mballoc.c 199 KB