* Possible regression: ext4 lsetxattr returns ENOSPC on malformed image since v7.3-rc1
@ 2026-09-02 16:03 Hengyu Liang
2026-09-03 1:48 ` Theodore Tso
0 siblings, 1 reply; 2+ messages in thread
From: Hengyu Liang @ 2026-09-02 16:03 UTC (permalink / raw)
To: adilger.kernel, linux-ext4, tytso; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 2642 bytes --]
Hi,
We found a stable ext4 behavior change: with the same malformed ext4 image,
a large lsetxattr() succeeds through v7.2, but returns ENOSPC on v7.3-rc1.
The minimized syzlang reproducer is attached as repro.prog.
The relevant operations are:
syz_mount_image$ext4(..., "./file2", ..., 0x42f, <embedded image>)
open("./file2",
O_APPEND|O_EXCL|O_NONBLOCK|O_SYNC|O_TRUNC, 0)
lsetxattr$trusted_overlay_upper("./file1",
"trusted.overlay.upper",
<65079-byte value>, 65079, 0)
Observed results:
v6.18 through v7.2:
syz_mount_image: success
open: success
lsetxattr: success
v7.3-rc1:
syz_mount_image: success
open: success
lsetxattr: -1, errno=ENOSPC (28)
The behavior is stable across repeated runs.
The embedded filesystem is malformed. Running e2fsck -fn reports multiple
inode, directory-entry, and symlink inconsistencies, so it is not obvious
whether the old success result or the new ENOSPC result should be considered
correct.
One detail appears potentially relevant.
The filesystem has:
s_last_orphan = 15
and inode 15 is the root-level /file1 used by the lsetxattr() operation.
It is an inline-data inode with:
i_extra_isize = 32
while the mount options request:
debug_want_extra_isize=104
During mount-time orphan cleanup, /file1 can therefore be processed through:
ext4_orphan_cleanup()
-> ext4_process_orphan()
-> ext4_truncate()
-> ext4_inline_data_truncate()
-> ext4_mark_inode_dirty()
The v7.2 to v7.3-rc1 range contains:
7461c60b9c6a
ext4: skip extra isize expansion during mount to prevent deadlock
This commit skips extra-isize expansion while the superblock is not active,
and its commit message specifically mentions the
ext4_process_orphan() -> ext4_truncate() -> ext4_mark_inode_dirty()
path.
This seems like a plausible source of the behavior change, since it could
leave the inode in a different state before the later lsetxattr() call.
However, I have not established that this commit is the direct or only
cause.
Neither behavior is obviously correct to me: the older kernels allow the
operation to succeed on a malformed filesystem, while v7.3-rc1 returns
ENOSPC rather than a corruption-related error. Therefore, I am not sure what
the expected behavior should be, but this seems to indicate a potential bug
in how ext4 handles this malformed state.
The reproducer can be run with syz-execprog, for example:
syz-execprog -os=linux -arch=amd64 \
-executor=syz-executor \
-sandbox=none -procs=1 -threaded=0 -repeat=1 \
repro.prog
Thanks,
Hengyu
[-- Attachment #2: repro.prog --]
[-- Type: text/plain, Size: 1895 bytes --]
syz_mount_image$ext4(&(0x7f0000000040)='ext4\x00', &(0x7f00000001c0)='./file2\x00', 0x404, &(0x7f0000000280)={[{@nogrpid}, {@jqfmt_vfsv0}, {@debug_want_extra_isize={'debug_want_extra_isize', 0x3d, 0x68}}, {@debug}, {@nombcache}, {@quota}, {@nolazytime}]}, 0x3, 0x42f, &(0x7f0000000940)="$eJzs289rHFUcAPDvzCat/WViqT+aVo1WMfgjadJae/CiKHhQEPRQjzFJS+y2kSaCLUGjSD1Kwbt4FPwLPOlF1JPgVe9SKJJLq6eV2Z1Jdje7aZJustX9fGCS92be8t53Z97ue/N2AuhZw9mfJGJ/RPweEQO1bGOB4dq/W8uLU38vL04lUam89VdSLXdzeXGqKFq8bl+R6YtIP0viSIt65y9fOT9ZLs9cyvNjCxfeH5u/fOW52QuT52bOzVycOH365InxF05NPN+ROLO4bg59NHf08GvvXHtj6sy1d3/+Ninib4qjQ4bXO/hkpdLh6rrrQF066etiQ9iUUq2bRn+1/w9EKVZP3kC8+mlXGwdsq0qlUnmg/eGlCvA/lkS3WwB0R/FFn81/i22Hhh53hRsv1SZAWdy38q12pC/SvEx/0/y2k4Yj4szSP19lW2zPfQgAgAbfZ+OfZ1uN/9Kovy90b76GMhgR90XEwYg4FRGHIuL+iGrZByPioU3W37xIsnb8k17fUmAblI3/XszXthrHf8XoLwZLee5ANf7+5OxseeZ4/p6MRP/uLD++Th0/vPLbF+2O1Y//si2rvxgL5u243re78TXTkwuTdxJzvRufRAz1tYo/WVkJSCLicEQMbbGO2ae/Odru2O3jX0cH1pkqX0c8VTv/S9EUfyFZf31y7J4ozxwfK66KtX759eqb7eq/o/g7IDv/e1te/yvxDyb167Xzm6/j6h+ft53TbPX635W83bDvw8mFhUvjEbuS12uNrt8/0VRuYrV8Fv/Isdb9/2CsvhNHIiK7iB+OiEci4tG87Y9FxOMRcWyd+H96+Yn3th7/9srin97U+V9N7IrmPa0TpfM/ftdQ6eBm4s/O/8lqaiTfs5HPv420a2tXMwAAAPz3pBGxP5J0dCWdpqOjtd/wH4q9aXlufuGZs3MfXJyuPSMwGP1pcadroO5+6Hg+rS/yE035E/l94y9Le6r50am58nS3g4cet69N/8/8Wep264Bt53kt6F36P/Qu/R96l/4PvatF/9/TjXYAO6/V9//HXWgHsPOa+r9lP+gh5v/Qu/R/6F36P/Sk+T1x+4fkJSTWJCK9K5ohsU2Jbn8yAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdMa/AQAA//9QOObV")
open(&(0x7f0000000000)='./file2\x00', 0x101e80, 0x0)
lsetxattr$trusted_overlay_upper(&(0x7f0000000100)='./file1\x00', &(0x7f00000000c0), &(0x7f0000000040)=ANY=[], 0xfe37, 0x0)
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: Possible regression: ext4 lsetxattr returns ENOSPC on malformed image since v7.3-rc1
2026-09-02 16:03 Possible regression: ext4 lsetxattr returns ENOSPC on malformed image since v7.3-rc1 Hengyu Liang
@ 2026-09-03 1:48 ` Theodore Tso
0 siblings, 0 replies; 2+ messages in thread
From: Theodore Tso @ 2026-09-03 1:48 UTC (permalink / raw)
To: Hengyu Liang; +Cc: adilger.kernel, linux-ext4, linux-kernel
On Wed, Sep 02, 2026 at 12:03:52PM -0500, Hengyu Liang wrote:
>
> We found a stable ext4 behavior change: with the same malformed ext4 image,
> a large lsetxattr() succeeds through v7.2, but returns ENOSPC on v7.3-rc1.
What happens with a malformed ext4 image is quite frankly, not
interesting to me. How we handle a maliciously corrupted image is not
something which is defined. This is *especially* true given the use
of the mount option debug_want_extra_isize=104, which is not a
real-world use case, making this case doubly irrelevant.
(We've never actually used the code path which is designed to simulate
expanding the base inode in the two decades of ext4's existence. This
is because it's rare that we want to sacrifice bytes for all inodes,
especially if the field is for a feature which might not be useful for
most users. For most features that might only be used by a subset of
users, using an extended attribute, although it's less efficient, is
the preferred approach.)
Cheers,
- Ted
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-03 1:48 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 16:03 Possible regression: ext4 lsetxattr returns ENOSPC on malformed image since v7.3-rc1 Hengyu Liang
2026-09-03 1:48 ` Theodore Tso
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox