Skip to content

Commit

Permalink
detect/dataset: fix dataset set logic
Browse files Browse the repository at this point in the history
The set operation of dataset keyword was not done only signature
when there is a full match. This was not correct with regards to
expectation.

This patch changes the behavior of the dataset keyword to do a
match and a post match for the set operation. In the match, the
buffer data that needs to end up in the set is captured and in
post match the dataset is updated (if ever the signature is fully
matching).

Ticket: OISF#5576
  • Loading branch information
regit committed Oct 29, 2022
1 parent 160c778 commit c91fc12
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 6 deletions.
87 changes: 81 additions & 6 deletions src/detect-dataset.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@
#include "util-path.h"
#include "util-conf.h"

int DetectDatasetMatch (ThreadVars *, DetectEngineThreadCtx *, Packet *,
const Signature *, const SigMatchCtx *);
int DetectDatasetMatch(DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *);
static int DetectDatasetSetup (DetectEngineCtx *, Signature *, const char *);
void DetectDatasetFree (DetectEngineCtx *, void *);

Expand All @@ -53,6 +52,7 @@ void DetectDatasetRegister (void)
sigmatch_table[DETECT_DATASET].url = "/rules/dataset-keywords.html#dataset";
sigmatch_table[DETECT_DATASET].Setup = DetectDatasetSetup;
sigmatch_table[DETECT_DATASET].Free = DetectDatasetFree;
sigmatch_table[DETECT_DATASET].Match = DetectDatasetMatch;
}

/*
Expand Down Expand Up @@ -86,17 +86,42 @@ int DetectDatasetBufferMatch(DetectEngineThreadCtx *det_ctx,
}
case DETECT_DATASET_CMD_SET: {
//PrintRawDataFp(stdout, data, data_len);
int r = DatasetAdd(sd->set, data, data_len);
if (r == 1)
return 1;
break;
/* Simulate original behavior where there is no alert when data is in set */
int r = DatasetLookup(sd->set, data, data_len);
if (r == 1) {
return 0;
}
DetectDatasetMatchData *dmd =
(DetectDatasetMatchData *)DetectThreadCtxGetKeywordThreadCtx(
det_ctx, sd->thread_ctx_id);
if (dmd == NULL) {
return 0;
}
dmd->data_len = data_len;
dmd->data = data;
return 1;
}
default:
abort();
}
return 0;
}

int DetectDatasetMatch(
DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
{
const DetectDatasetData *sd = (DetectDatasetData *)ctx;
DetectDatasetMatchData *dmd = (DetectDatasetMatchData *)DetectThreadCtxGetKeywordThreadCtx(
det_ctx, sd->thread_ctx_id);

if (dmd == NULL || dmd->data_len == 0) {
return 0;
}
int r = DatasetAdd(sd->set, dmd->data, dmd->data_len);
dmd->data_len = 0;
return r;
}

static int DetectDatasetParse(const char *str, char *cmd, int cmd_len, char *name, int name_len,
enum DatasetTypes *type, char *load, size_t load_size, char *save, size_t save_size,
uint64_t *memcap, uint32_t *hashsize)
Expand Down Expand Up @@ -328,10 +353,32 @@ static int SetupSavePath(const DetectEngineCtx *de_ctx,
return 0;
}

static void *DetectDatasetMatchDataThreadInit(void *data)
{
DetectDatasetMatchData *scmd = SCCalloc(1, sizeof(DetectDatasetMatchData));
if (unlikely(scmd == NULL))
return NULL;

scmd->data = NULL;
scmd->data_len = 0;
scmd->data_len_max = 0;
return scmd;
}

static void DetectDatasetMatchDataThreadFree(void *ctx)
{
if (ctx != NULL) {
DetectDatasetMatchData *scmd = (DetectDatasetMatchData *)ctx;
SCFree(scmd);
}
}

int DetectDatasetSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
{
DetectDatasetData *cd = NULL;
DetectDatasetData *scd = NULL;
SigMatch *sm = NULL;
SigMatch *smp = NULL;
uint8_t cmd = 0;
uint64_t memcap = 0;
uint32_t hashsize = 0;
Expand Down Expand Up @@ -419,6 +466,30 @@ int DetectDatasetSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawst
if (sm == NULL)
goto error;

if (cmd == DETECT_DATASET_CMD_SET) {
smp = SigMatchAlloc();
if (smp == NULL)
goto error;

scd = SCCalloc(1, sizeof(DetectDatasetData));
if (unlikely(scd == NULL))
goto error;

cd->thread_ctx_id = DetectRegisterThreadCtxFuncs(de_ctx, "dataset",
DetectDatasetMatchDataThreadInit, (void *)cd, DetectDatasetMatchDataThreadFree, 0);
if (cd->thread_ctx_id == -1)
goto error;
scd->thread_ctx_id = cd->thread_ctx_id;

scd->set = set;
scd->cmd = cmd;

smp->type = DETECT_DATASET;
smp->ctx = (SigMatchCtx *)scd;

SigMatchAppendSMToList(s, smp, DETECT_SM_LIST_POSTMATCH);
}

sm->type = DETECT_DATASET;
sm->ctx = (SigMatchCtx *)cd;
SigMatchAppendSMToList(s, sm, list);
Expand All @@ -429,6 +500,10 @@ int DetectDatasetSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawst
SCFree(cd);
if (sm != NULL)
SCFree(sm);
if (smp != NULL)
SCFree(smp);
if (scd != NULL)
SCFree(scd);
return -1;
}

Expand Down
7 changes: 7 additions & 0 deletions src/detect-dataset.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,15 @@
typedef struct DetectDatasetData_ {
Dataset *set;
uint8_t cmd;
int thread_ctx_id;
} DetectDatasetData;

typedef struct DetectDatasetMatchData_ {
const uint8_t *data;
uint32_t data_len;
uint32_t data_len_max;
} DetectDatasetMatchData;

int DetectDatasetBufferMatch(DetectEngineThreadCtx *det_ctx,
const DetectDatasetData *sd,
const uint8_t *data, const uint32_t data_len);
Expand Down

0 comments on commit c91fc12

Please sign in to comment.