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

rust/src/detect.rs
src/detect-engine-uint.c
src/detect-engine-uint.h
src/detect-filesize.c
src/detect-filesize.h

index 582728b28555c9bc91950f94e4f68dfacf36986b..27c53671720f3f03314bde552f73c28cf1da2b1f 100644 (file)
@@ -205,6 +205,16 @@ pub unsafe extern "C" fn rs_detect_u64_parse(
     return std::ptr::null_mut();
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn rs_detect_u64_match(
+    arg: u64, ctx: &DetectUintData<u64>,
+) -> std::os::raw::c_int {
+    if detect_match_uint(ctx, arg) {
+        return 1;
+    }
+    return 0;
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn rs_detect_u64_free(ctx: *mut std::os::raw::c_void) {
     // Just unbox...
index 9f10dc68cbbf5258eb5ddf108b4fe6382fa09bba..a02552bcd9dec983230f3b535722078f8c54aed7 100644 (file)
@@ -138,3 +138,13 @@ bool PrefilterPacketU16Compare(PrefilterPacketHeaderValue v, void *smctx)
         return true;
     return false;
 }
+
+int DetectU64Match(const uint64_t parg, const DetectUintData_u64 *du64)
+{
+    return rs_detect_u64_match(parg, du64);
+}
+
+DetectUintData_u64 *DetectU64Parse(const char *u64str)
+{
+    return rs_detect_u64_parse(u64str);
+}
index e20c3f713dbefb18df133fde13b1771df8f050ff..ab78c10f6d49d915a23fe3e489e3fabd8d97b6a8 100644 (file)
 #define DETECT_UINT_LT  DetectUintModeLt
 #define DETECT_UINT_LTE DetectUintModeLte
 
+typedef DetectUintData_u64 DetectU64Data;
 typedef DetectUintData_u32 DetectU32Data;
 typedef DetectUintData_u16 DetectU16Data;
 typedef DetectUintData_u8 DetectU8Data;
 
+int DetectU64Match(const uint64_t parg, const DetectUintData_u64 *du64);
+DetectUintData_u64 *DetectU64Parse(const char *u64str);
+
 int DetectU32Match(const uint32_t parg, const DetectUintData_u32 *du32);
 DetectUintData_u32 *DetectU32Parse(const char *u32str);
 void PrefilterPacketU32Set(PrefilterPacketHeaderValue *v, void *smctx);
index eb79407279502f8e23ad48f97d0ae19a1af3c041..044dc8bbfe2cc136394b98b77e26a312ccff04df 100644 (file)
@@ -34,6 +34,7 @@
 #include "detect-parse.h"
 #include "detect-engine.h"
 #include "detect-engine-state.h"
+#include "detect-engine-uint.h"
 
 #include "detect-filesize.h"
 #include "util-debug.h"
 #include "flow-util.h"
 #include "stream-tcp.h"
 
-/**
- * \brief Regex for parsing our filesize
- */
-#define PARSE_REGEX  "^(?:\\s*)(<|>)?(?:\\s*)([0-9]{1,23}[a-zA-Z]{0,2})(?:\\s*)(?:(<>)(?:\\s*)([0-9]{1,23}[a-zA-Z]{0,2}))?\\s*$"
-
-static DetectParseRegex parse_regex;
 
 /*prototypes*/
 static int DetectFilesizeMatch (DetectEngineThreadCtx *det_ctx, Flow *f,
@@ -73,7 +68,6 @@ void DetectFilesizeRegister(void)
 #ifdef UNITTESTS
     sigmatch_table[DETECT_FILESIZE].RegisterTests = DetectFilesizeRegisterTests;
 #endif
-    DetectSetupParseRegexes(PARSE_REGEX, &parse_regex);
 
     g_file_match_list_id = DetectBufferTypeRegister("files");
 }
@@ -87,7 +81,7 @@ void DetectFilesizeRegister(void)
  * \param flags direction flags
  * \param file file being inspected
  * \param s signature being inspected
- * \param m sigmatch that we will cast into DetectFilesizeData
+ * \param m sigmatch that we will cast into DetectU64Data
  *
  * \retval 0 no match
  * \retval 1 match
@@ -97,171 +91,21 @@ static int DetectFilesizeMatch (DetectEngineThreadCtx *det_ctx, Flow *f,
 {
     SCEnter();
 
-    DetectFilesizeData *fsd = (DetectFilesizeData *)m;
+    DetectU64Data *fsd = (DetectU64Data *)m;
     int ret = 0;
     uint64_t file_size = FileTrackedSize(file);
 
-    SCLogDebug("file size %"PRIu64", check %"PRIu64, file_size, fsd->size1);
+    SCLogDebug("file size %" PRIu64 ", check %" PRIu64, file_size, fsd->arg1);
 
     if (file->state == FILE_STATE_CLOSED) {
-        switch (fsd->mode) {
-            case DETECT_FILESIZE_EQ:
-                if (file_size == fsd->size1)
-                    ret = 1;
-                break;
-            case DETECT_FILESIZE_LT:
-                if (file_size < fsd->size1)
-                    ret = 1;
-                break;
-            case DETECT_FILESIZE_GT:
-                if (file_size > fsd->size1)
-                    ret = 1;
-                break;
-            case DETECT_FILESIZE_RA:
-                if (file_size > fsd->size1 && file_size < fsd->size2)
-                    ret = 1;
-                break;
-        }
-    /* truncated, error: only see if what we have meets the GT condition */
+        return DetectU64Match(file_size, fsd);
+        /* truncated, error: only see if what we have meets the GT condition */
     } else if (file->state > FILE_STATE_CLOSED) {
-        if (fsd->mode == DETECT_FILESIZE_GT && file_size > fsd->size1)
-            ret = 1;
-    }
-    SCReturnInt(ret);
-}
-
-/**
- * \brief parse filesize options
- *
- * \param str pointer to the user provided filesize
- *
- * \retval fsd pointer to DetectFilesizeData on success
- * \retval NULL on failure
- */
-static DetectFilesizeData *DetectFilesizeParse (const char *str)
-{
-
-    DetectFilesizeData *fsd = NULL;
-    char *arg1 = NULL;
-    char *arg2 = NULL;
-    char *arg3 = NULL;
-    char *arg4 = NULL;
-    int ret = 0, res = 0;
-    size_t pcre2_len;
-
-    ret = DetectParsePcreExec(&parse_regex, str, 0, 0);
-    if (ret < 3 || ret > 5) {
-        SCLogError(SC_ERR_PCRE_PARSE, "filesize option pcre parse error: \"%s\"", str);
-        goto error;
-    }
-    const char *str_ptr;
-
-    SCLogDebug("ret %d", ret);
-
-    res = SC_Pcre2SubstringGet(parse_regex.match, 1, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
-    if (res < 0) {
-        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
-        goto error;
-    }
-    arg1 = (char *) str_ptr;
-    SCLogDebug("Arg1 \"%s\"", arg1);
-
-    res = pcre2_substring_get_bynumber(parse_regex.match, 2, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
-    if (res < 0) {
-        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
-        goto error;
-    }
-    arg2 = (char *) str_ptr;
-    SCLogDebug("Arg2 \"%s\"", arg2);
-
-    if (ret > 3) {
-        res = pcre2_substring_get_bynumber(
-                parse_regex.match, 3, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
-        if (res < 0) {
-            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
-            goto error;
-        }
-        arg3 = (char *) str_ptr;
-        SCLogDebug("Arg3 \"%s\"", arg3);
-
-        if (ret > 4) {
-            res = pcre2_substring_get_bynumber(
-                    parse_regex.match, 4, (PCRE2_UCHAR8 **)&str_ptr, &pcre2_len);
-            if (res < 0) {
-                SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre2_substring_get_bynumber failed");
-                goto error;
-            }
-            arg4 = (char *) str_ptr;
-            SCLogDebug("Arg4 \"%s\"", arg4);
-        }
-    }
-
-    fsd = SCMalloc(sizeof (DetectFilesizeData));
-    if (unlikely(fsd == NULL))
-    goto error;
-    memset(fsd, 0, sizeof(DetectFilesizeData));
-
-    if (arg1 != NULL && arg1[0] == '<')
-        fsd->mode = DETECT_FILESIZE_LT;
-    else if (arg1 != NULL && arg1[0] == '>')
-        fsd->mode = DETECT_FILESIZE_GT;
-    else
-        fsd->mode = DETECT_FILESIZE_EQ;
-
-    if (arg3 != NULL && strcmp("<>", arg3) == 0) {
-        if (arg1 != NULL && strlen(arg1) != 0) {
-            SCLogError(SC_ERR_INVALID_ARGUMENT,"Range specified but mode also set");
-            goto error;
-        }
-        fsd->mode = DETECT_FILESIZE_RA;
-    }
-
-    /** set the first value */
-    if (ParseSizeStringU64(arg2, &fsd->size1) < 0) {
-        SCLogError(SC_ERR_SIZE_PARSE, "Error parsing filesize value - %s", arg2);
-        goto error;
-    }
-
-    /** set the second value if specified */
-    if (arg4 != NULL && strlen(arg4) > 0) {
-        if (fsd->mode != DETECT_FILESIZE_RA) {
-            SCLogError(SC_ERR_INVALID_ARGUMENT,"Multiple filesize values specified"
-                                           " but mode is not range");
-            goto error;
-        }
-
-        if (ParseSizeStringU64(arg4, &fsd->size2) < 0) {
-            SCLogError(SC_ERR_SIZE_PARSE, "Error parsing filesize value - %s", arg4);
-            goto error;
-        }
-
-        if (fsd->size2 <= fsd->size1){
-            SCLogError(SC_ERR_INVALID_ARGUMENT,"filesize2:%"PRIu64" <= filesize:"
-                        "%"PRIu64"",fsd->size2,fsd->size1);
-            goto error;
+        if (fsd->mode == DETECT_UINT_GT || fsd->mode == DETECT_UINT_GTE) {
+            ret = DetectU64Match(file_size, fsd);
         }
     }
-
-    pcre2_substring_free((PCRE2_UCHAR *)arg1);
-    pcre2_substring_free((PCRE2_UCHAR *)arg2);
-    if (arg3 != NULL)
-        pcre2_substring_free((PCRE2_UCHAR *)arg3);
-    if (arg4 != NULL)
-        pcre2_substring_free((PCRE2_UCHAR *)arg4);
-    return fsd;
-
-error:
-    if (fsd)
-        SCFree(fsd);
-    if (arg1 != NULL)
-        pcre2_substring_free((PCRE2_UCHAR *)arg1);
-    if (arg2 != NULL)
-        pcre2_substring_free((PCRE2_UCHAR *)arg2);
-    if (arg3 != NULL)
-        pcre2_substring_free((PCRE2_UCHAR *)arg3);
-    if (arg4 != NULL)
-        pcre2_substring_free((PCRE2_UCHAR *)arg4);
-    return NULL;
+    SCReturnInt(ret);
 }
 
 /**
@@ -277,10 +121,10 @@ error:
 static int DetectFilesizeSetup (DetectEngineCtx *de_ctx, Signature *s, const char *str)
 {
     SCEnter();
-    DetectFilesizeData *fsd = NULL;
+    DetectU64Data *fsd = NULL;
     SigMatch *sm = NULL;
 
-    fsd = DetectFilesizeParse(str);
+    fsd = DetectU64Parse(str);
     if (fsd == NULL)
         goto error;
 
@@ -305,14 +149,13 @@ error:
 }
 
 /**
- * \brief this function will free memory associated with DetectFilesizeData
+ * \brief this function will free memory associated with DetectU64Data
  *
- * \param ptr pointer to DetectFilesizeData
+ * \param ptr pointer to DetectU64Data
  */
 static void DetectFilesizeFree(DetectEngineCtx *de_ctx, void *ptr)
 {
-    DetectFilesizeData *fsd = (DetectFilesizeData *)ptr;
-    SCFree(fsd);
+    rs_detect_u64_free(ptr);
 }
 
 #ifdef UNITTESTS
@@ -327,11 +170,11 @@ static void DetectFilesizeFree(DetectEngineCtx *de_ctx, void *ptr)
 static int DetectFilesizeParseTest01(void)
 {
     int ret = 0;
-    DetectFilesizeData *fsd = NULL;
+    DetectU64Data *fsd = NULL;
 
-    fsd = DetectFilesizeParse("10");
+    fsd = DetectU64Parse("10");
     if (fsd != NULL) {
-        if (fsd->size1 == 10 && fsd->mode == DETECT_FILESIZE_EQ)
+        if (fsd->arg1 == 10 && fsd->mode == DETECT_UINT_EQ)
             ret = 1;
 
         DetectFilesizeFree(NULL, fsd);
@@ -343,11 +186,11 @@ static int DetectFilesizeParseTest01(void)
 static int DetectFilesizeParseTest02(void)
 {
     int ret = 0;
-    DetectFilesizeData *fsd = NULL;
+    DetectU64Data *fsd = NULL;
 
-    fsd = DetectFilesizeParse(" < 10  ");
+    fsd = DetectU64Parse(" < 10  ");
     if (fsd != NULL) {
-        if (fsd->size1 == 10 && fsd->mode == DETECT_FILESIZE_LT)
+        if (fsd->arg1 == 10 && fsd->mode == DETECT_UINT_LT)
             ret = 1;
 
         DetectFilesizeFree(NULL, fsd);
@@ -359,11 +202,11 @@ static int DetectFilesizeParseTest02(void)
 static int DetectFilesizeParseTest03(void)
 {
     int ret = 0;
-    DetectFilesizeData *fsd = NULL;
+    DetectU64Data *fsd = NULL;
 
-    fsd = DetectFilesizeParse(" > 10 ");
+    fsd = DetectU64Parse(" > 10 ");
     if (fsd != NULL) {
-        if (fsd->size1 == 10 && fsd->mode == DETECT_FILESIZE_GT)
+        if (fsd->arg1 == 10 && fsd->mode == DETECT_UINT_GT)
             ret = 1;
 
         DetectFilesizeFree(NULL, fsd);
@@ -375,12 +218,11 @@ static int DetectFilesizeParseTest03(void)
 static int DetectFilesizeParseTest04(void)
 {
     int ret = 0;
-    DetectFilesizeData *fsd = NULL;
+    DetectU64Data *fsd = NULL;
 
-    fsd = DetectFilesizeParse(" 5 <> 10 ");
+    fsd = DetectU64Parse(" 5 <> 10 ");
     if (fsd != NULL) {
-        if (fsd->size1 == 5 && fsd->size2 == 10 &&
-            fsd->mode == DETECT_FILESIZE_RA)
+        if (fsd->arg1 == 5 && fsd->arg2 == 10 && fsd->mode == DETECT_UINT_RA)
             ret = 1;
 
         DetectFilesizeFree(NULL, fsd);
@@ -392,12 +234,11 @@ static int DetectFilesizeParseTest04(void)
 static int DetectFilesizeParseTest05(void)
 {
     int ret = 0;
-    DetectFilesizeData *fsd = NULL;
+    DetectU64Data *fsd = NULL;
 
-    fsd = DetectFilesizeParse("5<>10");
+    fsd = DetectU64Parse("5<>10");
     if (fsd != NULL) {
-        if (fsd->size1 == 5 && fsd->size2 == 10 &&
-            fsd->mode == DETECT_FILESIZE_RA)
+        if (fsd->arg1 == 5 && fsd->arg2 == 10 && fsd->mode == DETECT_UINT_RA)
             ret = 1;
 
         DetectFilesizeFree(NULL, fsd);
@@ -411,8 +252,8 @@ static int DetectFilesizeParseTest05(void)
  *
  */
 
-static int DetectFilesizeInitTest(DetectEngineCtx **de_ctx, Signature **sig,
-                                DetectFilesizeData **fsd, const char *str)
+static int DetectFilesizeInitTest(
+        DetectEngineCtx **de_ctx, Signature **sig, DetectU64Data **fsd, const char *str)
 {
     char fullstr[1024];
     int result = 0;
@@ -439,7 +280,7 @@ static int DetectFilesizeInitTest(DetectEngineCtx **de_ctx, Signature **sig,
 
     *sig = (*de_ctx)->sig_list;
 
-    *fsd = DetectFilesizeParse(str);
+    *fsd = DetectU64Parse(str);
 
     result = 1;
 
@@ -457,12 +298,12 @@ end:
 static int DetectFilesizeSetpTest01(void)
 {
 
-    DetectFilesizeData *fsd = NULL;
+    DetectU64Data *fsd = NULL;
     uint8_t res = 0;
     Signature *sig = NULL;
     DetectEngineCtx *de_ctx = NULL;
 
-    res = DetectFilesizeInitTest(&de_ctx, &sig, &fsd, "1 <> 2 ");
+    res = DetectFilesizeInitTest(&de_ctx, &sig, &fsd, "1 <> 3 ");
     if (res == 0) {
         goto end;
     }
@@ -471,14 +312,13 @@ static int DetectFilesizeSetpTest01(void)
         goto cleanup;
 
     if (fsd != NULL) {
-        if (fsd->size1 == 1 && fsd->size2 == 2 &&
-                fsd->mode == DETECT_FILESIZE_RA)
+        if (fsd->arg1 == 1 && fsd->arg2 == 3 && fsd->mode == DETECT_UINT_RA)
             res = 1;
     }
 
 cleanup:
     if (fsd)
-        SCFree(fsd);
+        DetectFilesizeFree(NULL, fsd);
     SigGroupCleanup(de_ctx);
     SigCleanSignatures(de_ctx);
     DetectEngineCtxFree(de_ctx);
index cecb29f0e8631a17a3a7816905e14c9440c3c2c5..803b0a3607d6fc514db413ff05b80f6e84ccc6c8 100644 (file)
 #ifndef __DETECT_FILESIZE_H__
 #define        __DETECT_FILESIZE_H__
 
-#define DETECT_FILESIZE_LT   0   /**< "less than" operator */
-#define DETECT_FILESIZE_GT   1   /**< "greater than" operator */
-#define DETECT_FILESIZE_RA   2   /**< range operator */
-#define DETECT_FILESIZE_EQ   3   /**< equal operator */
-
-typedef struct DetectFilesizeData_ {
-    uint64_t size1;     /**< 1st value in the signature*/
-    uint64_t size2;     /**< 2nd value in the signature*/
-    uint8_t mode;       /**< operator used in the signature */
-} DetectFilesizeData;
-
-//int DetectFilesizeMatch (ThreadVars *, DetectEngineThreadCtx *, Flow *,
-//                       uint8_t, void *, Signature *, SigMatch *);
 void DetectFilesizeRegister(void);
 
 #endif /* _DETECT_URILEN_H */