···26662666unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc);2667266726682668/**26692669+ * ieee80211_get_mesh_hdrlen - get mesh extension header length26702670+ * @meshhdr: the mesh extension header, only the flags field26712671+ * (first byte) will be accessed26722672+ * Returns the length of the extension header, which is always at26732673+ * least 6 bytes and at most 18 if address 5 and 6 are present.26742674+ */26752675+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);26762676+26772677+/**26692678 * DOC: Data path helpers26702679 *26712680 * In addition to generic utilities, cfg80211 also offers
···531531532532 if (ieee80211_is_action(hdr->frame_control)) {533533 u8 category;534534+535535+ /* make sure category field is present */536536+ if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE)537537+ return RX_DROP_MONITOR;538538+534539 mgmt = (struct ieee80211_mgmt *)hdr;535540 category = mgmt->u.action.category;536541 if (category != WLAN_CATEGORY_MESH_ACTION &&···888883 */889884 if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&890885 ieee80211_is_data_present(hdr->frame_control)) {891891- u16 ethertype;892892- u8 *payload;886886+ unsigned int hdrlen;887887+ __be16 ethertype;893888894894- payload = rx->skb->data +895895- ieee80211_hdrlen(hdr->frame_control);896896- ethertype = (payload[6] << 8) | payload[7];897897- if (cpu_to_be16(ethertype) ==898898- rx->sdata->control_port_protocol)889889+ hdrlen = ieee80211_hdrlen(hdr->frame_control);890890+891891+ if (rx->skb->len < hdrlen + 8)892892+ return RX_DROP_MONITOR;893893+894894+ skb_copy_bits(rx->skb, hdrlen + 6, ðertype, 2);895895+ if (ethertype == rx->sdata->control_port_protocol)899896 return RX_CONTINUE;900897 }901898···1474146714751468 hdr = (struct ieee80211_hdr *)rx->skb->data;14761469 fc = hdr->frame_control;14701470+14711471+ if (ieee80211_is_ctl(fc))14721472+ return RX_CONTINUE;14731473+14771474 sc = le16_to_cpu(hdr->seq_ctrl);14781475 frag = sc & IEEE80211_SCTL_FRAG;1479147614801477 if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||14811481- (rx->skb)->len < 24 ||14821478 is_multicast_ether_addr(hdr->addr1))) {14831479 /* not fragmented */14841480 goto out;···1904189419051895 hdr = (struct ieee80211_hdr *) skb->data;19061896 hdrlen = ieee80211_hdrlen(hdr->frame_control);18971897+18981898+ /* make sure fixed part of mesh header is there, also checks skb len */18991899+ if (!pskb_may_pull(rx->skb, hdrlen + 6))19001900+ return RX_DROP_MONITOR;19011901+19021902+ mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);19031903+19041904+ /* make sure full mesh header is there, also checks skb len */19051905+ if (!pskb_may_pull(rx->skb,19061906+ hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))19071907+ return RX_DROP_MONITOR;19081908+19091909+ /* reload pointers */19101910+ hdr = (struct ieee80211_hdr *) skb->data;19071911 mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);1908191219091913 /* frame is in RMC, don't forward */···19261902 mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata))19271903 return RX_DROP_MONITOR;1928190419291929- if (!ieee80211_is_data(hdr->frame_control))19051905+ if (!ieee80211_is_data(hdr->frame_control) ||19061906+ !(status->rx_flags & IEEE80211_RX_RA_MATCH))19301907 return RX_CONTINUE;1931190819321909 if (!mesh_hdr->ttl)···19411916 if (is_multicast_ether_addr(hdr->addr1)) {19421917 mpp_addr = hdr->addr3;19431918 proxied_addr = mesh_hdr->eaddr1;19441944- } else {19191919+ } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {19201920+ /* has_a4 already checked in ieee80211_rx_mesh_check */19451921 mpp_addr = hdr->addr4;19461922 proxied_addr = mesh_hdr->eaddr2;19231923+ } else {19241924+ return RX_DROP_MONITOR;19471925 }1948192619491927 rcu_read_lock();···19741946 }19751947 skb_set_queue_mapping(skb, q);1976194819771977- if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))19781978- goto out;19791979-19801949 if (!--mesh_hdr->ttl) {19811950 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);19821982- return RX_DROP_MONITOR;19511951+ goto out;19831952 }1984195319851954 if (!ifmsh->mshcfg.dot11MeshForwarding)···23832358 }23842359 break;23852360 case WLAN_CATEGORY_SELF_PROTECTED:23612361+ if (len < (IEEE80211_MIN_ACTION_SIZE +23622362+ sizeof(mgmt->u.action.u.self_prot.action_code)))23632363+ break;23642364+23862365 switch (mgmt->u.action.u.self_prot.action_code) {23872366 case WLAN_SP_MESH_PEERING_OPEN:23882367 case WLAN_SP_MESH_PEERING_CLOSE:···24052376 }24062377 break;24072378 case WLAN_CATEGORY_MESH_ACTION:23792379+ if (len < (IEEE80211_MIN_ACTION_SIZE +23802380+ sizeof(mgmt->u.action.u.mesh_action.action_code)))23812381+ break;23822382+24082383 if (!ieee80211_vif_is_mesh(&sdata->vif))24092384 break;24102385 if (mesh_action_is_path_sel(mgmt) &&···29512918 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))29522919 local->dot11ReceivedFragmentCount++;2953292029542954- if (ieee80211_is_mgmt(fc))29552955- err = skb_linearize(skb);29562956- else29212921+ if (ieee80211_is_mgmt(fc)) {29222922+ /* drop frame if too short for header */29232923+ if (skb->len < ieee80211_hdrlen(fc))29242924+ err = -ENOBUFS;29252925+ else29262926+ err = skb_linearize(skb);29272927+ } else {29572928 err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));29292929+ }2958293029592931 if (err) {29602932 dev_kfree_skb(skb);
+35-7
net/mac80211/util.c
···643643 break;644644 }645645646646- if (id != WLAN_EID_VENDOR_SPECIFIC &&647647- id != WLAN_EID_QUIET &&648648- test_bit(id, seen_elems)) {649649- elems->parse_error = true;650650- left -= elen;651651- pos += elen;652652- continue;646646+ switch (id) {647647+ case WLAN_EID_SSID:648648+ case WLAN_EID_SUPP_RATES:649649+ case WLAN_EID_FH_PARAMS:650650+ case WLAN_EID_DS_PARAMS:651651+ case WLAN_EID_CF_PARAMS:652652+ case WLAN_EID_TIM:653653+ case WLAN_EID_IBSS_PARAMS:654654+ case WLAN_EID_CHALLENGE:655655+ case WLAN_EID_RSN:656656+ case WLAN_EID_ERP_INFO:657657+ case WLAN_EID_EXT_SUPP_RATES:658658+ case WLAN_EID_HT_CAPABILITY:659659+ case WLAN_EID_HT_OPERATION:660660+ case WLAN_EID_VHT_CAPABILITY:661661+ case WLAN_EID_VHT_OPERATION:662662+ case WLAN_EID_MESH_ID:663663+ case WLAN_EID_MESH_CONFIG:664664+ case WLAN_EID_PEER_MGMT:665665+ case WLAN_EID_PREQ:666666+ case WLAN_EID_PREP:667667+ case WLAN_EID_PERR:668668+ case WLAN_EID_RANN:669669+ case WLAN_EID_CHANNEL_SWITCH:670670+ case WLAN_EID_EXT_CHANSWITCH_ANN:671671+ case WLAN_EID_COUNTRY:672672+ case WLAN_EID_PWR_CONSTRAINT:673673+ case WLAN_EID_TIMEOUT_INTERVAL:674674+ if (test_bit(id, seen_elems)) {675675+ elems->parse_error = true;676676+ left -= elen;677677+ pos += elen;678678+ continue;679679+ }680680+ break;653681 }654682655683 if (calc_crc && id < 64 && (filter & (1ULL << id)))
+1-2
net/wireless/core.c
···529529 for (i = 0; i < sband->n_channels; i++) {530530 sband->channels[i].orig_flags =531531 sband->channels[i].flags;532532- sband->channels[i].orig_mag =533533- sband->channels[i].max_antenna_gain;532532+ sband->channels[i].orig_mag = INT_MAX;534533 sband->channels[i].orig_mpwr =535534 sband->channels[i].max_power;536535 sband->channels[i].band = band;