hwsim_del() queues the currently published PIB for RCU freeing before
unregistering the hardware. The unregister path can still invoke driver
callbacks, including set_promiscuous_mode(), after that grace period has
started. A callback can consequently dereference the freed PIB.

Unregister the hardware first, then fetch and free the final PIB. This also
handles a PIB replacement performed by a callback during unregister.

Fixes: 1c9f4a3fce77 ("ieee802154: hwsim: fix rcu handling")
Reported-by: [email protected]
Closes: https://syzkaller.appspot.com/bug?extid=4707bb8a43a42fca2b97
Cc: [email protected]
Signed-off-by: Yousef Alhouseen <[email protected]>
---
 drivers/net/ieee802154/mac802154_hwsim.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ieee802154/mac802154_hwsim.c 
b/drivers/net/ieee802154/mac802154_hwsim.c
index 6daa0f198..2a2d8a9eb 100644
--- a/drivers/net/ieee802154/mac802154_hwsim.c
+++ b/drivers/net/ieee802154/mac802154_hwsim.c
@@ -1004,12 +1004,11 @@ static void hwsim_del(struct hwsim_phy *phy)
                list_del_rcu(&e->list);
                hwsim_free_edge(e);
        }
-       pib = rcu_dereference(phy->pib);
        rcu_read_unlock();
 
-       kfree_rcu(pib, rcu);
-
        ieee802154_unregister_hw(phy->hw);
+       pib = rcu_dereference_protected(phy->pib, 1);
+       kfree_rcu(pib, rcu);
        ieee802154_free_hw(phy->hw);
 }
 
-- 
2.54.0


Reply via email to