aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanohar@qti.qualcomm.com>2017-05-15 00:41:55 -0400
committerJohannes Berg <johannes.berg@intel.com>2017-05-17 08:24:29 -0400
commit5667c86acf021e6dcf02584408b4484a273ac68f (patch)
tree0fa26498af9173f5eddfe41f2ca81a6689fc6963
parent29cee56c0be46ad01e78af104a06223c65ee0c67 (diff)
mac80211: strictly check mesh address extension mode
Mesh forwarding path checks for address extension mode to fetch appropriate proxied address and MPP address. Existing condition that looks for 6 address format is not strict enough so that frames with improper values are processed and invalid entries are added into MPP table. Fix that by adding a stricter check before processing the packet. Per IEEE Std 802.11s-2011 spec. Table 7-6g1 lists address extension mode 0x3 as reserved one. And also Table Table 9-13 does not specify 0x3 as valid address field. Fixes: 9b395bc3be1c ("mac80211: verify that skb data is present") Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--net/mac80211/rx.c3
-rw-r--r--net/wireless/util.c10
2 files changed, 8 insertions, 5 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 35f4c7d7a500..1f75280ba26c 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2492,7 +2492,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
2492 if (is_multicast_ether_addr(hdr->addr1)) { 2492 if (is_multicast_ether_addr(hdr->addr1)) {
2493 mpp_addr = hdr->addr3; 2493 mpp_addr = hdr->addr3;
2494 proxied_addr = mesh_hdr->eaddr1; 2494 proxied_addr = mesh_hdr->eaddr1;
2495 } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) { 2495 } else if ((mesh_hdr->flags & MESH_FLAGS_AE) ==
2496 MESH_FLAGS_AE_A5_A6) {
2496 /* has_a4 already checked in ieee80211_rx_mesh_check */ 2497 /* has_a4 already checked in ieee80211_rx_mesh_check */
2497 mpp_addr = hdr->addr4; 2498 mpp_addr = hdr->addr4;
2498 proxied_addr = mesh_hdr->eaddr2; 2499 proxied_addr = mesh_hdr->eaddr2;
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 7198373e2920..4992f1025c9d 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -454,6 +454,8 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
454 if (iftype == NL80211_IFTYPE_MESH_POINT) 454 if (iftype == NL80211_IFTYPE_MESH_POINT)
455 skb_copy_bits(skb, hdrlen, &mesh_flags, 1); 455 skb_copy_bits(skb, hdrlen, &mesh_flags, 1);
456 456
457 mesh_flags &= MESH_FLAGS_AE;
458
457 switch (hdr->frame_control & 459 switch (hdr->frame_control &
458 cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { 460 cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
459 case cpu_to_le16(IEEE80211_FCTL_TODS): 461 case cpu_to_le16(IEEE80211_FCTL_TODS):
@@ -469,9 +471,9 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
469 iftype != NL80211_IFTYPE_STATION)) 471 iftype != NL80211_IFTYPE_STATION))
470 return -1; 472 return -1;
471 if (iftype == NL80211_IFTYPE_MESH_POINT) { 473 if (iftype == NL80211_IFTYPE_MESH_POINT) {
472 if (mesh_flags & MESH_FLAGS_AE_A4) 474 if (mesh_flags == MESH_FLAGS_AE_A4)
473 return -1; 475 return -1;
474 if (mesh_flags & MESH_FLAGS_AE_A5_A6) { 476 if (mesh_flags == MESH_FLAGS_AE_A5_A6) {
475 skb_copy_bits(skb, hdrlen + 477 skb_copy_bits(skb, hdrlen +
476 offsetof(struct ieee80211s_hdr, eaddr1), 478 offsetof(struct ieee80211s_hdr, eaddr1),
477 tmp.h_dest, 2 * ETH_ALEN); 479 tmp.h_dest, 2 * ETH_ALEN);
@@ -487,9 +489,9 @@ int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
487 ether_addr_equal(tmp.h_source, addr))) 489 ether_addr_equal(tmp.h_source, addr)))
488 return -1; 490 return -1;
489 if (iftype == NL80211_IFTYPE_MESH_POINT) { 491 if (iftype == NL80211_IFTYPE_MESH_POINT) {
490 if (mesh_flags & MESH_FLAGS_AE_A5_A6) 492 if (mesh_flags == MESH_FLAGS_AE_A5_A6)
491 return -1; 493 return -1;
492 if (mesh_flags & MESH_FLAGS_AE_A4) 494 if (mesh_flags == MESH_FLAGS_AE_A4)
493 skb_copy_bits(skb, hdrlen + 495 skb_copy_bits(skb, hdrlen +
494 offsetof(struct ieee80211s_hdr, eaddr1), 496 offsetof(struct ieee80211s_hdr, eaddr1),
495 tmp.h_source, ETH_ALEN); 497 tmp.h_source, ETH_ALEN);