* [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