[Kernel Bug] WARNING in ext4_fill_super

10 views
Skip to first unread message

李龙兴

unread,
Feb 2, 2026, 2:04:39 AM (5 days ago) Feb 2
to syzk...@googlegroups.com, ke...@kernel.org, an...@kernel.org, ak...@linux-foundation.org, linux-h...@vger.kernel.org, linux-...@vger.kernel.org
Dear Linux kernel developers and maintainers,

We would like to report a new kernel bug found by our tool. The issue
is a WARNING in ext4_fill_super. Details are as follows.

Kernel commit: v6.18.2
Kernel config: see attachment
report: see attachment

We are currently analyzing the root cause and working on a
reproducible PoC. We will provide further updates in this thread as
soon as we have more information.

Best regards,
Longxing Li

loop4: detected capacity change from 0 to 514
------------[ cut here ]------------
strnlen: detected buffer overflow: 65 byte read of buffer size 64
WARNING: CPU: 0 PID: 12320 at lib/string_helpers.c:1035
__fortify_report+0x9c/0xd0 lib/string_helpers.c:1035
Modules linked in:
CPU: 0 UID: 0 PID: 12320 Comm: syz.4.59 Not tainted 6.18.2 #1 PREEMPT(full)
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
RIP: 0010:__fortify_report+0x9c/0xd0 lib/string_helpers.c:1035
Code: ed 48 c7 c0 80 c8 cf 8b 48 0f 44 d8 e8 cd dd 17 fd 4d 89 e0 48
89 ea 4c 89 f6 48 89 d9 48 c7 c7 00 c9 cf 8b e8 b5 57 d6 fc 90 <0f> 0b
90 90 5b 5d 41 5c 41 5d 41 5e c3 cc cc cc cc 48 89 de 48 c7
RSP: 0018:ffffc90011f9fa18 EFLAGS: 00010282
RAX: 0000000000000000 RBX: ffffffff8bcfc880 RCX: ffffffff817afc38
RDX: ffff8881095eca80 RSI: ffffffff817afc45 RDI: 0000000000000001
RBP: 0000000000000041 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000040
R13: 0000000000000000 R14: ffffffff8bcfd240 R15: ffff88803c484400
FS: 00007f9e5f45c640(0000) GS:ffff8880cf053000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000123400000 CR4: 0000000000752ef0
PKRU: 80000000
Call Trace:
<TASK>
__fortify_panic+0x23/0x30 lib/string_helpers.c:1042
strnlen include/linux/fortify-string.h:235 [inline]
sized_strscpy include/linux/fortify-string.h:309 [inline]
parse_apply_sb_mount_options fs/ext4/super.c:2486 [inline]
__ext4_fill_super fs/ext4/super.c:5306 [inline]
ext4_fill_super+0x3972/0xaf70 fs/ext4/super.c:5736
get_tree_bdev_flags+0x38c/0x620 fs/super.c:1698
vfs_get_tree+0x8e/0x340 fs/super.c:1758
fc_mount fs/namespace.c:1199 [inline]
do_new_mount_fc fs/namespace.c:3642 [inline]
do_new_mount fs/namespace.c:3718 [inline]
path_mount+0x7b9/0x23a0 fs/namespace.c:4028
do_mount fs/namespace.c:4041 [inline]
__do_sys_mount fs/namespace.c:4229 [inline]
__se_sys_mount fs/namespace.c:4206 [inline]
__x64_sys_mount+0x293/0x310 fs/namespace.c:4206
do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
do_syscall_64+0xcd/0xfa0 arch/x86/entry/syscall_64.c:94
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x56755e
Code: 48 c7 c0 ff ff ff ff eb aa e8 3e 1c 00 00 66 2e 0f 1f 84 00 00
00 00 00 0f 1f 40 00 f3 0f 1e fa 49 89 ca b8 a5 00 00 00 0f 05 <48> 3d
01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f9e5f45bdf8 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5
RAX: ffffffffffffffda RBX: 00007f9e5f45be80 RCX: 000000000056755e
RDX: 0000000020000140 RSI: 0000000020000440 RDI: 00007f9e5f45be40
RBP: 0000000020000140 R08: 00007f9e5f45be80 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000020000440
R13: 00007f9e5f45be40 R14: 00000000000003d5 R15: 0000000020000200
</TASK>

