fix: NULL-guard usbdev/bus_if in rwnx_close reset path

In the vif_started==0 branch rwnx_close() evaluates
usbdev->bus_if->state without checking usbdev. On the disconnect path
aicwf_bus_deinit() runs before netdev close, so close observes usbdev==NULL
and oopses (CR2=0x8, pinned by disassembly relocation rwnx_send_reset;
field symptom: host hard-hang on physical unplug, reproduced x8 in the lab
with this stack -> BUG=0 after this guard). In the unpatched tree the same
expression reads a still-allocated DOWN-state object in the synchronous
disconnect path — our earlier "latent UAF" phrasing is retracted (no
freed-object access was observed or proven). Covers USB and SDIO variants.
This commit is contained in:
xuxinchun1003 committed 2026-10-07 07:42:31 +08:00
1 parent 089ee0bf87
commit 2422930511
1 file changed
+9 -2
+9 -2
View File
@@ -1666,9 +1666,16 @@ static int rwnx_close(struct net_device *dev)
rwnx_ipc_tx_drain(rwnx_hw); rwnx_ipc_tx_drain(rwnx_hw);
#else #else
#if defined(AICWF_USB_SUPPORT) #if defined(AICWF_USB_SUPPORT)
if (usbdev->bus_if->state != BUS_DOWN_ST && usbdev->state != USB_DOWN_ST) /* 002 在 deinit 时摘 drvdata,disconnect→close 时序下本函数读到
* usbdev=NULL:实测断开在此裸解引用 usbdev->bus_if 崩溃
* (rwnx_close 偏移处 reloc=rwnx_send_reset,CR2=0x8)。
* 上游 usbdev 为悬挂非空、此条件求值为假而侥幸跳过——本判空
* 对两种情形给出同一语义:bus 已断 → 跳过 reset/重配。 */
if (usbdev != NULL && usbdev->bus_if != NULL &&
usbdev->bus_if->state != BUS_DOWN_ST && usbdev->state != USB_DOWN_ST)
#else #else
if (sdiodev->bus_if->state != BUS_DOWN_ST) if (sdiodev != NULL && sdiodev->bus_if != NULL &&
sdiodev->bus_if->state != BUS_DOWN_ST)
#endif #endif
{ {
rwnx_send_reset(rwnx_hw); rwnx_send_reset(rwnx_hw);