From: Philippe Antoine Date: Wed, 23 Mar 2022 20:43:50 +0000 (+0100) Subject: detect: use generic integer functions for filesize X-Git-Tag: suricata-7.0.0-beta1~514 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35b6dcec7e82fadb7077c6dc4c9382d080d9e771;p=thirdparty%2Fsuricata.git detect: use generic integer functions for filesize Ticket: #4112 --- diff --git a/rust/src/detect.rs b/rust/src/detect.rs index 582728b285..27c5367172 100644 --- a/rust/src/detect.rs +++ b/rust/src/detect.rs @@ -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, +) -> 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... diff --git a/src/detect-engine-uint.c b/src/detect-engine-uint.c index 9f10dc68cb..a02552bcd9 100644 --- a/src/detect-engine-uint.c +++ b/src/detect-engine-uint.c @@ -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); +} diff --git a/src/detect-engine-uint.h b/src/detect-engine-uint.h index e20c3f713d..ab78c10f6d 100644 --- a/src/detect-engine-uint.h +++ b/src/detect-engine-uint.h @@ -37,10 +37,14 @@ #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); diff --git a/src/detect-filesize.c b/src/detect-filesize.c index eb79407279..044dc8bbfe 100644 --- a/src/detect-filesize.c +++ b/src/detect-filesize.c @@ -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" @@ -41,12 +42,6 @@ #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); diff --git a/src/detect-filesize.h b/src/detect-filesize.h index cecb29f0e8..803b0a3607 100644 --- a/src/detect-filesize.h +++ b/src/detect-filesize.h @@ -24,19 +24,6 @@ #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 */