https://drive.google.com/file/d/12W8B3IU88RBdBpV4nMcAj9TVOzlx6xL-/view?usp=drive_link

https://drive.google.com/file/d/1efTUJTmSTMuJqSpCq686RjXdUzhyEJDL/view?usp=drive_link

李龙兴

unread,
Feb 2, 2026, 2:04:39 AM (5 days ago) Feb 2
to syzk...@googlegroups.com, ke...@kernel.org, an...@kernel.org, ak...@linux-foundation.org, linux-h...@vger.kernel.org, linux-...@vger.kernel.org

Andy Shevchenko

unread,
Feb 6, 2026, 9:26:12 AM (yesterday) Feb 6
to 李龙兴, Theodore Ts'o, Andreas Dilger, linux...@vger.kernel.org, syzk...@googlegroups.com, ke...@kernel.org, an...@kernel.org, ak...@linux-foundation.org, linux-h...@vger.kernel.org, linux-...@vger.kernel.org
On Mon, Feb 02, 2026 at 12:19:45PM +0800, 李龙兴 wrote:
> Dear Linux kernel developers and maintainers,
>
> We would like to report a new kernel bug found by our tool. The issue
> is a WARNING in ext4_fill_super. Details are as follows.

First of all, the warning appears in parse_apply_sb_mount_options().

> Kernel commit: v6.18.2
> Kernel config: see attachment
> report: see attachment

