From patchwork Mon Dec 29 09:59:59 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arik Nemtsov X-Patchwork-Id: 5549141 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: X-Original-To: patchwork-linux-wireless@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BAF769F2B9 for ; Mon, 29 Dec 2014 10:00:09 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 8CF3C2011E for ; Mon, 29 Dec 2014 10:00:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6AE4B2010F for ; Mon, 29 Dec 2014 10:00:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751287AbaL2KAE (ORCPT ); Mon, 29 Dec 2014 05:00:04 -0500 Received: from mail-wg0-f54.google.com ([74.125.82.54]:52898 "EHLO mail-wg0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751114AbaL2KAD (ORCPT ); Mon, 29 Dec 2014 05:00:03 -0500 Received: by mail-wg0-f54.google.com with SMTP id z12so677814wgg.13 for ; Mon, 29 Dec 2014 02:00:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=E1LOg251sL5b9AANaNUTrMQ3vPv5FMkLlZIP//uws10=; b=ahBFL3WN12GVsQ6F6S3x+1NP9Cd0O/vEieQFLgrWnt8eZwv/92ClTV8r8A7XdlPZP1 VCRjL+zoNCqUK3x1m8ZkajVQNy+wN1PIrdQYvETEG+QphK6bwhPadP9IJM7oPPsbvXz9 gOHC2ajoN/vgw3RseNnotzR8WsSANd6oPFTZa6hm1GWRI0E6qaRVryVhUsXmKT0RHoH7 CgZUOAm4QYwR79np99T0dEO7f09vRJ0XYKtP8AK8Rm/lmCGUiEAUg6Pl71ZIRma8bJk8 7XMliY/gvJxelhEKrK8OhGsTWbZejcq5HnbUPV9VQZZMJjMAVLI2qqaQ36S7+t9Uet9h oENA== X-Gm-Message-State: ALoCoQka5W7Ie39uBN/R3ebMu7DfN6Idr5hrGqLRys2SR4YHAyQNLdXxHO8DFuY4aNgGXX9ux1t4 X-Received: by 10.180.91.193 with SMTP id cg1mr94805740wib.26.1419847201734; Mon, 29 Dec 2014 02:00:01 -0800 (PST) Received: from athena.ger.corp.intel.com (85-250-108-142.bb.netvision.net.il. [85.250.108.142]) by mx.google.com with ESMTPSA id cy3sm4398359wjb.22.2014.12.29.02.00.00 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 29 Dec 2014 02:00:01 -0800 (PST) From: Arik Nemtsov To: Cc: Johannes Berg , "Luis R. Rodriguez" , Arik Nemtsov Subject: [PATCH] cfg80211: fix deadlock during reg chan check Date: Mon, 29 Dec 2014 11:59:59 +0200 Message-Id: <1419847199-25493-1-git-send-email-arik@wizery.com> X-Mailer: git-send-email 2.1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If a P2P GO is active, the cfg80211_reg_can_beacon function will take the wdev lock, in its call to cfg80211_go_permissive_chan. But the wdev lock is already taken by the parent channel-checking function, causing a deadlock. Split the checking code into two parts. The first part will check if the wdev is active and saves the channel under the wdev lock. The second part will check actual channel validity according to type. Signed-off-by: Arik Nemtsov Reviewed-by: Ilan Peer Reviewed-by: Emmanuel Grumbach --- Requires the patch "cfg80211: correctly check ad-hoc channels" to be applied first. net/wireless/reg.c | 56 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 978a5fd..fde4e17 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -1533,45 +1533,40 @@ static void reg_call_notifier(struct wiphy *wiphy, static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) { - struct ieee80211_channel *ch; struct cfg80211_chan_def chandef; struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - bool ret = true; + enum nl80211_iftype iftype; wdev_lock(wdev); + iftype = wdev->iftype; + /* make sure the interface is active */ if (!wdev->netdev || !netif_running(wdev->netdev)) - goto out; + goto wdev_inactive_unlock; - switch (wdev->iftype) { + switch (iftype) { case NL80211_IFTYPE_AP: case NL80211_IFTYPE_P2P_GO: if (!wdev->beacon_interval) - goto out; - - ret = cfg80211_reg_can_beacon(wiphy, - &wdev->chandef, wdev->iftype); + goto wdev_inactive_unlock; + chandef = wdev->chandef; break; case NL80211_IFTYPE_ADHOC: if (!wdev->ssid_len) - goto out; - - ret = cfg80211_reg_can_beacon(wiphy, - &wdev->chandef, wdev->iftype); + goto wdev_inactive_unlock; + chandef = wdev->chandef; break; case NL80211_IFTYPE_STATION: case NL80211_IFTYPE_P2P_CLIENT: if (!wdev->current_bss || !wdev->current_bss->pub.channel) - goto out; + goto wdev_inactive_unlock; - ch = wdev->current_bss->pub.channel; - if (rdev->ops->get_channel && - !rdev_get_channel(rdev, wdev, &chandef)) - ret = cfg80211_chandef_usable(wiphy, &chandef, - IEEE80211_CHAN_DISABLED); - else - ret = !(ch->flags & IEEE80211_CHAN_DISABLED); + if (!rdev->ops->get_channel || + rdev_get_channel(rdev, wdev, &chandef)) + cfg80211_chandef_create(&chandef, + wdev->current_bss->pub.channel, + NL80211_CHAN_NO_HT); break; case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: @@ -1584,9 +1579,26 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) break; } -out: wdev_unlock(wdev); - return ret; + + switch (iftype) { + case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_P2P_GO: + case NL80211_IFTYPE_ADHOC: + return cfg80211_reg_can_beacon(wiphy, &chandef, iftype); + case NL80211_IFTYPE_STATION: + case NL80211_IFTYPE_P2P_CLIENT: + return cfg80211_chandef_usable(wiphy, &chandef, + IEEE80211_CHAN_DISABLED); + default: + break; + } + + return true; + +wdev_inactive_unlock: + wdev_unlock(wdev); + return true; } static void reg_leave_invalid_chans(struct wiphy *wiphy)