diff options
-rw-r--r-- | net/wireless/reg.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index ca11f31b3bec..9f4f8439e16a 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -2191,6 +2191,14 @@ static void print_regdomain_info(const struct ieee80211_regdomain *rd) | |||
2191 | print_rd_rules(rd); | 2191 | print_rd_rules(rd); |
2192 | } | 2192 | } |
2193 | 2193 | ||
2194 | static int reg_set_rd_core(const struct ieee80211_regdomain *rd) | ||
2195 | { | ||
2196 | if (!is_world_regdom(rd->alpha2)) | ||
2197 | return -EINVAL; | ||
2198 | update_world_regdomain(rd); | ||
2199 | return 0; | ||
2200 | } | ||
2201 | |||
2194 | /* Takes ownership of rd only if it doesn't fail */ | 2202 | /* Takes ownership of rd only if it doesn't fail */ |
2195 | static int __set_regdom(const struct ieee80211_regdomain *rd, | 2203 | static int __set_regdom(const struct ieee80211_regdomain *rd, |
2196 | struct regulatory_request *lr) | 2204 | struct regulatory_request *lr) |
@@ -2199,18 +2207,6 @@ static int __set_regdom(const struct ieee80211_regdomain *rd, | |||
2199 | const struct ieee80211_regdomain *intersected_rd = NULL; | 2207 | const struct ieee80211_regdomain *intersected_rd = NULL; |
2200 | struct wiphy *request_wiphy; | 2208 | struct wiphy *request_wiphy; |
2201 | 2209 | ||
2202 | /* Some basic sanity checks first */ | ||
2203 | |||
2204 | if (!reg_is_valid_request(rd->alpha2)) | ||
2205 | return -EINVAL; | ||
2206 | |||
2207 | if (is_world_regdom(rd->alpha2)) { | ||
2208 | if (lr->initiator != NL80211_REGDOM_SET_BY_CORE) | ||
2209 | return -EINVAL; | ||
2210 | update_world_regdomain(rd); | ||
2211 | return 0; | ||
2212 | } | ||
2213 | |||
2214 | if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) && | 2210 | if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) && |
2215 | !is_unknown_alpha2(rd->alpha2)) | 2211 | !is_unknown_alpha2(rd->alpha2)) |
2216 | return -EINVAL; | 2212 | return -EINVAL; |
@@ -2320,10 +2316,28 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
2320 | struct regulatory_request *lr; | 2316 | struct regulatory_request *lr; |
2321 | int r; | 2317 | int r; |
2322 | 2318 | ||
2319 | if (!reg_is_valid_request(rd->alpha2)) { | ||
2320 | kfree(rd); | ||
2321 | return -EINVAL; | ||
2322 | } | ||
2323 | |||
2323 | lr = get_last_request(); | 2324 | lr = get_last_request(); |
2324 | 2325 | ||
2325 | /* Note that this doesn't update the wiphys, this is done below */ | 2326 | /* Note that this doesn't update the wiphys, this is done below */ |
2326 | r = __set_regdom(rd, lr); | 2327 | switch (lr->initiator) { |
2328 | case NL80211_REGDOM_SET_BY_CORE: | ||
2329 | r = reg_set_rd_core(rd); | ||
2330 | break; | ||
2331 | case NL80211_REGDOM_SET_BY_USER: | ||
2332 | case NL80211_REGDOM_SET_BY_DRIVER: | ||
2333 | case NL80211_REGDOM_SET_BY_COUNTRY_IE: | ||
2334 | r = __set_regdom(rd, lr); | ||
2335 | break; | ||
2336 | default: | ||
2337 | WARN(1, "invalid initiator %d\n", lr->initiator); | ||
2338 | return -EINVAL; | ||
2339 | } | ||
2340 | |||
2327 | if (r) { | 2341 | if (r) { |
2328 | if (r == -EALREADY) | 2342 | if (r == -EALREADY) |
2329 | reg_set_request_processed(); | 2343 | reg_set_request_processed(); |