Skip to content

Commit e9c1ca2

Browse files
committed
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: OISF#6397. Fixes: ad88efc ("detect: support multi buffer matching")
1 parent c530865 commit e9c1ca2

File tree

3 files changed

+43
-11
lines changed

3 files changed

+43
-11
lines changed

src/detect-engine.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,8 @@ int DetectBufferSetActiveList(DetectEngineCtx *de_ctx, Signature *s, const int l
14441444
s->init_data->curbuf->id = list;
14451445
s->init_data->curbuf->head = NULL;
14461446
s->init_data->curbuf->tail = NULL;
1447+
s->init_data->curbuf->multi_capable =
1448+
DetectEngineBufferTypeSupportsMultiInstanceGetById(de_ctx, list);
14471449
SCLogDebug("new: idx %u list %d set up curbuf %p", s->init_data->buffer_index - 1, list,
14481450
s->init_data->curbuf);
14491451

@@ -1470,6 +1472,7 @@ int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
14701472
if (new_list == -1) {
14711473
SCReturnInt(-1);
14721474
}
1475+
int base_list = s->init_data->list;
14731476
SCLogDebug("new_list %d", new_list);
14741477
s->init_data->list = new_list;
14751478
s->init_data->list_set = false;
@@ -1482,6 +1485,8 @@ int DetectBufferGetActiveList(DetectEngineCtx *de_ctx, Signature *s)
14821485
return -1;
14831486
}
14841487
s->init_data->curbuf = &s->init_data->buffers[s->init_data->buffer_index++];
1488+
s->init_data->curbuf->multi_capable =
1489+
DetectEngineBufferTypeSupportsMultiInstanceGetById(de_ctx, base_list);
14851490
}
14861491
if (s->init_data->curbuf == NULL) {
14871492
SCLogError("failed to setup buffer");

src/detect-parse.c

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -289,19 +289,32 @@ int DetectEngineContentModifierBufferSetup(DetectEngineCtx *de_ctx,
289289
SCLogError("no matches for previous buffer");
290290
return -1;
291291
}
292-
if (SignatureInitDataBufferCheckExpand(s) < 0) {
293-
SCLogError("failed to expand rule buffer array");
294-
return -1;
292+
bool reuse_buffer = false;
293+
if (s->init_data->curbuf != NULL && (int)s->init_data->curbuf->id != sm_list) {
294+
for (uint32_t x = 0; x < s->init_data->buffer_index; x++) {
295+
if (s->init_data->buffers[x].id == (uint32_t)sm_list) {
296+
s->init_data->curbuf = &s->init_data->buffers[x];
297+
reuse_buffer = true;
298+
break;
299+
}
300+
}
295301
}
296302

297-
/* initialize a new buffer */
298-
s->init_data->curbuf = &s->init_data->buffers[s->init_data->buffer_index++];
299-
s->init_data->curbuf->id = sm_list;
300-
s->init_data->curbuf->head = NULL;
301-
s->init_data->curbuf->tail = NULL;
302-
SCLogDebug("idx %u list %d set up curbuf %p s->init_data->buffer_index %u",
303-
s->init_data->buffer_index - 1, sm_list, s->init_data->curbuf,
304-
s->init_data->buffer_index);
303+
if (!reuse_buffer) {
304+
if (SignatureInitDataBufferCheckExpand(s) < 0) {
305+
SCLogError("failed to expand rule buffer array");
306+
return -1;
307+
}
308+
309+
/* initialize a new buffer */
310+
s->init_data->curbuf = &s->init_data->buffers[s->init_data->buffer_index++];
311+
s->init_data->curbuf->id = sm_list;
312+
s->init_data->curbuf->head = NULL;
313+
s->init_data->curbuf->tail = NULL;
314+
SCLogDebug("idx %u list %d set up curbuf %p s->init_data->buffer_index %u",
315+
s->init_data->buffer_index - 1, sm_list, s->init_data->curbuf,
316+
s->init_data->buffer_index);
317+
}
305318
}
306319

307320
/* transfer the sm from the pmatch list to sm_list */
@@ -469,6 +482,18 @@ void SigMatchAppendSMToList(Signature *s, SigMatch *new, const int list)
469482
SCLogDebug("reset: list %d != s->init_data->list %d", list, s->init_data->list);
470483
s->init_data->list = DETECT_SM_LIST_NOTSET;
471484
}
485+
486+
if (s->init_data->curbuf != NULL && (int)s->init_data->curbuf->id != list) {
487+
for (uint32_t x = 0; x < s->init_data->buffer_index; x++) {
488+
if (s->init_data->buffers[x].id == (uint32_t)list &&
489+
!s->init_data->buffers[x].multi_capable) {
490+
SCLogDebug("reusing buffer %u as it isn't multi-capable", x);
491+
s->init_data->curbuf = &s->init_data->buffers[x];
492+
break;
493+
}
494+
}
495+
}
496+
472497
if ((s->init_data->curbuf != NULL && (int)s->init_data->curbuf->id != list) ||
473498
s->init_data->curbuf == NULL) {
474499
if (SignatureInitDataBufferCheckExpand(s) < 0) {

src/detect.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,8 @@ typedef struct SignatureInitDataBuffer_ {
515515
bool sm_init; /**< initialized by sigmatch, which is likely something like `urilen:10; http.uri;
516516
content:"abc";`. These need to be in the same list. Unset once `http.uri` is
517517
set up. */
518+
bool multi_capable; /**< true if we can have multiple instances of this buffer, so e.g. for
519+
http.uri. */
518520
/* sig match list */
519521
SigMatch *head;
520522
SigMatch *tail;

0 commit comments

Comments
 (0)