public inbox for linux-ext4@vger.kernel.org
 help / color / mirror / Atom feed
* 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