1. 28 Apr, 2023 6 commits
    • Theodore Ts'o's avatar
      ext4: clean up error handling in __ext4_fill_super() · d4fab7b2
      Theodore Ts'o authored
      There were two ways to return an error code; one was via setting the
      'err' variable, and the second, if err was zero, was via the 'ret'
      variable.  This was both confusing and fragile, and when code was
      factored out of __ext4_fill_super(), some of the error codes returned
      by the original code was replaced by -EINVAL, and in one case, the
      error code was placed by 0, triggering a kernel null pointer
      dereference.
      
      Clean this up by removing the 'ret' variable, leaving only one way to
      set the error code to be returned, and restore the errno codes that
      were returned via the the mount system call as they were before we
      started refactoring __ext4_fill_super().
      Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
      Reviewed-by: default avatarJason Yan <yanaijie@huawei.com>
      d4fab7b2
    • Theodore Ts'o's avatar
      ext4: reflect error codes from ext4_multi_mount_protect() to its callers · 3b50d501
      Theodore Ts'o authored
      This will allow more fine-grained errno codes to be returned by the
      mount system call.
      
      Cc: Andreas Dilger <adilger.kernel@dilger.ca>
      Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
      3b50d501
    • Theodore Ts'o's avatar
      ext4: fix lost error code reporting in __ext4_fill_super() · d5e72c4e
      Theodore Ts'o authored
      When code was factored out of __ext4_fill_super() into
      ext4_percpu_param_init() the error return was discarded.  This meant
      that it was possible for __ext4_fill_super() to return zero,
      indicating success, without the struct super getting completely filled
      in, leading to a potential NULL pointer dereference.
      
      Reported-by: syzbot+bbf0f9a213c94f283a5c@syzkaller.appspotmail.com
      Fixes: 1f79467c ("ext4: factor out ext4_percpu_param_init() ...")
      Link: https://syzkaller.appspot.com/bug?id=6dac47d5e58af770c0055f680369586ec32e144cSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
      Reviewed-by: default avatarJason Yan <yanaijie@huawei.com>
      d5e72c4e
    • Nathan Chancellor's avatar
      ext4: fix unused iterator variable warnings · 856dd6c5
      Nathan Chancellor authored
      When CONFIG_QUOTA is disabled, there are warnings around unused iterator
      variables:
      
        fs/ext4/super.c: In function 'ext4_put_super':
        fs/ext4/super.c:1262:13: error: unused variable 'i' [-Werror=unused-variable]
         1262 |         int i, err;
              |             ^
        fs/ext4/super.c: In function '__ext4_fill_super':
        fs/ext4/super.c:5200:22: error: unused variable 'i' [-Werror=unused-variable]
         5200 |         unsigned int i;
              |                      ^
        cc1: all warnings being treated as errors
      
      The kernel has updated to GNU11, allowing the variables to be declared
      within the for loop.  Do so to clear up the warnings.
      
      Fixes: dcbf8758 ("ext4: factor out ext4_flex_groups_free()")
      Signed-off-by: default avatarNathan Chancellor <nathan@kernel.org>
      Reviewed-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
      Reviewed-by: default avatarJan Kara <jack@suse.cz>
      Reviewed-by: default avatarJason Yan <yanaijie@huawei.com>
      Link: https://lore.kernel.org/r/20230420-ext4-unused-variables-super-c-v1-1-138b6db6c21c@kernel.orgSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
      856dd6c5
    • Ye Bin's avatar
      ext4: fix use-after-free read in ext4_find_extent for bigalloc + inline · 83565959
      Ye Bin authored
      Syzbot found the following issue:
      loop0: detected capacity change from 0 to 2048
      EXT4-fs (loop0): mounted filesystem 00000000-0000-0000-0000-000000000000 without journal. Quota mode: none.
      ==================================================================
      BUG: KASAN: use-after-free in ext4_ext_binsearch_idx fs/ext4/extents.c:768 [inline]
      BUG: KASAN: use-after-free in ext4_find_extent+0x76e/0xd90 fs/ext4/extents.c:931
      Read of size 4 at addr ffff888073644750 by task syz-executor420/5067
      
      CPU: 0 PID: 5067 Comm: syz-executor420 Not tainted 6.2.0-rc1-syzkaller #0
      Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022
      Call Trace:
       <TASK>
       __dump_stack lib/dump_stack.c:88 [inline]
       dump_stack_lvl+0x1b1/0x290 lib/dump_stack.c:106
       print_address_description+0x74/0x340 mm/kasan/report.c:306
       print_report+0x107/0x1f0 mm/kasan/report.c:417
       kasan_report+0xcd/0x100 mm/kasan/report.c:517
       ext4_ext_binsearch_idx fs/ext4/extents.c:768 [inline]
       ext4_find_extent+0x76e/0xd90 fs/ext4/extents.c:931
       ext4_clu_mapped+0x117/0x970 fs/ext4/extents.c:5809
       ext4_insert_delayed_block fs/ext4/inode.c:1696 [inline]
       ext4_da_map_blocks fs/ext4/inode.c:1806 [inline]
       ext4_da_get_block_prep+0x9e8/0x13c0 fs/ext4/inode.c:1870
       ext4_block_write_begin+0x6a8/0x2290 fs/ext4/inode.c:1098
       ext4_da_write_begin+0x539/0x760 fs/ext4/inode.c:3082
       generic_perform_write+0x2e4/0x5e0 mm/filemap.c:3772
       ext4_buffered_write_iter+0x122/0x3a0 fs/ext4/file.c:285
       ext4_file_write_iter+0x1d0/0x18f0
       call_write_iter include/linux/fs.h:2186 [inline]
       new_sync_write fs/read_write.c:491 [inline]
       vfs_write+0x7dc/0xc50 fs/read_write.c:584
       ksys_write+0x177/0x2a0 fs/read_write.c:637
       do_syscall_x64 arch/x86/entry/common.c:50 [inline]
       do_syscall_64+0x3d/0xb0 arch/x86/entry/common.c:80
       entry_SYSCALL_64_after_hwframe+0x63/0xcd
      RIP: 0033:0x7f4b7a9737b9
      RSP: 002b:00007ffc5cac3668 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
      RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f4b7a9737b9
      RDX: 00000000175d9003 RSI: 0000000020000200 RDI: 0000000000000004
      RBP: 00007f4b7a933050 R08: 0000000000000000 R09: 0000000000000000
      R10: 000000000000079f R11: 0000000000000246 R12: 00007f4b7a9330e0
      R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
       </TASK>
      
      Above issue is happens when enable bigalloc and inline data feature. As
      commit 131294c3 fixed delayed allocation bug in ext4_clu_mapped for
      bigalloc + inline. But it only resolved issue when has inline data, if
      inline data has been converted to extent(ext4_da_convert_inline_data_to_extent)
      before writepages, there is no EXT4_STATE_MAY_INLINE_DATA flag. However
      i_data is still store inline data in this scene. Then will trigger UAF
      when find extent.
      To resolve above issue, there is need to add judge "ext4_has_inline_data(inode)"
      in ext4_clu_mapped().
      
      Fixes: 131294c3 ("ext4: fix delayed allocation bug in ext4_clu_mapped for bigalloc + inline")
      Reported-by: syzbot+bf4bb7731ef73b83a3b4@syzkaller.appspotmail.com
      Reviewed-by: default avatarJan Kara <jack@suse.cz>
      Reviewed-by: default avatarYe Bin <yebin10@huawei.com>
      Reviewed-by: default avatarTudor Ambarus <tudor.ambarus@linaro.org>
      Tested-by: default avatarTudor Ambarus <tudor.ambarus@linaro.org>
      Link: https://lore.kernel.org/r/20230406111627.1916759-1-tudor.ambarus@linaro.orgSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
      83565959
    • Zhihao Cheng's avatar
      ext4: fix i_disksize exceeding i_size problem in paritally written case · 1dedde69
      Zhihao Cheng authored
      It is possible for i_disksize can exceed i_size, triggering a warning.
      
      generic_perform_write
       copied = iov_iter_copy_from_user_atomic(len) // copied < len
       ext4_da_write_end
       | ext4_update_i_disksize
       |  new_i_size = pos + copied;
       |  WRITE_ONCE(EXT4_I(inode)->i_disksize, newsize) // update i_disksize
       | generic_write_end
       |  copied = block_write_end(copied, len) // copied = 0
       |   if (unlikely(copied < len))
       |    if (!PageUptodate(page))
       |     copied = 0;
       |  if (pos + copied > inode->i_size) // return false
       if (unlikely(copied == 0))
        goto again;
       if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
        status = -EFAULT;
        break;
       }
      
      We get i_disksize greater than i_size here, which could trigger WARNING
      check 'i_size_read(inode) < EXT4_I(inode)->i_disksize' while doing dio:
      
      ext4_dio_write_iter
       iomap_dio_rw
        __iomap_dio_rw // return err, length is not aligned to 512
       ext4_handle_inode_extension
        WARN_ON_ONCE(i_size_read(inode) < EXT4_I(inode)->i_disksize) // Oops
      
       WARNING: CPU: 2 PID: 2609 at fs/ext4/file.c:319
       CPU: 2 PID: 2609 Comm: aa Not tainted 6.3.0-rc2
       RIP: 0010:ext4_file_write_iter+0xbc7
       Call Trace:
        vfs_write+0x3b1
        ksys_write+0x77
        do_syscall_64+0x39
      
      Fix it by updating 'copied' value before updating i_disksize just like
      ext4_write_inline_data_end() does.
      
      A reproducer can be found in the buganizer link below.
      
      Link: https://bugzilla.kernel.org/show_bug.cgi?id=217209
      Fixes: 64769240 ("ext4: Add delayed allocation support in data=writeback mode")
      Signed-off-by: default avatarZhihao Cheng <chengzhihao1@huawei.com>
      Reviewed-by: default avatarJan Kara <jack@suse.cz>
      Link: https://lore.kernel.org/r/20230321013721.89818-1-chengzhihao1@huawei.comSigned-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
      1dedde69
  2. 20 Apr, 2023 3 commits
  3. 15 Apr, 2023 9 commits
  4. 14 Apr, 2023 12 commits
  5. 06 Apr, 2023 10 commits