mirror of
https://github.com/torvalds/linux.git
synced 2024-12-13 22:53:20 +00:00
e02a3b9458
There is a leak in rtl8712 driver.
The problem was in non-freed adapter data if
firmware load failed.
This leak can be reproduced with this code:
https://syzkaller.appspot.com/text?tag=ReproC&x=16612f02d00000,
Autoload must fail (to not hit memory leak reported by syzkaller)
There are 2 possible ways how rtl871x_load_fw_cb() and
r871xu_dev_remove() can be called (in case of fw load error).
1st case:
r871xu_dev_remove() then rtl871x_load_fw_cb()
In this case r871xu_dev_remove() will wait for
completion and then will jump to the end, because
rtl871x_load_fw_cb() set intfdata to NULL:
if (pnetdev) {
struct _adapter *padapter = netdev_priv(pnetdev);
/* never exit with a firmware callback pending */
wait_for_completion(&padapter->rtl8712_fw_ready);
pnetdev = usb_get_intfdata(pusb_intf);
usb_set_intfdata(pusb_intf, NULL);
if (!pnetdev)
goto firmware_load_fail;
... clean up code here ...
}
2nd case:
rtl871x_load_fw_cb() then r871xu_dev_remove()
In this case pnetdev (from code snippet above) will
be zero (because rtl871x_load_fw_cb() set it to NULL)
And clean up code won't be executed again.
So, in all cases we need to free adapted data in rtl871x_load_fw_cb(),
because disconnect function cannot take care of it. And there won't be
any race conditions, because complete() call happens after setting
intfdata to NULL.
In previous patch I moved out free_netdev() from r8712_free_drv_sw()
and that's why now it's possible to free adapter data and then call
complete.
Fixes:
|
||
---|---|---|
.. | ||
basic_types.h | ||
drv_types.h | ||
ethernet.h | ||
hal_init.c | ||
ieee80211.c | ||
ieee80211.h | ||
Kconfig | ||
Makefile | ||
mlme_linux.c | ||
mlme_osdep.h | ||
mp_custom_oid.h | ||
os_intfs.c | ||
osdep_intf.h | ||
osdep_service.h | ||
recv_linux.c | ||
recv_osdep.h | ||
rtl871x_cmd.c | ||
rtl871x_cmd.h | ||
rtl871x_debug.h | ||
rtl871x_eeprom.c | ||
rtl871x_eeprom.h | ||
rtl871x_event.h | ||
rtl871x_ht.h | ||
rtl871x_io.c | ||
rtl871x_io.h | ||
rtl871x_ioctl_linux.c | ||
rtl871x_ioctl_rtl.c | ||
rtl871x_ioctl_rtl.h | ||
rtl871x_ioctl_set.c | ||
rtl871x_ioctl_set.h | ||
rtl871x_ioctl.h | ||
rtl871x_led.h | ||
rtl871x_mlme.c | ||
rtl871x_mlme.h | ||
rtl871x_mp_ioctl.c | ||
rtl871x_mp_ioctl.h | ||
rtl871x_mp_phy_regdef.h | ||
rtl871x_mp.c | ||
rtl871x_mp.h | ||
rtl871x_pwrctrl.c | ||
rtl871x_pwrctrl.h | ||
rtl871x_recv.c | ||
rtl871x_recv.h | ||
rtl871x_rf.h | ||
rtl871x_security.c | ||
rtl871x_security.h | ||
rtl871x_sta_mgt.c | ||
rtl871x_wlan_sme.h | ||
rtl871x_xmit.c | ||
rtl871x_xmit.h | ||
rtl8712_bitdef.h | ||
rtl8712_cmd.c | ||
rtl8712_cmd.h | ||
rtl8712_cmdctrl_bitdef.h | ||
rtl8712_cmdctrl_regdef.h | ||
rtl8712_debugctrl_bitdef.h | ||
rtl8712_debugctrl_regdef.h | ||
rtl8712_edcasetting_bitdef.h | ||
rtl8712_edcasetting_regdef.h | ||
rtl8712_efuse.c | ||
rtl8712_efuse.h | ||
rtl8712_event.h | ||
rtl8712_fifoctrl_bitdef.h | ||
rtl8712_fifoctrl_regdef.h | ||
rtl8712_gp_bitdef.h | ||
rtl8712_gp_regdef.h | ||
rtl8712_hal.h | ||
rtl8712_interrupt_bitdef.h | ||
rtl8712_io.c | ||
rtl8712_led.c | ||
rtl8712_macsetting_bitdef.h | ||
rtl8712_macsetting_regdef.h | ||
rtl8712_powersave_bitdef.h | ||
rtl8712_powersave_regdef.h | ||
rtl8712_ratectrl_bitdef.h | ||
rtl8712_ratectrl_regdef.h | ||
rtl8712_recv.c | ||
rtl8712_recv.h | ||
rtl8712_regdef.h | ||
rtl8712_security_bitdef.h | ||
rtl8712_spec.h | ||
rtl8712_syscfg_bitdef.h | ||
rtl8712_syscfg_regdef.h | ||
rtl8712_timectrl_bitdef.h | ||
rtl8712_timectrl_regdef.h | ||
rtl8712_wmac_bitdef.h | ||
rtl8712_wmac_regdef.h | ||
rtl8712_xmit.c | ||
rtl8712_xmit.h | ||
sta_info.h | ||
TODO | ||
usb_halinit.c | ||
usb_intf.c | ||
usb_ops_linux.c | ||
usb_ops.c | ||
usb_ops.h | ||
usb_osintf.h | ||
wifi.h | ||
wlan_bssdef.h | ||
xmit_linux.c | ||
xmit_osdep.h |