mirror of
https://github.com/torvalds/linux.git
synced 2026-10-25 08:16:03 +01:00
wifi: mac80211: fix mesh fast xmit path deletion UAF
mesh_fast_tx_cache() stores raw mesh_path pointers. Path deletion
flushes the cache and then frees the path with kfree_rcu(), but a
lookup that already holds the path can insert a new cache entry
after the flush. The cache then points at freed memory.
Set MESH_PATH_DELETED before flushing, and skip inserting a cache
entry if the path or MPP path is already deleted. Check this under
the cache walk lock so it is ordered with the flush. Use WRITE_ONCE()
for the deletion flag updates because the cache check reads flags
without taking state_lock.
Fixes: d5edb9ae8d ("wifi: mac80211: mesh fast xmit support")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Assisted-by: LLM
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Link: https://patch.msgid.link/1daa7a98199fe6965c2da7c42717073a6fd39a0b.1789615568.git.zihanx@nebusec.ai
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
5e4f350979
commit
ee3aadc43e
|
|
@ -577,6 +577,12 @@ void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
|
|||
goto unlock_sta;
|
||||
|
||||
spin_lock(&cache->walk_lock);
|
||||
if ((READ_ONCE(mpath->flags) & MESH_PATH_DELETED) ||
|
||||
(mppath && (READ_ONCE(mppath->flags) & MESH_PATH_DELETED))) {
|
||||
kfree(entry);
|
||||
goto unlock_cache;
|
||||
}
|
||||
|
||||
prev = rhashtable_lookup_get_insert_fast(&cache->rht,
|
||||
&entry->rhash,
|
||||
fast_tx_rht_params);
|
||||
|
|
@ -808,7 +814,8 @@ static void mesh_path_free_rcu(struct mesh_table *tbl,
|
|||
struct ieee80211_sub_if_data *sdata = mpath->sdata;
|
||||
|
||||
spin_lock_bh(&mpath->state_lock);
|
||||
mpath->flags |= MESH_PATH_RESOLVING | MESH_PATH_DELETED;
|
||||
WRITE_ONCE(mpath->flags,
|
||||
mpath->flags | MESH_PATH_RESOLVING | MESH_PATH_DELETED);
|
||||
mesh_gate_del(tbl, mpath);
|
||||
spin_unlock_bh(&mpath->state_lock);
|
||||
timer_shutdown_sync(&mpath->timer);
|
||||
|
|
@ -822,6 +829,9 @@ static void __mesh_path_del(struct mesh_table *tbl, struct mesh_path *mpath)
|
|||
{
|
||||
hlist_del_rcu(&mpath->walk_list);
|
||||
rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params);
|
||||
spin_lock_bh(&mpath->state_lock);
|
||||
WRITE_ONCE(mpath->flags, mpath->flags | MESH_PATH_DELETED);
|
||||
spin_unlock_bh(&mpath->state_lock);
|
||||
if (tbl == &mpath->sdata->u.mesh.mpp_paths)
|
||||
mesh_fast_tx_flush_addr(mpath->sdata, mpath->dst);
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user