From: Victor Julien Date: Thu, 21 Jun 2012 18:35:51 +0000 (+0200) Subject: dcerpc/smb/smb2: more robust error checking, cosmetic code updates. X-Git-Tag: suricata-1.3rc1~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2055b509a3efffde7f8c67f58601e790f3005e46;p=thirdparty%2Fsuricata.git dcerpc/smb/smb2: more robust error checking, cosmetic code updates. --- diff --git a/src/app-layer-dcerpc-udp.c b/src/app-layer-dcerpc-udp.c index 950d333c10..91d6ca525e 100644 --- a/src/app-layer-dcerpc-udp.c +++ b/src/app-layer-dcerpc-udp.c @@ -70,7 +70,7 @@ static uint32_t FragmentDataParser(Flow *f, void *dcerpcudp_state, stub_len = (sstate->dcerpc.fraglenleft < input_len) ? sstate->dcerpc.fraglenleft : input_len; if (stub_len == 0) { - SCReturnUInt(0); + SCReturnUInt(0); } /* if the frag is the the first frag irrespective of it being a part of * a multi frag PDU or not, it indicates the previous PDU's stub would @@ -630,14 +630,15 @@ static int DCERPCUDPParse(Flow *f, void *dcerpc_state, while (sstate->bytesprocessed < DCERPC_UDP_HDR_LEN && input_len) { hdrretval = DCERPCUDPParseHeader(f, dcerpc_state, pstate, input, input_len, output); - if(hdrretval == -1) { + if (hdrretval == -1 || hdrretval > (int32_t)input_len) { sstate->bytesprocessed = 0; SCReturnInt(hdrretval); } else { - parsed += retval; - input_len -= retval; + parsed += hdrretval; + input_len -= hdrretval; } } + #if 0 printf("Done with DCERPCUDPParseHeader bytesprocessed %u/%u left %u\n", sstate->bytesprocessed, sstate->dcerpc.dcerpchdrudp.fraglen, input_len); @@ -659,7 +660,7 @@ static int DCERPCUDPParse(Flow *f, void *dcerpc_state, && input_len) { retval = FragmentDataParser(f, dcerpc_state, pstate, input + parsed, input_len, output); - if (retval) { + if (retval || retval > (int32_t)input_len) { parsed += retval; input_len -= retval; } else if (input_len) { diff --git a/src/app-layer-dcerpc.c b/src/app-layer-dcerpc.c index 7cfe6becc3..a793b88f1c 100644 --- a/src/app-layer-dcerpc.c +++ b/src/app-layer-dcerpc.c @@ -229,53 +229,53 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t switch (dcerpc->dcerpcbindbindack.ctxbytesprocessed) { case 0: if (input_len >= 44) { - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.ctxid = *(p); - dcerpc->dcerpcbindbindack.ctxid |= *(p + 1) << 8; - dcerpc->dcerpcbindbindack.uuid[3] = *(p + 4); - dcerpc->dcerpcbindbindack.uuid[2] = *(p + 5); - dcerpc->dcerpcbindbindack.uuid[1] = *(p + 6); - dcerpc->dcerpcbindbindack.uuid[0] = *(p + 7); - dcerpc->dcerpcbindbindack.uuid[5] = *(p + 8); - dcerpc->dcerpcbindbindack.uuid[4] = *(p + 9); - dcerpc->dcerpcbindbindack.uuid[7] = *(p + 10); - dcerpc->dcerpcbindbindack.uuid[6] = *(p + 11); - dcerpc->dcerpcbindbindack.uuid[8] = *(p + 12); - dcerpc->dcerpcbindbindack.uuid[9] = *(p + 13); - dcerpc->dcerpcbindbindack.uuid[10] = *(p + 14); - dcerpc->dcerpcbindbindack.uuid[11] = *(p + 15); - dcerpc->dcerpcbindbindack.uuid[12] = *(p + 16); - dcerpc->dcerpcbindbindack.uuid[13] = *(p + 17); - dcerpc->dcerpcbindbindack.uuid[14] = *(p + 18); - dcerpc->dcerpcbindbindack.uuid[15] = *(p + 19); - dcerpc->dcerpcbindbindack.version = *(p + 20); - dcerpc->dcerpcbindbindack.version |= *(p + 21) << 8; - dcerpc->dcerpcbindbindack.versionminor = *(p + 22); - dcerpc->dcerpcbindbindack.versionminor |= *(p + 23) << 8; - } else { /* Big Endian */ - dcerpc->dcerpcbindbindack.ctxid = *(p) << 8; - dcerpc->dcerpcbindbindack.ctxid |= *(p + 1); - dcerpc->dcerpcbindbindack.uuid[0] = *(p + 4); - dcerpc->dcerpcbindbindack.uuid[1] = *(p + 5); - dcerpc->dcerpcbindbindack.uuid[2] = *(p + 6); - dcerpc->dcerpcbindbindack.uuid[3] = *(p + 7); - dcerpc->dcerpcbindbindack.uuid[4] = *(p + 8); - dcerpc->dcerpcbindbindack.uuid[5] = *(p + 9); - dcerpc->dcerpcbindbindack.uuid[6] = *(p + 10); - dcerpc->dcerpcbindbindack.uuid[7] = *(p + 11); - dcerpc->dcerpcbindbindack.uuid[8] = *(p + 12); - dcerpc->dcerpcbindbindack.uuid[9] = *(p + 13); - dcerpc->dcerpcbindbindack.uuid[10] = *(p + 14); - dcerpc->dcerpcbindbindack.uuid[11] = *(p + 15); - dcerpc->dcerpcbindbindack.uuid[12] = *(p + 16); - dcerpc->dcerpcbindbindack.uuid[13] = *(p + 17); - dcerpc->dcerpcbindbindack.uuid[14] = *(p + 18); - dcerpc->dcerpcbindbindack.uuid[15] = *(p + 19); - dcerpc->dcerpcbindbindack.version = *(p + 20) << 8; - dcerpc->dcerpcbindbindack.version |= *(p + 21); - dcerpc->dcerpcbindbindack.versionminor = *(p + 22) << 8; - dcerpc->dcerpcbindbindack.versionminor |= *(p + 23); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.ctxid = *(p); + dcerpc->dcerpcbindbindack.ctxid |= *(p + 1) << 8; + dcerpc->dcerpcbindbindack.uuid[3] = *(p + 4); + dcerpc->dcerpcbindbindack.uuid[2] = *(p + 5); + dcerpc->dcerpcbindbindack.uuid[1] = *(p + 6); + dcerpc->dcerpcbindbindack.uuid[0] = *(p + 7); + dcerpc->dcerpcbindbindack.uuid[5] = *(p + 8); + dcerpc->dcerpcbindbindack.uuid[4] = *(p + 9); + dcerpc->dcerpcbindbindack.uuid[7] = *(p + 10); + dcerpc->dcerpcbindbindack.uuid[6] = *(p + 11); + dcerpc->dcerpcbindbindack.uuid[8] = *(p + 12); + dcerpc->dcerpcbindbindack.uuid[9] = *(p + 13); + dcerpc->dcerpcbindbindack.uuid[10] = *(p + 14); + dcerpc->dcerpcbindbindack.uuid[11] = *(p + 15); + dcerpc->dcerpcbindbindack.uuid[12] = *(p + 16); + dcerpc->dcerpcbindbindack.uuid[13] = *(p + 17); + dcerpc->dcerpcbindbindack.uuid[14] = *(p + 18); + dcerpc->dcerpcbindbindack.uuid[15] = *(p + 19); + dcerpc->dcerpcbindbindack.version = *(p + 20); + dcerpc->dcerpcbindbindack.version |= *(p + 21) << 8; + dcerpc->dcerpcbindbindack.versionminor = *(p + 22); + dcerpc->dcerpcbindbindack.versionminor |= *(p + 23) << 8; + } else { /* Big Endian */ + dcerpc->dcerpcbindbindack.ctxid = *(p) << 8; + dcerpc->dcerpcbindbindack.ctxid |= *(p + 1); + dcerpc->dcerpcbindbindack.uuid[0] = *(p + 4); + dcerpc->dcerpcbindbindack.uuid[1] = *(p + 5); + dcerpc->dcerpcbindbindack.uuid[2] = *(p + 6); + dcerpc->dcerpcbindbindack.uuid[3] = *(p + 7); + dcerpc->dcerpcbindbindack.uuid[4] = *(p + 8); + dcerpc->dcerpcbindbindack.uuid[5] = *(p + 9); + dcerpc->dcerpcbindbindack.uuid[6] = *(p + 10); + dcerpc->dcerpcbindbindack.uuid[7] = *(p + 11); + dcerpc->dcerpcbindbindack.uuid[8] = *(p + 12); + dcerpc->dcerpcbindbindack.uuid[9] = *(p + 13); + dcerpc->dcerpcbindbindack.uuid[10] = *(p + 14); + dcerpc->dcerpcbindbindack.uuid[11] = *(p + 15); + dcerpc->dcerpcbindbindack.uuid[12] = *(p + 16); + dcerpc->dcerpcbindbindack.uuid[13] = *(p + 17); + dcerpc->dcerpcbindbindack.uuid[14] = *(p + 18); + dcerpc->dcerpcbindbindack.uuid[15] = *(p + 19); + dcerpc->dcerpcbindbindack.version = *(p + 20) << 8; + dcerpc->dcerpcbindbindack.version |= *(p + 21); + dcerpc->dcerpcbindbindack.versionminor = *(p + 22) << 8; + dcerpc->dcerpcbindbindack.versionminor |= *(p + 23); + } //if (dcerpc->dcerpcbindbindack.ctxid == dcerpc->dcerpcbindbindack.numctxitems // - dcerpc->dcerpcbindbindack.numctxitemsleft) { @@ -321,20 +321,20 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t // SCReturnUInt(0); //} } else { - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.ctxid = *(p++); - } else { - dcerpc->dcerpcbindbindack.ctxid = *(p++) << 8; - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.ctxid = *(p++); + } else { + dcerpc->dcerpcbindbindack.ctxid = *(p++) << 8; + } if (!(--input_len)) break; } case 1: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.ctxid |= *(p++) << 8; - } else { - dcerpc->dcerpcbindbindack.ctxid |= *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.ctxid |= *(p++) << 8; + } else { + dcerpc->dcerpcbindbindack.ctxid |= *(p++); + } if (!(--input_len)) break; case 2: @@ -348,72 +348,72 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t if (!(--input_len)) break; case 4: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[3] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[0] = *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.uuid[3] = *(p++); + } else { + dcerpc->dcerpcbindbindack.uuid[0] = *(p++); + } if (!(--input_len)) break; case 5: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[2] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[1] = *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.uuid[2] = *(p++); + } else { + dcerpc->dcerpcbindbindack.uuid[1] = *(p++); + } if (!(--input_len)) break; case 6: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[1] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[2] = *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.uuid[1] = *(p++); + } else { + dcerpc->dcerpcbindbindack.uuid[2] = *(p++); + } if (!(--input_len)) break; case 7: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[0] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[3] = *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.uuid[0] = *(p++); + } else { + dcerpc->dcerpcbindbindack.uuid[3] = *(p++); + } if (!(--input_len)) break; case 8: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[5] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[4] = *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.uuid[5] = *(p++); + } else { + dcerpc->dcerpcbindbindack.uuid[4] = *(p++); + } if (!(--input_len)) break; case 9: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[4] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[5] = *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.uuid[4] = *(p++); + } else { + dcerpc->dcerpcbindbindack.uuid[5] = *(p++); + } if (!(--input_len)) break; case 10: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[7] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[6] = *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.uuid[7] = *(p++); + } else { + dcerpc->dcerpcbindbindack.uuid[6] = *(p++); + } if (!(--input_len)) break; case 11: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.uuid[6] = *(p++); - } else { - dcerpc->dcerpcbindbindack.uuid[7] = *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.uuid[6] = *(p++); + } else { + dcerpc->dcerpcbindbindack.uuid[7] = *(p++); + } if (!(--input_len)) break; case 12: - /* The following bytes are in the same order for both big and little endian */ - dcerpc->dcerpcbindbindack.uuid[8] = *(p++); + /* The following bytes are in the same order for both big and little endian */ + dcerpc->dcerpcbindbindack.uuid[8] = *(p++); if (!(--input_len)) break; case 13: @@ -445,35 +445,35 @@ static uint32_t DCERPCParseBINDCTXItem(DCERPC *dcerpc, uint8_t *input, uint32_t if (!(--input_len)) break; case 20: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.version = *(p++); - } else { - dcerpc->dcerpcbindbindack.version = *(p++) << 8; - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.version = *(p++); + } else { + dcerpc->dcerpcbindbindack.version = *(p++) << 8; + } if (!(--input_len)) break; case 21: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.version |= *(p++) << 8; - } else { - dcerpc->dcerpcbindbindack.version |= *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.version |= *(p++) << 8; + } else { + dcerpc->dcerpcbindbindack.version |= *(p++); + } if (!(--input_len)) break; case 22: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.versionminor = *(p++); - } else { - dcerpc->dcerpcbindbindack.versionminor = *(p++) << 8; - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.versionminor = *(p++); + } else { + dcerpc->dcerpcbindbindack.versionminor = *(p++) << 8; + } if (!(--input_len)) break; case 23: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.versionminor |= *(p++) << 8; - } else { - dcerpc->dcerpcbindbindack.versionminor |= *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.versionminor |= *(p++) << 8; + } else { + dcerpc->dcerpcbindbindack.versionminor |= *(p++); + } if (!(--input_len)) break; case 24: @@ -618,13 +618,13 @@ static uint32_t DCERPCParseBINDACKCTXItem(DCERPC *dcerpc, uint8_t *input, uint32 switch (dcerpc->dcerpcbindbindack.ctxbytesprocessed) { case 0: if (input_len >= 24) { - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.result = *p; - dcerpc->dcerpcbindbindack.result |= *(p + 1) << 8; - } else { - dcerpc->dcerpcbindbindack.result = *p << 8; - dcerpc->dcerpcbindbindack.result |= *(p + 1); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.result = *p; + dcerpc->dcerpcbindbindack.result |= *(p + 1) << 8; + } else { + dcerpc->dcerpcbindbindack.result = *p << 8; + dcerpc->dcerpcbindbindack.result |= *(p + 1); + } TAILQ_FOREACH(uuid_entry, &dcerpc->dcerpcbindbindack.uuid_list, next) { if (uuid_entry->internal_id == dcerpc->dcerpcbindbindack.uuid_internal_id) { uuid_entry->result = dcerpc->dcerpcbindbindack.result; @@ -658,20 +658,20 @@ static uint32_t DCERPCParseBINDACKCTXItem(DCERPC *dcerpc, uint8_t *input, uint32 dcerpc->dcerpcbindbindack.ctxbytesprocessed += (24); SCReturnUInt(24U); } else { - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.result = *(p++); - } else { - dcerpc->dcerpcbindbindack.result = *(p++) << 8; - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.result = *(p++); + } else { + dcerpc->dcerpcbindbindack.result = *(p++) << 8; + } if (!(--input_len)) break; } case 1: - if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { - dcerpc->dcerpcbindbindack.result |= *(p++) << 8; - } else { - dcerpc->dcerpcbindbindack.result |= *(p++); - } + if (dcerpc->dcerpchdr.packed_drep[0] & 0x10) { + dcerpc->dcerpcbindbindack.result |= *(p++) << 8; + } else { + dcerpc->dcerpcbindbindack.result |= *(p++); + } if (!(--input_len)) break; case 2: @@ -902,9 +902,9 @@ static uint32_t DCERPCParseBIND(DCERPC *dcerpc, uint8_t *input, uint32_t input_l --input_len; break; default: - dcerpc->bytesprocessed++; - SCReturnUInt(1); - break; + dcerpc->bytesprocessed++; + SCReturnUInt(1); + break; } } dcerpc->bytesprocessed += (p - input); @@ -986,9 +986,9 @@ static uint32_t DCERPCParseBINDACK(DCERPC *dcerpc, uint8_t *input, uint32_t inpu --input_len; break; default: - dcerpc->bytesprocessed++; - SCReturnUInt(1); - break; + dcerpc->bytesprocessed++; + SCReturnUInt(1); + break; } dcerpc->bytesprocessed += (p - input); SCReturnUInt((uint32_t)(p - input)); @@ -1173,8 +1173,8 @@ end: static int DCERPCParseHeader(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { SCEnter(); uint8_t *p = input; - if (input_len) { + if (input_len) { SCLogDebug("dcerpc->bytesprocessed %u", dcerpc->bytesprocessed); switch (dcerpc->bytesprocessed) { case 0: @@ -1259,35 +1259,35 @@ static int DCERPCParseHeader(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) if (!(--input_len)) break; case 8: - dcerpc->dcerpchdr.frag_length = *(p++); + dcerpc->dcerpchdr.frag_length = *(p++); if (!(--input_len)) break; case 9: - dcerpc->dcerpchdr.frag_length |= *(p++) << 8; + dcerpc->dcerpchdr.frag_length |= *(p++) << 8; if (!(--input_len)) break; case 10: - dcerpc->dcerpchdr.auth_length = *(p++); + dcerpc->dcerpchdr.auth_length = *(p++); if (!(--input_len)) break; case 11: - dcerpc->dcerpchdr.auth_length |= *(p++) << 8; + dcerpc->dcerpchdr.auth_length |= *(p++) << 8; if (!(--input_len)) break; case 12: - dcerpc->dcerpchdr.call_id = *(p++); + dcerpc->dcerpchdr.call_id = *(p++); if (!(--input_len)) break; case 13: - dcerpc->dcerpchdr.call_id |= *(p++) << 8; + dcerpc->dcerpchdr.call_id |= *(p++) << 8; if (!(--input_len)) break; case 14: - dcerpc->dcerpchdr.call_id |= *(p++) << 16; + dcerpc->dcerpchdr.call_id |= *(p++) << 16; if (!(--input_len)) break; case 15: - dcerpc->dcerpchdr.call_id |= *(p++) << 24; + dcerpc->dcerpchdr.call_id |= *(p++) << 24; if (!(dcerpc->dcerpchdr.packed_drep[0] & 0x10)) { dcerpc->dcerpchdr.frag_length = SCByteSwap16(dcerpc->dcerpchdr.frag_length); dcerpc->dcerpchdr.auth_length = SCByteSwap16(dcerpc->dcerpchdr.auth_length); @@ -1359,7 +1359,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { * all the endless loops cases */ int counter = 0; - while(input_len) { + while (input_len) { /* in case we have any corner cases remainging, we have this */ if (counter++ == 30) { SCLogDebug("Somehow seem to be stuck inside the dce " @@ -1370,7 +1370,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { while (dcerpc->bytesprocessed < DCERPC_HDR_LEN && input_len) { hdrretval = DCERPCParseHeader(dcerpc, input + parsed, input_len); - if (hdrretval == -1) { + if (hdrretval == -1 || hdrretval > (int32_t)input_len) { SCLogDebug("Error parsing dce header. Discarding " "PDU and reseting parsing state to parse next PDU"); /* error parsing pdu header. Let's clear the dce state */ @@ -1431,7 +1431,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { retval = DCERPCParseBIND(dcerpc, input + parsed, input_len); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; } else if (input_len) { @@ -1450,7 +1450,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { while (dcerpc->dcerpcbindbindack.numctxitemsleft && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { retval = DCERPCParseBINDCTXItem(dcerpc, input + parsed, input_len); - if (retval) { + if (retval && retval <= input_len) { if (dcerpc->dcerpcbindbindack.ctxbytesprocessed == 44) { dcerpc->dcerpcbindbindack.ctxbytesprocessed = 0; } @@ -1481,12 +1481,20 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { if (input_len) { retval = DCERPCThrowOutExtraData(dcerpc, input + parsed, input_len); - input_len -= retval; - parsed += retval; - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); + if (retval && retval <= input_len) { + input_len -= retval; + parsed += retval; + if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { + DCERPCResetParsingState(dcerpc); + } else { + dcerpc->pdu_fragged = 1; + } } else { - dcerpc->pdu_fragged = 1; + SCLogDebug("Error Parsing DCERPC"); + parsed = 0; + input_len = 0; + DCERPCResetParsingState(dcerpc); + SCReturnInt(0); } } else { dcerpc->pdu_fragged = 1; @@ -1500,7 +1508,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { retval = DCERPCParseBINDACK(dcerpc, input + parsed, input_len); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; SCLogDebug("DCERPCParseBINDACK processed %u/%u input_len left %u", @@ -1521,7 +1529,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { + dcerpc->dcerpcbindbindack.secondaryaddrlen && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { retval = DCERPCParseSecondaryAddr(dcerpc, input + parsed, input_len); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; SCLogDebug("DCERPCParseSecondaryAddr %u/%u left %u secondaryaddr len(%u)", @@ -1548,7 +1556,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { + dcerpc->dcerpcbindbindack.secondaryaddrlen + dcerpc->pad && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { retval = PaddingParser(dcerpc, input + parsed, input_len); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; SCLogDebug("PaddingParser %u/%u left %u pad(%u)", @@ -1568,7 +1576,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { < DCERPC_HDR_LEN + 14 + dcerpc->pad + dcerpc->dcerpcbindbindack.secondaryaddrlen && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { retval = DCERPCGetCTXItems(dcerpc, input + parsed, input_len); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; SCLogDebug("DCERPCGetCTXItems %u/%u (%u)", dcerpc->bytesprocessed, @@ -1590,7 +1598,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { while (dcerpc->dcerpcbindbindack.numctxitemsleft && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { retval = DCERPCParseBINDACKCTXItem(dcerpc, input + parsed, input_len); - if (retval) { + if (retval && retval <= input_len) { if (dcerpc->dcerpcbindbindack.ctxbytesprocessed == 24) { dcerpc->dcerpcbindbindack.ctxbytesprocessed = 0; } @@ -1626,12 +1634,20 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { if (input_len) { retval = DCERPCThrowOutExtraData(dcerpc, input + parsed, input_len); - input_len -= retval; - parsed += retval; - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); + if (retval && retval <= input_len) { + input_len -= retval; + parsed += retval; + if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { + DCERPCResetParsingState(dcerpc); + } else { + dcerpc->pdu_fragged = 1; + } } else { - dcerpc->pdu_fragged = 1; + SCLogDebug("Error Parsing DCERPC"); + parsed = 0; + input_len = 0; + DCERPCResetParsingState(dcerpc); + SCReturnInt(0); } } else { dcerpc->pdu_fragged = 1; @@ -1645,7 +1661,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && input_len) { retval = DCERPCParseREQUEST(dcerpc, input + parsed, input_len); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; dcerpc->padleft = dcerpc->dcerpchdr.frag_length - dcerpc->bytesprocessed; @@ -1664,7 +1680,7 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { && dcerpc->bytesprocessed < dcerpc->dcerpchdr.frag_length && dcerpc->padleft && input_len) { retval = StubDataParser(dcerpc, input + parsed, input_len); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; } else if (input_len) { @@ -1701,12 +1717,20 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { if (input_len) { retval = DCERPCThrowOutExtraData(dcerpc, input + parsed, input_len); - input_len -= retval; - parsed += retval; - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); + if (retval && retval <= input_len) { + input_len -= retval; + parsed += retval; + if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { + DCERPCResetParsingState(dcerpc); + } else { + dcerpc->pdu_fragged = 1; + } } else { - dcerpc->pdu_fragged = 1; + SCLogDebug("Error Parsing DCERPC"); + parsed = 0; + input_len = 0; + DCERPCResetParsingState(dcerpc); + SCReturnInt(0); } } else { dcerpc->pdu_fragged = 1; @@ -1726,12 +1750,20 @@ int32_t DCERPCParser(DCERPC *dcerpc, uint8_t *input, uint32_t input_len) { SCLogDebug("DCERPC Type 0x%02x not implemented yet", dcerpc->dcerpchdr.type); retval = DCERPCThrowOutExtraData(dcerpc, input + parsed, input_len); - input_len -= retval; - parsed += retval; - if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { - DCERPCResetParsingState(dcerpc); + if (retval && retval <= input_len) { + input_len -= retval; + parsed += retval; + if (dcerpc->bytesprocessed == dcerpc->dcerpchdr.frag_length) { + DCERPCResetParsingState(dcerpc); + } else { + dcerpc->pdu_fragged = 1; + } } else { - dcerpc->pdu_fragged = 1; + SCLogDebug("Error Parsing DCERPC"); + parsed = 0; + input_len = 0; + DCERPCResetParsingState(dcerpc); + SCReturnInt(0); } break; } diff --git a/src/app-layer-smb.c b/src/app-layer-smb.c index e7b0da785e..6ba5eb588b 100644 --- a/src/app-layer-smb.c +++ b/src/app-layer-smb.c @@ -346,9 +346,9 @@ static uint32_t SMBParseReadAndX(Flow *f, void *smb_state, --input_len; break; default: - sstate->bytesprocessed++; - SCReturnUInt(1); - break; + sstate->bytesprocessed++; + SCReturnUInt(1); + break; } sstate->bytesprocessed += (p - input); @@ -508,33 +508,39 @@ static uint32_t SMBParseTransact(Flow *f, void *smb_state, /* Data Offset */ sstate->andx.dataoffset |= *(p++) << 8; if (!(--input_len)) + break; case 26: - /* Setup Count */ - p++; - if (!(--input_len)) + /* Setup Count */ + p++; + if (!(--input_len)) + break; case 27: - /* Reserved */ - p++; - if (!(--input_len)) + /* Reserved */ + p++; + if (!(--input_len)) + break; case 28: - p++; - if (!(--input_len)) + p++; + if (!(--input_len)) + break; case 29: - p++; - if (!(--input_len)) + p++; + if (!(--input_len)) + break; case 30: - p++; - if (!(--input_len)) - case 31: - p++; - --input_len; + p++; + if (!(--input_len)) break; + case 31: + p++; + --input_len; + break; default: - SCLogDebug("SMB_COM_TRANSACTION AndX bytes processed is greater than 31 %u", sstate->andx.andxbytesprocessed); - sstate->bytesprocessed++; - sstate->andx.andxbytesprocessed++; - SCReturnUInt(1); - break; + SCLogDebug("SMB_COM_TRANSACTION AndX bytes processed is greater than 31 %u", sstate->andx.andxbytesprocessed); + sstate->bytesprocessed++; + sstate->andx.andxbytesprocessed++; + SCReturnUInt(1); + break; } sstate->bytesprocessed += (p - input); sstate->andx.andxbytesprocessed += (p - input); @@ -584,7 +590,7 @@ static int32_t DataParser(void *smb_state, AppLayerParserState *pstate, if (sstate->andx.paddingparsed) { parsed = DCERPCParser(&sstate->dcerpc, input, input_len); - if (parsed == -1) { + if (parsed == -1 || parsed > sstate->bytecount.bytecountleft || parsed > (int32_t)input_len) { SCReturnInt(-1); } else { sstate->dcerpc_present = 1; @@ -669,24 +675,36 @@ static uint32_t SMBParseWordCount(Flow *f, void *smb_state, == SMB_COM_READ_ANDX) { retval = SMBParseReadAndX(f, sstate, pstate, input, input_len, output); - sstate->wordcount.wordcountleft -= retval; - SCLogDebug("SMB_COM_READ_ANDX returned %d - %u bytes at offset %"PRIu64"", retval, sstate->andx.datalength, sstate->andx.dataoffset); - SCReturnUInt(retval); + if (retval <= sstate->wordcount.wordcountleft) { + sstate->wordcount.wordcountleft -= retval; + SCLogDebug("SMB_COM_READ_ANDX returned %d - %u bytes at offset %"PRIu64"", retval, sstate->andx.datalength, sstate->andx.dataoffset); + SCReturnUInt(retval); + } else { + SCReturnUInt(0U); + } } else if (((sstate->smb.flags & SMB_FLAGS_SERVER_TO_REDIR) == 0) && sstate->smb.command == SMB_COM_WRITE_ANDX) { retval = SMBParseWriteAndX(f, sstate, pstate, input, input_len, output); - sstate->wordcount.wordcountleft -= retval; - SCLogDebug("SMB_COM_WRITE_ANDX returned %d - %u bytes at offset %"PRIu64"", retval, sstate->andx.datalength, sstate->andx.dataoffset); - SCReturnUInt(retval); + if (retval <= sstate->wordcount.wordcountleft) { + sstate->wordcount.wordcountleft -= retval; + SCLogDebug("SMB_COM_WRITE_ANDX returned %d - %u bytes at offset %"PRIu64"", retval, sstate->andx.datalength, sstate->andx.dataoffset); + SCReturnUInt(retval); + } else { + SCReturnUInt(0U); + } } else if (sstate->smb.command == SMB_COM_TRANSACTION) { retval = SMBParseTransact(f, sstate, pstate, input, input_len, output); - sstate->wordcount.wordcountleft -= retval; - SCLogDebug("SMB_COM_TRANSACTION returned %d - %u bytes at offset %"PRIu64"", retval, sstate->andx.datalength, sstate->andx.dataoffset); - SCReturnUInt(retval); + if (retval <= sstate->wordcount.wordcountleft) { + sstate->wordcount.wordcountleft -= retval; + SCLogDebug("SMB_COM_TRANSACTION returned %d - %u bytes at offset %"PRIu64"", retval, sstate->andx.datalength, sstate->andx.dataoffset); + SCReturnUInt(retval); + } else { + SCReturnUInt(0U); + } } else { /* Generic WordCount Handler */ while (sstate->wordcount.wordcountleft-- && input_len--) { @@ -724,15 +742,19 @@ static uint32_t SMBParseByteCount(Flow *f, void *smb_state, { if (sstate->andx.paddingparsed == 0) { ures = PaddingParser(sstate, pstate, input + parsed, input_len, output); - parsed += ures; - input_len -= ures; + if (ures <= input_len) { + parsed += ures; + input_len -= ures; + } else { + SCReturnUInt(0U); + } } if (sstate->andx.datalength && input_len) { /* Uncomment the next line to help debug DCERPC over SMB */ //hexdump(f, input + parsed, input_len); sres = DataParser(sstate, pstate, input + parsed, input_len, output); - if (sres != -1) { + if (sres != -1 && sres <= (int32_t)input_len) { parsed += (uint32_t)sres; input_len -= (uint32_t)sres; } else { /* Did not Validate as DCERPC over SMB */ @@ -1051,7 +1073,7 @@ static int SMBParse(Flow *f, void *smb_state, AppLayerParserState *pstate, while (input_len && sstate->bytesprocessed < NBSS_HDR_LEN) { retval = NBSSParseHeader(f, smb_state, pstate, input + parsed, input_len, output); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; SCLogDebug("[1] NBSS Header (%u/%u) Type 0x%02x Length 0x%04x " @@ -1073,7 +1095,7 @@ static int SMBParse(Flow *f, void *smb_state, AppLayerParserState *pstate, /* inside while */ hdrretval = SMBParseHeader(f, smb_state, pstate, input + parsed, input_len, output); - if (hdrretval == -1) { + if (hdrretval == -1 || hdrretval > (int32_t)input_len) { SCLogDebug("Error parsing SMB Header"); sstate->bytesprocessed = 0; SCReturnInt(0); @@ -1093,7 +1115,7 @@ static int SMBParse(Flow *f, void *smb_state, AppLayerParserState *pstate, /* inside if */ retval = SMBGetWordCount(f, smb_state, pstate, input + parsed, input_len, output); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; } else if (input_len) { @@ -1116,7 +1138,7 @@ static int SMBParse(Flow *f, void *smb_state, AppLayerParserState *pstate, /* inside while */ retval = SMBParseWordCount(f, smb_state, pstate, input + parsed, input_len, output); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; } else if (input_len) { @@ -1142,7 +1164,7 @@ static int SMBParse(Flow *f, void *smb_state, AppLayerParserState *pstate, /* inside while */ retval = SMBGetByteCount(f, smb_state, pstate, input + parsed, input_len, output); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; } else if (input_len) { @@ -1172,7 +1194,7 @@ static int SMBParse(Flow *f, void *smb_state, AppLayerParserState *pstate, /* inside while */ retval = SMBParseByteCount(f, smb_state, pstate, input + parsed, input_len, output); - if (retval) { + if (retval && retval <= input_len) { parsed += retval; input_len -= retval; } else if (input_len) { diff --git a/src/app-layer-smb2.c b/src/app-layer-smb2.c index 85b8ffdae7..7518648fe1 100644 --- a/src/app-layer-smb2.c +++ b/src/app-layer-smb2.c @@ -75,14 +75,17 @@ static uint32_t NBSSParseHeader(void *smb2_state, AppLayerParserState *pstate, SCReturnUInt(4U); } else { sstate->nbss.type = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; } case 1: sstate->nbss.length = (*(p++) & 0x01) << 16; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 2: sstate->nbss.length |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 3: sstate->nbss.length |= *(p++); --input_len; @@ -96,8 +99,10 @@ static uint32_t NBSSParseHeader(void *smb2_state, AppLayerParserState *pstate, static uint32_t SMB2ParseHeader(void *smb2_state, AppLayerParserState *pstate, uint8_t *input, uint32_t input_len, AppLayerParserResult *output) { SCEnter(); + SMB2State *sstate = (SMB2State *) smb2_state; uint8_t *p = input; + if (input_len) { switch (sstate->bytesprocessed) { case 4: @@ -185,194 +190,256 @@ static uint32_t SMB2ParseHeader(void *smb2_state, AppLayerParserState *pstate, //sstate->smb2.protocol[1] = *(p++); if (*(p++) != 'S') return 0; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 6: //sstate->smb2.protocol[2] = *(p++); if (*(p++) != 'M') return 0; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 7: //sstate->smb2.protocol[3] = *(p++); if (*(p++) != 'B') return 0; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 8: sstate->smb2.StructureSize = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 9: sstate->smb2.StructureSize |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 10: sstate->smb2.CreditCharge = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 11: sstate->smb2.CreditCharge |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 12: sstate->smb2.Status = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 13: sstate->smb2.Status |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 14: sstate->smb2.Status |= *(p++) << 16; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 15: sstate->smb2.Status |= *(p++) << 24; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 16: sstate->smb2.Command = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 17: sstate->smb2.Command |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 18: sstate->smb2.CreditRequestResponse = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 19: sstate->smb2.CreditRequestResponse |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 20: sstate->smb2.Flags = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 21: sstate->smb2.Flags |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 22: sstate->smb2.Flags |= *(p++) << 16; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 23: sstate->smb2.Flags |= *(p++) << 24; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 24: sstate->smb2.NextCommand = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 25: sstate->smb2.NextCommand |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 26: sstate->smb2.NextCommand |= *(p++) << 16; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 27: sstate->smb2.NextCommand |= *(p++) << 24; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 28: sstate->smb2.MessageId = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 29: sstate->smb2.MessageId = *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 30: sstate->smb2.MessageId = *(p++) << 16; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 31: sstate->smb2.MessageId = (uint64_t) *(p++) << 24; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 32: sstate->smb2.MessageId = (uint64_t) *(p++) << 32; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 33: sstate->smb2.MessageId = (uint64_t) *(p++) << 40; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 34: sstate->smb2.MessageId = (uint64_t) *(p++) << 48; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 35: sstate->smb2.MessageId = (uint64_t) *(p++) << 56; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 36: sstate->smb2.ProcessId = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 37: sstate->smb2.ProcessId |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 38: sstate->smb2.ProcessId |= *(p++) << 16; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 39: sstate->smb2.ProcessId |= *(p++) << 24; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 40: sstate->smb2.TreeId = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 41: sstate->smb2.TreeId |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 42: sstate->smb2.TreeId |= *(p++) << 16; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 43: sstate->smb2.TreeId |= *(p++) << 24; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 44: sstate->smb2.SessionId = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 45: sstate->smb2.SessionId |= *(p++) << 8; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 46: sstate->smb2.SessionId |= *(p++) << 16; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 47: sstate->smb2.SessionId |= (uint64_t) *(p++) << 24; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 48: sstate->smb2.SessionId |= (uint64_t) *(p++) << 32; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 49: sstate->smb2.SessionId |= (uint64_t) *(p++) << 40; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 50: sstate->smb2.SessionId |= (uint64_t) *(p++) << 48; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 51: sstate->smb2.SessionId |= (uint64_t) *(p++) << 56; - if (!(--input_len)) break; + if (!(--input_len)) + break; case 52: sstate->smb2.Signature[0] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 53: sstate->smb2.Signature[1] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 54: sstate->smb2.Signature[2] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 55: sstate->smb2.Signature[3] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 56: sstate->smb2.Signature[4] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 57: sstate->smb2.Signature[5] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 58: sstate->smb2.Signature[6] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 59: sstate->smb2.Signature[7] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 60: sstate->smb2.Signature[8] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 61: sstate->smb2.Signature[9] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 62: sstate->smb2.Signature[10] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 63: sstate->smb2.Signature[11] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 64: sstate->smb2.Signature[12] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 65: sstate->smb2.Signature[13] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 66: sstate->smb2.Signature[14] = *(p++); - if (!(--input_len)) break; + if (!(--input_len)) + break; case 67: sstate->smb2.Signature[15] = *(p++); --input_len; @@ -396,8 +463,12 @@ static int SMB2Parse(Flow *f, void *smb2_state, AppLayerParserState *pstate, while (sstate->bytesprocessed < NBSS_HDR_LEN && input_len) { retval = NBSSParseHeader(smb2_state, pstate, input, input_len, output); - parsed += retval; - input_len -= retval; + if (retval <= input_len) { + parsed += retval; + input_len -= retval; + } else { + return -1; + } SCLogDebug("NBSS Header (%u/%u) Type 0x%02x Length 0x%04x parsed %u input_len %u", sstate->bytesprocessed, NBSS_HDR_LEN, sstate->nbss.type, @@ -409,8 +480,12 @@ static int SMB2Parse(Flow *f, void *smb2_state, AppLayerParserState *pstate, while (input_len && (sstate->bytesprocessed >= NBSS_HDR_LEN && sstate->bytesprocessed < NBSS_HDR_LEN + SMB2_HDR_LEN)) { retval = SMB2ParseHeader(smb2_state, pstate, input + parsed, input_len, output); - parsed += retval; - input_len -= retval; + if (retval <= input_len) { + parsed += retval; + input_len -= retval; + } else { + return -1; + } SCLogDebug("SMB2 Header (%u/%u) Command 0x%04x parsed %u input_len %u", sstate->bytesprocessed, NBSS_HDR_LEN + SMB2_HDR_LEN,