summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanohar@qti.qualcomm.com>2017-05-15 07:41:55 +0300
committerBen Hutchings <ben@decadent.org.uk>2017-09-15 20:30:43 +0300
commit035fd2a017a26a566732a878b8856187111cad68 (patch)
tree805654c3e816ae9d4478c290c02230b5f39b753b
parentbef118e469b2de6eea62be03a18f0897782d63f8 (diff)
downloadlinux-035fd2a017a26a566732a878b8856187111cad68.tar.xz
mac80211: strictly check mesh address extension mode
commit 5667c86acf021e6dcf02584408b4484a273ac68f upstream. 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> [bwh: Backported to 3.2: add mesh_flags variable in ieee80211_data_to_8023(), added separately upstream] Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
-rw-r--r--net/mac80211/rx.c3
-rw-r--r--net/wireless/util.c14
2 files changed, 12 insertions, 5 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 96c34c15b1ea..0cfb95a37540 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1959,7 +1959,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
if (is_multicast_ether_addr(hdr->addr1)) {
mpp_addr = hdr->addr3;
proxied_addr = mesh_hdr->eaddr1;
- } else if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6) {
+ } else if ((mesh_hdr->flags & MESH_FLAGS_AE) ==
+ MESH_FLAGS_AE_A5_A6) {
/* has_a4 already checked in ieee80211_rx_mesh_check */
mpp_addr = hdr->addr4;
proxied_addr = mesh_hdr->eaddr2;
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 5fba039ca6dd..870c52dcd384 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -360,12 +360,15 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
if (iftype == NL80211_IFTYPE_MESH_POINT) {
struct ieee80211s_hdr *meshdr =
(struct ieee80211s_hdr *) (skb->data + hdrlen);
+ u8 mesh_flags;
+
/* make sure meshdr->flags is on the linear part */
if (!pskb_may_pull(skb, hdrlen + 1))
return -1;
- if (meshdr->flags & MESH_FLAGS_AE_A4)
+ mesh_flags = meshdr->flags & MESH_FLAGS_AE;
+ if (mesh_flags == MESH_FLAGS_AE_A4)
return -1;
- if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
+ if (mesh_flags == MESH_FLAGS_AE_A5_A6) {
skb_copy_bits(skb, hdrlen +
offsetof(struct ieee80211s_hdr, eaddr1),
dst, ETH_ALEN);
@@ -386,12 +389,15 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
if (iftype == NL80211_IFTYPE_MESH_POINT) {
struct ieee80211s_hdr *meshdr =
(struct ieee80211s_hdr *) (skb->data + hdrlen);
+ u8 mesh_flags;
+
/* make sure meshdr->flags is on the linear part */
if (!pskb_may_pull(skb, hdrlen + 1))
return -1;
- if (meshdr->flags & MESH_FLAGS_AE_A5_A6)
+ mesh_flags = meshdr->flags & MESH_FLAGS_AE;
+ if (mesh_flags == MESH_FLAGS_AE_A5_A6)
return -1;
- if (meshdr->flags & MESH_FLAGS_AE_A4)
+ if (mesh_flags == MESH_FLAGS_AE_A4)
skb_copy_bits(skb, hdrlen +
offsetof(struct ieee80211s_hdr, eaddr1),
src, ETH_ALEN);