diff options
-rw-r--r-- | net/wireless/nl80211.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d21b1581a665..7386421e2ad3 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -201,6 +201,38 @@ cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info) | |||
201 | return __cfg80211_rdev_from_attrs(netns, info->attrs); | 201 | return __cfg80211_rdev_from_attrs(netns, info->attrs); |
202 | } | 202 | } |
203 | 203 | ||
204 | static int validate_beacon_head(const struct nlattr *attr, | ||
205 | struct netlink_ext_ack *extack) | ||
206 | { | ||
207 | const u8 *data = nla_data(attr); | ||
208 | unsigned int len = nla_len(attr); | ||
209 | const struct element *elem; | ||
210 | const struct ieee80211_mgmt *mgmt = (void *)data; | ||
211 | unsigned int fixedlen = offsetof(struct ieee80211_mgmt, | ||
212 | u.beacon.variable); | ||
213 | |||
214 | if (len < fixedlen) | ||
215 | goto err; | ||
216 | |||
217 | if (ieee80211_hdrlen(mgmt->frame_control) != | ||
218 | offsetof(struct ieee80211_mgmt, u.beacon)) | ||
219 | goto err; | ||
220 | |||
221 | data += fixedlen; | ||
222 | len -= fixedlen; | ||
223 | |||
224 | for_each_element(elem, data, len) { | ||
225 | /* nothing */ | ||
226 | } | ||
227 | |||
228 | if (for_each_element_completed(elem, data, len)) | ||
229 | return 0; | ||
230 | |||
231 | err: | ||
232 | NL_SET_ERR_MSG_ATTR(extack, attr, "malformed beacon head"); | ||
233 | return -EINVAL; | ||
234 | } | ||
235 | |||
204 | static int validate_ie_attr(const struct nlattr *attr, | 236 | static int validate_ie_attr(const struct nlattr *attr, |
205 | struct netlink_ext_ack *extack) | 237 | struct netlink_ext_ack *extack) |
206 | { | 238 | { |
@@ -338,8 +370,9 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { | |||
338 | 370 | ||
339 | [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, | 371 | [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, |
340 | [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, | 372 | [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, |
341 | [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY, | 373 | [NL80211_ATTR_BEACON_HEAD] = |
342 | .len = IEEE80211_MAX_DATA_LEN }, | 374 | NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_beacon_head, |
375 | IEEE80211_MAX_DATA_LEN), | ||
343 | [NL80211_ATTR_BEACON_TAIL] = | 376 | [NL80211_ATTR_BEACON_TAIL] = |
344 | NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr, | 377 | NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_ie_attr, |
345 | IEEE80211_MAX_DATA_LEN), | 378 | IEEE80211_MAX_DATA_LEN), |