]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
dcerpc/smb/smb2: more robust error checking, cosmetic code updates.
authorVictor Julien <victor@inliniac.net>
Thu, 21 Jun 2012 18:35:51 +0000 (20:35 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 21 Jun 2012 18:35:51 +0000 (20:35 +0200)
src/app-layer-dcerpc-udp.c
src/app-layer-dcerpc.c
src/app-layer-smb.c
src/app-layer-smb2.c

index 950d333c1018e4649ea33dcd71ece898da7876cb..91d6ca525eec972a32dd50779af5f9a5961f2684 100644 (file)
@@ -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) {
index 7cfe6becc39f53f353869e6f305452e704d3ec51..a793b88f1cfd8de16cafd9048976b44feacd6048 100644 (file)
@@ -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;
         }
index e7b0da785eca15aaac81d61a2634099e9217374c..6ba5eb588ba7d6d99f1137fbf26600c9487d86c6 100644 (file)
@@ -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) {
index 85b8ffdae7f2af92a031c6c9ec48f81196e6eed2..7518648fe1de15a289c393ca63acb6af5be37255 100644 (file)
@@ -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,