* kernel bug found and suggestions for fixing it
@ 2025-03-05 14:49 =?gb18030?B?ZmZoZ2Z2?=
2025-03-05 15:03 ` =?gb18030?B?u9i4tKO6a2VybmVsIGJ1ZyBmb3VuZCBhbmQgc3VnZ2VzdGlvbnMgZm9yIGZpeGluZyBpdA==?= =?gb18030?B?ZmZoZ2Z2?=
2025-03-05 15:29 ` kernel bug found and suggestions for fixing it Sergey Senozhatsky
0 siblings, 2 replies; 3+ messages in thread
From: =?gb18030?B?ZmZoZ2Z2?= @ 2025-03-05 14:49 UTC (permalink / raw)
To: =?gb18030?B?bWluY2hhbg==?=, =?gb18030?B?c2Vub3poYXRza3k=?=,
=?gb18030?B?YWtwbQ==?=, =?gb18030?B?bGludXgtbW0=?=,
=?gb18030?B?bGludXgta2VybmVs?=
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb18030", Size: 6015 bytes --]
Hello, I found a bug titled " BUG: corrupted list in fix_fullness_group " with modified syzkaller in the lasted upstream related to ZSMALLOC.
If you fix this issue, please add the following tag to the commit: Reported-by: Jianzhou Zhao <xnxc22xnxc22@qq.com>, xingwei lee <xrivendell7@gmail.com>, Zhizhuo Tang <strforexctzzchange@foxmail.com>
------------[ cut here ]-----------------------------------------
BUG: corrupted list in fix_fullness_group
==================================================================
list_add corruption. next->prev should be prev (ffff8880436a4020), but was ffff8881436a4020. (next=ffff8880436a4020).
------------[ cut here ]------------
kernel BUG at lib/list_debug.c:29!
invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI
CPU: 0 PID: 86 Comm: kswapd0 Not tainted 6.9.0-rc7 #51
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
RIP: 0010:__list_add_valid_or_report+0xb7/0x110 lib/list_debug.c:29
Code: 02 bd 8a e8 7b f3 22 fd 90 0f 0b 48 c7 c7 60 03 bd 8a e8 6c f3 22 fd 90 0f 0b 4c 89 e1 48 c7 c7 c0 03 bd 8a e8 5a f3 22 fd 90 <0f> 0b 48 89 f1 48 c7 c7 40 04 bd 8a 4c 89 e6 e8 45 f3 22 fd 90 0f
RSP: 0018:ffff888011886c88 EFLAGS: 00010282
RAX: 0000000000000075 RBX: ffff88802348c688 RCX: ffffffff8164b313
RDX: 0000000000000000 RSI: ffffffff81652eae RDI: 0000000000000001
RBP: ffff888011886ca0 R08: ffff888011890000 R09: ffffed1002310d51
R10: ffffed1002310d50 R11: ffff888011886a87 R12: ffff8880436a4020
R13: ffff88802348c6a0 R14: ffff8880436a4020 R15: ffff88802348c6a0
FS: 0000000000000000(0000) GS:ffff88802d000000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fd266fc6018 CR3: 000000001fc46000 CR4: 0000000000750ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
<task>
__list_add_valid include/linux/list.h:88 [inline]
__list_add include/linux/list.h:150 [inline]
list_add include/linux/list.h:169 [inline]
insert_zspage mm/zsmalloc.c:672 [inline]
fix_fullness_group+0x3f8/0x540 mm/zsmalloc.c:708
zs_malloc+0x588/0x13b0 mm/zsmalloc.c:1355
zs_zpool_malloc+0x35/0xa0 mm/zsmalloc.c:366
zpool_malloc+0x8b/0xc0 mm/zpool.c:258
zswap_compress mm/zswap.c:1049 [inline]
zswap_store+0xaaa/0x26c0 mm/zswap.c:1580
swap_writepage+0x99/0x2b0 mm/page_io.c:198
pageout+0x384/0x810 mm/vmscan.c:660
shrink_folio_list+0x12f3/0x3bd0 mm/vmscan.c:1323
evict_folios+0x753/0x1890 mm/vmscan.c:4537
try_to_shrink_lruvec+0x6be/0xa20 mm/vmscan.c:4733
shrink_one+0x41e/0x7d0 mm/vmscan.c:4772
shrink_many mm/vmscan.c:4835 [inline]
lru_gen_shrink_node+0x6f6/0xe60 mm/vmscan.c:4935
shrink_node+0x1a70/0x23a0 mm/vmscan.c:5894
kswapd_shrink_node mm/vmscan.c:6704 [inline]
balance_pgdat+0x974/0x15d0 mm/vmscan.c:6895
kswapd+0x513/0xaf0 mm/vmscan.c:7164
kthread+0x313/0x410 kernel/kthread.c:388
ret_from_fork+0x56/0x90 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
</task>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:__list_add_valid_or_report+0xb7/0x110 lib/list_debug.c:29
Code: 02 bd 8a e8 7b f3 22 fd 90 0f 0b 48 c7 c7 60 03 bd 8a e8 6c f3 22 fd 90 0f 0b 4c 89 e1 48 c7 c7 c0 03 bd 8a e8 5a f3 22 fd 90 <0f> 0b 48 89 f1 48 c7 c7 40 04 bd 8a 4c 89 e6 e8 45 f3 22 fd 90 0f
RSP: 0018:ffff888011886c88 EFLAGS: 00010282
RAX: 0000000000000075 RBX: ffff88802348c688 RCX: ffffffff8164b313
RDX: 0000000000000000 RSI: ffffffff81652eae RDI: 0000000000000001
RBP: ffff888011886ca0 R08: ffff888011890000 R09: ffffed1002310d51
R10: ffffed1002310d50 R11: ffff888011886a87 R12: ffff8880436a4020
R13: ffff88802348c6a0 R14: ffff8880436a4020 R15: ffff88802348c6a0
FS: 0000000000000000(0000) GS:ffff88802d000000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fd266fc6018 CR3: 000000001fc46000 CR4: 0000000000750ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
==================================================================
I use the same kernel as syzbot instance upstream: 7eb172143d5508b4da468ed59ee857c6e5e01da6
kernel config: https://syzkaller.appspot.com/text?tag=KernelConfig&x=da4b04ae798b7ef6
compiler: gcc version 11.4.0
===============================================================================
Unfortunately, the modified syzkaller does not generate an effective repeat program.
The following is my analysis of the bug and repair suggestions, hoping to help with the repair of the bug:
## Root cause analysis
The crash was caused by a list node corruption while the zsmalloc memory allocator was adjusting the memory page's fullness list. The specific cause could be:
Concurrent access is not synchronized correctly. The fix_fullness_group() did not hold the zspool lock correctly when manipulating the class->fullness_list linked list, causing multiple CPU cores (such as kswapd and memory allocation threads) to modify the linked list node simultaneously.
Memory overreach /UAF (Use-After-Free).In the zs_malloc path, the linked list pointer may be abnormal because the object metadata is overwritten.
### Repair suggestions
Hardening lock mechanism. Ensure that the correct pool locks are held in zs_malloc and page migration paths.
Patch example:
mm/zsmalloc.c:
static int fix_fullness_group(struct size_class *class, struct zspage *zspage)
{
int newfg;
newfg = get_fullness_group(class, zspage);
if (newfg == zspage->fullness)
goto out;
++ spin_lock(&class->lock);
remove_zspage(class, zspage);
insert_zspage(class, zspage, newfg);
++ spin_unlock(&class->lock);
out:
return newfg;
}
=========================================================================
I hope it helps.
Best regards
Jianzhou Zhao
xingwei lee
Zhizhuo Tang
ÉÏÒ»·â ÏÂÒ»·â</strforexctzzchange@foxmail.com></xrivendell7@gmail.com></xnxc22xnxc22@qq.com>
^ permalink raw reply [flat|nested] 3+ messages in thread* =?gb18030?B?u9i4tKO6a2VybmVsIGJ1ZyBmb3VuZCBhbmQgc3VnZ2VzdGlvbnMgZm9yIGZpeGluZyBpdA==?=
2025-03-05 14:49 kernel bug found and suggestions for fixing it =?gb18030?B?ZmZoZ2Z2?=
@ 2025-03-05 15:03 ` =?gb18030?B?ZmZoZ2Z2?=
2025-03-05 15:29 ` kernel bug found and suggestions for fixing it Sergey Senozhatsky
1 sibling, 0 replies; 3+ messages in thread
From: =?gb18030?B?ZmZoZ2Z2?= @ 2025-03-05 15:03 UTC (permalink / raw)
To: =?gb18030?B?bWluY2hhbg==?=, =?gb18030?B?c2Vub3poYXRza3k=?=,
=?gb18030?B?YWtwbQ==?=, =?gb18030?B?bGludXgtbW0=?=,
=?gb18030?B?bGludXgta2VybmVs?=
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb18030", Size: 6206 bytes --]
Sorry I provided the crash log for 6.9-rc7, but after analysis it seems likely that this issue also exists in the latest version of the kernel (v6.14-rc5).
------------------ Original email ------------------
Hello, I found a bug titled " BUG: corrupted list in fix_fullness_group " with modified syzkaller in the lasted upstream related to ZSMALLOC.
If you fix this issue, please add the following tag to the commit: Reported-by: Jianzhou Zhao <xnxc22xnxc22@qq.com>, xingwei lee <xrivendell7@gmail.com>, Zhizhuo Tang <strforexctzzchange@foxmail.com>
------------[ cut here ]-----------------------------------------
BUG: corrupted list in fix_fullness_group
==================================================================
list_add corruption. next->prev should be prev (ffff8880436a4020), but was ffff8881436a4020. (next=ffff8880436a4020).
------------[ cut here ]------------
kernel BUG at lib/list_debug.c:29!
invalid opcode: 0000 [#1] PREEMPT SMP KASAN NOPTI
CPU: 0 PID: 86 Comm: kswapd0 Not tainted 6.9.0-rc7 #51
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
RIP: 0010:__list_add_valid_or_report+0xb7/0x110 lib/list_debug.c:29
Code: 02 bd 8a e8 7b f3 22 fd 90 0f 0b 48 c7 c7 60 03 bd 8a e8 6c f3 22 fd 90 0f 0b 4c 89 e1 48 c7 c7 c0 03 bd 8a e8 5a f3 22 fd 90 <0f> 0b 48 89 f1 48 c7 c7 40 04 bd 8a 4c 89 e6 e8 45 f3 22 fd 90 0f
RSP: 0018:ffff888011886c88 EFLAGS: 00010282
RAX: 0000000000000075 RBX: ffff88802348c688 RCX: ffffffff8164b313
RDX: 0000000000000000 RSI: ffffffff81652eae RDI: 0000000000000001
RBP: ffff888011886ca0 R08: ffff888011890000 R09: ffffed1002310d51
R10: ffffed1002310d50 R11: ffff888011886a87 R12: ffff8880436a4020
R13: ffff88802348c6a0 R14: ffff8880436a4020 R15: ffff88802348c6a0
FS: 0000000000000000(0000) GS:ffff88802d000000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fd266fc6018 CR3: 000000001fc46000 CR4: 0000000000750ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
Call Trace:
<task>
__list_add_valid include/linux/list.h:88 [inline]
__list_add include/linux/list.h:150 [inline]
list_add include/linux/list.h:169 [inline]
insert_zspage mm/zsmalloc.c:672 [inline]
fix_fullness_group+0x3f8/0x540 mm/zsmalloc.c:708
zs_malloc+0x588/0x13b0 mm/zsmalloc.c:1355
zs_zpool_malloc+0x35/0xa0 mm/zsmalloc.c:366
zpool_malloc+0x8b/0xc0 mm/zpool.c:258
zswap_compress mm/zswap.c:1049 [inline]
zswap_store+0xaaa/0x26c0 mm/zswap.c:1580
swap_writepage+0x99/0x2b0 mm/page_io.c:198
pageout+0x384/0x810 mm/vmscan.c:660
shrink_folio_list+0x12f3/0x3bd0 mm/vmscan.c:1323
evict_folios+0x753/0x1890 mm/vmscan.c:4537
try_to_shrink_lruvec+0x6be/0xa20 mm/vmscan.c:4733
shrink_one+0x41e/0x7d0 mm/vmscan.c:4772
shrink_many mm/vmscan.c:4835 [inline]
lru_gen_shrink_node+0x6f6/0xe60 mm/vmscan.c:4935
shrink_node+0x1a70/0x23a0 mm/vmscan.c:5894
kswapd_shrink_node mm/vmscan.c:6704 [inline]
balance_pgdat+0x974/0x15d0 mm/vmscan.c:6895
kswapd+0x513/0xaf0 mm/vmscan.c:7164
kthread+0x313/0x410 kernel/kthread.c:388
ret_from_fork+0x56/0x90 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
</task>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:__list_add_valid_or_report+0xb7/0x110 lib/list_debug.c:29
Code: 02 bd 8a e8 7b f3 22 fd 90 0f 0b 48 c7 c7 60 03 bd 8a e8 6c f3 22 fd 90 0f 0b 4c 89 e1 48 c7 c7 c0 03 bd 8a e8 5a f3 22 fd 90 <0f> 0b 48 89 f1 48 c7 c7 40 04 bd 8a 4c 89 e6 e8 45 f3 22 fd 90 0f
RSP: 0018:ffff888011886c88 EFLAGS: 00010282
RAX: 0000000000000075 RBX: ffff88802348c688 RCX: ffffffff8164b313
RDX: 0000000000000000 RSI: ffffffff81652eae RDI: 0000000000000001
RBP: ffff888011886ca0 R08: ffff888011890000 R09: ffffed1002310d51
R10: ffffed1002310d50 R11: ffff888011886a87 R12: ffff8880436a4020
R13: ffff88802348c6a0 R14: ffff8880436a4020 R15: ffff88802348c6a0
FS: 0000000000000000(0000) GS:ffff88802d000000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fd266fc6018 CR3: 000000001fc46000 CR4: 0000000000750ef0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
PKRU: 55555554
==================================================================
I use the same kernel as syzbot instance upstream: 7eb172143d5508b4da468ed59ee857c6e5e01da6
kernel config: https://syzkaller.appspot.com/text?tag=KernelConfig&x=da4b04ae798b7ef6
compiler: gcc version 11.4.0
===============================================================================
Unfortunately, the modified syzkaller does not generate an effective repeat program.
The following is my analysis of the bug and repair suggestions, hoping to help with the repair of the bug:
## Root cause analysis
The crash was caused by a list node corruption while the zsmalloc memory allocator was adjusting the memory page's fullness list. The specific cause could be:
Concurrent access is not synchronized correctly. The fix_fullness_group() did not hold the zspool lock correctly when manipulating the class->fullness_list linked list, causing multiple CPU cores (such as kswapd and memory allocation threads) to modify the linked list node simultaneously.
Memory overreach /UAF (Use-After-Free).In the zs_malloc path, the linked list pointer may be abnormal because the object metadata is overwritten.
### Repair suggestions
Hardening lock mechanism. Ensure that the correct pool locks are held in zs_malloc and page migration paths.
Patch example:
mm/zsmalloc.c:
static int fix_fullness_group(struct size_class *class, struct zspage *zspage)
{
int newfg;
newfg = get_fullness_group(class, zspage);
if (newfg == zspage->fullness)
goto out;
++ spin_lock(&class->lock);
remove_zspage(class, zspage);
insert_zspage(class, zspage, newfg);
++ spin_unlock(&class->lock);
out:
return newfg;
}
=========================================================================
I hope it helps.
Best regards
Jianzhou Zhao
xingwei lee
Zhizhuo Tang</strforexctzzchange@foxmail.com></xrivendell7@gmail.com></xnxc22xnxc22@qq.com>
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: kernel bug found and suggestions for fixing it
2025-03-05 14:49 kernel bug found and suggestions for fixing it =?gb18030?B?ZmZoZ2Z2?=
2025-03-05 15:03 ` =?gb18030?B?u9i4tKO6a2VybmVsIGJ1ZyBmb3VuZCBhbmQgc3VnZ2VzdGlvbnMgZm9yIGZpeGluZyBpdA==?= =?gb18030?B?ZmZoZ2Z2?=
@ 2025-03-05 15:29 ` Sergey Senozhatsky
1 sibling, 0 replies; 3+ messages in thread
From: Sergey Senozhatsky @ 2025-03-05 15:29 UTC (permalink / raw)
To: ffhgfv; +Cc: minchan, senozhatsky, akpm, linux-mm, linux-kernel
On (25/03/05 09:49), ffhgfv wrote:
> Hello, I found a bug titled " BUG: corrupted list in fix_fullness_group "
> with modified syzkaller in the lasted upstream related to ZSMALLOC.
[..]
> static int fix_fullness_group(struct size_class *class, struct zspage *zspage)
> {
> int newfg;
>
> newfg = get_fullness_group(class, zspage);
> if (newfg == zspage->fullness)
> goto out;
> ++ spin_lock(&class->lock);
> remove_zspage(class, zspage);
> insert_zspage(class, zspage, newfg);
> ++ spin_unlock(&class->lock);
> out:
> return newfg;
> }
fix_fullness_group() is *always* called under class->lock.
zs_malloc() calls it under class->lock, so does zs_free().
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-03-05 19:39 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-03-05 14:49 kernel bug found and suggestions for fixing it =?gb18030?B?ZmZoZ2Z2?=
2025-03-05 15:03 ` =?gb18030?B?u9i4tKO6a2VybmVsIGJ1ZyBmb3VuZCBhbmQgc3VnZ2VzdGlvbnMgZm9yIGZpeGluZyBpdA==?= =?gb18030?B?ZmZoZ2Z2?=
2025-03-05 15:29 ` kernel bug found and suggestions for fixing it Sergey Senozhatsky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox