2022-11-23 15:41:07

by Phil Turnbull

[permalink] [raw]
Subject: [PATCH 0/4] wilc1000: Improve RSN and attribute parsing

This patch series improves RSN and attribute parsing in the WILC1000
driver to prevent several out of bound reads and writes.

Phil Turnbull (4):
wifi: wilc1000: validate pairwise and authentication suite offsets
wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_OPER_CHANNEL
attribute
wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_CHANNEL_LIST
attribute
wifi: wilc1000: validate number of channels

.../wireless/microchip/wilc1000/cfg80211.c | 39 ++++++++++++++-----
drivers/net/wireless/microchip/wilc1000/hif.c | 21 +++++++---
2 files changed, 46 insertions(+), 14 deletions(-)

--
2.34.1


2022-11-23 15:41:40

by Phil Turnbull

[permalink] [raw]
Subject: [PATCH 2/4] wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_OPER_CHANNEL attribute

Validate that the IEEE80211_P2P_ATTR_OPER_CHANNEL attribute contains
enough space for a 'struct struct wilc_attr_oper_ch'. If the attribute is
too small then it triggers an out-of-bounds write later in the function.

Signed-off-by: Phil Turnbull <[email protected]>
Tested-by: Ajay Kathat <[email protected]>
Acked-by: Ajay Kathat <[email protected]>
---
drivers/net/wireless/microchip/wilc1000/cfg80211.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
index 9bbfff803357..aedf0e8b69b9 100644
--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
@@ -959,14 +959,24 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
return;

while (index + sizeof(*e) <= len) {
+ u16 attr_size;
+
e = (struct wilc_attr_entry *)&buf[index];
+ attr_size = le16_to_cpu(e->attr_len);
+
+ if (index + sizeof(*e) + attr_size > len)
+ return;
+
if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
ch_list_idx = index;
- else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL)
+ else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL &&
+ attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e)))
op_ch_idx = index;
+
if (ch_list_idx && op_ch_idx)
break;
- index += le16_to_cpu(e->attr_len) + sizeof(*e);
+
+ index += sizeof(*e) + attr_size;
}

if (ch_list_idx) {
--
2.34.1

2022-11-23 15:41:41

by Phil Turnbull

[permalink] [raw]
Subject: [PATCH 1/4] wifi: wilc1000: validate pairwise and authentication suite offsets

There is no validation of 'offset' which can trigger an out-of-bounds
read when extracting RSN capabilities.

Signed-off-by: Phil Turnbull <[email protected]>
Tested-by: Ajay Kathat <[email protected]>
Acked-by: Ajay Kathat <[email protected]>
---
drivers/net/wireless/microchip/wilc1000/hif.c | 21 ++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/microchip/wilc1000/hif.c b/drivers/net/wireless/microchip/wilc1000/hif.c
index eb1d1ba3a443..67df8221b5ae 100644
--- a/drivers/net/wireless/microchip/wilc1000/hif.c
+++ b/drivers/net/wireless/microchip/wilc1000/hif.c
@@ -482,14 +482,25 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,

rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
if (rsn_ie) {
+ int rsn_ie_len = sizeof(struct element) + rsn_ie[1];
int offset = 8;

- param->mode_802_11i = 2;
- param->rsn_found = true;
/* extract RSN capabilities */
- offset += (rsn_ie[offset] * 4) + 2;
- offset += (rsn_ie[offset] * 4) + 2;
- memcpy(param->rsn_cap, &rsn_ie[offset], 2);
+ if (offset < rsn_ie_len) {
+ /* skip over pairwise suites */
+ offset += (rsn_ie[offset] * 4) + 2;
+
+ if (offset < rsn_ie_len) {
+ /* skip over authentication suites */
+ offset += (rsn_ie[offset] * 4) + 2;
+
+ if (offset + 1 < rsn_ie_len) {
+ param->mode_802_11i = 2;
+ param->rsn_found = true;
+ memcpy(param->rsn_cap, &rsn_ie[offset], 2);
+ }
+ }
+ }
}

if (param->rsn_found) {
--
2.34.1

2022-11-23 15:41:46

by Phil Turnbull

[permalink] [raw]
Subject: [PATCH 3/4] wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_CHANNEL_LIST attribute

Validate that the IEEE80211_P2P_ATTR_CHANNEL_LIST attribute contains
enough space for a 'struct wilc_attr_oper_ch'. If the attribute is too
small then it can trigger an out-of-bounds write later in the function.

'struct wilc_attr_oper_ch' is variable sized so also check 'attr_len'
does not extend beyond the end of 'buf'.

Signed-off-by: Phil Turnbull <[email protected]>
Tested-by: Ajay Kathat <[email protected]>
Acked-by: Ajay Kathat <[email protected]>
---
drivers/net/wireless/microchip/wilc1000/cfg80211.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
index aedf0e8b69b9..c4d5a272ccc0 100644
--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
@@ -967,7 +967,8 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
if (index + sizeof(*e) + attr_size > len)
return;

- if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
+ if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST &&
+ attr_size >= (sizeof(struct wilc_attr_ch_list) - sizeof(*e)))
ch_list_idx = index;
else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL &&
attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e)))
--
2.34.1

