Avoid undefined behavior in pointer arithmetic in IE parsing
authorJouni Malinen <j@w1.fi>
Sat, 17 Oct 2015 23:22:34 +0000 (02:22 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 24 Oct 2015 18:43:54 +0000 (21:43 +0300)
Reorder terms in a way that no invalid pointers are generated with
pos+len operations. end-pos is always defined (with a valid pos pointer)
while pos+len could end up pointing beyond the end pointer which would
be undefined behavior.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/common/ieee802_11_common.c

index 833fcf8..778185d 100644 (file)
@@ -398,8 +398,8 @@ int ieee802_11_ie_count(const u8 *ies, size_t ies_len)
        pos = ies;
        end = ies + ies_len;
 
-       while (pos + 2 <= end) {
-               if (pos + 2 + pos[1] > end)
+       while (end - pos >= 2) {
+               if (2 + pos[1] > end - pos)
                        break;
                count++;
                pos += 2 + pos[1];
@@ -419,8 +419,8 @@ struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
        end = ies + ies_len;
        ie = NULL;
 
-       while (pos + 1 < end) {
-               if (pos + 2 + pos[1] > end)
+       while (end - pos > 1) {
+               if (2 + pos[1] > end - pos)
                        return NULL;
                if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
                    WPA_GET_BE32(&pos[2]) == oui_type) {
@@ -441,8 +441,8 @@ struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len,
         * There may be multiple vendor IEs in the message, so need to
         * concatenate their data fields.
         */
-       while (pos + 1 < end) {
-               if (pos + 2 + pos[1] > end)
+       while (end - pos > 1) {
+               if (2 + pos[1] > end - pos)
                        break;
                if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
                    WPA_GET_BE32(&pos[2]) == oui_type)