From: syzbot <syzbot+175753aff92b396b1f30@syzkaller.appspotmail.com>
To: kapoorarnav43@gmail.com
Cc: kapoorarnav43@gmail.com, linux-kernel@vger.kernel.org,
syzkaller-bugs@googlegroups.com
Subject: Re: Private message regarding: [syzbot] [fs?] KMSAN: kernel-infoleak-after-free in anon_pipe_read
Date: Mon, 12 Jan 2026 01:44:47 -0800 [thread overview]
Message-ID: <6964c28f.050a0220.eaf7.0099.GAE@google.com> (raw)
In-Reply-To: <e3d876de-cee9-457c-bbde-648e3507ba63n@googlegroups.com>
> From: Arnav Kapoor <kapoorarnav43@gmail.com>
> Date: Sun, 12 Jan 2026 16:45:00 +0000
> Subject: [PATCH] mm/zswap: clear folio before decompression to prevent
> infoleak
>
> #syz test
>
> KMSAN reported an infoleak in anon_pipe_read() where uninitialized memory
> from a decompressed zswap page was copied to userspace:
>
> BUG: KMSAN: kernel-infoleak-after-free in anon_pipe_read+0x769/0x1e80
> Uninit was stored to memory at:
> zswap_decompress+0x2bd/0x1000 mm/zswap.c:946
> Bytes 0-1023 of 1024 are uninitialized
>
> The issue occurs when zswap decompresses a page but the decompression
> doesn't write a full PAGE_SIZE of data. The function zswap_decompress()
> writes decompressed data directly into the folio without first clearing
> it. If the decompressed size is less than PAGE_SIZE (which can happen
> with certain compression algorithms or corrupted data), or if
> decompression fails partway through, the remainder of the page contains
> uninitialized memory.
>
> This uninitialized data can then:
> 1. Be placed in pipe buffers when the page is used in splice operations
> 2. Get copied to userspace via read() on the pipe
> 3. Leak kernel memory contents to userspace
>
> The call chain observed:
> zswap_load()
> -> zswap_decompress() [writes partial data to folio]
> -> [folio ends up in pipe buffer via shmem_file_splice_read]
> -> anon_pipe_read()
> -> copy_page_to_iter() [copies uninitialized tail to userspace]
>
> Fix this by clearing the entire folio before decompression. This ensures
> that even if decompression writes less than PAGE_SIZE, or fails after
> partial write, the remainder of the page contains zeros rather than
> uninitialized memory.
>
> We use folio_zero_range() which is efficient as it can use optimized
> memset implementations and handles compound pages correctly.
>
> Alternative approaches considered:
> 1. Zero only the tail after decompression - more complex, requires
> tracking actual bytes written, and doesn't help if decompression fails
> 2. Check dlen and zero tail only when dlen < PAGE_SIZE - still leaves
> a race if decompression fails after partial write
>
> The performance impact is minimal since:
> - This is a relatively rare path (swap-in from zswap)
> - Modern CPUs have efficient memory zeroing (often using cache-bypassing
> instructions)
> - The cost is much less than the decompression itself
>
> Reported-by: syzbot+175753aff92b396b1f30@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=175753aff92b396b1f30
> Fixes: 0ab0abcf5115 ("mm/zswap: remove the memcpy if acomp is not
> sleepable")
> Signed-off-by: Arnav Kapoor <kapoorarnav43@gmail.com>
> ---
> mm/zswap.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/mm/zswap.c b/mm/zswap.c
> index 000000000000..111111111111 100644
> --- a/mm/zswap.c
> +++ b/mm/zswap.c
> @@ -932,6 +932,13 @@ static bool zswap_decompress(struct zswap_entry
> *entry, struct folio *folio)
> int decomp_ret = 0, dlen = PAGE_SIZE;
> u8 *src, *obj;
> + /*
> + * Clear the folio before decompression to prevent leaking uninitialized
> + * memory to userspace if decompression writes less than PAGE_SIZE or
> + * fails partway through.
> + */
> + folio_zero_range(folio, 0, folio_size(folio));
> +
> acomp_ctx = acomp_ctx_get_cpu_lock(pool);
> obj = zs_obj_read_begin(pool->zs_pool, entry->handle, acomp_ctx->buffer);
> --
> 2.43.0
>
>
>
>
> On Monday, 12 January 2026 at 14:05:27 UTC+5:30 syzbot wrote:
>
> Hello,
>
> syzbot found the following issue on:
>
> HEAD commit: 7f98ab9da046 Merge tag 'for-6.19-rc4-tag' of git://git.ker..
> git tree: upstream
> console output: https://syzkaller.appspot.com/x/log.txt?x=1334af92580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=b3903bdf68407a14
> dashboard link: https://syzkaller.appspot.com/bug?extid=175753aff92b396b1f30
> compiler: Debian clang version 20.1.8
> (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD
> 20.1.8
> userspace arch: i386
>
> Unfortunately, I don't have any reproducer for this issue yet.
>
> Downloadable assets:
> disk image:
> https://storage.googleapis.com/syzbot-assets/c40942ffda39/disk-7f98ab9d.raw.xz
> vmlinux:
> https://storage.googleapis.com/syzbot-assets/63f72388d8d6/vmlinux-7f98ab9d.xz
> kernel image:
> https://storage.googleapis.com/syzbot-assets/751895685a54/bzImage-7f98ab9d.xz
>
> IMPORTANT: if you fix the issue, please add the following tag to the
> commit:
> Reported-by: syzbot+175753...@syzkaller.appspotmail.com
>
> =====================================================
> BUG: KMSAN: kernel-infoleak-after-free in instrument_copy_to_user
> include/linux/instrumented.h:114 [inline]
> BUG: KMSAN: kernel-infoleak-after-free in copy_to_user_iter
> lib/iov_iter.c:24 [inline]
> BUG: KMSAN: kernel-infoleak-after-free in iterate_ubuf
> include/linux/iov_iter.h:30 [inline]
> BUG: KMSAN: kernel-infoleak-after-free in iterate_and_advance2
> include/linux/iov_iter.h:302 [inline]
> BUG: KMSAN: kernel-infoleak-after-free in iterate_and_advance
> include/linux/iov_iter.h:330 [inline]
> BUG: KMSAN: kernel-infoleak-after-free in _copy_to_iter+0xef3/0x33f0
> lib/iov_iter.c:197
> instrument_copy_to_user include/linux/instrumented.h:114 [inline]
> copy_to_user_iter lib/iov_iter.c:24 [inline]
> iterate_ubuf include/linux/iov_iter.h:30 [inline]
> iterate_and_advance2 include/linux/iov_iter.h:302 [inline]
> iterate_and_advance include/linux/iov_iter.h:330 [inline]
> _copy_to_iter+0xef3/0x33f0 lib/iov_iter.c:197
> copy_page_to_iter+0x482/0x910 lib/iov_iter.c:374
> anon_pipe_read+0x769/0x1e80 fs/pipe.c:343
> new_sync_read fs/read_write.c:491 [inline]
> vfs_read+0x8ed/0xf90 fs/read_write.c:572
> ksys_read fs/read_write.c:715 [inline]
> __do_sys_read fs/read_write.c:724 [inline]
> __se_sys_read fs/read_write.c:722 [inline]
> __ia32_sys_read+0x1f9/0x4d0 fs/read_write.c:722
> ia32_sys_call+0x191f/0x4340 arch/x86/include/generated/asm/syscalls_32.h:4
> do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:83 [inline]
> __do_fast_syscall_32+0x154/0x320 arch/x86/entry/syscall_32.c:307
> do_fast_syscall_32+0x38/0x80 arch/x86/entry/syscall_32.c:332
> do_SYSENTER_32+0x1f/0x30 arch/x86/entry/syscall_32.c:370
> entry_SYSENTER_compat_after_hwframe+0x84/0x8e
>
> Uninit was stored to memory at:
> memcpy_to_folio include/linux/highmem.h:518 [inline]
> zswap_decompress+0x2bd/0x1000 mm/zswap.c:946
> zswap_load+0x262/0x570 mm/zswap.c:1627
> swap_read_folio+0x662/0x3050 mm/page_io.c:637
> swap_cluster_readahead+0x725/0xb20 mm/swap_state.c:652
> shmem_swapin_cluster mm/shmem.c:1745 [inline]
> shmem_swapin_folio+0x1fd9/0x3ee0 mm/shmem.c:2329
> shmem_get_folio_gfp+0x92a/0x1fc0 mm/shmem.c:2489
> shmem_get_folio mm/shmem.c:2662 [inline]
> shmem_file_splice_read+0x350/0x11e0 mm/shmem.c:3567
> do_splice_read fs/splice.c:982 [inline]
> splice_file_to_pipe+0x5b4/0x8f0 fs/splice.c:1292
> do_splice+0x29d8/0x30d0 fs/splice.c:1376
> __do_splice fs/splice.c:1433 [inline]
> __do_sys_splice fs/splice.c:1636 [inline]
> __se_sys_splice+0x549/0x8c0 fs/splice.c:1618
> __ia32_sys_splice+0x112/0x1a0 fs/splice.c:1618
> ia32_sys_call+0x31a6/0x4340
> arch/x86/include/generated/asm/syscalls_32.h:314
> do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:83 [inline]
> __do_fast_syscall_32+0x154/0x320 arch/x86/entry/syscall_32.c:307
> do_fast_syscall_32+0x38/0x80 arch/x86/entry/syscall_32.c:332
> do_SYSENTER_32+0x1f/0x30 arch/x86/entry/syscall_32.c:370
> entry_SYSENTER_compat_after_hwframe+0x84/0x8e
>
> Uninit was created at:
> free_pages_prepare mm/page_alloc.c:1328 [inline]
> free_unref_folios+0x26a/0x29a0 mm/page_alloc.c:3000
> folios_put_refs+0xaac/0xb10 mm/swap.c:1002
> folios_put include/linux/mm.h:1671 [inline]
> __folio_batch_release+0xe1/0x100 mm/swap.c:1062
> folio_batch_release include/linux/pagevec.h:101 [inline]
> shmem_undo_range+0x929/0x20c0 mm/shmem.c:1137
> shmem_truncate_range mm/shmem.c:1249 [inline]
> shmem_evict_inode+0x22c/0xed0 mm/shmem.c:1379
> evict+0x6a9/0xca0 fs/inode.c:837
> iput_final fs/inode.c:1951 [inline]
> iput+0xc6f/0x1070 fs/inode.c:2003
> do_unlinkat+0x58a/0xd80 fs/namei.c:5443
> __do_sys_unlink fs/namei.c:5474 [inline]
> __se_sys_unlink fs/namei.c:5472 [inline]
> __ia32_sys_unlink+0x70/0xa0 fs/namei.c:5472
> ia32_sys_call+0x1e4a/0x4340 arch/x86/include/generated/asm/syscalls_32.h:11
> do_syscall_32_irqs_on arch/x86/entry/syscall_32.c:83 [inline]
> __do_fast_syscall_32+0x154/0x320 arch/x86/entry/syscall_32.c:307
> do_fast_syscall_32+0x38/0x80 arch/x86/entry/syscall_32.c:332
> do_SYSENTER_32+0x1f/0x30 arch/x86/entry/syscall_32.c:370
> entry_SYSENTER_compat_after_hwframe+0x84/0x8e
>
> Bytes 0-1023 of 1024 are uninitialized
> Memory access of size 1024 starts at ffff8880731d2000
> Data copied to user address 0000000056912be0
>
> CPU: 1 UID: 0 PID: 5779 Comm: syz-executor Tainted: G W syzkaller #0
> PREEMPT(none)
> Tainted: [W]=WARN
> Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
> Google 10/25/2025
> =====================================================
>
>
> ---
> This report is generated by a bot. It may contain errors.
> See https://goo.gl/tpsmEJ for more information about syzbot.
> syzbot engineers can be reached at syzk...@googlegroups.com.
>
> syzbot will keep track of this issue. See:
> https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
>
> If the report is already addressed, let syzbot know by replying with:
> #syz fix: exact-commit-title
>
> If you want to overwrite report's subsystems, reply with:
> #syz set subsystems: new-subsystem
> (See the list of subsystem names on the web dashboard)
>
> If the report is a duplicate of another one, reply with:
> #syz dup: exact-subject-of-another-report
>
> If you want to undo deduplication, reply with:
> #syz undup
>
Command #1:
This crash does not have a reproducer. I cannot test it.
next parent reply other threads:[~2026-01-12 9:44 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <e3d876de-cee9-457c-bbde-648e3507ba63n@googlegroups.com>
2026-01-12 9:44 ` syzbot [this message]
[not found] <6dacd12e-19c1-4a11-9b38-70c07dca17d5n@googlegroups.com>
2026-01-12 10:00 ` Private message regarding: [syzbot] [fs?] KMSAN: kernel-infoleak-after-free in anon_pipe_read syzbot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6964c28f.050a0220.eaf7.0099.GAE@google.com \
--to=syzbot+175753aff92b396b1f30@syzkaller.appspotmail.com \
--cc=kapoorarnav43@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=syzkaller-bugs@googlegroups.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.