]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
detect: use generic integer functions for ttl
authorPhilippe Antoine <contact@catenacyber.fr>
Wed, 23 Mar 2022 20:11:34 +0000 (21:11 +0100)
committerVictor Julien <vjulien@oisf.net>
Thu, 2 Jun 2022 05:39:33 +0000 (07:39 +0200)
Ticket: #4112

src/detect-ttl.c
src/detect-ttl.h
src/tests/detect-ttl.c

index a7469c233b10909269d8d3771886dc0ba54fc615..20d1563bfee974acbe6666f9ab5fef28e218dd70 100644 (file)
 #include "detect.h"
 #include "detect-parse.h"
 #include "detect-engine-prefilter-common.h"
+#include "detect-engine-uint.h"
 
 #include "detect-ttl.h"
 #include "util-debug.h"
 #include "util-byte.h"
 
-/**
- * \brief Regex for parsing our ttl options
- */
-#define PARSE_REGEX  "^\\s*([0-9]*)?\\s*([<>=-]+)?\\s*([0-9]+)?\\s*$"
-
-static DetectParseRegex parse_regex;
-
 /* prototypes */
 static int DetectTtlMatch (DetectEngineThreadCtx *, Packet *,
         const Signature *, const SigMatchCtx *);
@@ -71,25 +65,9 @@ void DetectTtlRegister(void)
     sigmatch_table[DETECT_TTL].SupportsPrefilter = PrefilterTtlIsPrefilterable;
     sigmatch_table[DETECT_TTL].SetupPrefilter = PrefilterSetupTtl;
 
-    DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
     return;
 }
 
