public inbox for linux-ext4@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] ext4: fix use-after-free in update_super_work when racing with umount
@ 2026-03-19  7:36 Jiayuan Chen
  2026-03-19 10:50 ` Jan Kara
  2026-03-20 10:27 ` [syzbot ci] " syzbot ci
  0 siblings, 2 replies; 4+ messages in thread
From: Jiayuan Chen @ 2026-03-19  7:36 UTC (permalink / raw)
  To: linux-ext4, jack
  Cc: Jiayuan Chen, Jiayuan Chen, Theodore Ts'o, Andreas Dilger,
	Ye Bin, Ritesh Harjani, linux-kernel

From: Jiayuan Chen <jiayuan.chen@shopee.com>

Commit b98535d09179 ("ext4: fix bug_on in start_this_handle during umount
filesystem") moved ext4_unregister_sysfs() before flushing s_sb_upd_work
to prevent new error work from being queued via /proc/fs/ext4/xx/mb_groups
reads during unmount. However, this introduced a use-after-free because
update_super_work calls ext4_notify_error_sysfs() -> sysfs_notify() which
accesses the kobject's kernfs_node after it has been freed by kobject_del()
in ext4_unregister_sysfs():

  update_super_work                ext4_put_super
  -----------------                --------------
                                   ext4_unregister_sysfs(sb)
                                     kobject_del(&sbi->s_kobj)
                                       __kobject_del()
                                         sysfs_remove_dir()
                                           kobj->sd = NULL
                                         sysfs_put(sd)
                                           kernfs_put()  // RCU free
  ext4_notify_error_sysfs(sbi)
    sysfs_notify(&sbi->s_kobj)
      kn = kobj->sd              // stale pointer
      kernfs_get(kn)             // UAF on freed kernfs_node
                                   ext4_journal_destroy()
                                     flush_work(&sbi->s_sb_upd_work)

Instead of reordering the teardown sequence, fix this by making
ext4_notify_error_sysfs() detect that sysfs has already been torn down
by checking s_kobj.state_in_sysfs, and skipping the sysfs_notify() call
in that case. A dedicated mutex (s_error_notify_mutex) serializes
ext4_notify_error_sysfs() against kobject_del() in ext4_unregister_sysfs()
to prevent TOCTOU races where the kobject could be deleted between the
state_in_sysfs check and the sysfs_notify() call.

Fixes: b98535d09179 ("ext4: fix bug_on in start_this_handle during umount filesystem")
Cc: Jiayuan Chen <jiayuan.chen@linux.dev>
Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>

---
v1 -> v2: Use state_in_sysfs instead of reordering the teardown
sequence.
https://lore.kernel.org/linux-ext4/20260313065206.152645-1-jiayuan.chen@linux.dev/
---
 fs/ext4/ext4.h  | 1 +
 fs/ext4/sysfs.c | 9 ++++++++-
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index b76966dc06c0..c012e85d2515 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1574,6 +1574,7 @@ struct ext4_sb_info {
 	struct proc_dir_entry *s_proc;
 	struct kobject s_kobj;
 	struct completion s_kobj_unregister;
+	struct mutex s_error_notify_mutex; /* protects sysfs_notify vs kobject_del */
 	struct super_block *s_sb;
 	struct buffer_head *s_mmp_bh;
 
diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
index d2ecc1026c0c..f2505988e010 100644
--- a/fs/ext4/sysfs.c
+++ b/fs/ext4/sysfs.c
@@ -597,7 +597,10 @@ static const struct kobj_type ext4_feat_ktype = {
 
 void ext4_notify_error_sysfs(struct ext4_sb_info *sbi)
 {
-	sysfs_notify(&sbi->s_kobj, NULL, "errors_count");
+	mutex_lock(&sbi->s_error_notify_mutex);
+	if (sbi->s_kobj.state_in_sysfs)
+		sysfs_notify(&sbi->s_kobj, NULL, "errors_count");
+	mutex_unlock(&sbi->s_error_notify_mutex);
 }
 
 static struct kobject *ext4_root;
@@ -610,6 +613,7 @@ int ext4_register_sysfs(struct super_block *sb)
 	int err;
 
 	init_completion(&sbi->s_kobj_unregister);
+	mutex_init(&sbi->s_error_notify_mutex);
 	err = kobject_init_and_add(&sbi->s_kobj, &ext4_sb_ktype, ext4_root,
 				   "%s", sb->s_id);
 	if (err) {
@@ -644,7 +648,10 @@ void ext4_unregister_sysfs(struct super_block *sb)
 
 	if (sbi->s_proc)
 		remove_proc_subtree(sb->s_id, ext4_proc_root);
+
+	mutex_lock(&sbi->s_error_notify_mutex);
 	kobject_del(&sbi->s_kobj);
+	mutex_unlock(&sbi->s_error_notify_mutex);
 }
 
 int __init ext4_init_sysfs(void)
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] ext4: fix use-after-free in update_super_work when racing with umount
  2026-03-19  7:36 [PATCH v2] ext4: fix use-after-free in update_super_work when racing with umount Jiayuan Chen
@ 2026-03-19 10:50 ` Jan Kara
  2026-03-19 11:17   ` Jiayuan Chen
  2026-03-20 10:27 ` [syzbot ci] " syzbot ci
  1 sibling, 1 reply; 4+ messages in thread
From: Jan Kara @ 2026-03-19 10:50 UTC (permalink / raw)
  To: Jiayuan Chen
  Cc: linux-ext4, jack, Jiayuan Chen, Theodore Ts'o, Andreas Dilger,
	Ye Bin, Ritesh Harjani, linux-kernel

On Thu 19-03-26 15:36:50, Jiayuan Chen wrote:
> From: Jiayuan Chen <jiayuan.chen@shopee.com>
> 
> Commit b98535d09179 ("ext4: fix bug_on in start_this_handle during umount
> filesystem") moved ext4_unregister_sysfs() before flushing s_sb_upd_work
> to prevent new error work from being queued via /proc/fs/ext4/xx/mb_groups
> reads during unmount. However, this introduced a use-after-free because
> update_super_work calls ext4_notify_error_sysfs() -> sysfs_notify() which
> accesses the kobject's kernfs_node after it has been freed by kobject_del()
> in ext4_unregister_sysfs():
> 
>   update_super_work                ext4_put_super
>   -----------------                --------------
>                                    ext4_unregister_sysfs(sb)
>                                      kobject_del(&sbi->s_kobj)
>                                        __kobject_del()
>                                          sysfs_remove_dir()
>                                            kobj->sd = NULL
>                                          sysfs_put(sd)
>                                            kernfs_put()  // RCU free
>   ext4_notify_error_sysfs(sbi)
>     sysfs_notify(&sbi->s_kobj)
>       kn = kobj->sd              // stale pointer
>       kernfs_get(kn)             // UAF on freed kernfs_node
>                                    ext4_journal_destroy()
>                                      flush_work(&sbi->s_sb_upd_work)
> 
> Instead of reordering the teardown sequence, fix this by making
> ext4_notify_error_sysfs() detect that sysfs has already been torn down
> by checking s_kobj.state_in_sysfs, and skipping the sysfs_notify() call
> in that case. A dedicated mutex (s_error_notify_mutex) serializes
> ext4_notify_error_sysfs() against kobject_del() in ext4_unregister_sysfs()
> to prevent TOCTOU races where the kobject could be deleted between the
> state_in_sysfs check and the sysfs_notify() call.
> 
> Fixes: b98535d09179 ("ext4: fix bug_on in start_this_handle during umount filesystem")
> Cc: Jiayuan Chen <jiayuan.chen@linux.dev>
> Suggested-by: Jan Kara <jack@suse.cz>
> Signed-off-by: Jiayuan Chen <jiayuan.chen@shopee.com>

Thanks for the patch! Automated AI review
(https://sashiko.dev/#/patchset/20260319073651.79209-1-jiayuan.chen%40linux.dev)

has noticed two small issues with this:

> diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
> index d2ecc1026c0c..f2505988e010 100644
> --- a/fs/ext4/sysfs.c
> +++ b/fs/ext4/sysfs.c
> @@ -597,7 +597,10 @@ static const struct kobj_type ext4_feat_ktype = {
>  
>  void ext4_notify_error_sysfs(struct ext4_sb_info *sbi)
>  {
> -	sysfs_notify(&sbi->s_kobj, NULL, "errors_count");
> +	mutex_lock(&sbi->s_error_notify_mutex);
> +	if (sbi->s_kobj.state_in_sysfs)
> +		sysfs_notify(&sbi->s_kobj, NULL, "errors_count");
> +	mutex_unlock(&sbi->s_error_notify_mutex);
>  }
>  
>  static struct kobject *ext4_root;
> @@ -610,6 +613,7 @@ int ext4_register_sysfs(struct super_block *sb)
>  	int err;
>  
>  	init_completion(&sbi->s_kobj_unregister);
> +	mutex_init(&sbi->s_error_notify_mutex);
>  	err = kobject_init_and_add(&sbi->s_kobj, &ext4_sb_ktype, ext4_root,
>  				   "%s", sb->s_id);
>  	if (err) {

The initialization of s_error_notify_mutex should happen early in
ext4_fill_super() as ext4_notify_error_sysfs() can be called rather early
before ext4_register_sysfs() is called.

Also we should protect kobject_init_and_add() with s_error_notify_mutex to
handle the case where ext4_notify_error_sysfs() is racing with
ext4_register_sysfs().

								Honza
-- 
Jan Kara <jack@suse.com>
SUSE Labs, CR

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] ext4: fix use-after-free in update_super_work when racing with umount
  2026-03-19 10:50 ` Jan Kara
@ 2026-03-19 11:17   ` Jiayuan Chen
  0 siblings, 0 replies; 4+ messages in thread
From: Jiayuan Chen @ 2026-03-19 11:17 UTC (permalink / raw)
  To: Jan Kara
  Cc: linux-ext4, Jiayuan Chen, Theodore Ts'o, Andreas Dilger,
	Ye Bin, Ritesh Harjani, linux-kernel


On 3/19/26 6:50 PM, Jan Kara wrote:
> The initialization of s_error_notify_mutex should happen early in
> ext4_fill_super() as ext4_notify_error_sysfs() can be called rather early
> before ext4_register_sysfs() is called.
>
> Also we should protect kobject_init_and_add() with s_error_notify_mutex to
> handle the case where ext4_notify_error_sysfs() is racing with
> ext4_register_sysfs().
>
> 								Honza
> -- Jan Kara <jack@suse.com> SUSE Labs, CR


Hi Honza,

Thanks for the review! The AI catches are reasonable — I'll move
mutex_init() earlier in ext4_fill_super() and protect kobject_init_and_add()
with the mutex.

Thanks,
Jiayuan


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [syzbot ci] Re: ext4: fix use-after-free in update_super_work when racing with umount
  2026-03-19  7:36 [PATCH v2] ext4: fix use-after-free in update_super_work when racing with umount Jiayuan Chen
  2026-03-19 10:50 ` Jan Kara
@ 2026-03-20 10:27 ` syzbot ci
  1 sibling, 0 replies; 4+ messages in thread
From: syzbot ci @ 2026-03-20 10:27 UTC (permalink / raw)
  To: adilger.kernel, jack, jiayuan.chen, jiayuan.chen, linux-ext4,
	linux-kernel, riteshh, tytso, yebin10
  Cc: syzbot, syzkaller-bugs

syzbot ci has tested the following series

[v2] ext4: fix use-after-free in update_super_work when racing with umount
https://lore.kernel.org/all/20260319073651.79209-1-jiayuan.chen@linux.dev
* [PATCH v2] ext4: fix use-after-free in update_super_work when racing with umount

and found the following issue:
WARNING in ext4_notify_error_sysfs

Full report is available here:
https://ci.syzbot.org/series/3b258c63-ea54-492a-ab47-c09e62612658

***

WARNING in ext4_notify_error_sysfs

tree:      torvalds
URL:       https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
base:      0e4f8f1a3d081e834be5fd0a62bdb2554fadd307
arch:      amd64
compiler:  Debian clang version 21.1.8 (++20251221033036+2078da43e25a-1~exp1~20251221153213.50), Debian LLD 21.1.8
config:    https://ci.syzbot.org/builds/8149e3c8-4cb9-4fa0-9bf5-3d6deda6899d/config
C repro:   https://ci.syzbot.org/findings/6f6eafc6-a231-4909-9025-539fa10ffcfd/c_repro
syz repro: https://ci.syzbot.org/findings/6f6eafc6-a231-4909-9025-539fa10ffcfd/syz_repro

------------[ cut here ]------------
DEBUG_LOCKS_WARN_ON(lock->magic != lock)
WARNING: kernel/locking/mutex.c:593 at __mutex_lock_common kernel/locking/mutex.c:593 [inline], CPU#1: kworker/1:4/5883
WARNING: kernel/locking/mutex.c:593 at __mutex_lock+0x10a4/0x1300 kernel/locking/mutex.c:776, CPU#1: kworker/1:4/5883
Modules linked in:
CPU: 1 UID: 0 PID: 5883 Comm: kworker/1:4 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
Workqueue: events update_super_work

RIP: 0010:__mutex_lock_common kernel/locking/mutex.c:593 [inline]
RIP: 0010:__mutex_lock+0x10ab/0x1300 kernel/locking/mutex.c:776
Code: 11 90 48 c1 e8 03 42 0f b6 04 28 84 c0 0f 85 33 02 00 00 83 3d d9 e1 61 04 00 75 13 48 8d 3d 1c f7 64 04 48 c7 c6 c0 e0 cc 8b <67> 48 0f b9 3a 90 e9 ac f0 ff ff 90 0f 0b 90 e9 73 f4 ff ff 90 0f
RSP: 0018:ffffc90004dcf900 EFLAGS: 00010246
RAX: 0000000000000000 RBX: 1ffff920009b9f38 RCX: ffff888172d3d7c0
RDX: 0000000000000000 RSI: ffffffff8bcce0c0 RDI: ffffffff9014ec10
RBP: ffffc90004dcfaa8 R08: ffffffff9011d6c3 R09: 1ffffffff2023ad8
R10: dffffc0000000000 R11: fffffbfff2023ad9 R12: ffff888172218368
R13: dffffc0000000000 R14: 0000000000000000 R15: 0000000000000000
FS:  0000000000000000(0000) GS:ffff8882a945d000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000562af42c7d40 CR3: 0000000111346000 CR4: 00000000000006f0
Call Trace:
 <TASK>
 ext4_notify_error_sysfs+0x23/0xa0 fs/ext4/sysfs.c:600
 process_one_work kernel/workqueue.c:3276 [inline]
 process_scheduled_works+0xb6e/0x18c0 kernel/workqueue.c:3359
 worker_thread+0xa53/0xfc0 kernel/workqueue.c:3440
 kthread+0x388/0x470 kernel/kthread.c:436
 ret_from_fork+0x51e/0xb90 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
 </TASK>
----------------
Code disassembly (best guess):
   0:	11 90 48 c1 e8 03    	adc    %edx,0x3e8c148(%rax)
   6:	42 0f b6 04 28       	movzbl (%rax,%r13,1),%eax
   b:	84 c0                	test   %al,%al
   d:	0f 85 33 02 00 00    	jne    0x246
  13:	83 3d d9 e1 61 04 00 	cmpl   $0x0,0x461e1d9(%rip)        # 0x461e1f3
  1a:	75 13                	jne    0x2f
  1c:	48 8d 3d 1c f7 64 04 	lea    0x464f71c(%rip),%rdi        # 0x464f73f
  23:	48 c7 c6 c0 e0 cc 8b 	mov    $0xffffffff8bcce0c0,%rsi
* 2a:	67 48 0f b9 3a       	ud1    (%edx),%rdi <-- trapping instruction
  2f:	90                   	nop
  30:	e9 ac f0 ff ff       	jmp    0xfffff0e1
  35:	90                   	nop
  36:	0f 0b                	ud2
  38:	90                   	nop
  39:	e9 73 f4 ff ff       	jmp    0xfffff4b1
  3e:	90                   	nop
  3f:	0f                   	.byte 0xf


***

If these findings have caused you to resend the series or submit a
separate fix, please add the following tag to your commit message:
  Tested-by: syzbot@syzkaller.appspotmail.com

---
This report is generated by a bot. It may contain errors.
syzbot ci engineers can be reached at syzkaller@googlegroups.com.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-03-20 10:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-19  7:36 [PATCH v2] ext4: fix use-after-free in update_super_work when racing with umount Jiayuan Chen
2026-03-19 10:50 ` Jan Kara
2026-03-19 11:17   ` Jiayuan Chen
2026-03-20 10:27 ` [syzbot ci] " syzbot ci

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox