From: Timo Lindhorst <tlnd@online.de>
To: "Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
Cc: linville@tuxdriver.com, johannes@sipsolutions.net,
linux-wireless@vger.kernel.org, stable@vger.kernel.org,
Johannes Berg <johannes.berg@intel.com>
Subject: Re: [RFC 1/2] cfg80211: fix race on init and driver registration
Date: Fri, 25 Nov 2011 20:59:44 +0100 [thread overview]
Message-ID: <201111252059.44293.tlnd@online.de> (raw)
In-Reply-To: <1322060687-6512-2-git-send-email-mcgrof@qca.qualcomm.com>
Am Mittwoch, 23. November 2011, 16:04:46 schrieb Luis R. Rodriguez:
> There is a theoretical race that if hit will trigger
> a crash. The race is between when we issue the first
> regulatory hint, regulatory_hint_core(), gets processed
> by the workqueue and between when the first device
> gets registered to the wireless core. This is not easy
> to reproduce but it was easy to do so through the
> regulatory simulator I have been working on. This
> is a port of the fix I implemented there [1].
>
> [1]
> https://github.com/mcgrof/regsim/commit/a246ccf81f059cb662eee288aa13100f63
> 1e4cc8
>
> Cc: stable@vger.kernel.org
> Cc: Johannes Berg <johannes.berg@intel.com>
> Signed-off-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
> ---
> net/wireless/reg.c | 28 ++++++++++++++++++++--------
> 1 files changed, 20 insertions(+), 8 deletions(-)
>
> diff --git a/net/wireless/reg.c b/net/wireless/reg.c
> index 76b35df..df73b96 100644
> --- a/net/wireless/reg.c
> +++ b/net/wireless/reg.c
> @@ -57,8 +57,17 @@
> #define REG_DBG_PRINT(args...)
> #endif
>
> +static struct regulatory_request core_request_world = {
> + .initiator = NL80211_REGDOM_SET_BY_CORE,
> + .alpha2[0] = '0',
> + .alpha2[1] = '0',
> + .intersect = false,
> + .processed = true,
> + .country_ie_env = ENVIRON_ANY,
> +};
> +
> /* Receipt of information from last regulatory request */
> -static struct regulatory_request *last_request;
> +static struct regulatory_request *last_request = &core_request_world;
>
> /* To trigger userspace events */
> static struct platform_device *reg_pdev;
> @@ -165,6 +174,10 @@ static void reset_regdomains(void)
>
> cfg80211_world_regdom = &world_regdom;
> cfg80211_regdomain = NULL;
> +
> + if (last_request != &core_request_world)
> + kfree(last_request);
> + last_request = &core_request_world;
> }
This breaks setting the regdom correctly! reset_regdomains() is called from
within set_regdom() (i.e. via __set_regdom()), however, the subsequent
functions called within set_regdom() expect last_request to still hold the
currently processed request:
update_all_wiphy_regulatory(last_request->initiator);
print_regdomain(cfg80211_regdomain);
nl80211_send_reg_change_event(last_request);
reg_set_request_processed();
This, for instance, prevents to set the regdom from userspace -- or precisely:
the regdom is set, but the reg_timeout worker restores the settings after the
timeout, which is not canceled as intended within reg_set_request_processed(),
since last_request->initiator is not NL80211_REGDOM_SET_BY_USER anymore as
last_request was reset to &core_request_world.
The targeted race condition is already solved by letting last_request
initially point to the static core_request_world, isn't it? I'd thus suggest
not to touch last_request from within reset_regdomains().
> @@ -1409,7 +1422,8 @@ static int __regulatory_hint(struct wiphy *wiphy,
> }
>
> new_request:
> - kfree(last_request);
> + if (last_request != &core_request_world)
> + kfree(last_request);
>
> last_request = pending_request;
> last_request->intersect = intersect;
> @@ -1579,9 +1593,6 @@ static int regulatory_hint_core(const char *alpha2)
> {
> struct regulatory_request *request;
>
> - kfree(last_request);
> - last_request = NULL;
> -
> request = kzalloc(sizeof(struct regulatory_request),
> GFP_KERNEL);
> if (!request)
> @@ -1823,6 +1834,10 @@ static void restore_regulatory_settings(bool
> reset_user) /* First restore to the basic regulatory settings */
> cfg80211_regdomain = cfg80211_world_regdom;
>
> + if (last_request != &core_request_world)
> + kfree(last_request);
> + last_request = &core_request_world;
> +
> mutex_unlock(®_mutex);
> mutex_unlock(&cfg80211_mutex);
>
> @@ -2306,9 +2321,6 @@ void /* __init_or_exit */ regulatory_exit(void)
>
> reset_regdomains();
>
> - kfree(last_request);
> -
> - last_request = NULL;
We hence need to free last_request here if necessary:
- kfree(last_request);
+ if (last_request != &core_request_world)
+ kfree(last_request);
- last_request = NULL;
Regards,
Timo
next prev parent reply other threads:[~2011-11-25 20:00 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-23 15:04 [RFC 0/2] cfg80211: two stable fixes Luis R. Rodriguez
2011-11-23 15:04 ` [RFC 1/2] cfg80211: fix race on init and driver registration Luis R. Rodriguez
2011-11-25 19:59 ` Timo Lindhorst [this message]
2011-11-28 20:07 ` Luis R. Rodriguez
2011-11-23 15:04 ` [RFC 2/2] cfg80211: amend regulatory NULL dereference fix Luis R. Rodriguez
2011-11-24 15:22 ` Johannes Berg
2011-11-24 16:25 ` Luis R. Rodriguez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201111252059.44293.tlnd@online.de \
--to=tlnd@online.de \
--cc=johannes.berg@intel.com \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=mcgrof@qca.qualcomm.com \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).