-static inline int TtlMatch(const uint8_t pttl, const uint8_t mode,
-                           const uint8_t dttl1, const uint8_t dttl2)
-{
-    if (mode == DETECT_TTL_EQ && pttl == dttl1)
-        return 1;
-    else if (mode == DETECT_TTL_LT && pttl < dttl1)
-        return 1;
-    else if (mode == DETECT_TTL_GT && pttl > dttl1)
-        return 1;
-    else if (mode == DETECT_TTL_RA && (pttl > dttl1 && pttl < dttl2))
-        return 1;
-
-    return 0;
-}
-
 /**
  * \brief This function is used to match TTL rule option on a packet with
  *        those passed via ttl
@@ -97,7 +75,7 @@ static inline int TtlMatch(const uint8_t pttl, const uint8_t mode,
  * \param t pointer to thread vars
  * \param det_ctx pointer to the pattern matcher thread
  * \param p pointer to the current packet
- * \param m pointer to the sigmatch that we will cast into DetectTtlData
+ * \param m pointer to the sigmatch that we will cast into DetectU8Data
  *
  * \retval 0 no match
  * \retval 1 match
@@ -118,154 +96,8 @@ static int DetectTtlMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
         return 0;
     }
 
-    const DetectTtlData *ttld = (const DetectTtlData *)ctx;
-    return TtlMatch(pttl, ttld->mode, ttld->ttl1, ttld->ttl2);
-}
-
-/**
- * \brief This function is used to parse ttl options passed via ttl: keyword
- *
- * \param ttlstr Pointer to the user provided ttl options
- *
- * \retval ttld pointer to DetectTtlData on success
- * \retval NULL on failure
- */
-
-static DetectTtlData *DetectTtlParse (const char *ttlstr)
-{
-    size_t pcre2len;
-    char arg1[6] = "";
-    char arg2[6] = "";
-    char arg3[6] = "";
-
-    int ret = DetectParsePcreExec(&parse_regex, ttlstr, 0, 0);
-    if (ret < 2 || ret > 4) {
-        SCLogError(SC_ERR_PCRE_MATCH, "parse error, ret %" PRId32 "", ret);
-        return NULL;
-    }
-
-    pcre2len = sizeof(arg1);
-    int res = pcre2_substring_copy_bynumber(parse_regex.match, 1, (PCRE2_UCHAR8 *)arg1, &pcre2len);
-    if (res < 0) {
-        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed");
-        return NULL;
-    }
-    SCLogDebug("arg1 \"%s\"", arg1);
-
-    if (ret >= 3) {
-        pcre2len = sizeof(arg2);
-        res = pcre2_substring_copy_bynumber(parse_regex.match, 2, (PCRE2_UCHAR8 *)arg2, &pcre2len);
-        if (res < 0) {
-            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed");
-            return NULL;
-        }
-        SCLogDebug("arg2 \"%s\"", arg2);
-
-        if (ret >= 4) {
-            pcre2len = sizeof(arg3);
-            res = pcre2_substring_copy_bynumber(
-                    parse_regex.match, 3, (PCRE2_UCHAR8 *)arg3, &pcre2len);
-            if (res < 0) {
-                SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_copy_bynumber failed");
-                return NULL;
-            }
-            SCLogDebug("arg3 \"%s\"", arg3);
-        }
-    }
-
-    uint8_t ttl1 = 0;
-    uint8_t ttl2 = 0;
-    int mode = 0;
-
-    if (strlen(arg2) > 0) {
-        switch (arg2[0]) {
-            case '<':
-                if (strlen(arg3) == 0)
-                    return NULL;
-
-                mode = DETECT_TTL_LT;
-                if (StringParseUint8(&ttl1, 10, 0, (const char *)arg3) < 0) {
-                    SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid first ttl "
-                               "value: \"%s\"", arg3);
-                    return NULL;
-                }
-                SCLogDebug("ttl is %d",ttl1);
-                if (strlen(arg1) > 0)
-                    return NULL;
-
-                break;
-            case '>':
-                if (strlen(arg3) == 0)
-                    return NULL;
-
-                mode = DETECT_TTL_GT;
-                if (StringParseUint8(&ttl1, 10, 0, (const char *)arg3) < 0) {
-                    SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid first ttl "
-                               "value: \"%s\"", arg3);
-                    return NULL;
-                }
-                SCLogDebug("ttl is %d",ttl1);
-                if (strlen(arg1) > 0)
-                    return NULL;
-
-                break;
-            case '-':
-                if (strlen(arg1) == 0 || strlen(arg3) == 0)
-                    return NULL;
-
-                mode = DETECT_TTL_RA;
-
-                if (StringParseUint8(&ttl1, 10, 0, (const char *)arg1) < 0) {
-                    SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid first ttl "
-                               "value: \"%s\"", arg1);
-                    return NULL;
-                }
-                if (StringParseUint8(&ttl2, 10, 0, (const char *)arg3) < 0) {
-                    SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid second ttl "
-                               "value: \"%s\"", arg3);
-                    return NULL;
-                }
-                SCLogDebug("ttl is %d to %d",ttl1, ttl2);
-                if (ttl1 >= ttl2) {
-                    SCLogError(SC_ERR_INVALID_SIGNATURE, "invalid ttl range");
-                    return NULL;
-                }
-                break;
-            default:
-                mode = DETECT_TTL_EQ;
-
-                if ((strlen(arg2) > 0) ||
-                    (strlen(arg3) > 0) ||
-                    (strlen(arg1) == 0))
-                    return NULL;
-                if (StringParseUint8(&ttl1, 10, 0, (const char *)arg1) < 0) {
-                    SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid first ttl "
-                               "value: \"%s\"", arg1);
-                    return NULL;
-                }
-                break;
-        }
-    } else {
-        mode = DETECT_TTL_EQ;
-
-        if ((strlen(arg3) > 0) ||
-            (strlen(arg1) == 0))
-            return NULL;
-        if (StringParseUint8(&ttl1, 10, 0, (const char *)arg1) < 0) {
-            SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid first ttl "
-                        "value: \"%s\"", arg1);
-            return NULL;
-        }
-    }
-
-    DetectTtlData *ttld = SCMalloc(sizeof(DetectTtlData));
-    if (unlikely(ttld == NULL))
-        return NULL;
-    ttld->ttl1 = (uint8_t)ttl1;
-    ttld->ttl2 = (uint8_t)ttl2;
-    ttld->mode = mode;
-
-    return ttld;
+    const DetectU8Data *ttld = (const DetectU8Data *)ctx;
+    return DetectU8Match(pttl, ttld);
 }
 
 /**
@@ -280,7 +112,7 @@ static DetectTtlData *DetectTtlParse (const char *ttlstr)
  */
 static int DetectTtlSetup (DetectEngineCtx *de_ctx, Signature *s, const char *ttlstr)
 {
-    DetectTtlData *ttld = DetectTtlParse(ttlstr);
+    DetectU8Data *ttld = DetectU8Parse(ttlstr);
     if (ttld == NULL)
         return -1;
 
@@ -299,14 +131,13 @@ static int DetectTtlSetup (DetectEngineCtx *de_ctx, Signature *s, const char *tt
 }
 
 /**
- * \brief this function will free memory associated with DetectTtlData
+ * \brief this function will free memory associated with DetectU8Data
  *
- * \param ptr pointer to DetectTtlData
+ * \param ptr pointer to DetectU8Data
  */
 void DetectTtlFree(DetectEngineCtx *de_ctx, void *ptr)
 {
-    DetectTtlData *ttld = (DetectTtlData *)ptr;
-    SCFree(ttld);
+    rs_detect_u8_free(ptr);
 }
 
 /* prefilter code */
@@ -332,39 +163,20 @@ PrefilterPacketTtlMatch(DetectEngineThreadCtx *det_ctx, Packet *p, const void *p
     if (!PrefilterPacketHeaderExtraMatch(ctx, p))
         return;
 
-    if (TtlMatch(pttl, ctx->v1.u8[0], ctx->v1.u8[1], ctx->v1.u8[2]))
-    {
+    DetectU8Data du8;
+    du8.mode = ctx->v1.u8[0];
+    du8.arg1 = ctx->v1.u8[1];
+    du8.arg2 = ctx->v1.u8[2];
+    if (DetectU8Match(pttl, &du8)) {
         SCLogDebug("packet matches ttl/hl %u", pttl);
         PrefilterAddSids(&det_ctx->pmq, ctx->sigs_array, ctx->sigs_cnt);
     }
 }
 
-static void
-PrefilterPacketTtlSet(PrefilterPacketHeaderValue *v, void *smctx)
-{
-    const DetectTtlData *a = smctx;
-    v->u8[0] = a->mode;
-    v->u8[1] = a->ttl1;
-    v->u8[2] = a->ttl2;
-}
-
-static bool
-PrefilterPacketTtlCompare(PrefilterPacketHeaderValue v, void *smctx)
-{
-    const DetectTtlData *a = smctx;
-    if (v.u8[0] == a->mode &&
-        v.u8[1] == a->ttl1 &&
-        v.u8[2] == a->ttl2)
-        return true;
-    return false;
-}
-
 static int PrefilterSetupTtl(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
 {
-    return PrefilterSetupPacketHeader(de_ctx, sgh, DETECT_TTL,
-            PrefilterPacketTtlSet,
-            PrefilterPacketTtlCompare,
-            PrefilterPacketTtlMatch);
+    return PrefilterSetupPacketHeader(de_ctx, sgh, DETECT_TTL, PrefilterPacketU8Set,
+            PrefilterPacketU8Compare, PrefilterPacketTtlMatch);
 }
 
 static bool PrefilterTtlIsPrefilterable(const Signature *s)
index 86505f760b06ad8d78ce785b8493caa6d4e61944..0e561a1efe1694786733a2a11bddaadeaa60266f 100644 (file)
 #ifndef _DETECT_TTL_H
 #define        _DETECT_TTL_H
 
-#define DETECT_TTL_LT   0   /**< "less than" operator */
-#define DETECT_TTL_EQ   1   /**< "equals" operator (default) */
-#define DETECT_TTL_GT   2   /**< "greater than" operator */
-#define DETECT_TTL_RA   3   /**< "range" operator */
-
-typedef struct DetectTtlData_ {
-    uint8_t ttl1;   /**< first ttl value in the signature*/
-    uint8_t ttl2;   /**< second ttl value in the signature, in case of range
-                         operator*/
-    uint8_t mode;   /**< operator used in the signature */
-}DetectTtlData;
 
 void DetectTtlRegister(void);
 
index 52af50dddd56fcb004a1bedf33de2bc8e14a6226..0d014582f821d4989f1653f74a9da1e05b0a0343 100644 (file)
 
 static int DetectTtlParseTest01 (void)
 {
-    DetectTtlData *ttld = DetectTtlParse("10");
+    DetectU8Data *ttld = DetectU8Parse("10");
     FAIL_IF_NULL(ttld);
-    FAIL_IF_NOT(ttld->ttl1 == 10);
-    FAIL_IF_NOT(ttld->mode == DETECT_TTL_EQ);
+    FAIL_IF_NOT(ttld->arg1 == 10);
+    FAIL_IF_NOT(ttld->mode == DETECT_UINT_EQ);
     DetectTtlFree(NULL, ttld);
     PASS;
 }
@@ -40,10 +40,10 @@ static int DetectTtlParseTest01 (void)
 
 static int DetectTtlParseTest02 (void)
 {
-    DetectTtlData *ttld = DetectTtlParse("<10");
+    DetectU8Data *ttld = DetectU8Parse("<10");
     FAIL_IF_NULL(ttld);
-    FAIL_IF_NOT(ttld->ttl1 == 10);
-    FAIL_IF_NOT(ttld->mode == DETECT_TTL_LT);
+    FAIL_IF_NOT(ttld->arg1 == 10);
+    FAIL_IF_NOT(ttld->mode == DETECT_UINT_LT);
     DetectTtlFree(NULL, ttld);
     PASS;
 }
@@ -55,11 +55,11 @@ static int DetectTtlParseTest02 (void)
 
 static int DetectTtlParseTest03 (void)
 {
-    DetectTtlData *ttld = DetectTtlParse("1-2");
+    DetectU8Data *ttld = DetectU8Parse("1-3");
     FAIL_IF_NULL(ttld);
-    FAIL_IF_NOT(ttld->ttl1 == 1);
-    FAIL_IF_NOT(ttld->ttl2 == 2);
-    FAIL_IF_NOT(ttld->mode == DETECT_TTL_RA);
+    FAIL_IF_NOT(ttld->arg1 == 1);
+    FAIL_IF_NOT(ttld->arg2 == 3);
+    FAIL_IF_NOT(ttld->mode == DETECT_UINT_RA);
     DetectTtlFree(NULL, ttld);
     PASS;
 }
@@ -71,10 +71,10 @@ static int DetectTtlParseTest03 (void)
 
 static int DetectTtlParseTest04 (void)
 {
-    DetectTtlData *ttld = DetectTtlParse(" > 10 ");
+    DetectU8Data *ttld = DetectU8Parse(" > 10 ");
     FAIL_IF_NULL(ttld);
-    FAIL_IF_NOT(ttld->ttl1 == 10);
-    FAIL_IF_NOT(ttld->mode == DETECT_TTL_GT);
+    FAIL_IF_NOT(ttld->arg1 == 10);
+    FAIL_IF_NOT(ttld->mode == DETECT_UINT_GT);
     DetectTtlFree(NULL, ttld);
     PASS;
 }
@@ -86,11 +86,11 @@ static int DetectTtlParseTest04 (void)
 
 static int DetectTtlParseTest05 (void)
 {
-    DetectTtlData *ttld = DetectTtlParse(" 1 - 2 ");
+    DetectU8Data *ttld = DetectU8Parse(" 1 - 3 ");
     FAIL_IF_NULL(ttld);
-    FAIL_IF_NOT(ttld->ttl1 == 1);
-    FAIL_IF_NOT(ttld->ttl2 == 2);
-    FAIL_IF_NOT(ttld->mode == DETECT_TTL_RA);
+    FAIL_IF_NOT(ttld->arg1 == 1);
+    FAIL_IF_NOT(ttld->arg2 == 3);
+    FAIL_IF_NOT(ttld->mode == DETECT_UINT_RA);
     DetectTtlFree(NULL, ttld);
     PASS;
 }
@@ -102,7 +102,7 @@ static int DetectTtlParseTest05 (void)
 
 static int DetectTtlParseTest06 (void)
 {
-    DetectTtlData *ttld = DetectTtlParse(" 1 = 2 ");
+    DetectU8Data *ttld = DetectU8Parse(" 1 = 2 ");
     FAIL_IF_NOT_NULL(ttld);
     PASS;
 }
@@ -114,7 +114,7 @@ static int DetectTtlParseTest06 (void)
 
 static int DetectTtlParseTest07 (void)
 {
-    DetectTtlData *ttld = DetectTtlParse(" 1<>2 ");
+    DetectU8Data *ttld = DetectU8Parse(" 1<>2 ");
     FAIL_IF_NOT_NULL(ttld);
     PASS;
 }
@@ -132,17 +132,17 @@ static int DetectTtlSetupTest01(void)
     FAIL_IF_NULL(de_ctx);
     de_ctx->flags |= DE_QUIET;
 
-    Signature *s = DetectEngineAppendSig(de_ctx,
-            "alert ip any any -> any any (msg:\"with in ttl limit\"; ttl:1 - 2; sid:1;)");
+    Signature *s = DetectEngineAppendSig(
+            de_ctx, "alert ip any any -> any any (msg:\"with in ttl limit\"; ttl:1 - 3; sid:1;)");
     FAIL_IF_NULL(s);
     SigGroupBuild(de_ctx);
     FAIL_IF_NULL(s->sm_arrays[DETECT_SM_LIST_MATCH]);
     FAIL_IF_NULL(s->sm_arrays[DETECT_SM_LIST_MATCH]->ctx);
-    DetectTtlData *ttld = (DetectTtlData *)s->sm_arrays[DETECT_SM_LIST_MATCH]->ctx;
+    DetectU8Data *ttld = (DetectU8Data *)s->sm_arrays[DETECT_SM_LIST_MATCH]->ctx;
 
-    FAIL_IF_NOT(ttld->ttl1 == 1);
-    FAIL_IF_NOT(ttld->ttl2 == 2);
-    FAIL_IF_NOT(ttld->mode == DETECT_TTL_RA);
+    FAIL_IF_NOT(ttld->arg1 == 1);
+    FAIL_IF_NOT(ttld->arg2 == 3);
+    FAIL_IF_NOT(ttld->mode == DETECT_UINT_RA);
     DetectEngineCtxFree(de_ctx);
     PASS;
 }