Skip to content

Commit d34265a

Browse files
committed
cfg80211: reg: centralize freeing ignored requests
Instead of having a lot of places that free ignored requests and then return REG_REQ_OK, make reg_process_hint() process REG_REQ_IGNORE by freeing the request, and let functions it calls return that instead of freeing. This also fixes a leak when a second (different) country IE hint was ignored. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent 480908a commit d34265a

File tree

1 file changed

+35
-29
lines changed

1 file changed

+35
-29
lines changed

net/wireless/reg.c

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,9 @@ MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
273273

274274
static void reg_free_request(struct regulatory_request *request)
275275
{
276+
if (request == &core_request_world)
277+
return;
278+
276279
if (request != get_last_request())
277280
kfree(request);
278281
}
@@ -1905,13 +1908,17 @@ static void reg_set_request_processed(void)
19051908
* The wireless subsystem can use this function to process
19061909
* a regulatory request issued by the regulatory core.
19071910
*/
1908-
static void reg_process_hint_core(struct regulatory_request *core_request)
1911+
static enum reg_request_treatment
1912+
reg_process_hint_core(struct regulatory_request *core_request)
19091913
{
19101914
if (reg_query_database(core_request)) {
19111915
core_request->intersect = false;
19121916
core_request->processed = false;
19131917
reg_update_last_request(core_request);
1918+
return REG_REQ_OK;
19141919
}
1920+
1921+
return REG_REQ_IGNORE;
19151922
}
19161923

19171924
static enum reg_request_treatment
@@ -1957,16 +1964,15 @@ __reg_process_hint_user(struct regulatory_request *user_request)
19571964
* The wireless subsystem can use this function to process
19581965
* a regulatory request initiated by userspace.
19591966
*/
1960-
static void reg_process_hint_user(struct regulatory_request *user_request)
1967+
static enum reg_request_treatment
1968+
reg_process_hint_user(struct regulatory_request *user_request)
19611969
{
19621970
enum reg_request_treatment treatment;
19631971

19641972
treatment = __reg_process_hint_user(user_request);
19651973
if (treatment == REG_REQ_IGNORE ||
1966-
treatment == REG_REQ_ALREADY_SET) {
1967-
reg_free_request(user_request);
1968-
return;
1969-
}
1974+
treatment == REG_REQ_ALREADY_SET)
1975+
return REG_REQ_IGNORE;
19701976

19711977
user_request->intersect = treatment == REG_REQ_INTERSECT;
19721978
user_request->processed = false;
@@ -1975,9 +1981,10 @@ static void reg_process_hint_user(struct regulatory_request *user_request)
19751981
reg_update_last_request(user_request);
19761982
user_alpha2[0] = user_request->alpha2[0];
19771983
user_alpha2[1] = user_request->alpha2[1];
1978-
} else {
1979-
reg_free_request(user_request);
1984+
return REG_REQ_OK;
19801985
}
1986+
1987+
return REG_REQ_IGNORE;
19811988
}
19821989

19831990
static enum reg_request_treatment
@@ -2025,15 +2032,12 @@ reg_process_hint_driver(struct wiphy *wiphy,
20252032
case REG_REQ_OK:
20262033
break;
20272034
case REG_REQ_IGNORE:
2028-
reg_free_request(driver_request);
2029-
return REG_REQ_OK;
2035+
return REG_REQ_IGNORE;
20302036
case REG_REQ_INTERSECT:
20312037
case REG_REQ_ALREADY_SET:
20322038
regd = reg_copy_regd(get_cfg80211_regdom());
2033-
if (IS_ERR(regd)) {
2034-
reg_free_request(driver_request);
2035-
return REG_REQ_OK;
2036-
}
2039+
if (IS_ERR(regd))
2040+
return REG_REQ_IGNORE;
20372041

20382042
tmp = get_wiphy_regdom(wiphy);
20392043
rcu_assign_pointer(wiphy->regd, regd);
@@ -2056,12 +2060,12 @@ reg_process_hint_driver(struct wiphy *wiphy,
20562060
return REG_REQ_ALREADY_SET;
20572061
}
20582062

2059-
if (reg_query_database(driver_request))
2063+
if (reg_query_database(driver_request)) {
20602064
reg_update_last_request(driver_request);
2061-
else
2062-
reg_free_request(driver_request);
2065+
return REG_REQ_OK;
2066+
}
20632067

2064-
return REG_REQ_OK;
2068+
return REG_REQ_IGNORE;
20652069
}
20662070

20672071
static enum reg_request_treatment
@@ -2127,29 +2131,28 @@ reg_process_hint_country_ie(struct wiphy *wiphy,
21272131
case REG_REQ_OK:
21282132
break;
21292133
case REG_REQ_IGNORE:
2130-
return REG_REQ_OK;
2134+
return REG_REQ_IGNORE;
21312135
case REG_REQ_ALREADY_SET:
21322136
reg_free_request(country_ie_request);
21332137
return REG_REQ_ALREADY_SET;
21342138
case REG_REQ_INTERSECT:
2135-
reg_free_request(country_ie_request);
21362139
/*
21372140
* This doesn't happen yet, not sure we
21382141
* ever want to support it for this case.
21392142
*/
21402143
WARN_ONCE(1, "Unexpected intersection for country IEs");
2141-
return REG_REQ_OK;
2144+
return REG_REQ_IGNORE;
21422145
}
21432146

21442147
country_ie_request->intersect = false;
21452148
country_ie_request->processed = false;
21462149

2147-
if (reg_query_database(country_ie_request))
2150+
if (reg_query_database(country_ie_request)) {
21482151
reg_update_last_request(country_ie_request);
2149-
else
2150-
reg_free_request(country_ie_request);
2152+
return REG_REQ_OK;
2153+
}
21512154

2152-
return REG_REQ_OK;
2155+
return REG_REQ_IGNORE;
21532156
}
21542157

21552158
/* This processes *all* regulatory hints */
@@ -2163,11 +2166,11 @@ static void reg_process_hint(struct regulatory_request *reg_request)
21632166

21642167
switch (reg_request->initiator) {
21652168
case NL80211_REGDOM_SET_BY_CORE:
2166-
reg_process_hint_core(reg_request);
2167-
return;
2169+
treatment = reg_process_hint_core(reg_request);
2170+
break;
21682171
case NL80211_REGDOM_SET_BY_USER:
2169-
reg_process_hint_user(reg_request);
2170-
return;
2172+
treatment = reg_process_hint_user(reg_request);
2173+
break;
21712174
case NL80211_REGDOM_SET_BY_DRIVER:
21722175
if (!wiphy)
21732176
goto out_free;
@@ -2183,6 +2186,9 @@ static void reg_process_hint(struct regulatory_request *reg_request)
21832186
goto out_free;
21842187
}
21852188

2189+
if (treatment == REG_REQ_IGNORE)
2190+
goto out_free;
2191+
21862192
WARN(treatment != REG_REQ_OK && treatment != REG_REQ_ALREADY_SET,
21872193
"unexpected treatment value %d\n", treatment);
21882194

0 commit comments

Comments
 (0)