mac802154_beacon_worker() looks up beacon_req under RCU and takes a reference on the selected interface's netdev before dropping the RCU read lock. It then passes the selected wpan_dev to mac802154_transmit_beacon(). mac802154_transmit_beacon() ignores that argument when choosing sdata and reads local->beacon_req again. If the beacon request switches to another interface between the two reads, the worker pins the old interface while the transmit path uses the new one. Removing the new interface can then free its netdev before ieee802154_mlme_tx_locked() dereferences it, causing a KASAN use-after-free. Derive sdata from the wpan_dev already selected and pinned by the worker. This also removes the redundant RCU lookup. The reproducer hit the use-after-free on two separate v7.3 KASAN boots before this change and completed without a KASAN report in three runs afterward. Fixes: 5f26a690e8ef ("mac802154: fix netdev use-after-free in beacon worker") Cc: stable@vger.kernel.org Reviewed-by: Miquel Raynal Signed-off-by: Yifan Zhang --- net/mac802154/scan.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/net/mac802154/scan.c b/net/mac802154/scan.c index d393b1f..9f0e45b 100644 --- a/net/mac802154/scan.c +++ b/net/mac802154/scan.c @@ -353,7 +353,6 @@ int mac802154_process_beacon(struct ieee802154_local *local, static int mac802154_transmit_beacon(struct ieee802154_local *local, struct wpan_dev *wpan_dev) { - struct cfg802154_beacon_request *beacon_req; struct ieee802154_sub_if_data *sdata; struct sk_buff *skb; int ret; @@ -365,19 +364,9 @@ static int mac802154_transmit_beacon(struct ieee802154_local *local, if (!skb) return -ENOBUFS; - rcu_read_lock(); - beacon_req = rcu_dereference(local->beacon_req); - if (unlikely(!beacon_req)) { - rcu_read_unlock(); - kfree_skb(skb); - return -EINVAL; - } - - sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(beacon_req->wpan_dev); + sdata = IEEE802154_WPAN_DEV_TO_SUB_IF(wpan_dev); skb->dev = sdata->dev; - rcu_read_unlock(); - ret = ieee802154_beacon_push(skb, &local->beacon); if (ret) { kfree_skb(skb); -- 2.39.5 (Apple Git-154)