|
@@ -200,6 +200,38 @@ cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
|
|
|
return __cfg80211_rdev_from_attrs(netns, info->attrs);
|
|
return __cfg80211_rdev_from_attrs(netns, info->attrs);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static int validate_beacon_head(const struct nlattr *attr,
|
|
|
|
|
+ struct netlink_ext_ack *extack)
|
|
|
|
|
+{
|
|
|
|
|
+ const u8 *data = nla_data(attr);
|
|
|
|
|
+ unsigned int len = nla_len(attr);
|
|
|
|
|
+ const struct element *elem;
|
|
|
|
|
+ const struct ieee80211_mgmt *mgmt = (void *)data;
|
|
|
|
|
+ unsigned int fixedlen = offsetof(struct ieee80211_mgmt,
|
|
|
|
|
+ u.beacon.variable);
|
|
|
|
|
+
|
|
|
|
|
+ if (len < fixedlen)
|
|
|
|
|
+ goto err;
|
|
|
|
|
+
|
|
|
|
|
+ if (ieee80211_hdrlen(mgmt->frame_control) !=
|
|
|
|
|
+ offsetof(struct ieee80211_mgmt, u.beacon))
|
|
|
|
|
+ goto err;
|
|
|
|
|
+
|
|
|
|
|
+ data += fixedlen;
|
|
|
|
|
+ len -= fixedlen;
|
|
|
|
|
+
|
|
|
|
|
+ for_each_element(elem, data, len) {
|
|
|
|
|
+ /* nothing */
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (for_each_element_completed(elem, data, len))
|
|
|
|
|
+ return 0;
|
|
|
|
|
+
|
|
|
|
|
+err:
|
|
|
|
|
+ NL_SET_ERR_MSG_ATTR(extack, attr, "malformed beacon head");
|
|
|
|
|
+ return -EINVAL;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/* policy for the attributes */
|
|
/* policy for the attributes */
|
|
|
static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|
static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|
|
[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
|
|
[NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
|
|
@@ -4016,6 +4048,12 @@ static int nl80211_parse_beacon(struct nlattr *attrs[],
|
|
|
memset(bcn, 0, sizeof(*bcn));
|
|
memset(bcn, 0, sizeof(*bcn));
|
|
|
|
|
|
|
|
if (attrs[NL80211_ATTR_BEACON_HEAD]) {
|
|
if (attrs[NL80211_ATTR_BEACON_HEAD]) {
|
|
|
|
|
+ int ret = validate_beacon_head(attrs[NL80211_ATTR_BEACON_HEAD],
|
|
|
|
|
+ NULL);
|
|
|
|
|
+
|
|
|
|
|
+ if (ret)
|
|
|
|
|
+ return ret;
|
|
|
|
|
+
|
|
|
bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
|
|
bcn->head = nla_data(attrs[NL80211_ATTR_BEACON_HEAD]);
|
|
|
bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
|
|
bcn->head_len = nla_len(attrs[NL80211_ATTR_BEACON_HEAD]);
|
|
|
if (!bcn->head_len)
|
|
if (!bcn->head_len)
|