From a50e5fb8db83c5b57392204c21ea6c5c4ccefde6 Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Sat, 15 Dec 2018 11:03:10 +0200 Subject: mac80211: fix a kernel panic when TXing after TXQ teardown Recently TXQ teardown was moved earlier in ieee80211_unregister_hw(), to avoid a use-after-free of the netdev data. However, interfaces aren't fully removed at the point, and cfg80211_shutdown_all_interfaces can for example, TX a deauth frame. Move the TXQ teardown to the point between cfg80211_shutdown_all_interfaces and the free of netdev queues, so we can be sure they are torn down before netdev is freed, but after there is no ongoing TX. Fixes: 77cfaf52eca5 ("mac80211: Run TXQ teardown code before de-registering interfaces") Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho Signed-off-by: Johannes Berg --- net/mac80211/iface.c | 3 +++ net/mac80211/main.c | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 5f3c81e705c7..3a0171a65db3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -7,6 +7,7 @@ * Copyright 2008, Johannes Berg * Copyright 2013-2014 Intel Mobile Communications GmbH * Copyright (c) 2016 Intel Deutschland GmbH + * Copyright (C) 2018 Intel Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -1951,6 +1952,8 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) WARN(local->open_count, "%s: open count remains %d\n", wiphy_name(local->hw.wiphy), local->open_count); + ieee80211_txq_teardown_flows(local); + mutex_lock(&local->iflist_mtx); list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { list_del(&sdata->list); diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 83e71e6b2ebe..7b8320d4a8e4 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1262,7 +1262,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) rtnl_unlock(); ieee80211_led_exit(local); ieee80211_wep_free(local); - ieee80211_txq_teardown_flows(local); fail_flows: destroy_workqueue(local->workqueue); fail_workqueue: @@ -1288,7 +1287,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) #if IS_ENABLED(CONFIG_IPV6) unregister_inet6addr_notifier(&local->ifa6_notifier); #endif - ieee80211_txq_teardown_flows(local); rtnl_lock(); -- cgit v1.2.3-59-g8ed1b From d350a0f431189517b1af0dbbb605c273231a8966 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 15 Dec 2018 11:03:22 +0200 Subject: nl80211: fix memory leak if validate_pae_over_nl80211() fails If validate_pae_over_nl80211() were to fail in nl80211_crypto_settings(), we might leak the 'connkeys' allocation. Fix this. Fixes: 64bf3d4bc2b0 ("nl80211: Add CONTROL_PORT_OVER_NL80211 attribute") Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 8d763725498c..2317727d6413 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -8930,8 +8930,10 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) if (info->attrs[NL80211_ATTR_CONTROL_PORT_OVER_NL80211]) { int r = validate_pae_over_nl80211(rdev, info); - if (r < 0) + if (r < 0) { + kzfree(connkeys); return r; + } ibss.control_port_over_nl80211 = true; } -- cgit v1.2.3-59-g8ed1b From 34b1e0e9efe101822e83cc62d22443ed3867ae7a Mon Sep 17 00:00:00 2001 From: Sara Sharon Date: Sat, 15 Dec 2018 11:03:06 +0200 Subject: mac80211: free skb fraglist before freeing the skb mac80211 uses the frag list to build AMSDU. When freeing the skb, it may not be really freed, since someone is still holding a reference to it. In that case, when TCP skb is being retransmitted, the pointer to the frag list is being reused, while the data in there is no longer valid. Since we will never get frag list from the network stack, as mac80211 doesn't advertise the capability, we can safely free and nullify it before releasing the SKB. Signed-off-by: Sara Sharon Signed-off-by: Luca Coelho Signed-off-by: Johannes Berg --- net/mac80211/status.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/mac80211/status.c b/net/mac80211/status.c index a794ca729000..3f0b96e1e02f 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -556,6 +556,11 @@ static void ieee80211_report_used_skb(struct ieee80211_local *local, } ieee80211_led_tx(local); + + if (skb_has_frag_list(skb)) { + kfree_skb_list(skb_shinfo(skb)->frag_list); + skb_shinfo(skb)->frag_list = NULL; + } } /* -- cgit v1.2.3-59-g8ed1b