Skip to contentSkip to conversation

KMSAN: use-after-free in sw842_decompress (zswap writeback)

DISCUSSION dane phillips 1 participant 3 messages Jul 30 – Aug 2

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hi,

I am running syzkaller on commit 3dab139d4795 and it reported the use-after-free below. The issue occurs when zswap writeback decompresses a page that has already been freed by process exit.

Kernel version: 7.2.0-rc4-00503-g3dab139d4795
Config: CONFIG_KMSAN=y, CONFIG_ZSWAP=y, CONFIG_CRYPTO_842=y

The bug manifests in sw842_decompress accessing memory that was freed in exit_mmap, while the shrinker is still walking the zswap pool.

BUG: KMSAN: use-after-free in sw842_decompress+0x11c8/0x1750
lib/842/842_decompress.c:303
 sw842_decompress+0x11c8/0x1750 lib/842/842_decompress.c:303
 crypto842_sdecompress+0x46/0x60 crypto/842.c:53
 scomp_acomp_comp_decomp+0xa49/0x1120 include/crypto/internal/scompress.h:-1
 scomp_acomp_decompress+0x30/0x40 crypto/scompress.c:283
 crypto_acomp_decompress+0x5c4/0xe50 crypto/acompress.c:297
 zswap_decompress+0x4ba/0xcc0 mm/zswap.c:952
 zswap_writeback_entry mm/zswap.c:1032 [inline]
 shrink_memcg_cb+0x78f/0xda0 mm/zswap.c:1147
 __list_lru_walk_one+0x49a/0xde0 mm/list_lru.c:362
 list_lru_walk_one+0x5c/0x70 mm/list_lru.c:399
 list_lru_shrink_walk include/linux/list_lru.h:332 [inline]
 zswap_shrinker_scan+0x11f/0x290 mm/zswap.c:1181
 do_shrink_slab+0x736/0x1460 mm/shrinker.c:443
 shrink_slab_memcg mm/shrinker.c:560 [inline]
 shrink_slab+0xb70/0x14c0 mm/shrinker.c:638
 shrink_one+0x560/0xc10 mm/vmscan.c:5026
 shrink_many mm/vmscan.c:5087 [inline]
 lru_gen_shrink_node mm/vmscan.c:5165 [inline]
 shrink_node+0x47a5/0x5b70 mm/vmscan.c:6154
 kswapd_shrink_node mm/vmscan.c:7008 [inline]
 balance_pgdat mm/vmscan.c:7186 [inline]
 kswapd+0x3029/0x5a50 mm/vmscan.c:7462
 kthread+0x53f/0x600 kernel/kthread.c:436
 ret_from_fork+0x20f/0x8d0 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Uninit was stored to memory at:

 sw842_decompress+0x11c1/0x1750 lib/842/842_decompress.c:303
 crypto842_sdecompress+0x46/0x60 crypto/842.c:53
 scomp_acomp_comp_decomp+0xa49/0x1120 include/crypto/internal/scompress.h:-1
 scomp_acomp_decompress+0x30/0x40 crypto/scompress.c:283
 crypto_acomp_decompress+0x5c4/0xe50 crypto/acompress.c:297
 zswap_decompress+0x4ba/0xcc0 mm/zswap.c:952
 zswap_writeback_entry mm/zswap.c:1032 [inline]
 shrink_memcg_cb+0x78f/0xda0 mm/zswap.c:1147
 __list_lru_walk_one+0x49a/0xde0 mm/list_lru.c:362
 list_lru_walk_one+0x5c/0x70 mm/list_lru.c:399
 list_lru_shrink_walk include/linux/list_lru.h:332 [inline]
 zswap_shrinker_scan+0x11f/0x290 mm/zswap.c:1181
 do_shrink_slab+0x736/0x1460 mm/shrinker.c:443
 shrink_slab_memcg mm/shrinker.c:560 [inline]
 shrink_slab+0xb70/0x14c0 mm/shrinker.c:638
 shrink_one+0x560/0xc10 mm/vmscan.c:5026
 shrink_many mm/vmscan.c:5087 [inline]
 lru_gen_shrink_node mm/vmscan.c:5165 [inline]
 shrink_node+0x47a5/0x5b70 mm/vmscan.c:6154
 kswapd_shrink_node mm/vmscan.c:7008 [inline]
 balance_pgdat mm/vmscan.c:7186 [inline]
 kswapd+0x3029/0x5a50 mm/vmscan.c:7462
 kthread+0x53f/0x600 kernel/kthread.c:436
 ret_from_fork+0x20f/0x8d0 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Uninit was stored to memory at:

 next_bits+0xac2/0xda0 lib/842/842_decompress.c:118
 sw842_decompress+0x1a6/0x1750 lib/842/842_decompress.c:297
 crypto842_sdecompress+0x46/0x60 crypto/842.c:53
 scomp_acomp_comp_decomp+0xa49/0x1120 include/crypto/internal/scompress.h:-1
 scomp_acomp_decompress+0x30/0x40 crypto/scompress.c:283
 crypto_acomp_decompress+0x5c4/0xe50 crypto/acompress.c:297
 zswap_decompress+0x4ba/0xcc0 mm/zswap.c:952
 zswap_writeback_entry mm/zswap.c:1032 [inline]
 shrink_memcg_cb+0x78f/0xda0 mm/zswap.c:1147
 __list_lru_walk_one+0x49a/0xde0 mm/list_lru.c:362
 list_lru_walk_one+0x5c/0x70 mm/list_lru.c:399
 list_lru_shrink_walk include/linux/list_lru.h:332 [inline]
 zswap_shrinker_scan+0x11f/0x290 mm/zswap.c:1181
 do_shrink_slab+0x736/0x1460 mm/shrinker.c:443
 shrink_slab_memcg mm/shrinker.c:560 [inline]
 shrink_slab+0xb70/0x14c0 mm/shrinker.c:638
 shrink_one+0x560/0xc10 mm/vmscan.c:5026
 shrink_many mm/vmscan.c:5087 [inline]
 lru_gen_shrink_node mm/vmscan.c:5165 [inline]
 shrink_node+0x47a5/0x5b70 mm/vmscan.c:6154
 kswapd_shrink_node mm/vmscan.c:7008 [inline]
 balance_pgdat mm/vmscan.c:7186 [inline]
 kswapd+0x3029/0x5a50 mm/vmscan.c:7462
 kthread+0x53f/0x600 kernel/kthread.c:436
 ret_from_fork+0x20f/0x8d0 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Uninit was created at:

 __free_pages_prepare mm/page_alloc.c:1327 [inline]
 free_unref_folios+0x280/0x2880 mm/page_alloc.c:3011
 folios_put_refs+0xb2e/0xba0 mm/swap.c:1057
 free_pages_and_swap_cache+0x804/0x840 mm/swap_state.c:589
 __tlb_batch_free_encoded_pages mm/mmu_gather.c:138 [inline]
 tlb_batch_pages_flush mm/mmu_gather.c:151 [inline]
 tlb_flush_mmu_free mm/mmu_gather.c:417 [inline]
 tlb_flush_mmu+0x92b/0xe90 mm/mmu_gather.c:424
 zap_pte_range mm/memory.c:1973 [inline]
 zap_pmd_range mm/memory.c:2020 [inline]
 zap_pud_range mm/memory.c:2048 [inline]
 zap_p4d_range mm/memory.c:2069 [inline]
 __zap_vma_range+0x763f/0x9340 mm/memory.c:2109
 unmap_vmas+0x440/0x800 mm/memory.c:2178
 exit_mmap+0x27c/0xac0 mm/mmap.c:1300
 __mmput+0x134/0x650 kernel/fork.c:1187
 mmput+0x74/0x90 kernel/fork.c:1210
 exit_mm+0x2b1/0x4b0 kernel/exit.c:615
 do_exit+0x9a9/0x3c30 kernel/exit.c:997
 do_group_exit+0x258/0x390 kernel/exit.c:1152
 __do_sys_exit_group kernel/exit.c:1163 [inline]
 __se_sys_exit_group kernel/exit.c:1161 [inline]
 __x64_sys_exit_group+0x35/0x40 kernel/exit.c:1161
 x64_sys_call+0x3e6d/0x3ea0 arch/x86/include/generated/asm/syscalls_64.h:232
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x15d/0x3c0 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

