BUG: spinlock bad magic in sock_wfree

Status: closed as invalid on 2026/11/08 10:18
Subsystems: net
Labels: prio:normal
[Documentation on labels]
First crash: 3d11h, last: 3d11h
✨ AI-generated root cause summary:

Unrestricted writes to PCI configuration space via /proc/bus/pci/ (proc_bus_pci_write() and pci_user_write_config_dword()) allow userspace to overwrite critical host bridge registers. On a QEMU Q35 system, writing to device 00:00.0 at offset 0x60 modifies the PCIEXBAR register and sets bit 0 (PCIEXBAREN), remapping the PCIe MMCONFIG aperture directly over active system physical RAM. Subsequent reads from kernel data structures located in the shadowed physical address range (such as socket waitqueues at physical address 0x46117940) return all-ones (0xffffffff), causing waitqueue checks to spuriously succeed and triggering a 'spinlock bad magic' bug (.magic: ffffffff) when attempting to acquire the lock.

▶ ▼ ✨ Full AI root cause analysis
Based on kernel commit d164c7d754f0:

Root Cause Analysis

1. Involved Functions, Structs, and Files


2. Trigger Mechanism and Sequence of Events

  1. User-space PCI Configuration Write: The reproducer mounts procfs and opens ./proc/bus/pci/00/00.0, corresponding to the PCI Host Bridge (Intel Q35 MCH). It performs repeated writes of a 125-byte payload into configuration space.

  2. Overwriting PCIEXBAR on the Host Bridge: In proc_bus_pci_write(), the write loop invokes pci_user_write_config_dword() for each 4-byte chunk. At offset pos = 0x60 (as recorded in the task frame: RBP = 0x60), the user writes value 0x4ce5e1cb (R13 = 0x4ce5e1cb, matching bytes cb e1 e5 4c from offset 0x60 in the reproducer payload).

    • On the QEMU Q35 MCH, register 0x60 is PCIEXBAR (PCI Express Register Range Base Address / MMCONFIG ECAM window).
    • Bit 0 of 0x4ce5e1cb is 1, which asserts PCIEXBAREN (enable PCIe ECAM).
    • This reconfigures the host bridge to map the PCIe MMCONFIG MMIO aperture over physical memory in the 0x40000000..0x47ffffff range, superseding the physical RAM mapping for those addresses.
  3. Interrupt Handling and Direct Map Access: Inside pci_user_write_config_dword(), right after writing to hardware, raw_spin_unlock_irq(&pci_lock) is executed. As interrupts are re-enabled (sti), a pending APIC timer interrupt immediately vectors to sysvec_apic_timer_interrupt.

    • In timer softirq context, addrconf_rs_timer() invokes ndisc_send_rs() -> ndisc_send_skb().
    • The packet traverses IPv6 output and is handed off to an XFRM interface device (xfrmi_xmit()), where transmission error handling drops the skb with kfree_skb(skb).
    • kfree_skb() invokes skb_release_head_state(), calling the socket destructor sock_wfree() on skb->sk (net->ipv6.ndisc_sk).
    • sock_wfree() calls sock_def_write_space_wfree(sk, ...).
  4. Lock Read Corruption and spin_bug: sock_def_write_space_wfree() dereferences wq = rcu_dereference(sk->sk_wq) and tests waitqueue_active(&wq->wait).

    • The socket waitqueue structure wq->wait resides at virtual address 0xffff888046117940 in the kernel direct-map (PAGE_OFFSET), corresponding to physical address 0x46117940.
    • Because physical address 0x46117940 was just placed under the newly enabled PCIe MMCONFIG aperture, CPU reads targeting this physical range bypass system RAM and hit unpopulated PCIe configuration space, which floats high and returns all-ones (0xffffffff).
    • list_empty(&wq->wait.head) reads head->next as 0xffffffffffffffff, spuriously evaluating waitqueue_active() to true.
    • wake_up_interruptible_sync_poll() then invokes __wake_up_sync_key() -> __wake_up_common_lock(), attempting to acquire spin_lock_irqsave(&wq->wait.lock, flags).
    • In debug_spin_lock_before(), the lock fields read from 0xffff888046117940 are all-ones:
      • lock->magic is 0xffffffff (expected SPINLOCK_MAGIC = 0xdead4ead)
      • lock->owner is 0xffffffffffffffff (<none>/-1)
      • lock->owner_cpu is 0xffffffff (-1)
    • This triggers the spin_bug("bad magic") splat.
