-
Notifications
You must be signed in to change notification settings - Fork 1.6k
detect/var: Restrict var usage to single buffer #13584
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 |
---|---|---|
|
@@ -27,6 +27,24 @@ | |
|
||
typedef uint8_t DetectByteIndexType; | ||
|
||
bool DetectByteRetrieveSMVar(const char *, const Signature *, int sm_list, DetectByteIndexType *); | ||
bool DetectByteRetrieveSMVar(const char *, const Signature *, bool strict, int sm_list, | ||
DetectByteIndexType *, int rule_line); | ||
|
||
// Once a variable is found, apply strict semantics (error) else warning | ||
static inline bool DetectByteListMismatch( | ||
jlucovsky marked this conversation as resolved.
Show resolved
Hide resolved
|
||
bool any, int sm_list, int found_list, bool strict, const char *arg, int rule_line) | ||
{ | ||
if (any || sm_list == found_list) | ||
return false; | ||
|
||
if (strict) { | ||
return true; | ||
} | ||
|
||
SCLogWarning("Using byte variable from a different buffer may produce indeterminate " | ||
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. can we move this check into a validate callback so that the sid is available in a warning? 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. I think that Philippe's comment here also make sense: https://github.com/OISF/suricata/pull/13564/files/664e61a2678b90d25e3f27937059a2f4817aaece#r2183567368 (apologies for the very late reply) |
||
"results; variable: \"%s\" at line %" PRId32 "", | ||
arg, rule_line); | ||
return false; | ||
} | ||
|
||
#endif /* SURICATA_DETECT_BYTE_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -358,7 +358,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->rule_line)) { | ||
SCLogError("unknown byte_ keyword var seen in byte_math - %s", nbytes); | ||
goto error; | ||
} | ||
|
@@ -370,7 +371,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->rule_line)) { | ||
SCLogError("unknown byte_ keyword var seen in byte_math - %s", rvalue); | ||
goto error; | ||
} | ||
|
@@ -432,6 +434,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. | ||
* | ||
|
@@ -440,32 +451,28 @@ static void DetectByteMathFree(DetectEngineCtx *de_ctx, void *ptr) | |
* | ||
* \retval A pointer to the SigMatch if found, otherwise NULL. | ||
*/ | ||
SigMatch *DetectByteMathRetrieveSMVar(const char *arg, int sm_list, const Signature *s) | ||
const SigMatch *DetectByteMathRetrieveSMVar( | ||
const char *arg, int sm_list, 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)) { | ||
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. Still #13564 (comment)
Did you test a rule with 2 buffers, each buffer doing a byte_extract+ byte_math ? I am afraid that with this change, the second buffer will get their found_list from the first buffer when it uses to get the right sm_list == list in current code Do you have a test for it ? 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. This rule is handled correctly -- is this what you were thinking?
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. Ok... I will test it 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. So, buffers are ok because they run only the first loop of `DetectByteExtractRetrieveSMVar`` The second loop (where you removed the check list==sm_list) is run for DETECT_SM_LIST_PMATCH and DETECT_SM_LIST_BASE64_DATA So, this allows signature like |
||
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; | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,7 +55,7 @@ static int LuaBytevarMap(lua_State *L) | |
} | ||
|
||
DetectByteIndexType idx; | ||
if (!DetectByteRetrieveSMVar(name, s, -1, &idx)) { | ||
if (!DetectByteRetrieveSMVar(name, s, false, -1, &idx, 1)) { | ||
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. Why rule line 1 ? 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. I'll modify this to use a sentinel value since the line number is meant to indicate the offset into the rule file(s). |
||
luaL_error(L, "unknown byte_extract or byte_math variable: %s", name); | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.