diff options
author | Amitkumar Karwar <akarwar@marvell.com> | 2013-10-22 18:24:46 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-11-11 14:38:57 -0500 |
commit | 01c85adfff5a8462aeea70796314c39dab1d9cc2 (patch) | |
tree | 85168c8292f1bb2657b221c5a8fae007b2643c8c | |
parent | 2636c308fd720137d719c91da95adca2cd8f1c51 (diff) |
mwifiex: fix invalid memory access in mwifiex_update_autoindex_ies()
While parsing TLVs, return failure if number of remaining bytes
are less than current tlv length. This avoids invalid memory
access.
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/mwifiex/ie.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/drivers/net/wireless/mwifiex/ie.c b/drivers/net/wireless/mwifiex/ie.c index 220af4fe0fc6..81ac001ee741 100644 --- a/drivers/net/wireless/mwifiex/ie.c +++ b/drivers/net/wireless/mwifiex/ie.c | |||
@@ -82,7 +82,7 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv, | |||
82 | struct mwifiex_ie_list *ie_list) | 82 | struct mwifiex_ie_list *ie_list) |
83 | { | 83 | { |
84 | u16 travel_len, index, mask; | 84 | u16 travel_len, index, mask; |
85 | s16 input_len; | 85 | s16 input_len, tlv_len; |
86 | struct mwifiex_ie *ie; | 86 | struct mwifiex_ie *ie; |
87 | u8 *tmp; | 87 | u8 *tmp; |
88 | 88 | ||
@@ -91,11 +91,13 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv, | |||
91 | 91 | ||
92 | ie_list->len = 0; | 92 | ie_list->len = 0; |
93 | 93 | ||
94 | while (input_len > 0) { | 94 | while (input_len >= sizeof(struct mwifiex_ie_types_header)) { |
95 | ie = (struct mwifiex_ie *)(((u8 *)ie_list) + travel_len); | 95 | ie = (struct mwifiex_ie *)(((u8 *)ie_list) + travel_len); |
96 | input_len -= le16_to_cpu(ie->ie_length) + MWIFIEX_IE_HDR_SIZE; | 96 | tlv_len = le16_to_cpu(ie->ie_length); |
97 | travel_len += le16_to_cpu(ie->ie_length) + MWIFIEX_IE_HDR_SIZE; | 97 | travel_len += tlv_len + MWIFIEX_IE_HDR_SIZE; |
98 | 98 | ||
99 | if (input_len < tlv_len + MWIFIEX_IE_HDR_SIZE) | ||
100 | return -1; | ||
99 | index = le16_to_cpu(ie->ie_index); | 101 | index = le16_to_cpu(ie->ie_index); |
100 | mask = le16_to_cpu(ie->mgmt_subtype_mask); | 102 | mask = le16_to_cpu(ie->mgmt_subtype_mask); |
101 | 103 | ||
@@ -132,6 +134,7 @@ mwifiex_update_autoindex_ies(struct mwifiex_private *priv, | |||
132 | le16_add_cpu(&ie_list->len, | 134 | le16_add_cpu(&ie_list->len, |
133 | le16_to_cpu(priv->mgmt_ie[index].ie_length) + | 135 | le16_to_cpu(priv->mgmt_ie[index].ie_length) + |
134 | MWIFIEX_IE_HDR_SIZE); | 136 | MWIFIEX_IE_HDR_SIZE); |
137 | input_len -= tlv_len + MWIFIEX_IE_HDR_SIZE; | ||
135 | } | 138 | } |
136 | 139 | ||
137 | if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) | 140 | if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) |