CPU: 0 UID: 0 PID: 81 Comm: kswapd0 Tainted: G        W
7.2.0-rc4-00503-g3dab139d4795 #9 PREEMPT(lazy)
Tainted: [W]=WARN
Hardware name: QEMU Ubuntu 26.04 PC (i440FX + PIIX, 1996), BIOS

1.17.0-debian-1.17.0-1ubuntu1 04/01/2014
=====================================================

The full syzkaller log is available if needed. I do not yet have a reliable reproducer.

Thanks,

Dane Phillips

#1 lore raw

I got the mechanism wrong in my first mail, correcting before anyone wastes time on it.

I read the "Uninit was created at" chain as causal. It isn't. That chain just says where the page had been before the allocator handed it back out. exit_mmap has nothing to do with it and there's no race with process exit.

The poison is in the compressed input, not in a swapped-out page:

next_bits+0xac2 lib/842/842_decompress.c:118
sw842_decompress+0x1a6 lib/842/842_decompress.c:297 sw842_decompress+0x11c8 lib/842/842_decompress.c:303

297 is the opcode fetch, 303 uses it.

What I think is happening: zpool_obj_read_begin() copies exactly entry->length bytes into acomp_ctx->buffer, which is kmalloc'd and never zeroed, and sw842_decompress reads past entry->length into whatever was there before. next_bits() does full 8-byte loads while p->ilen >= 8, so entry->length not being a multiple of 8 looks like the trigger.

So the subject should be something like "KMSAN: uninit-value in sw842_decompress, over-read of compressed input past entry->length" rather than use-after-free.

Testing that now with kzalloc_node() for the buffer, plus a sweep of compressed lengths across residues mod 8. Also rerunning with lzo, zstd and deflate to see whether this is lib/842 or zswap's bounce buffer.

Two things I should have mentioned the first time: the kernel was already tainted W from an unrelated get_xsave_addr warning earlier in that boot, and the tree was 503 commits past 7.2.0-rc4. I'll redo it clean on mainline.

More once I have something.

Dane

Quoted 142 lines · dane phillips

Hi,

I am running syzkaller on commit 3dab139d4795 and it reported the use-after-free below. The issue occurs when zswap writeback decompresses a page that has already been freed by process exit.

Kernel version: 7.2.0-rc4-00503-g3dab139d4795
Config: CONFIG_KMSAN=y, CONFIG_ZSWAP=y, CONFIG_CRYPTO_842=y

The bug manifests in sw842_decompress accessing memory that was freed in exit_mmap, while the shrinker is still walking the zswap pool.

BUG: KMSAN: use-after-free in sw842_decompress+0x11c8/0x1750
lib/842/842_decompress.c:303
 sw842_decompress+0x11c8/0x1750 lib/842/842_decompress.c:303
 crypto842_sdecompress+0x46/0x60 crypto/842.c:53
 scomp_acomp_comp_decomp+0xa49/0x1120 include/crypto/internal/scompress.h:-1
 scomp_acomp_decompress+0x30/0x40 crypto/scompress.c:283
 crypto_acomp_decompress+0x5c4/0xe50 crypto/acompress.c:297
 zswap_decompress+0x4ba/0xcc0 mm/zswap.c:952
 zswap_writeback_entry mm/zswap.c:1032 [inline]
 shrink_memcg_cb+0x78f/0xda0 mm/zswap.c:1147
 __list_lru_walk_one+0x49a/0xde0 mm/list_lru.c:362
 list_lru_walk_one+0x5c/0x70 mm/list_lru.c:399
 list_lru_shrink_walk include/linux/list_lru.h:332 [inline]
 zswap_shrinker_scan+0x11f/0x290 mm/zswap.c:1181
 do_shrink_slab+0x736/0x1460 mm/shrinker.c:443
 shrink_slab_memcg mm/shrinker.c:560 [inline]
 shrink_slab+0xb70/0x14c0 mm/shrinker.c:638
 shrink_one+0x560/0xc10 mm/vmscan.c:5026
 shrink_many mm/vmscan.c:5087 [inline]
 lru_gen_shrink_node mm/vmscan.c:5165 [inline]
 shrink_node+0x47a5/0x5b70 mm/vmscan.c:6154
 kswapd_shrink_node mm/vmscan.c:7008 [inline]
 balance_pgdat mm/vmscan.c:7186 [inline]
 kswapd+0x3029/0x5a50 mm/vmscan.c:7462
 kthread+0x53f/0x600 kernel/kthread.c:436
 ret_from_fork+0x20f/0x8d0 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Uninit was stored to memory at:

 sw842_decompress+0x11c1/0x1750 lib/842/842_decompress.c:303
 crypto842_sdecompress+0x46/0x60 crypto/842.c:53
 scomp_acomp_comp_decomp+0xa49/0x1120 include/crypto/internal/scompress.h:-1
 scomp_acomp_decompress+0x30/0x40 crypto/scompress.c:283
 crypto_acomp_decompress+0x5c4/0xe50 crypto/acompress.c:297
 zswap_decompress+0x4ba/0xcc0 mm/zswap.c:952
 zswap_writeback_entry mm/zswap.c:1032 [inline]
 shrink_memcg_cb+0x78f/0xda0 mm/zswap.c:1147
 __list_lru_walk_one+0x49a/0xde0 mm/list_lru.c:362
 list_lru_walk_one+0x5c/0x70 mm/list_lru.c:399
 list_lru_shrink_walk include/linux/list_lru.h:332 [inline]
 zswap_shrinker_scan+0x11f/0x290 mm/zswap.c:1181
 do_shrink_slab+0x736/0x1460 mm/shrinker.c:443
 shrink_slab_memcg mm/shrinker.c:560 [inline]
 shrink_slab+0xb70/0x14c0 mm/shrinker.c:638
 shrink_one+0x560/0xc10 mm/vmscan.c:5026
 shrink_many mm/vmscan.c:5087 [inline]
 lru_gen_shrink_node mm/vmscan.c:5165 [inline]
 shrink_node+0x47a5/0x5b70 mm/vmscan.c:6154
 kswapd_shrink_node mm/vmscan.c:7008 [inline]
 balance_pgdat mm/vmscan.c:7186 [inline]
 kswapd+0x3029/0x5a50 mm/vmscan.c:7462
 kthread+0x53f/0x600 kernel/kthread.c:436
 ret_from_fork+0x20f/0x8d0 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Uninit was stored to memory at:

 next_bits+0xac2/0xda0 lib/842/842_decompress.c:118
 sw842_decompress+0x1a6/0x1750 lib/842/842_decompress.c:297
 crypto842_sdecompress+0x46/0x60 crypto/842.c:53
 scomp_acomp_comp_decomp+0xa49/0x1120 include/crypto/internal/scompress.h:-1
 scomp_acomp_decompress+0x30/0x40 crypto/scompress.c:283
 crypto_acomp_decompress+0x5c4/0xe50 crypto/acompress.c:297
 zswap_decompress+0x4ba/0xcc0 mm/zswap.c:952
 zswap_writeback_entry mm/zswap.c:1032 [inline]
 shrink_memcg_cb+0x78f/0xda0 mm/zswap.c:1147
 __list_lru_walk_one+0x49a/0xde0 mm/list_lru.c:362
 list_lru_walk_one+0x5c/0x70 mm/list_lru.c:399
 list_lru_shrink_walk include/linux/list_lru.h:332 [inline]
 zswap_shrinker_scan+0x11f/0x290 mm/zswap.c:1181
 do_shrink_slab+0x736/0x1460 mm/shrinker.c:443
 shrink_slab_memcg mm/shrinker.c:560 [inline]
 shrink_slab+0xb70/0x14c0 mm/shrinker.c:638
 shrink_one+0x560/0xc10 mm/vmscan.c:5026
 shrink_many mm/vmscan.c:5087 [inline]
 lru_gen_shrink_node mm/vmscan.c:5165 [inline]
 shrink_node+0x47a5/0x5b70 mm/vmscan.c:6154
 kswapd_shrink_node mm/vmscan.c:7008 [inline]
 balance_pgdat mm/vmscan.c:7186 [inline]
 kswapd+0x3029/0x5a50 mm/vmscan.c:7462
 kthread+0x53f/0x600 kernel/kthread.c:436
 ret_from_fork+0x20f/0x8d0 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Uninit was created at:

 __free_pages_prepare mm/page_alloc.c:1327 [inline]
 free_unref_folios+0x280/0x2880 mm/page_alloc.c:3011
 folios_put_refs+0xb2e/0xba0 mm/swap.c:1057
 free_pages_and_swap_cache+0x804/0x840 mm/swap_state.c:589
 __tlb_batch_free_encoded_pages mm/mmu_gather.c:138 [inline]
 tlb_batch_pages_flush mm/mmu_gather.c:151 [inline]
 tlb_flush_mmu_free mm/mmu_gather.c:417 [inline]
 tlb_flush_mmu+0x92b/0xe90 mm/mmu_gather.c:424
 zap_pte_range mm/memory.c:1973 [inline]
 zap_pmd_range mm/memory.c:2020 [inline]
 zap_pud_range mm/memory.c:2048 [inline]
 zap_p4d_range mm/memory.c:2069 [inline]
 __zap_vma_range+0x763f/0x9340 mm/memory.c:2109
 unmap_vmas+0x440/0x800 mm/memory.c:2178
 exit_mmap+0x27c/0xac0 mm/mmap.c:1300
 __mmput+0x134/0x650 kernel/fork.c:1187
 mmput+0x74/0x90 kernel/fork.c:1210
 exit_mm+0x2b1/0x4b0 kernel/exit.c:615
 do_exit+0x9a9/0x3c30 kernel/exit.c:997
 do_group_exit+0x258/0x390 kernel/exit.c:1152
 __do_sys_exit_group kernel/exit.c:1163 [inline]
 __se_sys_exit_group kernel/exit.c:1161 [inline]
 __x64_sys_exit_group+0x35/0x40 kernel/exit.c:1161
 x64_sys_call+0x3e6d/0x3ea0 arch/x86/include/generated/asm/syscalls_64.h:232
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x15d/0x3c0 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