Second, you should include people based on the actual subsystem, unless it's
proven that the problem is in lib/*.

Cc'ed to ext4.

> We are currently analyzing the root cause and working on a
> reproducible PoC. We will provide further updates in this thread as
> soon as we have more information.


> https://drive.google.com/file/d/1efTUJTmSTMuJqSpCq686RjXdUzhyEJDL/

--
With Best Regards,
Andy Shevchenko


Andy Shevchenko

unread,
Feb 6, 2026, 10:08:24 AM (yesterday) Feb 6
to 李龙兴, Theodore Ts'o, Andreas Dilger, linux...@vger.kernel.org, syzk...@googlegroups.com, ke...@kernel.org, an...@kernel.org, ak...@linux-foundation.org, linux-h...@vger.kernel.org, linux-...@vger.kernel.org
On Fri, Feb 06, 2026 at 04:20:15PM +0200, Andy Shevchenko wrote:
> On Mon, Feb 02, 2026 at 12:19:45PM +0800, 李龙兴 wrote:
> > Dear Linux kernel developers and maintainers,
> >
> > We would like to report a new kernel bug found by our tool. The issue
> > is a WARNING in ext4_fill_super. Details are as follows.
>
> First of all, the warning appears in parse_apply_sb_mount_options().
>
> > Kernel commit: v6.18.2
> > Kernel config: see attachment
> > report: see attachment
>
> Second, you should include people based on the actual subsystem, unless it's
> proven that the problem is in lib/*.
>
> Cc'ed to ext4.
>
> > We are currently analyzing the root cause and working on a
> > reproducible PoC. We will provide further updates in this thread as
> > soon as we have more information.

You need to add more information here, esp. about the tested environment,
architecture, and compiler (I can deduct some from the .config, but still...).

So, as far as I can see this may only happen in the case when _Static_assert()
is evaluated to something that strict { $SMTH } is meaningful to the
preprocessor to have sizeof() > 0 (or sizeof(struct {}) is > 0).

In both cases sounds like a compiler bug.

Other possible explanation is the instrumentation that makes sizeof($FOO[])
return bigger sizes.

But TBH, all of the above looks to me like a nonsense. Maybe I missed something.

Note, if strscpy_pad(a, b) is broken, it should be much more visible and much
easier to reproduce even without syzkaller. Do we have (Kunit) test cases for
strscpy*()? If not, you should start adding them first.

Andy Shevchenko

unread,
Feb 6, 2026, 10:12:47 AM (yesterday) Feb 6
to 李龙兴, Theodore Ts'o, Andreas Dilger, linux...@vger.kernel.org, syzk...@googlegroups.com, ke...@kernel.org, an...@kernel.org, ak...@linux-foundation.org, linux-h...@vger.kernel.org, linux-...@vger.kernel.org
Actually, the documentation says that strscpy*() must be used against C-strings.
This can explain the bug, id est the given string in mount options is not
NUL-terminated. That's where bug may come from. So, the Q is why is mount options
not NUL-terminated when it comes to ext4_fill_super()?

Kees Cook

unread,
Feb 6, 2026, 2:29:15 PM (22 hours ago) Feb 6
to Andy Shevchenko, 李龙兴, Theodore Ts'o, Andreas Dilger, linux...@vger.kernel.org, syzk...@googlegroups.com, an...@kernel.org, ak...@linux-foundation.org, linux-h...@vger.kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org
On Fri, Feb 06, 2026 at 05:12:34PM +0200, Andy Shevchenko wrote:
> On Fri, Feb 06, 2026 at 05:08:19PM +0200, Andy Shevchenko wrote:
> > On Fri, Feb 06, 2026 at 04:20:15PM +0200, Andy Shevchenko wrote:
> > > On Mon, Feb 02, 2026 at 12:19:45PM +0800, 李龙兴 wrote:
> > > > Dear Linux kernel developers and maintainers,
> > > >
> > > > We would like to report a new kernel bug found by our tool. The issue
> > > > is a WARNING in ext4_fill_super. Details are as follows.
> > >
> > > First of all, the warning appears in parse_apply_sb_mount_options().
> [...]
> Actually, the documentation says that strscpy*() must be used against C-strings.
> This can explain the bug, id est the given string in mount options is not
> NUL-terminated. That's where bug may come from. So, the Q is why is mount options
> not NUL-terminated when it comes to ext4_fill_super()?

parse_apply_sb_mount_options(...):
...
char s_mount_opts[64];
...
if (strscpy_pad(s_mount_opts, sbi->s_es->s_mount_opts) < 0)
return -E2BIG;

Is sbi->s_es->s_mount_opts expected to be a C string? If not, this
strscpy_pad() should likely be memtostr_pad(). (s_mount_opts is expected
to be a C string based on its use with later C string API calls.)

It seems like s_mount_opts is expected to be a C string, I can see it
being used that way in lots of other places, e.g.:

fs/ext4/ioctl.c: strscpy_pad(ret.mount_opts, es->s_mount_opts);
fs/ext4/ioctl.c: strscpy_pad(es->s_mount_opts, params->mount_opts);
fs/ext4/super.c: if (!sbi->s_es->s_mount_opts[0])
fs/ext4/super.c: if (strscpy_pad(s_mount_opts, sbi->s_es->s_mount_opts) < 0)

I can't tell where es->s_mount_opts comes from originally?

This one:

fs/ext4/ioctl.c: strscpy_pad(es->s_mount_opts, params->mount_opts);

comes through ext4_ioctl_set_tune_sb() which has:

if (strnlen(params.mount_opts, sizeof(params.mount_opts)) ==
sizeof(params.mount_opts))
return -E2BIG;

So it's already checked for, and suggests it must be NUL-terminated.

> > > > loop4: detected capacity change from 0 to 514
> > > > ------------[ cut here ]------------
> > > > strnlen: detected buffer overflow: 65 byte read of buffer size 64
> > > > WARNING: CPU: 0 PID: 12320 at lib/string_helpers.c:1035
> > > > __fortify_report+0x9c/0xd0 lib/string_helpers.c:1035
> > > > [...]
> > > > Call Trace:
> > > > <TASK>
> > > > __fortify_panic+0x23/0x30 lib/string_helpers.c:1042
> > > > strnlen include/linux/fortify-string.h:235 [inline]
> > > > sized_strscpy include/linux/fortify-string.h:309 [inline]
> > > > parse_apply_sb_mount_options fs/ext4/super.c:2486 [inline]
> > > > __ext4_fill_super fs/ext4/super.c:5306 [inline]
> > > > ext4_fill_super+0x3972/0xaf70 fs/ext4/super.c:5736
> > > > get_tree_bdev_flags+0x38c/0x620 fs/super.c:1698
> > > > vfs_get_tree+0x8e/0x340 fs/super.c:1758
> > > > fc_mount fs/namespace.c:1199 [inline]
> > > > do_new_mount_fc fs/namespace.c:3642 [inline]

So, something via do_new_mount_fc? Probably:

static int ext4_fill_super(struct super_block *sb, struct fs_context *fc)

which calls __ext4_fill_super(), and eventually
parse_apply_sb_mount_options(). Which depends on:

struct ext4_fs_context *ctx = fc->fs_private;

But I can't figure out where that comes from. Seems like fs_parse(), but
I don't see where mount option strings would come through...

Anyone more familiar with this know?

-Kees

--
Kees Cook

Kees Cook

unread,
Feb 6, 2026, 2:53:12 PM (22 hours ago) Feb 6
to Andy Shevchenko, 李龙兴, Theodore Ts'o, Andreas Dilger, linux...@vger.kernel.org, syzk...@googlegroups.com, an...@kernel.org, ak...@linux-foundation.org, linux-h...@vger.kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org
On Fri, Feb 06, 2026 at 11:29:11AM -0800, Kees Cook wrote:
> But I can't figure out where that comes from. Seems like fs_parse(), but
> I don't see where mount option strings would come through...

Oh! This is coming directly from disk. So we need an in-place sanity
check. How about this?


diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 87205660c5d0..9ad6005615d8 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -2485,6 +2485,13 @@ static int parse_apply_sb_mount_options(struct super_block *sb,
if (!sbi->s_es->s_mount_opts[0])
return 0;

+ if (strnlen(sbi->s_es->s_mount_opts, sizeof(sbi->s_es->s_mount_opts)) ==
+ sizeof(sbi->s_es->s_mount_opts)) {
+ ext4_msg(sb, KERN_ERR,
+ "Mount options in superblock are not NUL-terminated");
+ return -EINVAL;
+ }
+
if (strscpy_pad(s_mount_opts, sbi->s_es->s_mount_opts) < 0)
return -E2BIG;


--
Kees Cook

Kees Cook

unread,
Feb 6, 2026, 3:36:34 PM (21 hours ago) Feb 6
to Andy Shevchenko, 李龙兴, Theodore Ts'o, Andreas Dilger, linux...@vger.kernel.org, syzk...@googlegroups.com, an...@kernel.org, ak...@linux-foundation.org, linux-h...@vger.kernel.org, linux-...@vger.kernel.org, linux-...@vger.kernel.org
Oh, wait. I see these commits now:

8ecb790ea8c3 ("ext4: avoid potential buffer over-read in parse_apply_sb_mount_options()")
ee5a977b4e77 ("ext4: fix string copying in parse_apply_sb_mount_options()")

Ugh, the history is that fundamentally s_mount_opts should be
__nonstring. Old code handled this fine (by using kstrndup), but when
ioctl get/set was added in commit 04a91570ac67 ("ext4: implemet new
ioctls to set and get superblock parameters"), s_mount_opts started
being treated as a C string, which would lead to over-reads (due to lack
of NUL-termination).

So, should on-disk s_mount_opts be required to be NUL-terminated? I
would argue yes, since right now a mount of such a thing will crash with
the reported failure in this thread. So likely, my proposed fix is the
best option?

-Kees

--
Kees Cook
Reply all
Reply to author
Forward
0 new messages