aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-10-29 16:05:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-10-29 16:05:51 -0400
commitab3d59d265e772e734c36fe738809cb1a910f566 (patch)
treeb6d29908d3d45b078d025341b1cc272ba4c0a6d0 /net/mac80211
parent42d36074e53eadfd79e6db518b5caf8fba914f8b (diff)
parent8c6e30936a7893a85f6222084f0f26aceb81137a (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
Conflicts: drivers/net/wireless/mwifiex/cfg80211.c
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ibss.c2
-rw-r--r--net/mac80211/rx.c74
-rw-r--r--net/mac80211/util.c42
3 files changed, 92 insertions, 26 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 3d5332e367f8..c7386b2b767e 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1110,7 +1110,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1110 sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH; 1110 sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
1111 sdata->u.ibss.ibss_join_req = jiffies; 1111 sdata->u.ibss.ibss_join_req = jiffies;
1112 1112
1113 memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN); 1113 memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
1114 sdata->u.ibss.ssid_len = params->ssid_len; 1114 sdata->u.ibss.ssid_len = params->ssid_len;
1115 1115
1116 mutex_unlock(&sdata->u.ibss.mtx); 1116 mutex_unlock(&sdata->u.ibss.mtx);
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index d07216ab5f72..8c1f1527d671 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -531,6 +531,11 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
531 531
532 if (ieee80211_is_action(hdr->frame_control)) { 532 if (ieee80211_is_action(hdr->frame_control)) {
533 u8 category; 533 u8 category;
534
535 /* make sure category field is present */
536 if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
537 return RX_DROP_MONITOR;
538
534 mgmt = (struct ieee80211_mgmt *)hdr; 539 mgmt = (struct ieee80211_mgmt *)hdr;
535 category = mgmt->u.action.category; 540 category = mgmt->u.action.category;
536 if (category != WLAN_CATEGORY_MESH_ACTION && 541 if (category != WLAN_CATEGORY_MESH_ACTION &&
@@ -883,14 +888,16 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
883 */ 888 */
884 if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION && 889 if (rx->sta && rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
885 ieee80211_is_data_present(hdr->frame_control)) { 890 ieee80211_is_data_present(hdr->frame_control)) {
886 u16 ethertype; 891 unsigned int hdrlen;
887 u8 *payload; 892 __be16 ethertype;
888 893
889 payload = rx->skb->data + 894 hdrlen = ieee80211_hdrlen(hdr->frame_control);
890 ieee80211_hdrlen(hdr->frame_control); 895
891 ethertype = (payload[6] << 8) | payload[7]; 896 if (rx->skb->len < hdrlen + 8)
892 if (cpu_to_be16(ethertype) == 897 return RX_DROP_MONITOR;
893 rx->sdata->control_port_protocol) 898
899 skb_copy_bits(rx->skb, hdrlen + 6, &ethertype, 2);
900 if (ethertype == rx->sdata->control_port_protocol)
894 return RX_CONTINUE; 901 return RX_CONTINUE;
895 } 902 }
896 903
@@ -1467,11 +1474,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
1467 1474
1468 hdr = (struct ieee80211_hdr *)rx->skb->data; 1475 hdr = (struct ieee80211_hdr *)rx->skb->data;
1469 fc = hdr->frame_control; 1476 fc = hdr->frame_control;
1477
1478 if (ieee80211_is_ctl(fc))
1479 return RX_CONTINUE;
1480
1470 sc = le16_to_cpu(hdr->seq_ctrl); 1481 sc = le16_to_cpu(hdr->seq_ctrl);
1471 frag = sc & IEEE80211_SCTL_FRAG; 1482 frag = sc & IEEE80211_SCTL_FRAG;
1472 1483
1473 if (likely((!ieee80211_has_morefrags(fc) && frag == 0) || 1484 if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
1474 (rx->skb)->len < 24 ||
1475 is_multicast_ether_addr(hdr->addr1))) { 1485 is_multicast_ether_addr(hdr->addr1))) {
1476 /* not fragmented */ 1486 /* not fragmented */
1477 goto out; 1487 goto out;
@@ -1894,6 +1904,20 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1894 1904
1895 hdr = (struct ieee80211_hdr *) skb->data; 1905 hdr = (struct ieee80211_hdr *) skb->data;
1896 hdrlen = ieee80211_hdrlen(hdr->frame_control); 1906 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1907
1908 /* make sure fixed part of mesh header is there, also checks skb len */
1909 if (!pskb_may_pull(rx->skb, hdrlen + 6))
1910 return RX_DROP_MONITOR;
1911
1912 mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
1913
1914 /* make sure full mesh header is there, also checks skb len */
1915 if (!pskb_may_pull(rx->skb,
1916 hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr)))
1917 return RX_DROP_MONITOR;
1918
1919 /* reload pointers */
1920 hdr = (struct ieee80211_hdr *) skb->data;
1897 mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); 1921 mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
1898 1922
1899 /* frame is in RMC, don't forward */ 1923 /* frame is in RMC, don't forward */
@@ -1902,7 +1926,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1902 mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata)) 1926 mesh_rmc_check(hdr->addr3, mesh_hdr, rx->sdata))
1903 return RX_DROP_MONITOR; 1927 return RX_DROP_MONITOR;
1904 1928
1905 if (!ieee80211_is_data(hdr->frame_control)) 1929 if (!ieee80211_is_data(hdr->frame_control) ||
1930 !(status->rx_flags & IEEE80211_RX_RA_MATCH))
1906 return RX_CONTINUE; 1931 return RX_CONTINUE;
1907 1932
1908 if (!mesh_hdr->ttl) 1933 if (!mesh_hdr->ttl)
@@ -1916,9 +1941,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1916 if (is_multicast_ether_addr(hdr->addr1)) { 1941 if (is_multicast_ether_addr(hdr->addr1)) {
1917 mpp_addr = hdr->addr3; 1942 mpp_addr = hdr->addr3;
1918 proxied_addr = mesh_hdr->eaddr1; 1943 proxied_addr = mesh_hdr->eaddr1;
1919 } else { 1944 } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
1945 /* has_a4 already checked in ieee80211_rx_mesh_check */
1920 mpp_addr = hdr->addr4; 1946 mpp_addr = hdr->addr4;
1921 proxied_addr = mesh_hdr->eaddr2; 1947 proxied_addr = mesh_hdr->eaddr2;
1948 } else {
1949 return RX_DROP_MONITOR;
1922 } 1950 }
1923 1951
1924 rcu_read_lock(); 1952 rcu_read_lock();
@@ -1946,12 +1974,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1946 } 1974 }
1947 skb_set_queue_mapping(skb, q); 1975 skb_set_queue_mapping(skb, q);
1948 1976
1949 if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
1950 goto out;
1951
1952 if (!--mesh_hdr->ttl) { 1977 if (!--mesh_hdr->ttl) {
1953 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); 1978 IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
1954 return RX_DROP_MONITOR; 1979 goto out;
1955 } 1980 }
1956 1981
1957 if (!ifmsh->mshcfg.dot11MeshForwarding) 1982 if (!ifmsh->mshcfg.dot11MeshForwarding)
@@ -2358,6 +2383,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2358 } 2383 }
2359 break; 2384 break;
2360 case WLAN_CATEGORY_SELF_PROTECTED: 2385 case WLAN_CATEGORY_SELF_PROTECTED:
2386 if (len < (IEEE80211_MIN_ACTION_SIZE +
2387 sizeof(mgmt->u.action.u.self_prot.action_code)))
2388 break;
2389
2361 switch (mgmt->u.action.u.self_prot.action_code) { 2390 switch (mgmt->u.action.u.self_prot.action_code) {
2362 case WLAN_SP_MESH_PEERING_OPEN: 2391 case WLAN_SP_MESH_PEERING_OPEN:
2363 case WLAN_SP_MESH_PEERING_CLOSE: 2392 case WLAN_SP_MESH_PEERING_CLOSE:
@@ -2376,6 +2405,10 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
2376 } 2405 }
2377 break; 2406 break;
2378 case WLAN_CATEGORY_MESH_ACTION: 2407 case WLAN_CATEGORY_MESH_ACTION:
2408 if (len < (IEEE80211_MIN_ACTION_SIZE +
2409 sizeof(mgmt->u.action.u.mesh_action.action_code)))
2410 break;
2411
2379 if (!ieee80211_vif_is_mesh(&sdata->vif)) 2412 if (!ieee80211_vif_is_mesh(&sdata->vif))
2380 break; 2413 break;
2381 if (mesh_action_is_path_sel(mgmt) && 2414 if (mesh_action_is_path_sel(mgmt) &&
@@ -2918,10 +2951,15 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2918 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) 2951 if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc))
2919 local->dot11ReceivedFragmentCount++; 2952 local->dot11ReceivedFragmentCount++;
2920 2953
2921 if (ieee80211_is_mgmt(fc)) 2954 if (ieee80211_is_mgmt(fc)) {
2922 err = skb_linearize(skb); 2955 /* drop frame if too short for header */
2923 else 2956 if (skb->len < ieee80211_hdrlen(fc))
2957 err = -ENOBUFS;
2958 else
2959 err = skb_linearize(skb);
2960 } else {
2924 err = !pskb_may_pull(skb, ieee80211_hdrlen(fc)); 2961 err = !pskb_may_pull(skb, ieee80211_hdrlen(fc));
2962 }
2925 2963
2926 if (err) { 2964 if (err) {
2927 dev_kfree_skb(skb); 2965 dev_kfree_skb(skb);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index b3a84746d445..9556391b05d7 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -643,13 +643,41 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
643 break; 643 break;
644 } 644 }
645 645
646 if (id != WLAN_EID_VENDOR_SPECIFIC && 646 switch (id) {
647 id != WLAN_EID_QUIET && 647 case WLAN_EID_SSID:
648 test_bit(id, seen_elems)) { 648 case WLAN_EID_SUPP_RATES:
649 elems->parse_error = true; 649 case WLAN_EID_FH_PARAMS:
650 left -= elen; 650 case WLAN_EID_DS_PARAMS:
651 pos += elen; 651 case WLAN_EID_CF_PARAMS:
652 continue; 652 case WLAN_EID_TIM:
653 case WLAN_EID_IBSS_PARAMS:
654 case WLAN_EID_CHALLENGE:
655 case WLAN_EID_RSN:
656 case WLAN_EID_ERP_INFO:
657 case WLAN_EID_EXT_SUPP_RATES:
658 case WLAN_EID_HT_CAPABILITY:
659 case WLAN_EID_HT_OPERATION:
660 case WLAN_EID_VHT_CAPABILITY:
661 case WLAN_EID_VHT_OPERATION:
662 case WLAN_EID_MESH_ID:
663 case WLAN_EID_MESH_CONFIG:
664 case WLAN_EID_PEER_MGMT:
665 case WLAN_EID_PREQ:
666 case WLAN_EID_PREP:
667 case WLAN_EID_PERR:
668 case WLAN_EID_RANN:
669 case WLAN_EID_CHANNEL_SWITCH:
670 case WLAN_EID_EXT_CHANSWITCH_ANN:
671 case WLAN_EID_COUNTRY:
672 case WLAN_EID_PWR_CONSTRAINT:
673 case WLAN_EID_TIMEOUT_INTERVAL:
674 if (test_bit(id, seen_elems)) {
675 elems->parse_error = true;
676 left -= elen;
677 pos += elen;
678 continue;
679 }
680 break;
653 } 681 }
654 682
655 if (calc_crc && id < 64 && (filter & (1ULL << id))) 683 if (calc_crc && id < 64 && (filter & (1ULL << id)))