2022-11-23 15:41:46

by Phil Turnbull

[permalink] [raw]
Subject: [PATCH 4/4] wifi: wilc1000: validate number of channels

There is no validation of 'e->no_of_channels' which can trigger an
out-of-bounds write in the following 'memset' call. Validate that the
number of channels does not extends beyond the size of the channel list
element.

Signed-off-by: Phil Turnbull <[email protected]>
Tested-by: Ajay Kathat <[email protected]>
Acked-by: Ajay Kathat <[email protected]>
---
.../wireless/microchip/wilc1000/cfg80211.c | 22 ++++++++++++++-----
1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.c b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
index c4d5a272ccc0..b545d93c6e37 100644
--- a/drivers/net/wireless/microchip/wilc1000/cfg80211.c
+++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.c
@@ -981,19 +981,29 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
}

if (ch_list_idx) {
- u16 attr_size;
- struct wilc_ch_list_elem *e;
- int i;
+ u16 elem_size;

ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
- attr_size = le16_to_cpu(ch_list->attr_len);
- for (i = 0; i < attr_size;) {
+ /* the number of bytes following the final 'elem' member */
+ elem_size = le16_to_cpu(ch_list->attr_len) -
+ (sizeof(*ch_list) - sizeof(struct wilc_attr_entry));
+ for (unsigned int i = 0; i < elem_size;) {
+ struct wilc_ch_list_elem *e;
+
e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
+
+ i += sizeof(*e);
+ if (i > elem_size)
+ break;
+
+ i += e->no_of_channels;
+ if (i > elem_size)
+ break;
+
if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
memset(e->ch_list, sta_ch, e->no_of_channels);
break;
}
- i += e->no_of_channels;
}
}

--
2.34.1

2022-11-24 16:14:06

by Kalle Valo

[permalink] [raw]
Subject: Re: [PATCH 1/4] wifi: wilc1000: validate pairwise and authentication suite offsets

Phil Turnbull <[email protected]> wrote:

> There is no validation of 'offset' which can trigger an out-of-bounds
> read when extracting RSN capabilities.
>
> Signed-off-by: Phil Turnbull <[email protected]>
> Tested-by: Ajay Kathat <[email protected]>
> Acked-by: Ajay Kathat <[email protected]>

4 patches applied to wireless.git, thanks.

cd21d99e595e wifi: wilc1000: validate pairwise and authentication suite offsets
051ae669e450 wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_OPER_CHANNEL attribute
f9b62f9843c7 wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_CHANNEL_LIST attribute
0cdfa9e6f091 wifi: wilc1000: validate number of channels

--
https://patchwork.kernel.org/project/linux-wireless/patch/[email protected]/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches