]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
PAE: Validate input before pointer
authorMichael Braun <michael-dev@fami-braun.de>
Thu, 17 Aug 2017 23:14:28 +0000 (01:14 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 25 Sep 2017 18:26:32 +0000 (21:26 +0300)
ieee802_1x_kay_decode_mkpdu() calls ieee802_1x_mka_i_in_peerlist()
before body_len has been checked on all segments.

ieee802_1x_kay_decode_mkpdu() and ieee802_1x_mka_i_in_peerlist() might
continue and thus underflow left_len even if it finds left_len to small
(or before checking).

Additionally, ieee802_1x_mka_dump_peer_body() might perform out of bound
reads in this case.

Fix this by checking left_len and aborting if too small early.

Signed-off-by: Michael Braun <michael-dev@fami-braun.de>
src/pae/ieee802_1x_kay.c

index c4bfcbc635935b74f14e105bdc3b0f55bc44101b..cad0292ecda04506fbf67ba7bd4973597d8bb5d0 100644 (file)
@@ -964,21 +964,19 @@ ieee802_1x_mka_i_in_peerlist(struct ieee802_1x_mka_participant *participant,
                body_len = get_mka_param_body_len(hdr);
                body_type = get_mka_param_body_type(hdr);
 
-               if (body_type != MKA_LIVE_PEER_LIST &&
-                   body_type != MKA_POTENTIAL_PEER_LIST)
-                       continue;
-
-               ieee802_1x_mka_dump_peer_body(
-                       (struct ieee802_1x_mka_peer_body *)pos);
-
-               if (left_len < (MKA_HDR_LEN + body_len + DEFAULT_ICV_LEN)) {
+               if (left_len < (MKA_HDR_LEN + MKA_ALIGN_LENGTH(body_len) + DEFAULT_ICV_LEN)) {
                        wpa_printf(MSG_ERROR,
                                   "KaY: MKA Peer Packet Body Length (%zu bytes) is less than the Parameter Set Header Length (%zu bytes) + the Parameter Set Body Length (%zu bytes) + %d bytes of ICV",
                                   left_len, MKA_HDR_LEN,
-                                  body_len, DEFAULT_ICV_LEN);
-                       continue;
+                                  MKA_ALIGN_LENGTH(body_len),
+                                  DEFAULT_ICV_LEN);
+                       return FALSE;
                }
 
+               if (body_type != MKA_LIVE_PEER_LIST &&
+                   body_type != MKA_POTENTIAL_PEER_LIST)
+                       continue;
+
                if ((body_len % 16) != 0) {
                        wpa_printf(MSG_ERROR,
                                   "KaY: MKA Peer Packet Body Length (%zu bytes) should be a multiple of 16 octets",
@@ -986,6 +984,9 @@ ieee802_1x_mka_i_in_peerlist(struct ieee802_1x_mka_participant *participant,
                        continue;
                }
 
+               ieee802_1x_mka_dump_peer_body(
+                       (struct ieee802_1x_mka_peer_body *)pos);
+
                for (i = 0; i < body_len;
                     i += sizeof(struct ieee802_1x_mka_peer_id)) {
                        const struct ieee802_1x_mka_peer_id *peer_mi;
@@ -3018,7 +3019,7 @@ static int ieee802_1x_kay_decode_mkpdu(struct ieee802_1x_kay *kay,
                                   "KaY: MKA Peer Packet Body Length (%zu bytes) is less than the Parameter Set Header Length (%zu bytes) + the Parameter Set Body Length (%zu bytes) + %d bytes of ICV",
                                   left_len, MKA_HDR_LEN,
                                   body_len, DEFAULT_ICV_LEN);
-                       continue;
+                       return -1;
                }
 
                if (handled[body_type])