▶ ▼ ✨ AI Jobs (1)
ID Workflow Result Correct Bug Created Started Finished Revision
31e036cd assessment-security DenialOfService: ✅ Exploitable: ✅ FilesystemTrigger: ❌ FuzzingArtifact: ❌ MemoryCorruption: ✅ NetworkNeedsSetup: ❌ NetworkTrigger: ❌ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ❌ UserNamespace: ❌ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ BUG: spinlock bad magic in sock_wfree 2026/11/08 04:40 2026/11/08 04:40 2026/11/08 04:50 5cecaf1f

Sample crash report:
BUG: spinlock bad magic on CPU#1,
BUG: spinlock bad magic on CPU#1, syz.3.20/6131
 lock: 0xffff888046117940, .magic: ffffffff, .owner: <none>/-1, .owner_cpu: -1
CPU: 1 UID: 0 PID: 6131 Comm: syz.3.20 Not tainted syzkaller #0 PREEMPT(full) 
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
Call Trace:
 <IRQ>
 __dump_stack lib/dump_stack.c:94 [inline]
 dump_stack_lvl+0x100/0x190 lib/dump_stack.c:120
 spin_bug kernel/locking/spinlock_debug.c:78 [inline]
 debug_spin_lock_before kernel/locking/spinlock_debug.c:86 [inline]
 do_raw_spin_lock.cold+0x37/0x3c kernel/locking/spinlock_debug.c:115
 __raw_spin_lock_irqsave include/linux/spinlock_api_smp.h:156 [inline]
 _raw_spin_lock_irqsave+0x42/0x60 kernel/locking/spinlock.c:181
 __wake_up_common_lock kernel/sched/wait.c:124 [inline]
 __wake_up_sync_key+0x1c/0x50 kernel/sched/wait.c:188
 sock_def_write_space_wfree net/core/sock.c:3780 [inline]
 sock_wfree+0x5c9/0x7f0 net/core/sock.c:2734
 skb_release_head_state+0x35f/0x400 net/core/skbuff.c:1166
 skb_release_all net/core/skbuff.c:1186 [inline]
 __kfree_skb net/core/skbuff.c:1202 [inline]
 sk_skb_reason_drop+0xc4/0x1b0 net/core/skbuff.c:1241
 kfree_skb_reason include/linux/skbuff.h:1329 [inline]
 kfree_skb include/linux/skbuff.h:1338 [inline]
 xfrmi_xmit+0xd5c/0x23f0 net/xfrm/xfrm_interface_core.c:589
 __netdev_start_xmit include/linux/netdevice.h:5457 [inline]
 netdev_start_xmit include/linux/netdevice.h:5466 [inline]
 xmit_one net/core/dev.c:4068 [inline]
 dev_hard_start_xmit+0x121/0x760 net/core/dev.c:4084
 __dev_queue_xmit+0x1bef/0x48d0 net/core/dev.c:5088
 dev_queue_xmit include/linux/netdevice.h:3485 [inline]
 neigh_connected_output+0x3b5/0x5d0 net/core/neighbour.c:1662
 neigh_output include/net/neighbour.h:554 [inline]
 ip6_finish_output2+0xbd8/0x1f10 net/ipv6/ip6_output.c:138
 __ip6_finish_output+0x34e/0xdf0 net/ipv6/ip6_output.c:210
 ip6_finish_output net/ipv6/ip6_output.c:221 [inline]
 NF_HOOK_COND include/linux/netfilter.h:314 [inline]
 ip6_output+0x2a1/0xa50 net/ipv6/ip6_output.c:248
 dst_output include/net/dst.h:471 [inline]
 NF_HOOK include/linux/netfilter.h:325 [inline]
 ndisc_send_skb+0xa8e/0x1bf0 net/ipv6/ndisc.c:513
 ndisc_send_rs+0x129/0x680 net/ipv6/ndisc.c:724
 addrconf_rs_timer+0x424/0x880 net/ipv6/addrconf.c:4099
 call_timer_fn+0x198/0x5f0 kernel/time/timer.c:1749
 expire_timers kernel/time/timer.c:1800 [inline]
 __run_timers+0x757/0xb00 kernel/time/timer.c:2375
 __run_timer_base kernel/time/timer.c:2387 [inline]
 __run_timer_base kernel/time/timer.c:2379 [inline]
 run_timer_base+0x114/0x190 kernel/time/timer.c:2396
 run_timer_softirq+0x1a/0x50 kernel/time/timer.c:2406
 handle_softirqs+0x216/0xa20 kernel/softirq.c:669
 __do_softirq kernel/softirq.c:703 [inline]
 invoke_softirq kernel/softirq.c:542 [inline]
 __irq_exit_rcu+0x178/0x220 kernel/softirq.c:786
 irq_exit_rcu+0x9/0x30 kernel/softirq.c:809
 instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1062 [inline]
 sysvec_apic_timer_interrupt+0xa3/0xc0 arch/x86/kernel/apic/apic.c:1062
 </IRQ>
 <TASK>
 asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:674
RIP: 0010:__raw_spin_unlock_irq include/linux/spinlock_api_smp.h:220 [inline]
RIP: 0010:_raw_spin_unlock_irq+0x29/0x50 kernel/locking/spinlock.c:229
Code: 90 f3 0f 1e fa 53 48 8b 74 24 08 48 89 fb 48 83 c7 18 e8 8a 1b f7 f5 48 89 df e8 12 72 f7 f5 e8 8d 86 24 f6 fb bf 01 00 00 00 <e8> c2 3a e6 f5 65 48 83 3d 51 64 c8 09 00 74 06 5b e9 01 4d 00 00
RSP: 0018:ffffc90003487c28 EFLAGS: 00000206
RAX: 0000000000000517 RBX: ffffffff90cc2ac0 RCX: 0000000000000080
RDX: 0000000000000001 RSI: ffffffff8e629989 RDI: 0000000000000001
RBP: 0000000000000060 R08: 0000000000000001 R09: 0000000000000000
R10: 0000000000000001 R11: 0000000000000000 R12: ffff8880247aa000
R13: 000000004ce5e1cb R14: ffffffff8be39d00 R15: 0000000000000019
 pci_user_write_config_dword+0x150/0x230 drivers/pci/access.c:278
 proc_bus_pci_write+0x531/0x5e0 drivers/pci/proc.c:173
 pde_write fs/proc/inode.c:330 [inline]
 proc_reg_write+0x240/0x330 fs/proc/inode.c:342
 vfs_write+0x2aa/0x1050 fs/read_write.c:685
 ksys_write+0x12a/0x250 fs/read_write.c:739
 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
 do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f1f2d39fb19
Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f1f2e2a6028 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00007f1f2d625fa0 RCX: 00007f1f2d39fb19
RDX: 000000000000007d RSI: 0000200000000240 RDI: 0000000000000003
RBP: 00007f1f2d437b70 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007f1f2d626038 R14: 00007f1f2d625fa0 R15: 00007ffeebd3c9f8
 </TASK>
----------------
Code disassembly (best guess):
   0:	90                   	nop
   1:	f3 0f 1e fa          	endbr64
   5:	53                   	push   %rbx
   6:	48 8b 74 24 08       	mov    0x8(%rsp),%rsi
   b:	48 89 fb             	mov    %rdi,%rbx
   e:	48 83 c7 18          	add    $0x18,%rdi
  12:	e8 8a 1b f7 f5       	call   0xf5f71ba1
  17:	48 89 df             	mov    %rbx,%rdi
  1a:	e8 12 72 f7 f5       	call   0xf5f77231
  1f:	e8 8d 86 24 f6       	call   0xf62486b1
  24:	fb                   	sti
  25:	bf 01 00 00 00       	mov    $0x1,%edi
* 2a:	e8 c2 3a e6 f5       	call   0xf5e63af1 <-- trapping instruction
  2f:	65 48 83 3d 51 64 c8 	cmpq   $0x0,%gs:0x9c86451(%rip)        # 0x9c86489
  36:	09 00
  38:	74 06                	je     0x40
  3a:	5b                   	pop    %rbx
  3b:	e9 01 4d 00 00       	jmp    0x4d41

Crashes (1):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2026/11/08 04:39 upstream d164c7d754f0 5cecaf1f .config console log report syz / log C [disk image (non-bootable)] [vmlinux] [kernel image] ci-qemu-upstream BUG: spinlock bad magic in sock_wfree
* Struck through repros no longer work on HEAD.