linux/fs/ext4
Christian Brauner c17b44266a
ext4: free the sbi after a grace period
ext4_get_link() follows a symlink that keeps its target in a data block
in rcu pathwalk mode with ext4_getblk(EXT4_GET_BLOCKS_CACHED_NOWAIT).
That reads s_mount_state in the ASSERT() of ext4_getblk() and again in
ext4_es_lookup_extent(), and the lookup bumps the extent status hit or
miss counter, all through sb->s_fs_info.

ext4_put_super() destroys those counters, clears sb->s_fs_info and frees
the sbi without waiting for a grace period. A pathwalk that is still in
ext4_get_link() when the last reference to the mount goes away then
dereferences a NULL s_fs_info, the freed sbi or the destroyed percpu
counters.

With a pathwalk held up in ext4_get_link() while the last reference
goes away:

  KASAN: null-ptr-deref in range [0x00000000000000a8-0x00000000000000af]
  RIP: 0010:ext4_getblk+0xf0/0x640
  Call Trace:
   <TASK>
   ext4_get_link+0x26c/0x410
   pick_link+0xf96/0x1780
   step_into_slowpath+0x9b8/0x1250
   path_lookupat+0x484/0xb00
   filename_lookup+0x1f1/0x5b0
   vfs_statx+0xd7/0x3b0
   vfs_fstatat+0x4d/0x90
   __do_sys_newfstatat+0xa0/0x100
   do_syscall_64+0x10e/0x5e0
   entry_SYSCALL_64_after_hwframe+0x77/0x7f

So far that has been hard to hit. umount(2) waits for a grace period in
namespace_unlock() before it drops the mount, so only a mount whose last
reference goes away elsewhere, like the close of a file or a chdir out of
a lazily unmounted directory, can race a walker.

Keep sb->s_fs_info and free the sbi together with the extent status
counters after a grace period. Split the counters out of
ext4_es_unregister_shrinker() for that. The shrinker still gets wasted
in ext4_put_super(), the counters go with the sbi.

Fixes: 6493792d32 ("ext4: convert symlink external data block mapping to bdev")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261009-work-fixes-rcu-v1-1-7446d2d335e6@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
2026-10-14 22:08:02 +02:00
..
.kunitconfig
acl.c
acl.h
balloc.c ext4: guard against NULL s_group_info in ext4_get_group_info 2026-08-06 10:34:27 -04:00
bitmap.c ext4: remove sbi argument from ext4_chksum() 2025-05-20 10:31:12 -04:00
block_validity.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
crypto.c Various ext4 updates for 7.3-rc1, including: 2026-08-20 13:17:11 -07:00
dir.c ext4: validate readdir offset before accessing dirent 2026-07-22 11:49:33 -04:00
ext4_extents.h ext4: fix extents-test.c is not compiled when EXT4_KUNIT_TESTS=M 2026-03-27 23:36:06 -04:00
ext4_jbd2.c Various ext4 updates for 7.3-rc1, including: 2026-08-20 13:17:11 -07:00
ext4_jbd2.h ext4: enable scoped NOFS when starting a handle in nojournal mode 2026-07-22 23:47:06 -04:00
ext4.h ext4: free the sbi after a grace period 2026-10-14 22:08:02 +02:00
extents_status.c ext4: free the sbi after a grace period 2026-10-14 22:08:02 +02:00
extents_status.h ext4: free the sbi after a grace period 2026-10-14 22:08:02 +02:00
extents-test.c ext4: free the sbi after a grace period 2026-10-14 22:08:02 +02:00
extents.c ext4: free the sbi after a grace period 2026-10-14 22:08:02 +02:00
fast_commit.c treewide: refresh kmalloc_obj() conversions 2026-09-04 21:37:00 -07:00
fast_commit.h ext4: mark move extents fast-commit ineligible 2026-01-19 19:26:35 -05:00
file.c Various ext4 updates for 7.3-rc1, including: 2026-08-20 13:17:11 -07:00
fsmap.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
fsmap.h
fsync.c ext4: Fix data integrity writeout issues in nojournal mode 2026-07-27 16:25:33 +02:00
hash-test.c ext4: add Kunit coverage for directory hash computation 2026-06-03 10:30:15 -04:00
hash.c ext4: improve str2hashbuf by processing 4-byte chunks and removing function pointers 2026-06-03 10:30:15 -04:00
ialloc.c ext4: don't enable DAX on new encrypted files 2026-08-06 10:21:52 -04:00
indirect.c treewide: change inode->i_ino from unsigned long to u64 2026-03-06 14:31:28 +01:00
inline.c ext4: cleanup unused CONVERT_INLINE_DATA flag 2026-07-22 11:49:33 -04:00
inode-test.c ext4: add missing MODULE_DESCRIPTION() 2024-07-05 16:07:24 -04:00
inode.c ext4: Avoid entering writeback paths during fastcommit replay 2026-08-21 13:57:44 +02:00
ioctl.c ext4: validate donor file superblock early in EXT4_IOC_MOVE_EXT 2026-06-10 10:53:50 -04:00
Kconfig ext4: remove obsolete EXT3 config options 2025-09-25 14:47:05 -04:00
Makefile ext4: add Kunit coverage for directory hash computation 2026-06-03 10:30:15 -04:00
mballoc-test.c ext4: use anonymous devices for KUnit test superblocks 2026-06-29 10:31:52 +02:00
mballoc.c ext4: get ext4_group_desc in ext4_mb_prefetch only when necessary 2026-07-21 11:26:39 -04:00
mballoc.h ext4: fix mballoc-test.c is not compiled when EXT4_KUNIT_TESTS=M 2026-03-27 23:36:02 -04:00
migrate.c ext4: fix circular lock dependency in ext4_ext_migrate 2026-07-21 11:26:39 -04:00
mmp.c ext4: Convert write_mmp_block_thawed() to bh_submit() 2026-06-04 10:28:08 +02:00
move_extent.c Various clean ups and bug fixes in ext4 for 7.1: 2026-04-17 17:08:31 -07:00
namei.c Various ext4 updates for 7.3-rc1, including: 2026-08-20 13:17:11 -07:00
orphan.c ext4: fix spurious message about orphan cleanup on RO fs 2026-08-06 10:24:31 -04:00
page-io.c ext4: Make ext4_bio_write_folio() return void 2026-07-20 10:39:25 -07:00
readpage.c ext4: Further de-generalize the bio postprocessing code 2026-07-20 10:39:25 -07:00
resize.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
super.c ext4: free the sbi after a grace period 2026-10-14 22:08:02 +02:00
symlink.c ext4: prefer IS_ERR_OR_NULL over manual NULL check 2026-04-09 21:27:24 -04:00
sysfs.c ext4: fix use-after-free in update_super_work when racing with umount 2026-03-27 23:37:39 -04:00
truncate.h
verity.c fsverity updates for 7.0 2026-02-12 10:41:34 -08:00
xattr_hurd.c
xattr_security.c
xattr_trusted.c
xattr_user.c
xattr.c ext4: stop retrying saturated xattr cache entries 2026-08-06 10:23:48 -04:00
xattr.h ext4: remove ea_inode_array mechanism in favor of ext4_put_ea_inode() 2026-07-22 12:27:43 -04:00