detect: fix legacy modifiers leading to multi-buffer

Fix non-continious matches with content and pcre modifiers setting up
multiple buffers.

To address this store whether a buffer is multi-capable and if not reuse
an earlier buffer if possible.

Bug: #6397.

Fixes: ad88efc2d8 ("detect: support multi buffer matching")
pull/9637/head
Victor Julien 2 years ago committed by Victor Julien
parent c53086575a
commit e9c1ca2804

@ -1444,6 +1444,8 @@ int DetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int l
s->init_data->curbuf->id = list;
s->init_data->curbuf->head = NULL;
s->init_data->curbuf->tail = NULL;
s->init_data->curbuf->multi_capable =
DetectEngineBufferTypeSupportsMultiInstanceGetById(de_ctx, list);
SCLogDebug("new: idx %u list %d set up curbuf %p", s->init_data->buffer_index - 1, list,
s->init_data->curbuf);
@ -1470,6 +1472,7 @@ int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
if (new_list == -1) {
SCReturnInt(-1);
}
int base_list = s->init_data->list;
SCLogDebug("new_list %d", new_list);
s->init_data->list = new_list;
s->init_data->list_set = false;
@ -1482,6 +1485,8 @@ int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
return -1;
}
s->init_data->curbuf = &s->init_data->buffers[s->init_data->buffer_index++];
s->init_data->curbuf->multi_capable =
DetectEngineBufferTypeSupportsMultiInstanceGetById(de_ctx, base_list);
}
if (s->init_data->curbuf == NULL) {
SCLogError("failed to setup buffer");

@ -289,19 +289,32 @@ int DetectEngineContentModifierBufferSetup(DetectEngineCtx *de_ctx,
SCLogError("no matches for previous buffer");
return -1;
}
if (SignatureInitDataBufferCheckExpand(s) < 0) {
SCLogError("failed to expand rule buffer array");
return -1;
bool reuse_buffer = false;
if (s->init_data->curbuf != NULL && (int)s->init_data->curbuf->id != sm_list) {
for (uint32_t x = 0; x < s->init_data->buffer_index; x++) {
if (s->init_data->buffers[x].id == (uint32_t)sm_list) {
s->init_data->curbuf = &s->init_data->buffers[x];
reuse_buffer = true;
break;
}
}
}
/* initialize a new buffer */
s->init_data->curbuf = &s->init_data->buffers[s->init_data->buffer_index++];
s->init_data->curbuf->id = sm_list;
s->init_data->curbuf->head = NULL;
s->init_data->curbuf->tail = NULL;
SCLogDebug("idx %u list %d set up curbuf %p s->init_data->buffer_index %u",
s->init_data->buffer_index - 1, sm_list, s->init_data->curbuf,
s->init_data->buffer_index);
if (!reuse_buffer) {
if (SignatureInitDataBufferCheckExpand(s) < 0) {
SCLogError("failed to expand rule buffer array");
return -1;
}
/* initialize a new buffer */
s->init_data->curbuf = &s->init_data->buffers[s->init_data->buffer_index++];
s->init_data->curbuf->id = sm_list;
s->init_data->curbuf->head = NULL;
s->init_data->curbuf->tail = NULL;
SCLogDebug("idx %u list %d set up curbuf %p s->init_data->buffer_index %u",
s->init_data->buffer_index - 1, sm_list, s->init_data->curbuf,
s->init_data->buffer_index);
}
}
/* transfer the sm from the pmatch list to sm_list */
@ -469,6 +482,18 @@ void SigMatchAppendSMToList(Signature *s, SigMatch *new, const int list)
SCLogDebug("reset: list %d != s->init_data->list %d", list, s->init_data->list);
s->init_data->list = DETECT_SM_LIST_NOTSET;
}
if (s->init_data->curbuf != NULL && (int)s->init_data->curbuf->id != list) {
for (uint32_t x = 0; x < s->init_data->buffer_index; x++) {
if (s->init_data->buffers[x].id == (uint32_t)list &&
!s->init_data->buffers[x].multi_capable) {
SCLogDebug("reusing buffer %u as it isn't multi-capable", x);
s->init_data->curbuf = &s->init_data->buffers[x];
break;
}
}
}
if ((s->init_data->curbuf != NULL && (int)s->init_data->curbuf->id != list) ||
s->init_data->curbuf == NULL) {
if (SignatureInitDataBufferCheckExpand(s) < 0) {

@ -515,6 +515,8 @@ typedef struct SignatureInitDataBuffer_ {
bool sm_init; /**< initialized by sigmatch, which is likely something like `urilen:10; http.uri;
content:"abc";`. These need to be in the same list. Unset once `http.uri` is
set up. */
bool multi_capable; /**< true if we can have multiple instances of this buffer, so e.g. for
http.uri. */
/* sig match list */
SigMatch *head;
SigMatch *tail;

Loading…
Cancel
Save