* [BUG] KASAN: slab-out-of-bounds Read in copy_folio_from_iter_atomic
@ 2026-10-18 8:12 l1za0.sec
2026-10-19 1:37 ` Andrew Morton
0 siblings, 1 reply; 2+ messages in thread
From: l1za0.sec @ 2026-10-18 8:12 UTC (permalink / raw)
To: viro; +Cc: akpm, linux-block, linux-fsdevel, linux-kernel, Haocheng Yu
From: Haocheng Yu <l1za0.sec@gmail.com>
Hi,
We found a KASAN slab-out-of-bounds read in copy_folio_from_iter_atomic() while
fuzzing Linux with a modified version of syzkaller. We couldn't find a report
of the same issue on syzbot. We are investigating the root cause and trying to
develop a fix. Could you let us know whether this issue warrants a fix?
The crash occurs on Linux v7.3.0-rc5. KASAN reports an 8-byte read 8 bytes past
a 144-byte allocation in kmalloc-192.
Relevant stack trace:
iterate_iovec (include/linux/iov_iter.h:49)
__copy_from_iter (lib/iov_iter.c:261)
copy_folio_from_iter_atomic (lib/iov_iter.c:491)
generic_perform_write (mm/filemap.c:4392)
ext4_buffered_write_iter (fs/ext4/file.c:354)
ext4_file_write_iter (fs/ext4/file.c:794)
vfs_writev (fs/read_write.c:1058)
do_writev (fs/read_write.c:1104)
The reproducer mounts an ext4 image, opens a file, performs write operations,
and triggers the crash through writev() with a crafted iovec array.
Full reproducer:
# {Threaded:false Repeat:false RepeatTimes:0 Procs:1 Slowdown:1 Sandbox: SandboxArg:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false NicVF:false USB:false VhciInjection:false Wifi:false IEEE802154:false Sysctl:false Swap:false UseTmpDir:false HandleSegv:false Trace:false CallComments:true LegacyOptions:{Collide:false Fault:false FaultCall:0 FaultNth:0}}
syz_mount_image$ext4(&(0x7f0000000540)='ext4\x00', &(0x7f0000000580)='./file0\x00', 0x0, &(0x7f00000005c0), 0x1, 0x50d, &(0x7f0000000600)="$eJzs3F9oVNkZAPDvTv4YE9ukrS1V+pBiaQNqYpKpoWChgVIKlWLVh9L2JZg/hk6MNVGMpbSVQvWhD4W+tbT42qfQCqXtw+7Kwj7sg8uu7JOssPuy6xIiq/uyIrPcOzNqzCQxJuayzu8HZ+ac4x3PN3Pynblz4N4AGlZ3+pBE7IiIGxHRWWkuPaC78nR5cP5kWpIol48tJtlxZwfnT9YOrb2uI30oRLRFxLWLSez9w/JxZ+Yu/HKkVBo7U233zU6d7puZu7B/cmpkYmxi7FRxYGDoYLFYLA5t2nvtu3N+ouOlw/3/PXF76pvf/t/RJL6Xve944n1slu7oXvpZVjUnEb2bPVjOvvxYPWnOMRCe2m9Lc9ubIuJLEbEny//OaIrK5D348y8+6owPP1nptf//9d8/2MpYgc1XLndmZQV3ysALqxDpuX9S6K2csseOKBR6eyvn8DujvVCanpndOz599tRo5TdCV7QUxidLYweqvxW6oiVJ2/1Z/VF74In2YER8ISIuNW3P2r0npkujW7vUAVU7It75969OtHaskP+pm015Rwk8D2n+j/+l6Xdp/Z48h4aS5v8/7039KOQ/NBz5D41L/kPjkv/QuOQ/NC75D41L/kPjkv/QuOQ/NK5a/j+8DldFRaXhKnmvQwDA1iuXk8j7GmQgHyv/NMh7ZQKet/a7zXH8sXahep+OQrV8PSK7I1haH4yI1ohoiogHUbm/X5KeQ+QYP/Bstp354628YwAAAAAAAAAAAAAAAADWdnZw/mStbNWYo69t1UisZGG4coFnOu+Xq6XyL83ZNZ8RbdGSXSeaZNeB1iTV60I3YvF6RHeUFm/+6+qf0hLVv8MN/rd8Rsy/m3cE5Km1mHcE5Gn3T/KOgDxdv5R3BOTprYW8IyBPR4/lHQF5+vHBvCMgT39dzDsCXh6OiH319v8K8ZXsuS17fHL/pyMi2xfaiCOvR3TH6P3H+5bv/xRub3AYVrEwHHEoIi4v2/8r1A7paqq2Ppc2oiUZnyyNHYiIz0dET7RsS9v9q4zx/vSb5+r1H/tbOv8/763t/6UlHb+2F1iN43bztqWvGx2ZHdno+6Zi4fcRu5vrzX8t39uyvd72u4Vl+79d1ee07FxljBvtX9tTr//ccDr/r/SsPv88T+UrEd+qm//Jw2PSWt/s1Om+mbkL+yenRibGJsZOFQcGhg4Wi8XiUF+2HvTVVoXl3vvqP75Tr/+N++n8H7pq/vOT5n/76vOfrf+Pbg68/jF++Oo3dtXr/80P0vm/9fGzrP+tyfEswNZq3/mR2dkz/RGtyeHl/QPrj/lFVfs8ap9XOv89e+p//38xe66t/81L1v/13Cf2Pz878v16sVzszb7/98n//KTzP7pG/idL8n/9le/OvD1Xb+xdV9L5v/bTtfO/mAXTU+1x/re2p52gvOMEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACARvJpAAAA//+F6yev")
r0 = openat(0xffffffffffffff9c, &(0x7f0000000100)='./file1\x00', 0x125082, 0x145)
write$sequencer(r0, &(0x7f0000000c00)=ANY=[], 0xfe00)
r1 = openat(0xffffffffffffff9c, &(0x7f0000000100)='./file1\x00', 0xe502, 0x145)
writev(r1, &(0x7f0000000ec0)=[{0x0}, {&(0x7f0000000840)="586b0859f4af95118770", 0xa}, {&(0x7f00000009c0)="8ba6b3ff28e1552261532a8638589a01ca943d1b338821b188f6fde1a219b32ce19f8a192be9a4cbfdaecab1b63dd528fd2a7b599fb7fda779c1bcdd4cc19869a665aec8de9cf096226d5a2eb4dbfc3a2cacb0deb4a2f7ed94b6df317a9e3d7006cea5b4b74a6aa99d29e3b44743df80dcf0410bea753e08ea154402b9fc39c75ab138acbc6b78db0573b64f403e9936bcc0d5711e4b251bbaba470b70ec40969d972815b551b8ec8a044571ef208f09e1c5a579cd099f92abbb9a91f04388779aabd0597f60fd3be4dd7ec5146d835a4e19bcbfde95601fe01e774a6c7f4ef1ec9187c539e1dcf0dfd16aecd883346646e2e61e3219ecce73aa675cf8b565b0e14b248867f5e294c66cc9fe0a5ddd210f6aa39cddcc53f8090d16a68e48ab4dd031081d884001a4f3c22a9c89a13ad23452176831bdce107ab98953a8eae184b620b3aa38571bb9fc3184dbd19f2a9ae40a43954989e99aebc611b8a8ac18296adee0fd174bdba86721352647a259d3457f739b041bb27fb275a5a5359e497ed1477ff9f2be119278ad4385c7798ec6c9a677906a1fa3b1fde811a7a19bfb04d5a48941c30f8025bbef8a7535b3253b79b34cc2994906dc16e4c58acad1ceaacb3d6e6768ef349ea1729186e0a7128c61099927b0aa3920a3f26721aad8ca608faf2807c2c14cb203acad936b55b203dd6bee003597efc5ee82bce06cad5fe49aa3f43f779d2145c2233f79e369f07ad7a17e765326240a23101f3c770144687a7fca1ed59daf2ab4ec957ba25df7d26c59fd2d0f5524b5336b8a908fedac32413f35ae0b9a5cd6320dbb5869a822af03e21ba13265d86272823ead509786b64198096b779eab4aee154c491142ade2bea7fa138639fc639f6503d740fbce3b73d0999f85a8e7af2e7d265be30ac747a84da01eb0ef658a54358b8f4760e2352b776f552d5ab5c51f5816c6829dd527b185833ee4bafc14db9a21041473242c0a1f68040c03f2a306fa980ccdaa52aa9a0c4859dca6f81eb4e5754a821a6e6c3d99b5559328853e945a42a85f430e872164204652e7dd076c4ab71e80abeb509a0681a352ee837aca34f3ab01fbb740a93f1cc1481730cd005db430bd6ce18a25a8fbfed6506108e8a1d534aafa5c9281373ea9b435bd8f492c3702faf04fe364f31f360fec4503879d576314c353f315285e67c8f869d0809a6ab40dcf5804fb276b829714f99ece3b81490a2eb99521e535e738ca97b55804bcda92bc907e14c6c5825487ddf026c9018c787acd028d8a38ca5d53b86169b7d0cf46c48f7e675bf7d876cca862bcd8115c2f72fac73f6f0db8de16f5a18c3110bf729ac7400591839b89bf63643610c168a76d466aab7eba6c20be83a419aba0ceab172824f21a063a17ee3971ccf86a3cc410e03813b42a207536da", 0x3f7}, {0x0}, {0x0}, {0x0}, {0x0}, {0x0}, {0x0}], 0x9)
Best regards,
Haocheng Yu
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [BUG] KASAN: slab-out-of-bounds Read in copy_folio_from_iter_atomic
2026-10-18 8:12 [BUG] KASAN: slab-out-of-bounds Read in copy_folio_from_iter_atomic l1za0.sec
@ 2026-10-19 1:37 ` Andrew Morton
0 siblings, 0 replies; 2+ messages in thread
From: Andrew Morton @ 2026-10-19 1:37 UTC (permalink / raw)
To: l1za0.sec
Cc: viro, linux-block, linux-fsdevel, linux-kernel, Jens Axboe,
Tal Zussman, Daehyeon Ko, Keith Busch, Christoph Hellwig
On Sun, 18 Oct 2026 16:12:03 +0800 l1za0.sec@gmail.com wrote:
> From: Haocheng Yu <l1za0.sec@gmail.com>
>
> Hi,
>
> We found a KASAN slab-out-of-bounds read in copy_folio_from_iter_atomic() while
> fuzzing Linux with a modified version of syzkaller. We couldn't find a report
> of the same issue on syzbot. We are investigating the root cause and trying to
> develop a fix. Could you let us know whether this issue warrants a fix?
>
> The crash occurs on Linux v7.3.0-rc5. KASAN reports an 8-byte read 8 bytes past
> a 144-byte allocation in kmalloc-192.
>
> Relevant stack trace:
>
> iterate_iovec (include/linux/iov_iter.h:49)
> __copy_from_iter (lib/iov_iter.c:261)
> copy_folio_from_iter_atomic (lib/iov_iter.c:491)
> generic_perform_write (mm/filemap.c:4392)
> ext4_buffered_write_iter (fs/ext4/file.c:354)
> ext4_file_write_iter (fs/ext4/file.c:794)
> vfs_writev (fs/read_write.c:1058)
> do_writev (fs/read_write.c:1104)
>
> The reproducer mounts an ext4 image, opens a file, performs write operations,
> and triggers the crash through writev() with a crafted iovec array.
tl;dr: bug in bio_iov_iter_get_pages().
Thanks. Boy I burned a lot of tokens on this.
I was able to reproduce this. I found that Daehyeon's "iov_iter:
validate extracted segment for bvec alignment" makes the KASAN warnings
go away. https://lore.kernel.org/20261015061907.2713943-1-4ncienth@gmail.com
Daehyeon's patch is presently in mm.git's mm-unstable branch, with
cc:stable, targeted for upstreaming during the second week of the merge
window.
Daehyeon's patch prevents this reproducer from triggering the bug by
rejecting the misaligned direct-I/O request before extraction advances
the iterator. Without that check, extraction skips the initial empty
iovec and the following 10-byte segment, then encounters an alignment
error. The bio is discarded, but the iterator remains advanced. iomap
subsequently restores its byte count without restoring its position,
leaving 1025 bytes recorded when only 1015 remain. Buffered-I/O
fallback then walks beyond the imported iovec array. So Daehyeon's
patch avoids the bad path, but doesn't address the underlying failure
to restore the iterator when rejecting a bio.
Tal Zussman's atomic-write fixes also change the rejected-bio handling
in bio_iov_iter_get_pages(). In particular, his partial-pin fix
rejects an atomic bio rather than allowing a short atomic write to be
submitted. That introduces another cleanup path on which the iterator
may already have advanced. The rollback should therefore cover that
path as well, preferably through the common cleanup label in Tal's
version. The two fixes address different problems and are
complementary, but their error handling needs to be reconciled when
both are merged.
Proposed fix:
From: Andrew Morton <akpm@linux-foundation.org>
Subject: block: restore the iterator when rejecting a misaligned bio
Date: Sun, 18 Oct 2026 17:30:00 -0700
bio_iov_iter_get_pages() can extract some iovecs before encountering a
misaligned one. It releases the pages and rejects the entire bio, but
leaves the supplied iterator advanced.
An iomap direct-I/O caller may subsequently reexpand the iterator's
byte count and fall back to buffered I/O. The reexpanded count then
includes bytes before the iterator's current segment, potentially
causing iterate_iovec() to read beyond the imported iovec array.
In a reproducer using an initial empty iovec followed by 10-byte and
1015-byte segments, writev() returned 1015 instead of 1025 and KASAN
reported an 8-byte read beyond the nine-element iovec allocation.
Saving and restoring the iterator on the rejected-bio path makes
writev() return 1025 and eliminates the KASAN report.
Restore the entire iterator rather than reverting a byte count:
advancing past an empty segment changes its position without consuming
any bytes.
Leave successful and partially accepted bio paths unchanged.
Fixes: 14b007e17881 ("block: validate user space vectors during extraction")
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Haocheng Yu <l1za0.sec@gmail.com>
Closes: https://lore.kernel.org/20261018081203.2431035-1-l1za0.sec@gmail.com
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Keith Busch <kbusch@kernel.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Tal Zussman <tz2294@columbia.edu>
Cc: Daehyeon Ko <4ncienth@gmail.com>
Cc: <stable@vger.kernel.org>
---
Testing on x86-64 QEMU/KVM with generic KASAN:
- Before: the ext4 writev() reproducer returned 1015 instead of 1025
and triggered an 8-byte slab out-of-bounds read.
- After: 100 consecutive reproducer runs returned 1025 without KASAN;
60-second buffered and direct ext4 fio runs passed.
- Daehyeon's alignment patch independently avoids the reproducer.
Tal Zussman's pending atomic-write changes introduce another rejected-bio
cleanup path. If both patches are combined, restore the iterator there too.
---
block/bio.c | 3 +++
1 file changed, 3 insertions(+)
--- a/block/bio.c~bio-iov-iter-rollback
+++ a/block/bio.c
@@ -1285,6 +1285,7 @@ int bio_iov_iter_get_pages(struct bio *b
unsigned mem_align_mask, unsigned len_align_mask)
{
iov_iter_extraction_t flags = 0;
+ struct iov_iter saved_iter;
if (WARN_ON_ONCE(bio_flagged(bio, BIO_CLONED)))
return -EIO;
@@ -1303,6 +1304,7 @@ int bio_iov_iter_get_pages(struct bio *b
if (bio->bi_bdev && blk_queue_pci_p2pdma(bio->bi_bdev->bd_disk->queue))
flags |= ITER_ALLOW_P2PDMA;
+ saved_iter = *iter;
do {
ssize_t ret;
@@ -1320,6 +1322,7 @@ int bio_iov_iter_get_pages(struct bio *b
bio_release_pages(bio, false);
bio_clear_flag(bio, BIO_PAGE_PINNED);
bio->bi_vcnt = 0;
+ *iter = saved_iter;
}
if (!bio->bi_vcnt)
return ret;
_
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-10-19 1:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-18 8:12 [BUG] KASAN: slab-out-of-bounds Read in copy_folio_from_iter_atomic l1za0.sec
2026-10-19 1:37 ` Andrew Morton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®