]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect/byte_test: Allow nbytes value to be a variable
authorJeff Lucovsky <jlucovsky@oisf.net>
Fri, 7 Jul 2023 14:31:59 +0000 (10:31 -0400)
committerVictor Julien <vjulien@oisf.net>
Mon, 10 Jul 2023 07:27:03 +0000 (09:27 +0200)
Issue: 6144

This commit allows the byte_test keyword to accept an existing
variable name for a value (the value may still be specified directly as
an integer).

All nbytes values are subject to the same value constraints as before
- 23 if included with string
- 8 otherwise

src/detect-bytetest.c
src/detect-bytetest.h
src/detect-engine-content-inspection.c

index 23508143e9216c2f3362b0b2dd8e7f7fa033b840..d888664205a72ac49a9bae32612918ee96e31f75 100644 (file)
@@ -90,6 +90,58 @@ void DetectBytetestRegister (void)
     DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
 }
 
+/* 23 - This is the largest string (octal, with a zero prefix) that
+ *      will not overflow uint64_t.  The only way this length
+ *      could be over 23 and still not overflow is if it were zero
+ *      prefixed and we only support 1 byte of zero prefix for octal.
+ *
+ * "01777777777777777777777" = 0xffffffffffffffff
+ *
+ * 8 - Without string, the maximum byte extract count is 8.
+ */
+static inline bool DetectBytetestValidateNbytesOnly(const DetectBytetestData *data, int32_t nbytes)
+{
+    return ((data->flags & DETECT_BYTETEST_STRING) && nbytes <= 23) || (nbytes <= 8);
+}
+
+static bool DetectBytetestValidateNbytes(
+        const DetectBytetestData *data, int32_t nbytes, const char *optstr)
+{
+    if (!DetectBytetestValidateNbytesOnly(data, nbytes)) {
+        if (data->flags & DETECT_BYTETEST_STRING) {
+            /* 23 - This is the largest string (octal, with a zero prefix) that
+             *      will not overflow uint64_t.  The only way this length
+             *      could be over 23 and still not overflow is if it were zero
+             *      prefixed and we only support 1 byte of zero prefix for octal.
+             *
+             * "01777777777777777777777" = 0xffffffffffffffff
+             */
+            if (nbytes > 23) {
+                SCLogError("Cannot test more than 23 bytes with \"string\": %s", optstr);
+            }
+        } else {
+            if (nbytes > 8) {
+                SCLogError("Cannot test more than 8 bytes without \"string\": %s", optstr);
+            }
+            if (data->base != DETECT_BYTETEST_BASE_UNSET) {
+                SCLogError("Cannot use a base without \"string\": %s", optstr);
+            }
+        }
+        return false;
+    } else {
+        /*
+         * Even if the value is within the proper range, ensure
+         * that the base is unset unless string is used.
+         */
+        if (!(data->flags & DETECT_BYTETEST_STRING) && (data->base != DETECT_BYTETEST_BASE_UNSET)) {
+            SCLogError("Cannot use a base without \"string\": %s", optstr);
+            return false;
+        }
+    }
+
+    return true;
+}
+
 /** \brief Bytetest detection code
  *
  *  Byte test works on the packet payload.
@@ -102,14 +154,24 @@ void DetectBytetestRegister (void)
  *  \retval 1 match
  *  \retval 0 no match
  */
