forked from osmocom/wireshark
dot11crypt: add bounds check for TDLS elements
Fixes a buffer overrun (read) of at most 255 bytes which could occur while processing FTE in Dot11DecryptTDLSDeriveKey. While at it, according to 802.11-2016 9.4.1.9, "A status code of SUCCESS_POWER_SAVE_MODE also indicates a successful operation.". No idea when it makes a difference, but let's implement it too. Bug: 14686 Change-Id: Ia7a41cd965704a4d51fb5a4dc4d01885fc17375c Fixes: v2.1.0rc0-1825-g6991149557 ("[airpdcap] Add support to decrypt TDLS traffic") Link: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=8189 Reviewed-on: https://code.wireshark.org/review/27618 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman <a.broman58@gmail.com>
This commit is contained in:
parent
39586110d8
commit
f440561b8c
|
@ -17,6 +17,7 @@
|
|||
#include <wsutil/crc32.h>
|
||||
#include <wsutil/pint.h>
|
||||
|
||||
#include <epan/proto.h> /* for DISSECTOR_ASSERT. */
|
||||
#include <epan/tvbuff.h>
|
||||
#include <epan/to_str.h>
|
||||
#include <epan/strutil.h>
|
||||
|
@ -529,6 +530,10 @@ static INT Dot11DecryptScanForKeys(
|
|||
#endif
|
||||
DOT11DECRYPT_DEBUG_TRACE_START("Dot11DecryptScanForKeys");
|
||||
|
||||
/* Callers provide these guarantees, so let's make them explicit. */
|
||||
DISSECTOR_ASSERT(tot_len >= mac_header_len + DOT11DECRYPT_CRYPTED_DATA_MINLEN);
|
||||
DISSECTOR_ASSERT(tot_len <= DOT11DECRYPT_MAX_CAPLEN);
|
||||
|
||||
/* cache offset in the packet data */
|
||||
offset = mac_header_len;
|
||||
|
||||
|
@ -633,7 +638,9 @@ static INT Dot11DecryptScanForKeys(
|
|||
guint status, offset_rsne = 0, offset_fte = 0, offset_link = 0, offset_timeout = 0;
|
||||
DOT11DECRYPT_DEBUG_PRINT_LINE("Dot11DecryptScanForKeys", "Authentication: TDLS Action Frame", DOT11DECRYPT_DEBUG_LEVEL_3);
|
||||
|
||||
/* skip LLC header */
|
||||
/* Skip LLC header, after this we have at least
|
||||
* DOT11DECRYPT_CRYPTED_DATA_MINLEN-10 = 7 bytes in "data[offset]". That
|
||||
* TDLS payload contains a TDLS Action field (802.11-2016 9.6.13) */
|
||||
offset+=10;
|
||||
|
||||
/* check if the packet is a TDLS response or confirm */
|
||||
|
@ -642,11 +649,11 @@ static INT Dot11DecryptScanForKeys(
|
|||
DOT11DECRYPT_DEBUG_PRINT_LINE("Dot11DecryptScanForKeys", "Not Response nor confirm", DOT11DECRYPT_DEBUG_LEVEL_3);
|
||||
return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
|
||||
}
|
||||
|
||||
/* check status */
|
||||
offset++;
|
||||
|
||||
/* Check for SUCCESS (0) or SUCCESS_POWER_SAVE_MODE (85) Status Code */
|
||||
status=pntoh16(data+offset);
|
||||
if (status!=0) {
|
||||
if (status != 0 && status != 85) {
|
||||
DOT11DECRYPT_DEBUG_PRINT_LINE("Dot11DecryptScanForKeys", "TDLS setup not successfull", DOT11DECRYPT_DEBUG_LEVEL_3);
|
||||
return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
|
||||
}
|
||||
|
@ -657,20 +664,33 @@ static INT Dot11DecryptScanForKeys(
|
|||
/* search for RSN, Fast BSS Transition, Link Identifier and Timeout Interval IEs */
|
||||
|
||||
while(offset < (tot_len - 2)) {
|
||||
if (data[offset] == 48) {
|
||||
guint8 element_id = data[offset];
|
||||
guint8 length = data[offset + 1];
|
||||
guint min_length = length;
|
||||
switch (element_id) {
|
||||
case 48: /* RSN (802.11-2016 9.4.2.35) */
|
||||
offset_rsne = offset;
|
||||
} else if (data[offset] == 55) {
|
||||
min_length = 1;
|
||||
break;
|
||||
case 55: /* FTE (802.11-2016 9.4.2.48) */
|
||||
offset_fte = offset;
|
||||
} else if (data[offset] == 56) {
|
||||
/* Plus variable length optional parameter(s) */
|
||||
min_length = 2 + 16 + 32 + 32;
|
||||
break;
|
||||
case 56: /* Timeout Interval (802.11-2016 9.4.2.49) */
|
||||
offset_timeout = offset;
|
||||
} else if (data[offset] == 101) {
|
||||
min_length = 1 + 4;
|
||||
break;
|
||||
case 101: /* Link Identifier (802.11-2016 9.4.2.62) */
|
||||
offset_link = offset;
|
||||
min_length = 6 + 6 + 6;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tot_len < offset + data[offset + 1] + 2) {
|
||||
if (length < min_length || tot_len < offset + 2 + length) {
|
||||
return DOT11DECRYPT_RET_NO_VALID_HANDSHAKE;
|
||||
}
|
||||
offset += data[offset + 1] + 2;
|
||||
offset += 2 + length;
|
||||
}
|
||||
|
||||
if (offset_rsne == 0 || offset_fte == 0 ||
|
||||
|
|
Loading…
Reference in New Issue