cfg80211_send_mlme_event() uses GFP_KERNEL and could sleep. Better not
call it with rcu_read_lock held.
Reported-by: Johannes Berg <[email protected]>
Signed-off-by: Jouni Malinen <[email protected]>
---
net/mac80211/mlme.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
--- uml.orig/net/mac80211/mlme.c 2009-04-16 11:04:05.000000000 +0300
+++ uml/net/mac80211/mlme.c 2009-04-17 23:00:01.000000000 +0300
@@ -874,15 +874,6 @@ static void ieee80211_set_disassoc(struc
ieee80211_rx_bss_put(local, bss);
}
- if (self_disconnected) {
- if (deauth)
- ieee80211_send_deauth_disassoc(sdata,
- IEEE80211_STYPE_DEAUTH, reason);
- else
- ieee80211_send_deauth_disassoc(sdata,
- IEEE80211_STYPE_DISASSOC, reason);
- }
-
ifmgd->flags &= ~IEEE80211_STA_ASSOCIATED;
changed |= ieee80211_reset_erp_info(sdata);
@@ -901,6 +892,15 @@ static void ieee80211_set_disassoc(struc
rcu_read_unlock();
+ if (self_disconnected) {
+ if (deauth)
+ ieee80211_send_deauth_disassoc(sdata,
+ IEEE80211_STYPE_DEAUTH, reason);
+ else
+ ieee80211_send_deauth_disassoc(sdata,
+ IEEE80211_STYPE_DISASSOC, reason);
+ }
+
/* channel(_type) changes are handled by ieee80211_hw_config */
local->oper_channel_type = NL80211_CHAN_NO_HT;
--
Jouni Malinen PGP id EFC895FA
One of the code paths sending deauth/disassoc events ends up calling
this function with rcu_read_lock held, so we must use GFP_ATOMIC in
allocation routines.
Reported-by: Johannes Berg <[email protected]>
Signed-off-by: Jouni Malinen <[email protected]>
---
net/wireless/nl80211.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(patch managed to modify incorrect function with some pending patches,
so there is some extra context here to make sure these changes end up
in nl80211_send_mlme_event() regardless of whether the other patches
are applied or not since this fix is needed for both 2.6.30 and
current wireless-testing.git)
--- uml.orig/net/wireless/nl80211.c 2009-04-17 23:05:47.000000000 +0300
+++ uml/net/wireless/nl80211.c 2009-04-18 21:38:40.000000000 +0300
@@ -3483,17 +3483,17 @@ nla_put_failure:
static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
const u8 *buf, size_t len,
enum nl80211_commands cmd)
{
struct sk_buff *msg;
void *hdr;
- msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
if (!msg)
return;
hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
if (!hdr) {
nlmsg_free(msg);
return;
}
@@ -3502,17 +3502,17 @@ static void nl80211_send_mlme_event(stru
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
NLA_PUT(msg, NL80211_ATTR_FRAME, len, buf);
if (genlmsg_end(msg, hdr) < 0) {
nlmsg_free(msg);
return;
}
- genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL);
+ genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
return;
nla_put_failure:
genlmsg_cancel(msg, hdr);
nlmsg_free(msg);
}
void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
--
Jouni Malinen PGP id EFC895FA
On Fri, Apr 17, 2009 at 11:04:48PM +0300, Jouni Malinen wrote:
> cfg80211_send_mlme_event() uses GFP_KERNEL and could sleep. Better not
> call it with rcu_read_lock held.
Please drop this; moving the deauth/disassoc frame TX here is not the
best idea. I'll figure out something safer to fix this.
--
Jouni Malinen PGP id EFC895FA