-int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx,
-                          const Signature *s, const SigMatchCtx *ctx,
-                          const uint8_t *payload, uint32_t payload_len,
-                          uint8_t flags, int32_t offset, uint64_t value)
+int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx, const Signature *s,
+        const SigMatchCtx *ctx, const uint8_t *payload, uint32_t payload_len, uint16_t flags,
+        int32_t offset, int32_t nbytes, uint64_t value)
 {
     SCEnter();
 
+    if (payload_len == 0) {
+        SCReturnInt(0);
+    }
+
     const DetectBytetestData *data = (const DetectBytetestData *)ctx;
+    if (data->flags & DETECT_BYTETEST_NBYTES_VAR) {
+        if (!DetectBytetestValidateNbytesOnly(data, nbytes)) {
+            SCLogDebug("Invalid byte_test nbytes seen in byte_test - %d", nbytes);
+            SCReturnInt(0);
+        }
+    }
+
     const uint8_t *ptr = NULL;
     int32_t len = 0;
     uint64_t val = 0;
@@ -117,10 +179,6 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx,
     int neg;
     int match;
 
-    if (payload_len == 0) {
-        SCReturnInt(0);
-    }
-
     /* Calculate the ptr value for the bytetest and length remaining in
      * the packet from that point.
      */
@@ -149,9 +207,9 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx,
     /* Validate that the to-be-extracted is within the packet
      * \todo Should this validate it is in the *payload*?
      */
-    if (ptr < payload || data->nbytes > len) {
-        SCLogDebug("Data not within payload pkt=%p, ptr=%p, len=%"PRIu32", nbytes=%d",
-                    payload, ptr, len, data->nbytes);
+    if (ptr < payload || nbytes > len) {
+        SCLogDebug("Data not within payload pkt=%p, ptr=%p, len=%" PRIu32 ", nbytes=%d", payload,
+                ptr, len, nbytes);
         SCReturnInt(0);
     }
 
@@ -159,8 +217,7 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx,
 
     /* Extract the byte data */
     if (flags & DETECT_BYTETEST_STRING) {
-        extbytes = ByteExtractStringUint64(&val, data->base,
-                                           data->nbytes, (const char *)ptr);
+        extbytes = ByteExtractStringUint64(&val, data->base, nbytes, (const char *)ptr);
         if (extbytes <= 0) {
             /* ByteExtractStringUint64() returns 0 if there is no numeric value in data string */
             if (val == 0) {
@@ -168,7 +225,8 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx,
                 SCReturnInt(0);
             } else {
                 SCLogDebug("error extracting %d "
-                        "bytes of string data: %d", data->nbytes, extbytes);
+                           "bytes of string data: %d",
+                        nbytes, extbytes);
                 SCReturnInt(-1);
             }
         }
@@ -179,10 +237,11 @@ int DetectBytetestDoMatch(DetectEngineThreadCtx *det_ctx,
     else {
         int endianness = (flags & DETECT_BYTETEST_LITTLE) ?
                           BYTE_LITTLE_ENDIAN : BYTE_BIG_ENDIAN;
-        extbytes = ByteExtractUint64(&val, endianness, data->nbytes, ptr);
-        if (extbytes != data->nbytes) {
+        extbytes = ByteExtractUint64(&val, endianness, (uint16_t)nbytes, ptr);
+        if (extbytes != nbytes) {
             SCLogDebug("error extracting %d bytes "
-                   "of numeric data: %d", data->nbytes, extbytes);
+                       "of numeric data: %d",
+                    nbytes, extbytes);
             SCReturnInt(-1);
         }
 
@@ -258,10 +317,11 @@ static int DetectBytetestMatch(DetectEngineThreadCtx *det_ctx,
                         Packet *p, const Signature *s, const SigMatchCtx *ctx)
 {
     return DetectBytetestDoMatch(det_ctx, s, ctx, p->payload, p->payload_len,
-                                 ((DetectBytetestData *)ctx)->flags, 0, 0);
+            ((DetectBytetestData *)ctx)->flags, 0, 0, 0);
 }
 
-static DetectBytetestData *DetectBytetestParse(const char *optstr, char **value, char **offset)
+static DetectBytetestData *DetectBytetestParse(
+        const char *optstr, char **value, char **offset, char **nbytes_str)
 {
     DetectBytetestData *data = NULL;
     char *args[9] = {
@@ -324,9 +384,22 @@ static DetectBytetestData *DetectBytetestParse(const char *optstr, char **value,
      */
 
     /* Number of bytes */
-    if (StringParseUint32(&nbytes, 10, 0, args[0]) <= 0) {
-        SCLogError("Malformed number of bytes: %s", str_ptr);
-        goto error;
+    if (args[0][0] != '-' && isalpha((unsigned char)args[0][0])) {
+        if (nbytes_str == NULL) {
+            SCLogError("byte_test supplied with "
+                       "var name for nbytes.  \"value\" argument supplied to "
+                       "this function has to be non-NULL");
+            goto error;
+        }
+        *nbytes_str = SCStrdup(args[0]);
+        if (*nbytes_str == NULL)
+            goto error;
+        data->flags |= DETECT_BYTETEST_NBYTES_VAR;
+    } else {
+        if (StringParseUint32(&nbytes, 10, 0, args[0]) <= 0) {
+            SCLogError("Malformed number of bytes: %s", str_ptr);
+            goto error;
+        }
     }
 
     /* The operator is the next arg; it may contain a negation ! as the first char */
@@ -455,31 +528,14 @@ static DetectBytetestData *DetectBytetestParse(const char *optstr, char **value,
         }
     }
 
-    if (data->flags & DETECT_BYTETEST_STRING) {
-        /* 23 - This is the largest string (octal, with a zero prefix) that
-         *      will not overflow uint64_t.  The only way this length
-         *      could be over 23 and still not overflow is if it were zero
-         *      prefixed and we only support 1 byte of zero prefix for octal.
-         *
-         * "01777777777777777777777" = 0xffffffffffffffff
-         */
-        if (nbytes > 23) {
-            SCLogError("Cannot test more than 23 bytes with \"string\": %s", optstr);
-            goto error;
-        }
-    } else {
-        if (nbytes > 8) {
-            SCLogError("Cannot test more than 8 bytes without \"string\": %s", optstr);
+    if (!(data->flags & DETECT_BYTETEST_NBYTES_VAR)) {
+        if (!DetectBytetestValidateNbytes(data, nbytes, optstr)) {
             goto error;
         }
-        if (data->base != DETECT_BYTETEST_BASE_UNSET) {
-            SCLogError("Cannot use a base without \"string\": %s", optstr);
-            goto error;
-        }
-    }
 
-    /* This is max 23 so it will fit in a byte (see above) */
-    data->nbytes = (uint8_t)nbytes;
+        /* This is max 23 so it will fit in a byte (see above) */
+        data->nbytes = (uint8_t)nbytes;
+    }
 
     if (bitmask_index != -1 && data->flags & DETECT_BYTETEST_BITMASK) {
         if (ByteExtractStringUint32(&data->bitmask, 0, 0, args[bitmask_index]+strlen("bitmask")) <= 0) {
@@ -526,9 +582,10 @@ static int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, const char
     SigMatch *prev_pm = NULL;
     char *value = NULL;
     char *offset = NULL;
+    char *nbytes = NULL;
     int ret = -1;
 
-    DetectBytetestData *data = DetectBytetestParse(optstr, &value, &offset);
+    DetectBytetestData *data = DetectBytetestParse(optstr, &value, &offset, &nbytes);
     if (data == NULL)
         goto error;
 
@@ -621,6 +678,20 @@ static int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, const char
         offset = NULL;
     }
 
+    if (nbytes != NULL) {
+        DetectByteIndexType index;
+        if (!DetectByteRetrieveSMVar(nbytes, s, &index)) {
+            SCLogError("Unknown byte_extract var "
+                       "seen in byte_test - %s",
+                    nbytes);
+            goto error;
+        }
+        data->nbytes = index;
+        data->flags |= DETECT_BYTETEST_NBYTES_VAR;
+        SCFree(nbytes);
+        nbytes = NULL;
+    }
+
     sm = SigMatchAlloc();
     if (sm == NULL)
         goto error;
@@ -649,6 +720,8 @@ static int DetectBytetestSetup(DetectEngineCtx *de_ctx, Signature *s, const char
         SCFree(offset);
     if (value)
         SCFree(value);
+    if (nbytes)
+        SCFree(nbytes);
     DetectBytetestFree(de_ctx, data);
     return ret;
 }
@@ -684,7 +757,7 @@ static int DetectBytetestTestParse01(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, =, 1 , 0", NULL, NULL);
+    data = DetectBytetestParse("4, =, 1 , 0", NULL, NULL, NULL);
     if (data != NULL) {
         DetectBytetestFree(NULL, data);
         result = 1;
@@ -700,7 +773,7 @@ static int DetectBytetestTestParse02(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, !=, 1, 0", NULL, NULL);
+    data = DetectBytetestParse("4, !=, 1, 0", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_EQ)
             && (data->nbytes == 4)
@@ -724,7 +797,7 @@ static int DetectBytetestTestParse03(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, !=, 1, 0, relative", NULL, NULL);
+    data = DetectBytetestParse("4, !=, 1, 0, relative", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_EQ)
             && (data->nbytes == 4)
@@ -749,7 +822,7 @@ static int DetectBytetestTestParse04(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, !=, 1, 0, string, oct", NULL, NULL);
+    data = DetectBytetestParse("4, !=, 1, 0, string, oct", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_EQ)
             && (data->nbytes == 4)
@@ -774,7 +847,7 @@ static int DetectBytetestTestParse05(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, =, 1, 0, string, dec", NULL, NULL);
+    data = DetectBytetestParse("4, =, 1, 0, string, dec", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_EQ)
             && (data->nbytes == 4)
@@ -798,7 +871,7 @@ static int DetectBytetestTestParse06(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, >, 1, 0, string, hex", NULL, NULL);
+    data = DetectBytetestParse("4, >, 1, 0, string, hex", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_GT)
             && (data->nbytes == 4)
@@ -822,7 +895,7 @@ static int DetectBytetestTestParse07(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, <, 5, 0, big", NULL, NULL);
+    data = DetectBytetestParse("4, <, 5, 0, big", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_LT)
             && (data->nbytes == 4)
@@ -846,7 +919,7 @@ static int DetectBytetestTestParse08(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, <, 5, 0, little", NULL, NULL);
+    data = DetectBytetestParse("4, <, 5, 0, little", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_LT)
             && (data->nbytes == 4)
@@ -870,7 +943,7 @@ static int DetectBytetestTestParse09(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, !, 5, 0", NULL, NULL);
+    data = DetectBytetestParse("4, !, 5, 0", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_EQ)
             && (data->nbytes == 4)
@@ -894,7 +967,7 @@ static int DetectBytetestTestParse10(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("       4 , ! &, 5      , 0 , little ", NULL, NULL);
+    data = DetectBytetestParse("       4 , ! &, 5      , 0 , little ", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_AND)
             && (data->nbytes == 4)
@@ -919,7 +992,7 @@ static int DetectBytetestTestParse11(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4,!^,5,0,little,string,relative,hex", NULL, NULL);
+    data = DetectBytetestParse("4,!^,5,0,little,string,relative,hex", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_OR)
             && (data->nbytes == 4)
@@ -946,7 +1019,7 @@ static int DetectBytetestTestParse12(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, =, 1, 0, hex", NULL, NULL);
+    data = DetectBytetestParse("4, =, 1, 0, hex", NULL, NULL, NULL);
     if (data == NULL) {
         result = 1;
     }
@@ -961,7 +1034,7 @@ static int DetectBytetestTestParse13(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("9, =, 1, 0", NULL, NULL);
+    data = DetectBytetestParse("9, =, 1, 0", NULL, NULL, NULL);
     if (data == NULL) {
         result = 1;
     }
@@ -976,7 +1049,7 @@ static int DetectBytetestTestParse14(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("23,=,0xffffffffffffffffULL,0,string,oct", NULL, NULL);
+    data = DetectBytetestParse("23,=,0xffffffffffffffffULL,0,string,oct", NULL, NULL, NULL);
     if (data != NULL) {
         if (   (data->op == DETECT_BYTETEST_OP_EQ)
             && (data->nbytes == 23)
@@ -1000,7 +1073,7 @@ static int DetectBytetestTestParse15(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("24, =, 0xffffffffffffffffULL, 0, string", NULL, NULL);
+    data = DetectBytetestParse("24, =, 0xffffffffffffffffULL, 0, string", NULL, NULL, NULL);
     if (data == NULL) {
         result = 1;
     }
@@ -1015,7 +1088,7 @@ static int DetectBytetestTestParse16(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4,=,0,0xffffffffffffffffULL", NULL, NULL);
+    data = DetectBytetestParse("4,=,0,0xffffffffffffffffULL", NULL, NULL, NULL);
     if (data == NULL) {
         result = 1;
     }
@@ -1030,7 +1103,7 @@ static int DetectBytetestTestParse17(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, <, 5, 0, dce", NULL, NULL);
+    data = DetectBytetestParse("4, <, 5, 0, dce", NULL, NULL, NULL);
     if (data != NULL) {
         if ( (data->op == DETECT_BYTETEST_OP_LT) &&
              (data->nbytes == 4) &&
@@ -1052,7 +1125,7 @@ static int DetectBytetestTestParse18(void)
 {
     int result = 0;
     DetectBytetestData *data = NULL;
-    data = DetectBytetestParse("4, <, 5, 0", NULL, NULL);
+    data = DetectBytetestParse("4, <, 5, 0", NULL, NULL, NULL);
     if (data != NULL) {
         if ( (data->op == DETECT_BYTETEST_OP_LT) &&
              (data->nbytes == 4) &&
@@ -1372,7 +1445,7 @@ static int DetectBytetestTestParse22(void)
 static int DetectBytetestTestParse23(void)
 {
     DetectBytetestData *data;
-    data = DetectBytetestParse("4, <, 5, 0, bitmask 0xf8", NULL, NULL);
+    data = DetectBytetestParse("4, <, 5, 0, bitmask 0xf8", NULL, NULL, NULL);
 
     FAIL_IF_NULL(data);
     FAIL_IF_NOT(data->op == DETECT_BYTETEST_OP_LT);
@@ -1394,7 +1467,8 @@ static int DetectBytetestTestParse23(void)
 static int DetectBytetestTestParse24(void)
 {
     DetectBytetestData *data;
-    data = DetectBytetestParse("4, !<, 5, 0, relative,string,hex, big, bitmask 0xf8", NULL, NULL);
+    data = DetectBytetestParse(
+            "4, !<, 5, 0, relative,string,hex, big, bitmask 0xf8", NULL, NULL, NULL);
     FAIL_IF_NULL(data);
     FAIL_IF_NOT(data->op == DETECT_BYTETEST_OP_LT);
     FAIL_IF_NOT(data->nbytes == 4);
index 1f6489d4e7661e4c08f4e84b2d0742024f76acdb..4b4684972b91b277de2b7c5c13531cba043cf334 100644 (file)
 #define DETECT_BYTETEST_BASE_HEX   16 /**< "hex" type value string */
 
 /** Bytetest Flags */
-#define DETECT_BYTETEST_LITTLE    BIT_U8(0) /**< "little" endian value */
-#define DETECT_BYTETEST_BIG       BIT_U8(1) /**< "bi" endian value */
-#define DETECT_BYTETEST_STRING    BIT_U8(2) /**< "string" value */
-#define DETECT_BYTETEST_RELATIVE  BIT_U8(3) /**< "relative" offset */
-#define DETECT_BYTETEST_DCE       BIT_U8(4) /**< dce enabled */
-#define DETECT_BYTETEST_BITMASK   BIT_U8(5) /**< bitmask supplied*/
-#define DETECT_BYTETEST_VALUE_VAR  BIT_U8(6) /**< byte extract value enabled */
-#define DETECT_BYTETEST_OFFSET_VAR BIT_U8(7) /**< byte extract value enabled */
+#define DETECT_BYTETEST_LITTLE     BIT_U16(0) /**< "little" endian value */
+#define DETECT_BYTETEST_BIG        BIT_U16(1) /**< "bi" endian value */
+#define DETECT_BYTETEST_STRING     BIT_U16(2) /**< "string" value */
+#define DETECT_BYTETEST_RELATIVE   BIT_U16(3) /**< "relative" offset */
+#define DETECT_BYTETEST_DCE        BIT_U16(4) /**< dce enabled */
+#define DETECT_BYTETEST_BITMASK    BIT_U16(5) /**< bitmask supplied*/
+#define DETECT_BYTETEST_VALUE_VAR  BIT_U16(6) /**< byte extract value enabled */
+#define DETECT_BYTETEST_OFFSET_VAR BIT_U16(7) /**< byte extract value enabled */
+#define DETECT_BYTETEST_NBYTES_VAR BIT_U16(8) /**< byte extract value enabled */
 
 typedef struct DetectBytetestData_ {
     uint8_t nbytes;                   /**< Number of bytes to compare */
     uint8_t op;                       /**< Operator used to compare */
     uint8_t base;                     /**< String value base (oct|dec|hex) */
     uint8_t bitmask_shift_count;      /**< bitmask trailing 0 count */
-    uint8_t flags;                   /**< Flags (big|little|relative|string|bitmask) */
+    uint16_t flags;                   /**< Flags (big|little|relative|string|bitmask) */
     bool neg_op;
     int32_t offset;                   /**< Offset in payload */
     uint32_t bitmask;                 /**< bitmask value */
@@ -70,8 +71,7 @@ typedef struct DetectBytetestData_ {
  */
 void DetectBytetestRegister (void);
 
-int DetectBytetestDoMatch(DetectEngineThreadCtx *, const Signature *,
-                          const SigMatchCtx *ctx, const uint8_t *, uint32_t,
-                          uint8_t, int32_t, uint64_t);
+int DetectBytetestDoMatch(DetectEngineThreadCtx *, const Signature *, const SigMatchCtx *ctx,
+        const uint8_t *, uint32_t, uint16_t, int32_t, int32_t, uint64_t);
 
 #endif /* __DETECT_BYTETEST_H__ */
index 38be242b325b9b6a275ac68926c6b8dd241446a7..c9df628808b9c72bc3a64ff91acba43a4ca752b3 100644 (file)
@@ -479,15 +479,19 @@ uint8_t DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThrea
 
     } else if (smd->type == DETECT_BYTETEST) {
         DetectBytetestData *btd = (DetectBytetestData *)smd->ctx;
-        uint8_t btflags = btd->flags;
+        uint16_t btflags = btd->flags;
         int32_t offset = btd->offset;
         uint64_t value = btd->value;
+        int32_t nbytes = btd->nbytes;
         if (btflags & DETECT_BYTETEST_OFFSET_VAR) {
             offset = det_ctx->byte_values[offset];
         }
         if (btflags & DETECT_BYTETEST_VALUE_VAR) {
             value = det_ctx->byte_values[value];
         }
+        if (btflags & DETECT_BYTETEST_NBYTES_VAR) {
+            nbytes = det_ctx->byte_values[nbytes];
+        }
 
         /* if we have dce enabled we will have to use the endianness
          * specified by the dce header */
@@ -498,8 +502,8 @@ uint8_t DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThrea
                       DETECT_BYTETEST_LITTLE: 0);
         }
 
-        if (DetectBytetestDoMatch(det_ctx, s, smd->ctx, buffer, buffer_len, btflags,
-                                  offset, value) != 1) {
+        if (DetectBytetestDoMatch(det_ctx, s, smd->ctx, buffer, buffer_len, btflags, offset, nbytes,
+                    value) != 1) {
             goto no_match;
         }