In the Linux kernel, the following vulnerability has been resolved: PCI: Fix use-after-free in pcibusreleasedomainnr() Commit c14f7ccc9f5d ("PCI: Assign PCI domain IDs by idaalloc()") introduced a use-after-free bug in the bus removal cleanup. The issue was found with kfence: [ 19.293351] BUG: KFENCE: use-after-free read in pcibusreleasedomainnr+0x10/0x70 [ 19.302817] Use-after-free read at 0x000000007f3b80eb (in kfence-#115): [ 19.309677] pcibusreleasedomainnr+0x10/0x70 [ 19.309691] dwpciehostdeinit+0x28/0x78 [ 19.309702] tegrapciedeinitcontroller+0x1c/0x38 [pcietegra194] [ 19.309734] tegrapciedwprobe+0x648/0xb28 [pcietegra194] [ 19.309752] platformprobe+0x90/0xd8 ... [ 19.311457] kfence-#115: 0x00000000063a155a-0x00000000ba698da8, size=1072, cache=kmalloc-2k [ 19.311469] allocated by task 96 on cpu 10 at 19.279323s: [ 19.311562] _kmemcacheallocnode+0x260/0x278 [ 19.311571] kmalloctrace+0x24/0x30 [ 19.311580] pciallocbus+0x24/0xa0 [ 19.311590] pciregisterhostbridge+0x48/0x4b8 [ 19.311601] pciscanrootbusbridge+0xc0/0xe8 [ 19.311613] pcihostprobe+0x18/0xc0 [ 19.311623] dwpciehostinit+0x2c0/0x568 [ 19.311630] tegrapciedwprobe+0x610/0xb28 [pcietegra194] [ 19.311647] platformprobe+0x90/0xd8 ... [ 19.311782] freed by task 96 on cpu 10 at 19.285833s: [ 19.311799] releasepcibusdev+0x30/0x40 [ 19.311808] devicerelease+0x30/0x90 [ 19.311814] kobjectput+0xa8/0x120 [ 19.311832] deviceunregister+0x20/0x30 [ 19.311839] pciremovebus+0x78/0x88 [ 19.311850] pciremoverootbus+0x5c/0x98 [ 19.311860] dwpciehostdeinit+0x28/0x78 [ 19.311866] tegrapciedeinitcontroller+0x1c/0x38 [pcietegra194] [ 19.311883] tegrapciedwprobe+0x648/0xb28 [pcietegra194] [ 19.311900] platformprobe+0x90/0xd8 ... [ 19.313579] CPU: 10 PID: 96 Comm: kworker/u24:2 Not tainted 6.2.0 #4 [ 19.320171] Hardware name: /, BIOS 1.0-d7fb19b 08/10/2022 [ 19.325852] Workqueue: eventsunbound deferredprobeworkfunc The stack trace is a bit misleading as dwpciehostdeinit() doesn't directly call pcibusreleasedomainnr(). The issue turns out to be in pciremoverootbus() which first calls pciremovebus() which frees the struct pcibus when its struct device is released. Then pcibusreleasedomainnr() is called and accesses the freed struct pci_bus. Reordering these fixes the issue.