-
Notifications
You must be signed in to change notification settings - Fork 1.6k
detect/var: Restrict var usage to single buffer #13716
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,4 +1,4 @@ | ||||||
/* Copyright (C) 2020 Open Information Security Foundation | ||||||
/* Copyright (C) 2020-2025 Open Information Security Foundation | ||||||
* | ||||||
* You can copy, redistribute or modify this Program under the terms of | ||||||
* the GNU General Public License version 2 as published by the Free | ||||||
|
@@ -27,30 +27,63 @@ | |||||
#include "detect-byte-extract.h" | ||||||
#include "detect-bytemath.h" | ||||||
|
||||||
// Once a variable is found, apply strict semantics (error) else warning | ||||||
static bool DetectByteListMismatch(bool any, int sm_list, int found_list, bool strict, | ||||||
const char *arg, const DetectEngineCtx *de_ctx) | ||||||
{ | ||||||
if (any || sm_list == found_list) | ||||||
return false; | ||||||
|
||||||
if (strict) { | ||||||
return true; | ||||||
} | ||||||
|
||||||
if (de_ctx) { | ||||||
SCLogWarning("Using byte variable from a different buffer may produce indeterminate " | ||||||
"results; variable: \"%s\" at line %" PRId32 " from file %s; see issue #1412", | ||||||
arg, de_ctx->rule_line, de_ctx->rule_file); | ||||||
} | ||||||
return false; | ||||||
} | ||||||
|
||||||
/** | ||||||
* \brief Used to retrieve args from BM. | ||||||
* | ||||||
* \param arg The name of the variable being sought | ||||||
* \param s The signature to check for the variable | ||||||
* \param strict Match if and only iff the list sought and the list found equal. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do. |
||||||
* \param sm_list The caller's matching buffer | ||||||
* \param index When found, the value of the slot within the byte vars | ||||||
* | ||||||
* \retval true A match for the variable was found. | ||||||
* \retval false | ||||||
*/ | ||||||
bool DetectByteRetrieveSMVar( | ||||||
const char *arg, const Signature *s, int sm_list, DetectByteIndexType *index) | ||||||
bool DetectByteRetrieveSMVar(const char *arg, const Signature *s, bool strict, int sm_list, | ||||||
DetectByteIndexType *index, const DetectEngineCtx *de_ctx) | ||||||
{ | ||||||
SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(arg, sm_list, s); | ||||||
bool any = sm_list == -1; | ||||||
int found_list; | ||||||
const SigMatch *bed_sm = DetectByteExtractRetrieveSMVar(arg, &found_list, s); | ||||||
if (bed_sm != NULL) { | ||||||
if (DetectByteListMismatch(any, sm_list, found_list, strict, arg, de_ctx)) { | ||||||
return false; | ||||||
} | ||||||
|
||||||
SCLogDebug("[buf] found %s; list wanted: sm_list: %d, list found: %d", arg, sm_list, | ||||||
found_list); | ||||||
*index = ((SCDetectByteExtractData *)bed_sm->ctx)->local_id; | ||||||
return true; | ||||||
} | ||||||
|
||||||
SigMatch *bmd_sm = DetectByteMathRetrieveSMVar(arg, sm_list, s); | ||||||
const SigMatch *bmd_sm = DetectByteMathRetrieveSMVar(arg, &found_list, s); | ||||||
if (bmd_sm != NULL) { | ||||||
*index = ((DetectByteMathData *)bmd_sm->ctx)->local_id; | ||||||
return true; | ||||||
if (!DetectByteListMismatch(any, sm_list, found_list, strict, arg, de_ctx)) { | ||||||
*index = ((DetectByteMathData *)bmd_sm->ctx)->local_id; | ||||||
SCLogDebug("[list] found %s; list wanted: sm_list: %d, list found: %d", arg, sm_list, | ||||||
found_list); | ||||||
return true; | ||||||
} | ||||||
} | ||||||
|
||||||
return false; | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -360,7 +360,8 @@ static int DetectByteMathSetup(DetectEngineCtx *de_ctx, Signature *s, const char | |
|
||
if (nbytes != NULL) { | ||
DetectByteIndexType index; | ||
if (!DetectByteRetrieveSMVar(nbytes, s, sm_list, &index)) { | ||
if (!DetectByteRetrieveSMVar( | ||
nbytes, s, SigMatchStrictEnabled(DETECT_BYTEMATH), sm_list, &index, de_ctx)) { | ||
SCLogError("unknown byte_ keyword var seen in byte_math - %s", nbytes); | ||
goto error; | ||
} | ||
|
@@ -372,7 +373,8 @@ static int DetectByteMathSetup(DetectEngineCtx *de_ctx, Signature *s, const char | |
|
||
if (rvalue != NULL) { | ||
DetectByteIndexType index; | ||
if (!DetectByteRetrieveSMVar(rvalue, s, sm_list, &index)) { | ||
if (!DetectByteRetrieveSMVar( | ||
rvalue, s, SigMatchStrictEnabled(DETECT_BYTEMATH), sm_list, &index, de_ctx)) { | ||
SCLogError("unknown byte_ keyword var seen in byte_math - %s", rvalue); | ||
goto error; | ||
} | ||
|
@@ -434,6 +436,15 @@ static void DetectByteMathFree(DetectEngineCtx *de_ctx, void *ptr) | |
SCByteMathFree(ptr); | ||
} | ||
|
||
static inline bool DetectByteMathSMNameMatch(const SigMatch *sm, const char *arg) | ||
{ | ||
if (sm->type == DETECT_BYTEMATH) { | ||
const DetectByteMathData *bmd = (const DetectByteMathData *)sm->ctx; | ||
return strcmp(bmd->result, arg) == 0; | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* \brief Lookup the SigMatch for a named byte_math variable. | ||
* | ||
|
@@ -442,32 +453,27 @@ static void DetectByteMathFree(DetectEngineCtx *de_ctx, void *ptr) | |
* | ||
* \retval A pointer to the SigMatch if found, otherwise NULL. | ||
*/ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe update the function description, too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do. |
||
SigMatch *DetectByteMathRetrieveSMVar(const char *arg, int sm_list, const Signature *s) | ||
const SigMatch *DetectByteMathRetrieveSMVar(const char *arg, int *found_list, const Signature *s) | ||
{ | ||
for (uint32_t x = 0; x < s->init_data->buffer_index; x++) { | ||
SigMatch *sm = s->init_data->buffers[x].head; | ||
const SigMatch *sm = s->init_data->buffers[x].head; | ||
while (sm != NULL) { | ||
if (sm->type == DETECT_BYTEMATH) { | ||
const DetectByteMathData *bmd = (const DetectByteMathData *)sm->ctx; | ||
if (strcmp(bmd->result, arg) == 0) { | ||
SCLogDebug("Retrieved SM for \"%s\"", arg); | ||
return sm; | ||
} | ||
if (DetectByteMathSMNameMatch(sm, arg)) { | ||
SCLogDebug("Retrieved SM for \"%s\"", arg); | ||
*found_list = s->init_data->buffers[x].id; | ||
return sm; | ||
} | ||
sm = sm->next; | ||
} | ||
} | ||
|
||
for (int list = 0; list < DETECT_SM_LIST_MAX; list++) { | ||
SigMatch *sm = s->init_data->smlists[list]; | ||
const SigMatch *sm = s->init_data->smlists[list]; | ||
while (sm != NULL) { | ||
// Make sure that the linked buffers ore on the same list | ||
if (sm->type == DETECT_BYTEMATH && (sm_list == -1 || sm_list == list)) { | ||
const DetectByteMathData *bmd = (const DetectByteMathData *)sm->ctx; | ||
if (strcmp(bmd->result, arg) == 0) { | ||
SCLogDebug("Retrieved SM for \"%s\"", arg); | ||
return sm; | ||
} | ||
if (DetectByteMathSMNameMatch(sm, arg)) { | ||
SCLogDebug("Retrieved SM for \"%s\"", arg); | ||
*found_list = list; | ||
return sm; | ||
} | ||
sm = sm->next; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we clearly indicate the Suricata version, here?