detect: use generic integer functions for filesize

Ticket: #4112
pull/7467/head
Philippe Antoine 3 years ago committed by Victor Julien
parent bfdf5b1952
commit 35b6dcec7e

@ -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...

@ -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);
}

@ -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);

@ -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);

@ -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 */

Loading…
Cancel
Save