linux/drivers/net
Duoming Zhou 9cb83d4be0 wifi: brcmfmac: fix use-after-free when rescheduling brcmf_btcoex_info work
The brcmf_btcoex_detach() only shuts down the btcoex timer, if the
flag timer_on is false. However, the brcmf_btcoex_timerfunc(), which
runs as timer handler, sets timer_on to false. This creates critical
race conditions:

1.If brcmf_btcoex_detach() is called while brcmf_btcoex_timerfunc()
is executing, it may observe timer_on as false and skip the call to
timer_shutdown_sync().

2.The brcmf_btcoex_timerfunc() may then reschedule the brcmf_btcoex_info
worker after the cancel_work_sync() has been executed, resulting in
use-after-free bugs.

The use-after-free bugs occur in two distinct scenarios, depending on
the timing of when the brcmf_btcoex_info struct is freed relative to
the execution of its worker thread.

Scenario 1: Freed before the worker is scheduled

The brcmf_btcoex_info is deallocated before the worker is scheduled.
A race condition can occur when schedule_work(&bt_local->work) is
called after the target memory has been freed. The sequence of events
is detailed below:

CPU0                           | CPU1
brcmf_btcoex_detach            | brcmf_btcoex_timerfunc
                               |   bt_local->timer_on = false;
  if (cfg->btcoex->timer_on)   |
    ...                        |
  cancel_work_sync();          |
  ...                          |
  kfree(cfg->btcoex); // FREE  |
                               |   schedule_work(&bt_local->work); // USE

Scenario 2: Freed after the worker is scheduled

The brcmf_btcoex_info is freed after the worker has been scheduled
but before or during its execution. In this case, statements within
the brcmf_btcoex_handler() — such as the container_of macro and
subsequent dereferences of the brcmf_btcoex_info object will cause
a use-after-free access. The following timeline illustrates this
scenario:

CPU0                            | CPU1
brcmf_btcoex_detach             | brcmf_btcoex_timerfunc
                                |   bt_local->timer_on = false;
  if (cfg->btcoex->timer_on)    |
    ...                         |
  cancel_work_sync();           |
  ...                           |   schedule_work(); // Reschedule
                                |
  kfree(cfg->btcoex); // FREE   |   brcmf_btcoex_handler() // Worker
  /*                            |     btci = container_of(....); // USE
   The kfree() above could      |     ...
   also occur at any point      |     btci-> // USE
   during the worker's execution|
   */                           |

To resolve the race conditions, drop the conditional check and call
timer_shutdown_sync() directly. It can deactivate the timer reliably,
regardless of its current state. Once stopped, the timer_on state is
then set to false.

Fixes: 61730d4dff ("brcmfmac: support critical protocol API for DHCP")
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Duoming Zhou <duoming@zju.edu.cn>
Link: https://patch.msgid.link/20250822050839.4413-1-duoming@zju.edu.cn
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
2025-08-26 13:46:18 +02:00
..
arcnet
bonding bonding: send LACPDUs periodically in passive mode after receiving partner's LACPDU 2025-08-21 09:35:20 +02:00
caif
can treewide: rename GPIO set callbacks back to their original names 2025-08-07 10:07:06 +02:00
dsa net: dsa: microchip: Fix KSZ9477 HSR port setup issue 2025-08-20 19:25:38 -07:00
ethernet net/mlx5e: Preserve shared buffer capacity during headroom updates 2025-08-21 07:58:33 -07:00
fddi
fjes
hamradio hamradio: ignore ops-locked netdevs 2025-08-08 13:22:28 -07:00
hippi
hyperv hv_netvsc: Fix panic during namespace deletion with VF 2025-08-08 13:24:16 -07:00
ieee802154
ipa ipa: fix compile-testing with qcom-mdt=m 2025-08-04 17:15:15 -07:00
ipvlan net: s/dev_pre_changeaddr_notify/netif_pre_changeaddr_notify/ 2025-07-18 17:27:47 -07:00
mctp
mdio net: mdio: mdio-bcm-unimac: Correct rate fallback logic 2025-08-01 14:46:50 -07:00
netdevsim netdevsim: Fix wild pointer access in nsim_queue_free(). 2025-08-13 17:26:39 -07:00
ovpn Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2025-07-17 11:00:33 -07:00
pcs net: pcs: xpcs: mask readl() return value to 16 bits 2025-07-17 18:45:27 -07:00
phy phy: mscc: Fix timestamping for vsc8584 2025-08-19 17:52:02 -07:00
plip
ppp ppp: fix race conditions in ppp_fill_forward_path 2025-08-19 11:25:32 +02:00
pse-pd net: pse-pd: pd692x0: Skip power budget configuration when undefined 2025-08-21 07:56:08 -07:00
slip
team
thunderbolt
usb net: usb: asix_devices: Fix PHY address mask in MDIO bus initialization 2025-08-19 17:52:29 -07:00
vmxnet3
vxlan vxlan: remove redundant conversion of vni in vxlan_nl2conf 2025-07-23 17:09:29 -07:00
wan net: lapbether: ignore ops-locked netdevs 2025-08-08 13:22:28 -07:00
wireguard wireguard: peer: Replace sockaddr with sockaddr_inet 2025-07-25 15:29:58 -07:00
wireless wifi: brcmfmac: fix use-after-free when rescheduling brcmf_btcoex_info work 2025-08-26 13:46:18 +02:00
wwan
xen-netback
Kconfig
LICENSE.SRC
Makefile
Space.c
amt.c
bareudp.c
dummy.c
eql.c
geneve.c
gtp.c
ifb.c
loopback.c
macsec.c macsec: set IFF_UNICAST_FLT priv flag 2025-07-25 11:03:46 -07:00
macvlan.c
macvtap.c
mdio.c
mhi_net.c
mii.c
net_failover.c
netconsole.c
netkit.c
nlmon.c
ntb_netdev.c
pfcp.c
rionet.c
sungem_phy.c
tap.c net: s/dev_get_mac_address/netif_get_mac_address/ 2025-07-18 17:27:46 -07:00
tun.c net: s/dev_get_mac_address/netif_get_mac_address/ 2025-07-18 17:27:46 -07:00
tun_vnet.h
veth.c
virtio_net.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2025-07-17 11:00:33 -07:00
vrf.c vrf: Drop existing dst reference in vrf_ip6_input_dst 2025-07-26 11:28:45 -07:00
vsockmon.c
xen-netfront.c xen/netfront: Fix TX response spurious interrupts 2025-07-23 13:11:03 +02:00