Re: [syzbot] [ext4?] KASAN: slab-use-after-free Read in __ext4_iget

"Theodore Ts'o" <[email protected]>
Newsgroups gmane.comp.file-systems.reiserfs.general,gmane.comp.file-systems.ext4,gmane.linux.file-systems,gmane.linux.kernel
Message-ID <[email protected]>
#syz set subsystems: fs, reiserfs

On Tue, Jun 06, 2023 at 05:11:06PM -0700, syzbot wrote:
> Hello,
> 
> syzbot found the following issue on:
> 
> HEAD commit:    a4d7d7011219 Merge tag 'spi-fix-v6.4-rc5' of git://git.ker..
> git tree:       upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=1455f745280000
> kernel config:  https://syzkaller.appspot.com/x/.config?x=7474de833c217bf4
> dashboard link: https://syzkaller.appspot.com/bug?extid=5407ecf3112f882d2ef3
> compiler:       Debian clang version 15.0.7, GNU ld (GNU Binutils for Debian) 2.35.2

The stack traces on this are... intersting.  The use-after free is
coming when ext4_fill_super() tries to get the root inode, via
iget_locked(sb, EXT2_ROOT_INO)

> BUG: KASAN: slab-use-after-free in __ext4_iget+0x2f2/0x3f30 fs/ext4/inode.c:4700
> Read of size 8 at addr ffff888078ca5550 by task syz-executor.5/26112
	...
>  __ext4_iget+0x2f2/0x3f30 fs/ext4/inode.c:4700
>  __ext4_fill_super fs/ext4/super.c:5446 [inline]
>  ext4_fill_super+0x545b/0x6c60 fs/ext4/super.c:5672

However, we are getting back an object which is freed, and which was
originally allocated by reiserfs(!):

> Allocated by task 20729:
>  kasan_save_stack mm/kasan/common.c:45 [inline]
>  kasan_set_track+0x4f/0x70 mm/kasan/common.c:52
>  __kasan_slab_alloc+0x66/0x70 mm/kasan/common.c:328
>  kasan_slab_alloc include/linux/kasan.h:186 [inline]
>  slab_post_alloc_hook+0x68/0x3a0 mm/slab.h:711
>  slab_alloc_node mm/slub.c:3451 [inline]
>  slab_alloc mm/slub.c:3459 [inline]
>  __kmem_cache_alloc_lru mm/slub.c:3466 [inline]
>  kmem_cache_alloc_lru+0x11f/0x2e0 mm/slub.c:3482
>  alloc_inode_sb include/linux/fs.h:2705 [inline]
>  reiserfs_alloc_inode+0x2a/0xc0 fs/reiserfs/super.c:642
>  alloc_inode fs/inode.c:260 [inline]
>  iget5_locked+0xa0/0x270 fs/inode.c:1241
>  reiserfs_fill_super+0x12e4/0x2620 fs/reiserfs/super.c:2053
>  mount_bdev+0x2d0/0x3f0 fs/super.c:1380

There is no reproducer, but it seems to be triggering quite frequently
(over once day --- 20 times since June 16, 2023 as of this writing).
I've checked a number of the reports in the Syzkaller dashboard, and
they are all quite similar; somehow ext4 is getting an inode which is
freed, and whose memory was originally allocated by reiserfs.

I'm not sure if this is a reiserfs bug or a core VFS bug, since this
seems to imply that an an old reiserfs inode was left on the
inode_hashtable when a reiserfs file system was unmounted, and then
the struct super was reused and returned for a fresh ext4 mount, and
then when ext4 tried do an iget_locked(), it got the reserifs inode.

That reiserfs inode was either freed and left on the inode_hashtable,
or lifetime of the reiserfs root inode was allowed to last longer than
the reiserfs superblock (maybe someone is playing RCU games?) and so
since it was left on the inode_hashtable, the attempt to free reiserfs
root inode raced with ext4's attempt to fetch the ext4 inode via
iget_locked().

Perhaps one of the VFS or reiserfs maintainers could take a look?

       	       	  	   	      	       - Ted
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.