CVE: CVE-2022-50638
Published: 2025-12-09
Description: In the Linux kernel, the following vulnerability has been resolved:

ext4: fix bug_on in __es_tree_search caused by bad boot loader inode

We got a issue as fllows:
==================================================================
 kernel BUG at fs/ext4/extents_status.c:203!
 invalid opcode: 0000 [#1] PREEMPT SMP
 CPU: 1 PID: 945 Comm: cat Not tainted 6.0.0-next-20221007-dirty #349
 RIP: 0010:ext4_es_end.isra.0+0x34/0x42
 RSP: 0018:ffffc9000143b768 EFLAGS: 00010203
 RAX: [PII_REDACTED] RBX: ffff8881769cd0b8 RCX: [PII_REDACTED]
 RDX: [PII_REDACTED] RSI: ffffffff8fc27cf7 RDI: 00000000ffffffff
 RBP: ffff8881769cd0bc R08: [PII_REDACTED] R09: ffffc9000143b5f8
 R10: [PII_REDACTED] R11: [PII_REDACTED] R12: ffff8881769cd0a0
 R13: ffff8881768e5668 R14:[PII_REDACTED]8e52f0 R15: [PII_REDACTED]
 FS: 00007f359f7f05c0(0000)GS:ffff88842fd00000(0000)knlGS:[PII_REDACTED]
 CS:  0010 DS: 0000 ES: 0000 CR0: [PII_REDACTED]
 CR2: 00007f359f5a2000 CR3:[PII_REDACTED]30c000 CR4:[PII_REDACTED]0006e0
 DR0: [PII_REDACTED] DR1: [PII_REDACTED] DR2: [PII_REDACTED]
 DR3: [PII_REDACTED] DR6: 00000000fffe0ff0 DR7: [PII_REDACTED]
 Call Trace:
  <TASK>
  __es_tree_search.isra.0+0x6d/0xf5
  ext4_es_cache_extent+0xfa/0x230
  ext4_cache_extents+0xd2/0x110
  ext4_find_extent+0x5d5/0x8c0
  ext4_ext_map_blocks+0x9c/0x1d30
  ext4_map_blocks+0x431/0xa50
  ext4_mpage_readpages+0x48e/0xe40
  ext4_readahead+0x47/0x50
  read_pages+0x82/0x530
  page_cache_ra_unbounded+0x199/0x2a0
  do_page_cache_ra+0x47/0x70
  page_cache_ra_order+0x242/0x400
  ondemand_readahead+0x1e8/0x4b0
  page_cache_sync_ra+0xf4/0x110
  filemap_get_pages+0x131/0xb20
  filemap_read+0xda/0x4b0
  generic_file_read_iter+0x13a/0x250
  ext4_file_read_iter+0x59/0x1d0
  vfs_read+0x28f/0x460
  ksys_read+0x73/0x160
  __x64_sys_read+0x1e/0x30
  do_syscall_64+0x35/0x80
  entry_SYSCALL_64_after_hwframe+0x63/0xcd
  </TASK>
==================================================================

In the above issue, ioctl invokes the swap_inode_boot_loader function to
swap inode<5> and inode<12>. However, inode<5> contain incorrect imode and
disordered extents, and i_nlink is set to 1. The extents check for inode in
the ext4_iget function can be bypassed bacause 5 is EXT4_BOOT_LOADER_INO.
While links_count is set to 1, the extents are not initialized in
swap_inode_boot_loader. After the ioctl command is executed successfully,
the extents are swapped to inode<12>, in this case, run the `cat` command
to view inode<12>. And Bug_ON is triggered due to the incorrect extents.

When the boot loader inode is not initialized, its imode can be one of the
following:
1) the imode is a bad type, which is marked as bad_inode in ext4_iget and
   set to S_IFREG.
2) the imode is good type but not S_IFREG.
3) the imode is S_IFREG.

The BUG_ON may be triggered by bypassing the check in cases 1 and 2.
Therefore, when the boot loader inode is bad_inode or its imode is not
S_IFREG, initialize the inode to avoid triggering the BUG.
References: https://git.kernel.org/stable/c/5f8d36abd2059bf1bd016b17d1fe78d8613deddd; https://git.kernel.org/stable/c/71e99ec1315fe98d322b17b9a28f204aaf15ffee; https://git.kernel.org/stable/c/78e335fb573e6a85718c4c24d5a052718a99a9ed