cfg80211: check vendor IE length to avoid overrun
authorLuciano Coelho <coelho@ti.com>
Tue, 12 Feb 2013 18:11:38 +0000 (20:11 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 13 Feb 2013 09:14:17 +0000 (10:14 +0100)
cfg80211_find_vendor_ie() was checking only that the vendor IE would
fit in the remaining IEs buffer.  If a corrupt includes a vendor IE
that is too small, we could potentially overrun the IEs buffer.

Fix this by checking that the vendor IE fits in the reported IE length
field and skip it otherwise.

Reported-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Luciano Coelho <coelho@ti.com>
[change BUILD_BUG_ON to != 1 (from >= 2)]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/wireless/scan.c

index b7a16798498683946ef8625f7789eb9e4e153197..d0fc6da2d097526d9321c474246fedeb0f9b3baf 100644 (file)
@@ -365,14 +365,18 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
                if (!pos)
                        return NULL;
 
-               if (end - pos < sizeof(*ie))
-                       return NULL;
-
                ie = (struct ieee80211_vendor_ie *)pos;
+
+               /* make sure we can access ie->len */
+               BUILD_BUG_ON(offsetof(struct ieee80211_vendor_ie, len) != 1);
+
+               if (ie->len < sizeof(*ie))
+                       goto cont;
+
                ie_oui = ie->oui[0] << 16 | ie->oui[1] << 8 | ie->oui[2];
                if (ie_oui == oui && ie->oui_type == oui_type)
                        return pos;
-
+cont:
                pos += 2 + ie->len;
        }
        return NULL;