[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240903054808.126799-1-sunjunchao2870@gmail.com>
Date: Tue, 3 Sep 2024 13:48:08 +0800
From: Julian Sun <sunjunchao2870@...il.com>
To: linux-xfs@...r.kernel.org,
linux-fsdevel@...r.kernel.org,
linux-ext4@...r.kernel.org
Cc: tytso@....edu,
adilger.kernel@...ger.ca,
jack@...e.cz,
brauner@...nel.org,
djwong@...nel.org,
hch@....de,
Julian Sun <sunjunchao2870@...il.com>,
syzbot+296b1c84b9cbf306e5a0@...kaller.appspotmail.com
Subject: [PATCH] iomap: clean preallocated blocks in iomap_end() when 0 bytes was written.
Hi, all.
Recently, syzbot reported a issue as following:
WARNING: CPU: 1 PID: 5222 at fs/iomap/buffered-io.c:727 __iomap_write_begin fs/iomap/buffered-io.c:727 [inline]
WARNING: CPU: 1 PID: 5222 at fs/iomap/buffered-io.c:727 iomap_write_begin+0x13f0/0x16f0 fs/iomap/buffered-io.c:830
CPU: 1 UID: 0 PID: 5222 Comm: syz-executor247 Not tainted 6.11.0-rc2-syzkaller-00111-gee9a43b7cfe2 #0
RIP: 0010:__iomap_write_begin fs/iomap/buffered-io.c:727 [inline]
RIP: 0010:iomap_write_begin+0x13f0/0x16f0 fs/iomap/buffered-io.c:830
Call Trace:
<TASK>
iomap_unshare_iter fs/iomap/buffered-io.c:1351 [inline]
iomap_file_unshare+0x460/0x780 fs/iomap/buffered-io.c:1391
xfs_reflink_unshare+0x173/0x5f0 fs/xfs/xfs_reflink.c:1681
xfs_file_fallocate+0x6be/0xa50 fs/xfs/xfs_file.c:997
vfs_fallocate+0x553/0x6c0 fs/open.c:334
ksys_fallocate fs/open.c:357 [inline]
__do_sys_fallocate fs/open.c:365 [inline]
__se_sys_fallocate fs/open.c:363 [inline]
__x64_sys_fallocate+0xbd/0x110 fs/open.c:363
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf3/0x230 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f2d716a6899
syzbot constructed the following scenario: syzbot called the write()
system call, passed an illegal pointer, and attempted to write 0x1017
bytes, resulting in 0 bytes written and returning EFAULT to user
space. Then, it called the write() system call again, passed another
illegal pointer, and attempted to write 0xfea7 bytes, resulting in
0xe00 bytes written. Finally called copy_file_range() sys call and
fallocate() sys call with FALLOC_FL_UNSHARE_RANGE flag.
What happened here is: during the first write, xfs_buffered_write_iomap_begin()
used preallocated 512 blocks, inserted an extent with a length of 512 and
reserved 512 blocks in the quota, with the iomap length being 1M.
However, when the write failed(0 byte was written), only 0x1017 bytes were
passed to iomap_end() instead of the preallocated 1M bytes/512 blocks.
This caused only 3 blocks to be unreserved for the quota in iomap_end(),
instead of 512, and the corresponding extent information also only removed
3 blocks instead of 512.
As a result, during the second write, the iomap length was 3 blocks
instead of the expected 512 blocks, which ultimately triggered the
issue reported by syzbot in the fallocate() system call.
To resolve this issue, when a write fails, we should pass
iomap.length to iomap_end() to indicate it to clean up all
the resources, rather than just the length requested by the user.
This patch has already passed xfstests -g quick test on both xfs
and ext4 without causing additional failures.
Reported-and-tested-by: syzbot+296b1c84b9cbf306e5a0@...kaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=296b1c84b9cbf306e5a0
Fixes: f4b896c213f0 ("iomap: add the new iomap_iter model")
Signed-off-by: Julian Sun <sunjunchao2870@...il.com>
---
fs/iomap/iter.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/iomap/iter.c b/fs/iomap/iter.c
index 79a0614eaab7..6e3f6109cac5 100644
--- a/fs/iomap/iter.c
+++ b/fs/iomap/iter.c
@@ -76,7 +76,8 @@ int iomap_iter(struct iomap_iter *iter, const struct iomap_ops *ops)
int ret;
if (iter->iomap.length && ops->iomap_end) {
- ret = ops->iomap_end(iter->inode, iter->pos, iomap_length(iter),
+ ret = ops->iomap_end(iter->inode, iter->pos,
+ iter->processed > 0 ? iomap_length(iter) : iter->iomap.length,
iter->processed > 0 ? iter->processed : 0,
iter->flags, &iter->iomap);
if (ret < 0 && !iter->processed)
--
2.39.2
Powered by blists - more mailing lists