[BUG] KASAN: use-after-free in __unwind_start (arch/x86/kernel/unwind_orc.c) — stack overflow on qedi probe failure [qedi] [syzkaller]

Yang Zi <[email protected]>
Newsgroups org.kernel.vger.linux-scsi,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
Hi,

While fuzzing the kernel v7.1 with syzkaller, we hit a use-after-free during 
qedi driver probe that we believe originates in a stack overflow, not a classic 
slab lifetime bug.

Reproducer summary (see attached report/log):

    BUG: KASAN: use-after-free in __unwind_start+0x26/0x310 arch/x86/kernel/unwind_orc.c:715
    Write of size 112 at addr ffff88800ea57f40 by task modprobe/1146

The task was `modprobe (1146)` (Tainted G W O) loading qedi/qed. The crash is
preceded by qed initialization failures:
    [qed_hw_prepare_single:4684] Failed to get HW information
    [qed_probe:513] hw prepare failed
    [__qedi_probe:2563] Cannot initialize hardware
and critically the kernel reported:
    modprobe (1146) used greatest stack depth: 8 bytes left

Root-cause hypothesis: on qedi probe failure, the deep nested error/cleanup
path (qed_hw_prepare_single -> qed_int_igu_read_cam -> qed_hw_get_nvm_info ->
qed_mcp_cmd_init, ...) drives the process stack to within 8 bytes of the
limit. When the WARNING path triggers the ORC unwinder, `__unwind_start`
executes `memset(state, 0, sizeof(*state))` (STRUCT_UNWIND_STATE = 112B).
Writing 112 bytes through an 8-byte stack headroom overflows past the stack
boundary into a freed/unmapped physical page, which KASAN flags as a
use-after-free write (size 112). This is identical to the already-observed
id103 pattern (mode J).

The crash report attached below:

BUG: KASAN: use-after-free in __unwind_start+0x26/0x310 arch/x86/kernel/unwind_orc.c:715
Write of size 112 at addr ffff88800ea57f30 by task modprobe/1146

CPU: 0 UID: 0 PID: 1146 Comm: modprobe Tainted: G        W  O        7.1.0 #1 PREEMPT(lazy) 
Tainted: [W]=WARN, [O]=OOT_MODULE
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
Call Trace:
 <TASK>
 </TASK>

The buggy address belongs to the physical page:
page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xea57
flags: 0x100000000000000(node=0|zone=1)
raw: 0100000000000000 0000000000000000 ffffea00003a95c8 0000000000000000
raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff88800ea57e00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff88800ea57e80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
>ffff88800ea57f00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
                                     ^
 ffff88800ea57f80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
 ffff88800ea58000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
==================================================================
------------[ cut here ]------------
WARNING: kernel/entry/common.c:140 at raw_irqentry_exit_cond_resched+0x46/0x50 kernel/entry/common.c:140, CPU#0: modprobe/1146
Modules linked in: qedi(+) iscsi_boot_sysfs libiscsi scsi_transport_iscsi qed kt_runtime(O) uio_pci_kerneltracker_driver(O)
CPU: 0 UID: 0 PID: 1146 Comm: modprobe Tainted: G        W  O        7.1.0 #1 PREEMPT(lazy) 
Tainted: [W]=WARN, [O]=OOT_MODULE
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
RIP: 0010:raw_irqentry_exit_cond_resched+0x46/0x50 kernel/entry/common.c:140
Code: 36 e6 04 48 29 e0 48 3d 00 80 00 00 73 1b 65 48 8b 05 76 36 e6 04 48 f7 00 10 00 00 00 0f 85 31 4b 19 02 c3 cc cc cc cc cc 90 <0f> 0b 90 eb df 0f 1f 44 00 00 90 90 90 90 90 90 90 90 90 90 90 90
RSP: 0018:ffff88800ea57ca0 EFLAGS: 00010006
RAX: 0000000000008360 RBX: 0000000000000000 RCX: ffff888009cb51c0
RDX: 0000000000000000 RSI: dffffc0000000000 RDI: ffffffff8501e810
RBP: 0000000000000000 R08: ffff888008a8c053 R09: 1ffff1100115180a
R10: dffffc0000000000 R11: ffffed100115180b R12: 0000000000000000
R13: 0000000000000000 R14: ffff88800ea57d08 R15: 0000000000000000
FS:  00007fee16e6f080(0000) GS:ffff8880e6ae3000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00005627f0cc5518 CR3: 0000000050c6d000 CR4: 00000000000006f0
Call Trace:
 <TASK>
 </TASK>
irq event stamp: 90422
hardirqs last  enabled at (90421): [<ffffffff8367c433>] __raw_spin_unlock_irq include/linux/spinlock_api_smp.h:187 [inline]
hardirqs last  enabled at (90421): [<ffffffff8367c433>] _raw_spin_unlock_irq+0x23/0x40 kernel/locking/spinlock.c:206
hardirqs last disabled at (90422): [<ffffffff81380bcd>] handle_softirqs+0x3ed/0x540 kernel/softirq.c:637
softirqs last  enabled at (90212): [<ffffffff81380f0b>] __do_softirq kernel/softirq.c:656 [inline]
softirqs last  enabled at (90212): [<ffffffff81380f0b>] invoke_softirq kernel/softirq.c:496 [inline]
softirqs last  enabled at (90212): [<ffffffff81380f0b>] __irq_exit_rcu+0x8b/0x150 kernel/softirq.c:735
softirqs last disabled at (90203): [<ffffffff81380f0b>] __do_softirq kernel/softirq.c:656 [inline]
softirqs last disabled at (90203): [<ffffffff81380f0b>] invoke_softirq kernel/softirq.c:496 [inline]
softirqs last disabled at (90203): [<ffffffff81380f0b>] __irq_exit_rcu+0x8b/0x150 kernel/softirq.c:735
---[ end trace 0000000000000000 ]---
[qed_load_mcp_offsets:178()]The address of the MCP scratch-pad is not configured
[qed_mcp_cmd_init:257()]MCP is not initialized
[qed_mcp_cmd_and_union:589()]MFW is not initialized!
[qed_hw_get_nvm_info:4057()]Shared memory not initialized
[qed_int_igu_read_cam:2258()]IGU CAM returned invalid values igu_dsb_id=0xffff
[qed_hw_prepare_single:4682()]Failed to get HW information
[qed_probe:513()]hw prepare failed
[0000:00:05.0]:[__qedi_probe:2563]:6: Cannot initialize hardware
modprobe (1146) used greatest stack depth: 8 bytes left

Regards,
Yang Zi
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.