| From f3db6923dbec64a5caa13381b1b12553e5f68bd8 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 16 Jun 2021 10:09:01 +0800 |
| Subject: ieee802154: hwsim: Fix memory leak in hwsim_add_one |
| |
| From: Dongliang Mu <mudongliangabcd@gmail.com> |
| |
| [ Upstream commit 28a5501c3383f0e6643012c187b7c2027ef42aea ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/net/ieee802154/mac802154_hwsim.c | 5 +++++ |
| 1 file changed, 5 insertions(+) |
| |
| diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c |
| index 7a168170224a..6d479df2d9e5 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(); |
| |
| -- |
| 2.30.2 |
| |