[PATCH RFC] udf: Replace WARN_ON with udf_warn in udf_truncate_extents()

0 views
Skip to first unread message

syzbot

unread,
Jun 24, 2026, 7:32:17 AM (yesterday) Jun 24
to syzkaller-upst...@googlegroups.com, syz...@lists.linux.dev
A corrupted UDF image can present a file where the recorded i_size is
larger than the total length of its extents. When attempting to write to a
huge offset, the block allocation path tries to extend the file by adding
new extents. However, if the filesystem runs out of space, the error
cleanup path invokes udf_truncate_extents() to remove any partially added
extents beyond the original i_size.

Inside udf_truncate_extents(), inode_bmap() is called to find the extent
containing i_size. Since the total extent length is already smaller than
i_size, inode_bmap() reaches the end of the extents and returns 0. The code
then calculates byte_offset (which is strictly positive) and hits the
WARN_ON(byte_offset), producing the following trace:

WARNING: fs/udf/truncate.c:224 at udf_truncate_extents+0xd79/0xef0
fs/udf/truncate.c:224
Call Trace:
<TASK>
udf_do_extend_file+0xdc2/0x11e0 fs/udf/inode.c:621
inode_getblk fs/udf/inode.c:842 [inline]
udf_map_block+0xfc6/0x4280 fs/udf/inode.c:453
__udf_get_block+0x52/0x250 fs/udf/inode.c:467
__block_write_begin_int+0x6c2/0x1930 fs/buffer.c:2042
block_write_begin+0x8d/0x120 fs/buffer.c:2153
udf_write_begin+0x11a/0x270 fs/udf/inode.c:261
generic_perform_write+0x2ad/0x8b0 mm/filemap.c:4325
udf_file_write_iter+0x2a6/0x650 fs/udf/file.c:112
new_sync_write fs/read_write.c:595 [inline]
vfs_write+0x61e/0xbb0 fs/read_write.c:688
ksys_write+0x156/0x270 fs/read_write.c:740
do_syscall_64+0x15f/0x560 arch/x86/entry/syscall_64.c:94
</TASK>

The WARN_ON macro must not be used for conditions that can legitimately
happen, such as encountering a corrupted filesystem. Hitting this state is
a filesystem inconsistency, not a kernel bug. While panic_on_warn may be
set in some environments, WARNINGs are generally not fatal on production
systems, but they still incorrectly indicate a kernel bug. Therefore,
pr_err() (or in this case, udf_warn()) should be used instead if necessary.

Replace the WARN_ON with a udf_warn() call to log the inconsistency
gracefully. The function then safely returns 0, which is the correct
behavior since there are no extents beyond i_size to free.

Fixes: 7e49b6f2480c ("udf: Convert UDF to new truncate calling sequence")
Assisted-by: Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+43fc5b...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=43fc5ba6dcb33e3261ca
Link: https://syzkaller.appspot.com/ai_job?id=bab17bf0-0c15-4575-b262-063dfb760277
To: "Jan Kara" <ja...@suse.com>
To: <linux-...@vger.kernel.org>

---
diff --git a/fs/udf/truncate.c b/fs/udf/truncate.c
index 41b2bfd30..ef4a8d876 100644
--- a/fs/udf/truncate.c
+++ b/fs/udf/truncate.c
@@ -220,8 +220,14 @@ int udf_truncate_extents(struct inode *inode)
byte_offset = (offset << sb->s_blocksize_bits) +
(inode->i_size & (sb->s_blocksize - 1));
if (ret == 0) {
- /* We should extend the file? */
- WARN_ON(byte_offset);
+ if (byte_offset) {
+ /*
+ * Extents are shorter than i_size. This can happen for corrupted
+ * files. There is nothing to truncate.
+ */
+ udf_warn(sb, "Extent length is shorter than i_size. "
+ "Filesystem might be corrupted.\n");
+ }
return 0;
}
epos.offset -= adsize;


base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6
--
This is an AI-generated patch subject to moderation.
Reply with '#syz upstream' to Sign-off the patch as a human author
and send it to the upstream kernel mailing lists.
Reply with '#syz reject' to reject it ('#syz unreject' to undo).

See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
You can comment on the patch as usual, syzbot will try to address
the comments and send a new version of the patch if necessary.
syzbot engineers can be reached at syzk...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages