summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDongliang Mu <mudongliangabcd@gmail.com>2021-06-16 10:09:01 +0800
committerStefan Schmidt <stefan@datenfreihafen.org>2021-06-22 21:09:53 +0200
commit28a5501c3383f0e6643012c187b7c2027ef42aea (patch)
tree0196285db8eef1a31a6c117be5c5fa8a8f87389a
parentab372c2293f5d0b279f31c8d768566ea37602dc9 (diff)
downloadlinux-28a5501c3383f0e6643012c187b7c2027ef42aea.tar.gz
linux-28a5501c3383f0e6643012c187b7c2027ef42aea.tar.bz2
linux-28a5501c3383f0e6643012c187b7c2027ef42aea.zip
ieee802154: hwsim: Fix memory leak in hwsim_add_one
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>
-rw-r--r--drivers/net/ieee802154/mac802154_hwsim.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
index 366eaae3550a..baa7e21b7f4f 100644
--- a/drivers/net/ieee802154/mac802154_hwsim.c
+++ b/drivers/net/ieee802154/mac802154_hwsim.c
@@ -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();