* BUG: KCSAN: data-race in ext4_fill_super / super_s_dev_test
@ 2026-03-11 7:53 Jianzhou Zhao
0 siblings, 0 replies; only message in thread
From: Jianzhou Zhao @ 2026-03-11 7:53 UTC (permalink / raw)
To: linux-kernel, tytso, adilger.kernel, linux-ext4
Subject: [BUG] fs: KCSAN: data-race in ext4_fill_super / super_s_dev_test
Dear Maintainers,
We are writing to report a KCSAN-detected data race vulnerability within the VFS and ext4 subsystem. This bug was found by our custom fuzzing tool, RacePilot. The race occurs during the filesystem mount procedure when `ext4_check_journal_data_mode` (via `ext4_fill_super`) sets `SB_I_CGROUPWB` in `sb->s_iflags` without strict synchronization, while `super_s_dev_test` contemporaneously checks for the `SB_I_RETIRED` bit in the same `s_iflags` variable while iterating over `fs_supers`. We observed this bug on the Linux kernel version 6.18.0-08691-g2061f18ad76e-dirty.
Call Trace & Context
==================================================================
BUG: KCSAN: data-race in ext4_fill_super / super_s_dev_test
write to 0xffff88802f427058 of 8 bytes by task 25360 on cpu 1:
ext4_check_journal_data_mode fs/ext4/super.c:5021 [inline]
__ext4_fill_super fs/ext4/super.c:5364 [inline]
ext4_fill_super+0x1308/0x7590 fs/ext4/super.c:5777
get_tree_bdev_flags+0x256/0x370 fs/super.c:1699
get_tree_bdev+0x1f/0x30 fs/super.c:1722
ext4_get_tree+0x1c/0x30 fs/ext4/super.c:5809
...
__x64_sys_mount+0x1d7/0x210 fs/namespace.c:4201
read to 0xffff88802f427058 of 8 bytes by task 25340 on cpu 0:
super_s_dev_test+0x1c/0xa0 fs/super.c:1386
sget_fc+0x13a/0x6c0 fs/super.c:755
sget_dev fs/super.c:1413 [inline]
get_tree_bdev_flags+0x124/0x370 fs/super.c:1685
get_tree_bdev+0x1f/0x30 fs/super.c:1722
ext4_get_tree+0x1c/0x30 fs/ext4/super.c:5809
...
__x64_sys_mount+0x1d7/0x210 fs/namespace.c:4201
value changed: 0x0000000000000000 -> 0x0000000000004001
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 UID: 0 PID: 25340 Comm: syz.1.1392 Not tainted 6.18.0-08691-g2061f18ad76e-dirty #44 PREEMPT(voluntary)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
==================================================================
Execution Flow & Code Context
During the mounting phase of a new ext4 instance, the system allocates a superblock and inserts it into the `fs_supers` list globally (handled in `sget_fc()`). Later, the `ext4_fill_super()` phase modifies `sb->s_iflags` configuration properties directly. This happens without acquiring the `sb_lock` which covers list traversals. Concretely, in `fs/ext4/super.c`:
```c
// fs/ext4/super.c
static int ext4_check_journal_data_mode(struct super_block *sb)
{
...
} else {
sb->s_iflags |= SB_I_CGROUPWB; // <-- Plain concurrent write
}
return 0;
}
```
Whenever another concurrent mount thread (or internal iteration) searches through existing superblocks for the block device via `sget_dev()`, it iterates over the linked structures calling `super_s_dev_test()`. `super_s_dev_test` inspects `s->s_iflags` to verify the retired status.
```c
// fs/super.c
static int super_s_dev_test(struct super_block *s, struct fs_context *fc)
{
return !(s->s_iflags & SB_I_RETIRED) && // <-- Plain concurrent read
s->s_dev == *(dev_t *)fc->sget_key;
}
```
Root Cause Analysis
A KCSAN data race arises because one thread configures the internal superblock identifier flags concurrently while a secondary thread traverses the global list of superblocks scanning for active block devices. `s->s_iflags` acts as shared state globally visible through the filesystem subsystem list from the point it gets listed in `sget_fc`. The read evaluation of `s_iflags` overlaps with the logical OR operation, establishing an undocumented race.
Unfortunately, we were unable to generate a reproducer for this bug.
Potential Impact
This data race is functionally extremely minor or mostly benign since the read only targets the `SB_I_RETIRED` bit, while the write sets the `SB_I_CGROUPWB` bit. However, the lack of annotations can trigger aggressive compiler tearing implementations across architecture layouts, risking transient false `SB_I_RETIRED` positives causing unexpected remount disconnections. It generates excessive fuzzing alerts that obscure critical concurrency flaws.
Proposed Fix
We can wrap the evaluation condition in `super_s_dev_test()` explicitly to advise KCSAN and suppress the diagnostic alert effectively, affirming the concurrent access is tracked by the developers and functionally verified.
```diff
--- a/fs/super.c
+++ b/fs/super.c
@@ -1383,7 +1383,7 @@ static int super_s_dev_set(struct super_block *s, struct fs_context *fc)
static int super_s_dev_test(struct super_block *s, struct fs_context *fc)
{
- return !(s->s_iflags & SB_I_RETIRED) &&
+ return !(data_race(s->s_iflags) & SB_I_RETIRED) &&
s->s_dev == *(dev_t *)fc->sget_key;
}
```
We would be highly honored if this could be of any help.
Best regards,
RacePilot Team
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-03-11 7:54 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-11 7:53 BUG: KCSAN: data-race in ext4_fill_super / super_s_dev_test Jianzhou Zhao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox