Re: [PATCH 1/3] PCI/sysfs: fix null pointer dereference during PCI hotplug
From: duziming
Date: Tue Dec 23 2025 - 20:28:43 EST
在 2025/12/24 0:55, Bjorn Helgaas 写道:
Capitalize first word of subject to match history (seeThanks for your correction. We will include them in the v2 patch
"git log --oneline drivers/pci/pci-sysfs.c")
Drop "PCI" in "PCI hotplug" -- we already know this is PCI.
On Tue, Dec 16, 2025 at 04:39:10PM +0800, Ziming Du wrote:
During the concurrent process of creating and rescanning in VF, the resourceWrap this to fit in 75 columns so it still fits in 80 when git log
files for the same "pci_dev" may be created twice. The second creation attempt
fails, resulting the "res_attr" in "pci_dev" to 'kfree', but the pointer is not
set to NULL. This will subsequently lead to dereferencing a null pointer when
removing the device.
indents it.
Drop quotes around struct and member names, e.g., pci_dev, res_attr.
Drop '' around function names and add "()" after, e.g., kfree().
When we perform the following operation:Indent quoted material two spaces and drop the "" around it, e.g.,
"echo $vfcount > /sys/class/net/"$pfname"/device/sriov_numvfs &
sleep 0.5
echo 1 > /sys/bus/pci/rescan
pci_remove "$pfname" "
system will crash as follows:
When we perform the following operation:
echo $vfcount > /sys/class/net/"$pfname"/device/sriov_numvfs &
sleep 0.5
...
system will crash as follows.
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000Indent this quoted material two spaces and remove parts that aren't
Mem abort info:
ESR = 0x0000000096000004
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
FSC = 0x04: level 0 translation fault
Data abort info:
ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
CM = 0, WnR = 0, TnD = 0, TagAccess = 0
GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
user pgtable: 4k pages, 48-bit VAs, pgdp=000020400d47b000
0000000000000000 pgd=0000000000000000, p4d=0000000000000000
Internal error: Oops: 0000000096000004 #1 SMP
CPU: 115 PID: 13659 Comm: testEL_vf_resca Kdump: loaded Tainted: G W E 6.6.0 #9
Hardware name: Huawei TaiShan 2280 V2/BC82AMDD, BIOS 0.98 08/25/2019
pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
pc : __pi_strlen+0x14/0x150
lr : kernfs_name_hash+0x24/0xa8
sp : ffff8001425c38f0
x29: ffff8001425c38f0 x28: ffff204021a21540 x27: 0000000000000000
x26: 0000000000000000 x25: 0000000000000000 x24: ffff20400f97fad0
x23: ffff20403145a0c0 x22: 0000000000000000 x21: 0000000000000000
x20: 0000000000000000 x19: 0000000000000000 x18: ffffffffffffffff
x17: 2f35322f38302038 x16: 392e3020534f4942 x15: 00000000fffffffd
x14: 0000000000000000 x13: 30643378302f3863 x12: 3378302b636e7973
x11: 00000000ffff7fff x10: 0000000000000000 x9 : ffff800100594b3c
x8 : 0101010101010101 x7 : 0000000000210d00 x6 : 67241f72241f7224
x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
x2 : 0000000000000000 x1 : 0000000000000000 x0 : 0000000000000000
Call trace:
__pi_strlen+0x14/0x150
kernfs_find_ns+0x54/0x120
kernfs_remove_by_name_ns+0x58/0xf0
sysfs_remove_bin_file+0x24/0x38
pci_remove_resource_files+0x44/0x90
pci_remove_sysfs_dev_files+0x28/0x40
pci_stop_bus_device+0xb8/0x118
pci_stop_and_remove_bus_device+0x20/0x40
pci_iov_remove_virtfn+0xb8/0x138
sriov_disable+0xbc/0x190
pci_disable_sriov+0x30/0x48
hinic_pci_sriov_disable+0x54/0x138 [hinic]
hinic_remove+0x140/0x290 [hinic]
pci_device_remove+0x4c/0xf8
device_remove+0x54/0x90
device_release_driver_internal+0x1d4/0x238
device_release_driver+0x20/0x38
pci_stop_bus_device+0xa8/0x118
pci_stop_and_remove_bus_device_locked+0x28/0x50
remove_store+0x128/0x208
relevant.
Fix this by set the pointer to NULL after releasing 'res_attr' immediately.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Ziming Du <duziming2@xxxxxxxxxx>
---
drivers/pci/pci-sysfs.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index c2df915ad2d2..7e697b82c5e1 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1222,12 +1222,14 @@ static void pci_remove_resource_files(struct pci_dev *pdev)
if (res_attr) {
sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
kfree(res_attr);
+ pdev->res_attr[i] = NULL;
}
res_attr = pdev->res_attr_wc[i];
if (res_attr) {
sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
kfree(res_attr);
+ pdev->res_attr_wc[i] = NULL;
}
}
}
--
2.43.0