WARNING in pci_add_new_bus

Status: upstream: reported syz repro on 2026/11/02 03:47
Subsystems: pci
Labels: prio:normal
[Documentation on labels]
Reported-by: syzbot+ea7278bdcb20a491495b@syzkaller.appspotmail.com
First crash: 1d12h, last: 1d12h
✨ AI-generated root cause summary:

In drivers/pci/probe.c:pci_alloc_child_bus(), device_register(&child->dev) failure is checked using WARN_ON(ret < 0). When device_register() fails due to normal runtime resource exhaustion (such as -ENOMEM, triggered in syzkaller by fault injection via /proc/thread-self/fail-nth), this check emits a spurious kernel WARNING. Furthermore, pci_alloc_child_bus() assigns bridge->subordinate = child and updates bridge->resource[...].name before calling device_register(); when device_register() fails, put_device(&child->dev) frees the child bus via release_pcibus_dev(), but bridge->subordinate and bridge->resource names are not reset to NULL, leaving dangling pointers to freed memory.

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

Technical Analysis: Root Cause of WARNING in pci_alloc_child_bus

1. Overview & Location

The bug manifests in drivers/pci/probe.c within pci_alloc_child_bus() (called during bus allocation in pci_add_new_bus() during rescan via /sys/bus/pci/rescan):

// drivers/pci/probe.c:1263-1275
	for (i = 0; i < PCI_BRIDGE_RESOURCE_NUM; i++) {
		child->resource[i] = &bridge->resource[PCI_BRIDGE_RESOURCES+i];
		child->resource[i]->name = child->name;
	}
	bridge->subordinate = child;

add_dev:
	pci_set_bus_msi_domain(child);
	ret = device_register(&child->dev);
	if (WARN_ON(ret < 0)) {
		put_device(&child->dev);
		return NULL;
	}

2. Trigger Mechanism & Immediate Cause of WARNING

In the reproducer, fault injection is configured via /proc/thread-self/fail-nth before triggering a PCI bus rescan (rescan_store() -> pci_rescan_bus() -> pci_scan_child_bus_extend() -> pci_scan_bridge_extend() -> pci_add_new_bus() -> pci_alloc_child_bus()).

During device_register(&child->dev), internal allocations (e.g., inside device_add() or kobject_add()) fail, causing device_register() to return -ENOMEM (observed as RBP: 0x00000000fffffff4 in the CPU register dump, which corresponds to -12).

In Linux device core code, device_register() can legitimately fail at runtime due to resource exhaustion or transient allocation failures. Checking its return value with WARN_ON(ret < 0) is incorrect because -ENOMEM is a standard runtime condition rather than an internal kernel invariant violation. This causes the kernel warning to fire whenever allocation fails during device registration.

3. Incomplete Error Cleanup & Dangling Pointer

Prior to attempting device_register(&child->dev), pci_alloc_child_bus() performs the following initialization when bridge is non-NULL:

  1. Links the bridge's resources to the child: child->resource[i]->name = child->name (lines 1263–1266).
  2. Sets the bridge's subordinate pointer: bridge->subordinate = child (line 1267).

When device_register(&child->dev) returns an error:

  1. put_device(&child->dev) is called to drop the initial reference of child->dev.
  2. As a result, the bus class release function release_pcibus_dev() is invoked, which releases resources and calls kfree(pci_bus), freeing the struct pci_bus allocated for child.
  3. However, pci_alloc_child_bus() returns NULL without undoing the bridge assignments:
    • bridge->subordinate is not set back to NULL.
    • bridge->resource[PCI_BRIDGE_RESOURCES + i].name is left pointing into the freed child->name buffer.

This leaves bridge->subordinate as a dangling pointer to a freed struct pci_bus object, exposing the system to use-after-free and memory corruption during subsequent PCI bridge operations, bus rescans, or bridge device teardown (pci_remove_bus_device()).

▶ ▼ ✨ AI Jobs (1)
ID Workflow Result Correct Bug Created Started Finished Revision
c4703996 assessment-security DenialOfService: ✅ Exploitable: ✅ FilesystemTrigger: ❌ FuzzingArtifact: ❌ MemoryCorruption: ✅ NetworkNeedsSetup: ❌ NetworkTrigger: ❌ PeripheralTrigger: ❌ RemoteTrigger: ❌ Unprivileged: ❌ UserNamespace: ❌ VMGuestTrigger: ❌ VMHostTrigger: ❌ ❓ WARNING in pci_add_new_bus 2026/11/01 01:17 2026/11/01 01:17 2026/11/01 01:57 25a0ae84
▶ ▼ Discussions (2)
Title Replies (including bot) Last reply
[PATCH] PCI: Fix pci_alloc_child_bus() error path 1 (1) 2026/11/02 06:40
[syzbot] [pci?] WARNING in pci_add_new_bus 0 (1) 2026/11/02 03:47

Sample crash report:
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fc139c26038 R14: 00007fc139c25fa0 R15: 00007ffe91ac8be8
 </TASK>
------------[ cut here ]------------
ret < 0
WARNING: drivers/pci/probe.c:1272 at pci_alloc_child_bus drivers/pci/probe.c:1272 [inline], CPU#2: syz.3.21/6134
WARNING: drivers/pci/probe.c:1272 at pci_add_new_bus+0xda4/0x12e0 drivers/pci/probe.c:1293, CPU#2: syz.3.21/6134
Modules linked in:
CPU: 2 UID: 0 PID: 6134 Comm: syz.3.21 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
RIP: 0010:pci_alloc_child_bus drivers/pci/probe.c:1272 [inline]
RIP: 0010:pci_add_new_bus+0xda4/0x12e0 drivers/pci/probe.c:1293
Code: fd ff ff e8 1e 5e 95 fc 44 8b 74 24 18 31 ff 44 89 f6 e8 7f 58 95 fc 45 85 f6 74 dc 45 31 f6 e9 71 fd ff ff e8 fd 5d 95 fc 90 <0f> 0b 90 48 8b 3c 24 e8 c0 c6 03 01 31 db e9 92 fb ff ff e8 e4 5d
RSP: 0018:ffffc90003e3f988 EFLAGS: 00010293
RAX: 0000000000000000 RBX: ffff888050413000 RCX: 0000000000000000
RDX: ffff88802e362580 RSI: ffffffff8578e803 RDI: 0000000000000005
RBP: 00000000fffffff4 R08: 0000000000000000 R09: 00000000fffffff4
R10: ffff888050413153 R11: 0000000000000001 R12: ffff888024497000
R13: 1ffff920007c7f36 R14: ffff8880504130dc R15: ffff8880565849a0
FS:  00007fc13a9046c0(0000) GS:ffff8880d467f000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fc1399ecc40 CR3: 0000000035790000 CR4: 0000000000352ef0
Call Trace:
 <TASK>
 pci_scan_bridge_extend+0x9e3/0xb70 drivers/pci/probe.c:1473
 pci_scan_child_bus_extend+0x449/0x7b0 drivers/pci/probe.c:3138
 pci_scan_child_bus drivers/pci/probe.c:3216 [inline]
 pci_rescan_bus+0x18/0x40 drivers/pci/probe.c:3507
 rescan_store+0xfb/0x130 drivers/pci/pci-sysfs.c:474
 bus_attr_store+0x74/0xb0 drivers/base/bus.c:172
 sysfs_kf_write+0xf2/0x150 fs/sysfs/file.c:145
 kernfs_fop_write_iter+0x3e0/0x5f0 fs/kernfs/file.c:345
 new_sync_write fs/read_write.c:595 [inline]
 vfs_write+0x6af/0x1050 fs/read_write.c:687
 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:0x7fc13999f559
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:00007fc13a904028 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00007fc139c25fa0 RCX: 00007fc13999f559
RDX: 000000000000001e RSI: 0000200000000280 RDI: 0000000000000004
RBP: 00007fc139a36b50 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fc139c26038 R14: 00007fc139c25fa0 R15: 00007ffe91ac8be8
 </TASK>

Crashes (1):
Time Kernel Commit Syzkaller Config Log Report Syz repro C repro VM info Assets (help?) Manager Title
2026/11/01 01:17 upstream 36aad21d50d1 25a0ae84 .config console log report syz / log [disk image (non-bootable)] [vmlinux] [kernel image] ci-qemu-upstream WARNING in pci_add_new_bus
* Struck through repros no longer work on HEAD.