diff mbox

[3.0] nl80211: fix overflow in ssid_len

Message ID 1307468546-16915-1-git-send-email-coelho@ti.com (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Luciano Coelho June 7, 2011, 5:42 p.m. UTC
When one of the SSID's length passed in a scan or sched_scan request
is larger than 255, there will be an overflow in the u8 that is used
to store the length before checking.  This causes the check to fail
and we overrun the buffer when copying the SSID.

Fix this by checking the nl80211 attribute length before copying it to
the struct.

This is a follow up for the previous commit
208c72f4fe44fe09577e7975ba0e7fa0278f3d03, which didn't fix the problem
entirely.

Reported-by: Ido Yariv <ido@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
---
 net/wireless/nl80211.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

Comments

Luciano Coelho June 7, 2011, 6:25 p.m. UTC | #1
On Tue, 2011-06-07 at 20:42 +0300, Luciano Coelho wrote: 
> When one of the SSID's length passed in a scan or sched_scan request
> is larger than 255, there will be an overflow in the u8 that is used
> to store the length before checking.  This causes the check to fail
> and we overrun the buffer when copying the SSID.
> 
> Fix this by checking the nl80211 attribute length before copying it to
> the struct.
> 
> This is a follow up for the previous commit
> 208c72f4fe44fe09577e7975ba0e7fa0278f3d03, which didn't fix the problem
> entirely.
> 
> Reported-by: Ido Yariv <ido@wizery.com>
> Signed-off-by: Luciano Coelho <coelho@ti.com>
> ---

This should also go to stable, but since it won't apply directly there,
I'll wait till it's applied upstream and then backport it to stable
kernels.
diff mbox

Patch

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 1c57036..c859f50 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3412,11 +3412,11 @@  static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 	i = 0;
 	if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
 		nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
-			request->ssids[i].ssid_len = nla_len(attr);
-			if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) {
+			if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
 				err = -EINVAL;
 				goto out_free;
 			}
+			request->ssids[i].ssid_len = nla_len(attr);
 			memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
 			i++;
 		}
@@ -3578,12 +3578,11 @@  static int nl80211_start_sched_scan(struct sk_buff *skb,
 	if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
 		nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS],
 				    tmp) {
-			request->ssids[i].ssid_len = nla_len(attr);
-			if (request->ssids[i].ssid_len >
-			    IEEE80211_MAX_SSID_LEN) {
+			if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) {
 				err = -EINVAL;
 				goto out_free;
 			}
+			request->ssids[i].ssid_len = nla_len(attr);
 			memcpy(request->ssids[i].ssid, nla_data(attr),
 			       nla_len(attr));
 			i++;