CPU: 0 UID: 0 PID: 81 Comm: kswapd0 Tainted: G        W
7.2.0-rc4-00503-g3dab139d4795 #9 PREEMPT(lazy)
Tainted: [W]=WARN
Hardware name: QEMU Ubuntu 26.04 PC (i440FX + PIIX, 1996), BIOS

1.17.0-debian-1.17.0-1ubuntu1 04/01/2014
=====================================================

The full syzkaller log is available if needed. I do not yet have a reliable reproducer.

Thanks,

Dane Phillips

#2 lore raw

Retracting both of my earlier mails in this thread. There is no bug
here,
in zswap or in lib/842's input handling, and nobody should spend time
on it.

I could not reproduce the report; that trace should not have gone out and
I'm sorry for the noise.

Quoted 185 lines · dane phillips

I got the mechanism wrong in my first mail, correcting before anyone wastes time on it.

I read the "Uninit was created at" chain as causal. It isn't. That chain just says where the page had been before the allocator handed it back out. exit_mmap has nothing to do with it and there's no race with process exit.

The poison is in the compressed input, not in a swapped-out page:

next_bits+0xac2 lib/842/842_decompress.c:118
sw842_decompress+0x1a6 lib/842/842_decompress.c:297 sw842_decompress+0x11c8 lib/842/842_decompress.c:303

297 is the opcode fetch, 303 uses it.

What I think is happening: zpool_obj_read_begin() copies exactly entry->length bytes into acomp_ctx->buffer, which is kmalloc'd and never zeroed, and sw842_decompress reads past entry->length into whatever was there before. next_bits() does full 8-byte loads while p->ilen >= 8, so entry->length not being a multiple of 8 looks like the trigger.

So the subject should be something like "KMSAN: uninit-value in sw842_decompress, over-read of compressed input past entry->length" rather than use-after-free.

Testing that now with kzalloc_node() for the buffer, plus a sweep of compressed lengths across residues mod 8. Also rerunning with lzo, zstd and deflate to see whether this is lib/842 or zswap's bounce buffer.

Two things I should have mentioned the first time: the kernel was already tainted W from an unrelated get_xsave_addr warning earlier in that boot, and the tree was 503 commits past 7.2.0-rc4. I'll redo it clean on mainline.

More once I have something.

Dane

Quoted 142 lines · dane phillips

Hi,

I am running syzkaller on commit 3dab139d4795 and it reported the use-after-free below. The issue occurs when zswap writeback decompresses a page that has already been freed by process exit.

Kernel version: 7.2.0-rc4-00503-g3dab139d4795
Config: CONFIG_KMSAN=y, CONFIG_ZSWAP=y, CONFIG_CRYPTO_842=y

The bug manifests in sw842_decompress accessing memory that was freed in exit_mmap, while the shrinker is still walking the zswap pool.

BUG: KMSAN: use-after-free in sw842_decompress+0x11c8/0x1750
lib/842/842_decompress.c:303
 sw842_decompress+0x11c8/0x1750 lib/842/842_decompress.c:303
 crypto842_sdecompress+0x46/0x60 crypto/842.c:53
 scomp_acomp_comp_decomp+0xa49/0x1120 include/crypto/internal/scompress.h:-1
 scomp_acomp_decompress+0x30/0x40 crypto/scompress.c:283
 crypto_acomp_decompress+0x5c4/0xe50 crypto/acompress.c:297
 zswap_decompress+0x4ba/0xcc0 mm/zswap.c:952
 zswap_writeback_entry mm/zswap.c:1032 [inline]
 shrink_memcg_cb+0x78f/0xda0 mm/zswap.c:1147
 __list_lru_walk_one+0x49a/0xde0 mm/list_lru.c:362
 list_lru_walk_one+0x5c/0x70 mm/list_lru.c:399
 list_lru_shrink_walk include/linux/list_lru.h:332 [inline]
 zswap_shrinker_scan+0x11f/0x290 mm/zswap.c:1181
 do_shrink_slab+0x736/0x1460 mm/shrinker.c:443
 shrink_slab_memcg mm/shrinker.c:560 [inline]
 shrink_slab+0xb70/0x14c0 mm/shrinker.c:638
 shrink_one+0x560/0xc10 mm/vmscan.c:5026
 shrink_many mm/vmscan.c:5087 [inline]
 lru_gen_shrink_node mm/vmscan.c:5165 [inline]
 shrink_node+0x47a5/0x5b70 mm/vmscan.c:6154
 kswapd_shrink_node mm/vmscan.c:7008 [inline]
 balance_pgdat mm/vmscan.c:7186 [inline]
 kswapd+0x3029/0x5a50 mm/vmscan.c:7462
 kthread+0x53f/0x600 kernel/kthread.c:436
 ret_from_fork+0x20f/0x8d0 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Uninit was stored to memory at:

 sw842_decompress+0x11c1/0x1750 lib/842/842_decompress.c:303
 crypto842_sdecompress+0x46/0x60 crypto/842.c:53
 scomp_acomp_comp_decomp+0xa49/0x1120 include/crypto/internal/scompress.h:-1
 scomp_acomp_decompress+0x30/0x40 crypto/scompress.c:283
 crypto_acomp_decompress+0x5c4/0xe50 crypto/acompress.c:297
 zswap_decompress+0x4ba/0xcc0 mm/zswap.c:952
 zswap_writeback_entry mm/zswap.c:1032 [inline]
 shrink_memcg_cb+0x78f/0xda0 mm/zswap.c:1147
 __list_lru_walk_one+0x49a/0xde0 mm/list_lru.c:362
 list_lru_walk_one+0x5c/0x70 mm/list_lru.c:399
 list_lru_shrink_walk include/linux/list_lru.h:332 [inline]
 zswap_shrinker_scan+0x11f/0x290 mm/zswap.c:1181
 do_shrink_slab+0x736/0x1460 mm/shrinker.c:443
 shrink_slab_memcg mm/shrinker.c:560 [inline]
 shrink_slab+0xb70/0x14c0 mm/shrinker.c:638
 shrink_one+0x560/0xc10 mm/vmscan.c:5026
 shrink_many mm/vmscan.c:5087 [inline]
 lru_gen_shrink_node mm/vmscan.c:5165 [inline]
 shrink_node+0x47a5/0x5b70 mm/vmscan.c:6154
 kswapd_shrink_node mm/vmscan.c:7008 [inline]
 balance_pgdat mm/vmscan.c:7186 [inline]
 kswapd+0x3029/0x5a50 mm/vmscan.c:7462
 kthread+0x53f/0x600 kernel/kthread.c:436
 ret_from_fork+0x20f/0x8d0 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Uninit was stored to memory at:

 next_bits+0xac2/0xda0 lib/842/842_decompress.c:118
 sw842_decompress+0x1a6/0x1750 lib/842/842_decompress.c:297
 crypto842_sdecompress+0x46/0x60 crypto/842.c:53
 scomp_acomp_comp_decomp+0xa49/0x1120 include/crypto/internal/scompress.h:-1
 scomp_acomp_decompress+0x30/0x40 crypto/scompress.c:283
 crypto_acomp_decompress+0x5c4/0xe50 crypto/acompress.c:297
 zswap_decompress+0x4ba/0xcc0 mm/zswap.c:952
 zswap_writeback_entry mm/zswap.c:1032 [inline]
 shrink_memcg_cb+0x78f/0xda0 mm/zswap.c:1147
 __list_lru_walk_one+0x49a/0xde0 mm/list_lru.c:362
 list_lru_walk_one+0x5c/0x70 mm/list_lru.c:399
 list_lru_shrink_walk include/linux/list_lru.h:332 [inline]
 zswap_shrinker_scan+0x11f/0x290 mm/zswap.c:1181
 do_shrink_slab+0x736/0x1460 mm/shrinker.c:443
 shrink_slab_memcg mm/shrinker.c:560 [inline]
 shrink_slab+0xb70/0x14c0 mm/shrinker.c:638
 shrink_one+0x560/0xc10 mm/vmscan.c:5026
 shrink_many mm/vmscan.c:5087 [inline]
 lru_gen_shrink_node mm/vmscan.c:5165 [inline]
 shrink_node+0x47a5/0x5b70 mm/vmscan.c:6154
 kswapd_shrink_node mm/vmscan.c:7008 [inline]
 balance_pgdat mm/vmscan.c:7186 [inline]
 kswapd+0x3029/0x5a50 mm/vmscan.c:7462
 kthread+0x53f/0x600 kernel/kthread.c:436
 ret_from_fork+0x20f/0x8d0 arch/x86/kernel/process.c:158
 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245

