ieee802154: hwsim: Fix memory leak in hwsim_add_one
authorDongliang Mu <mudongliangabcd@gmail.com>
Wed, 16 Jun 2021 02:09:01 +0000 (10:09 +0800)
committerStefan Schmidt <stefan@datenfreihafen.org>
Tue, 22 Jun 2021 19:09:53 +0000 (21:09 +0200)
No matter from hwsim_remove or hwsim_del_radio_nl, hwsim_del fails to
remove the entry in the edges list. Take the example below, phy0, phy1
and e0 will be deleted, resulting in e1 not freed and accessed in the
future.

              hwsim_phys
                  |
    ------------------------------
    |                            |
phy0 (edges)                 phy1 (edges)
   ----> e1 (idx = 1)             ----> e0 (idx = 0)

Fix this by deleting and freeing all the entries in the edges list
between hwsim_edge_unsubscribe_me and list_del(&phy->list).

Reported-by: syzbot+b80c9959009a9325cdff@syzkaller.appspotmail.com
Fixes: 1c9f4a3fce77 ("ieee802154: hwsim: fix rcu handling")
Signed-off-by: Dongliang Mu <mudongliangabcd@gmail.com>
Acked-by: Alexander Aring <aahringo@redhat.com>
Link: https://lore.kernel.org/r/20210616020901.2759466-1-mudongliangabcd@gmail.com
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
drivers/net/ieee802154/mac802154_hwsim.c

index 366eaae3550a5ddc82d58731f2edd1d9db0fb4d9..baa7e21b7f4f99e08fc2c9d376a4910c47034786 100644 (file)
@@ -824,12 +824,17 @@ err_pib:
 static void hwsim_del(struct hwsim_phy *phy)
 {
        struct hwsim_pib *pib;
+       struct hwsim_edge *e;
 
        hwsim_edge_unsubscribe_me(phy);
 
        list_del(&phy->list);
 
        rcu_read_lock();
+       list_for_each_entry_rcu(e, &phy->edges, list) {
+               list_del_rcu(&e->list);
+               hwsim_free_edge(e);
+       }
        pib = rcu_dereference(phy->pib);
        rcu_read_unlock();