Uninit was created at:

 __free_pages_prepare mm/page_alloc.c:1327 [inline]
 free_unref_folios+0x280/0x2880 mm/page_alloc.c:3011
 folios_put_refs+0xb2e/0xba0 mm/swap.c:1057
 free_pages_and_swap_cache+0x804/0x840 mm/swap_state.c:589
 __tlb_batch_free_encoded_pages mm/mmu_gather.c:138 [inline]
 tlb_batch_pages_flush mm/mmu_gather.c:151 [inline]
 tlb_flush_mmu_free mm/mmu_gather.c:417 [inline]
 tlb_flush_mmu+0x92b/0xe90 mm/mmu_gather.c:424
 zap_pte_range mm/memory.c:1973 [inline]
 zap_pmd_range mm/memory.c:2020 [inline]
 zap_pud_range mm/memory.c:2048 [inline]
 zap_p4d_range mm/memory.c:2069 [inline]
 __zap_vma_range+0x763f/0x9340 mm/memory.c:2109
 unmap_vmas+0x440/0x800 mm/memory.c:2178
 exit_mmap+0x27c/0xac0 mm/mmap.c:1300
 __mmput+0x134/0x650 kernel/fork.c:1187
 mmput+0x74/0x90 kernel/fork.c:1210
 exit_mm+0x2b1/0x4b0 kernel/exit.c:615
 do_exit+0x9a9/0x3c30 kernel/exit.c:997
 do_group_exit+0x258/0x390 kernel/exit.c:1152
 __do_sys_exit_group kernel/exit.c:1163 [inline]
 __se_sys_exit_group kernel/exit.c:1161 [inline]
 __x64_sys_exit_group+0x35/0x40 kernel/exit.c:1161
 x64_sys_call+0x3e6d/0x3ea0 arch/x86/include/generated/asm/syscalls_64.h:232
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x15d/0x3c0 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f

CPU: 0 UID: 0 PID: 81 Comm: kswapd0 Tainted: G        W
7.2.0-rc4-00503-g3dab139d4795 #9 PREEMPT(lazy)
Tainted: [W]=WARN
Hardware name: QEMU Ubuntu 26.04 PC (i440FX + PIIX, 1996), BIOS

1.17.0-debian-1.17.0-1ubuntu1 04/01/2014
=====================================================

The full syzkaller log is available if needed. I do not yet have a reliable reproducer.

Thanks,

Dane Phillips