pkt-var: abuse flowvar postmatch logic for pktvars

Flowvars were already using a temporary store in the detect thread
ctx.

Use the same facility for pktvars. The reasons are:

1. packet is not always available, e.g. when running pcre on http
   buffers.

2. setting of vars should be done post match. Until now it was also
   possible that it is done on a partial match.
pull/2559/head
Victor Julien 9 years ago
parent 5e39486399
commit 0f708d427b

@ -715,7 +715,7 @@ static int DoInspectItem(ThreadVars *tv,
SCLogDebug("MATCH: tx %u packet %u", (uint)inspect_tx_id, (uint)p->pcap_cnt);
}
DetectFlowvarProcessList(det_ctx, f);
DetectVarProcessList(det_ctx, f, p);
return 1;
}

@ -33,6 +33,7 @@
#include "threads.h"
#include "flow.h"
#include "flow-var.h"
#include "pkt-var.h"
#include "detect-flowvar.h"
#include "util-spm.h"
@ -194,10 +195,10 @@ error:
/** \brief Store flowvar in det_ctx so we can exec it post-match */
int DetectFlowvarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx,
int DetectVarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx,
uint8_t *buffer, uint16_t len, int type)
{
DetectFlowvarList *fs = det_ctx->flowvarlist;
DetectVarList *fs = det_ctx->varlist;
/* first check if we have had a previous match for this idx */
for ( ; fs != NULL; fs = fs->next) {
@ -216,8 +217,8 @@ int DetectFlowvarStoreMatch(DetectEngineThreadCtx *det_ctx, uint32_t idx,
fs->idx = idx;
fs->next = det_ctx->flowvarlist;
det_ctx->flowvarlist = fs;
fs->next = det_ctx->varlist;
det_ctx->varlist = fs;
}
fs->len = len;
@ -266,29 +267,33 @@ static int DetectFlowvarPostMatch(ThreadVars *tv,
DetectEngineThreadCtx *det_ctx,
Packet *p, const Signature *s, const SigMatchCtx *ctx)
{
DetectFlowvarList *fs, *prev;
DetectVarList *fs, *prev;
const DetectFlowvarData *fd;
if (det_ctx->flowvarlist == NULL || p->flow == NULL)
if (det_ctx->varlist == NULL)
return 1;
fd = (const DetectFlowvarData *)ctx;
prev = NULL;
fs = det_ctx->flowvarlist;
fs = det_ctx->varlist;
while (fs != NULL) {
if (fd->idx == fs->idx) {
SCLogDebug("adding to the flow %u:", fs->idx);
//PrintRawDataFp(stdout, fs->buffer, fs->len);
FlowVarAddStrNoLock(p->flow, fs->idx, fs->buffer, fs->len);
/* memory at fs->buffer is now the responsibility of
* the flowvar code. */
if (fs->type == DETECT_VAR_TYPE_FLOW_POSTMATCH && p && p->flow) {
FlowVarAddStrNoLock(p->flow, fs->idx, fs->buffer, fs->len);
/* memory at fs->buffer is now the responsibility of
* the flowvar code. */
} else if (fs->type == DETECT_VAR_TYPE_PKT_POSTMATCH && p) {
PktVarAdd(p, fs->idx, fs->buffer, fs->len);
}
if (fs == det_ctx->flowvarlist) {
det_ctx->flowvarlist = fs->next;
if (fs == det_ctx->varlist) {
det_ctx->varlist = fs->next;
SCFree(fs);
fs = det_ctx->flowvarlist;
fs = det_ctx->varlist;
} else {
prev->next = fs->next;
SCFree(fs);
@ -307,14 +312,14 @@ static int DetectFlowvarPostMatch(ThreadVars *tv,
* - enforce storage for type ALWAYS (vars set from lua)
* Only called from DetectFlowvarProcessList() when flowvarlist is not NULL .
*/
void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f)
void DetectVarProcessListInternal(DetectVarList *fs, Flow *f, Packet *p)
{
DetectFlowvarList *next;
DetectVarList *next;
do {
next = fs->next;
if (fs->type == DETECT_FLOWVAR_TYPE_ALWAYS) {
if (fs->type == DETECT_VAR_TYPE_ALWAYS) {
SCLogDebug("adding to the flow %u:", fs->idx);
//PrintRawDataFp(stdout, fs->buffer, fs->len);

@ -36,18 +36,18 @@ typedef struct DetectFlowvarData_ {
void DetectFlowvarRegister (void);
int DetectFlowvarPostMatchSetup(Signature *s, uint32_t idx);
int DetectFlowvarStoreMatch(DetectEngineThreadCtx *, uint32_t, uint8_t *, uint16_t, int);
int DetectVarStoreMatch(DetectEngineThreadCtx *, uint32_t, uint8_t *, uint16_t, int);
/* For use only by DetectFlowvarProcessList() */
void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f);
static inline void DetectFlowvarProcessList(DetectEngineThreadCtx *det_ctx, Flow *f)
void DetectVarProcessListInternal(DetectVarList *fs, Flow *f, Packet *p);
static inline void DetectVarProcessList(DetectEngineThreadCtx *det_ctx, Flow *f, Packet *p)
{
DetectFlowvarList *fs = det_ctx->flowvarlist;
DetectVarList *fs = det_ctx->varlist;
SCLogDebug("flow %p det_ctx->flowvarlist %p", f, fs);
if (f && fs != NULL) {
det_ctx->flowvarlist = NULL;
DetectFlowvarProcessListInternal(fs, f);
SCLogDebug("flow %p det_ctx->varlist %p", f, fs);
if ((f || p) && fs != NULL) {
det_ctx->varlist = NULL;
DetectVarProcessListInternal(fs, f, p);
}
}

@ -219,21 +219,28 @@ int DetectPcrePayloadMatch(DetectEngineThreadCtx *det_ctx, const Signature *s,
if (ret > 1 && pe->idx != 0) {
uint8_t x;
for (x = 0; x < pe->idx; x++) {
SCLogDebug("capturing");
SCLogDebug("capturing %u", x);
const char *str_ptr;
ret = pcre_get_substring((char *)ptr, ov, MAX_SUBSTRINGS, x+1, &str_ptr);
if (unlikely(ret == 0))
continue;
if (pe->captypes[x] == VAR_TYPE_PKT_VAR && p != NULL) {
PktVarAdd(p, pe->capids[x], (uint8_t *)str_ptr, ret);
SCLogDebug("data %p/%u, type %u id %u p %p",
str_ptr, ret, pe->captypes[x], pe->capids[x], p);
if (pe->captypes[x] == VAR_TYPE_PKT_VAR) {
/* store max 64k. Errors are ignored */
capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff;
(void)DetectVarStoreMatch(det_ctx, pe->capids[x],
(uint8_t *)str_ptr, capture_len,
DETECT_VAR_TYPE_PKT_POSTMATCH);
} else if (pe->captypes[x] == VAR_TYPE_FLOW_VAR && f != NULL) {
/* store max 64k. Errors are ignored */
capture_len = (ret < 0xffff) ? (uint16_t)ret : 0xffff;
(void)DetectFlowvarStoreMatch(det_ctx, pe->capids[x],
(void)DetectVarStoreMatch(det_ctx, pe->capids[x],
(uint8_t *)str_ptr, capture_len,
DETECT_FLOWVAR_TYPE_POSTMATCH);
DETECT_VAR_TYPE_FLOW_POSTMATCH);
}
}
}
@ -717,10 +724,8 @@ static int DetectPcreSetup (DetectEngineCtx *de_ctx, Signature *s, char *regexst
uint8_t x;
for (x = 0; x < pd->idx; x++) {
if (pd->captypes[x] == VAR_TYPE_FLOW_VAR) {
if (DetectFlowvarPostMatchSetup(s, pd->capids[x]) < 0)
goto error_nofree;
}
if (DetectFlowvarPostMatchSetup(s, pd->capids[x]) < 0)
goto error_nofree;
}
if (!(pd->flags & DETECT_PCRE_RELATIVE))

@ -549,21 +549,19 @@ int SigMatchSignaturesRunPostMatch(ThreadVars *tv,
const Signature *s)
{
/* run the packet match functions */
if (s->sm_arrays[DETECT_SM_LIST_POSTMATCH] != NULL) {
SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_POSTMATCH];
if (smd != NULL) {
KEYWORD_PROFILING_SET_LIST(det_ctx, DETECT_SM_LIST_POSTMATCH);
SigMatchData *smd = s->sm_arrays[DETECT_SM_LIST_POSTMATCH];
SCLogDebug("running match functions, sm %p", smd);
if (smd != NULL) {
while (1) {
KEYWORD_PROFILING_START;
(void)sigmatch_table[smd->type].Match(tv, det_ctx, p, s, smd->ctx);
KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
if (smd->is_last)
break;
smd++;
}
while (1) {
KEYWORD_PROFILING_START;
(void)sigmatch_table[smd->type].Match(tv, det_ctx, p, s, smd->ctx);
KEYWORD_PROFILING_END(det_ctx, smd->type, 1);
if (smd->is_last)
break;
smd++;
}
}
@ -1472,7 +1470,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh
}
alerts++;
next:
DetectFlowvarProcessList(det_ctx, pflow);
DetectVarProcessList(det_ctx, pflow, p);
DetectReplaceFree(det_ctx);
RULE_PROFILING_END(det_ctx, s, smatch, p);

@ -490,20 +490,21 @@ typedef struct DetectReplaceList_ {
} DetectReplaceList;
/** only execute flowvar storage if rule matched */
#define DETECT_FLOWVAR_TYPE_POSTMATCH 1
#define DETECT_VAR_TYPE_FLOW_POSTMATCH 1
#define DETECT_VAR_TYPE_PKT_POSTMATCH 2
/** execute flowvar storage even if rule doesn't match (for lua) */
#define DETECT_FLOWVAR_TYPE_ALWAYS 2
#define DETECT_VAR_TYPE_ALWAYS 3
/** list for flowvar store candidates, to be stored from
* post-match function */
typedef struct DetectFlowvarList_ {
typedef struct DetectVarList_ {
uint32_t idx; /**< flowvar name idx */
uint16_t len; /**< data len */
int type; /**< type of store candidate POSTMATCH or ALWAYS */
uint8_t *buffer; /**< alloc'd buffer, may be freed by
post-match, post-non-match */
struct DetectFlowvarList_ *next;
} DetectFlowvarList;
struct DetectVarList_ *next;
} DetectVarList;
typedef struct DetectEngineIPOnlyThreadCtx_ {
uint8_t *sig_match_array; /* bit array of sig nums */
@ -877,8 +878,8 @@ typedef struct DetectEngineThreadCtx_ {
/* string to replace */
DetectReplaceList *replist;
/* flowvars to store in post match function */
DetectFlowvarList *flowvarlist;
/* vars to store in post match function */
DetectVarList *varlist;
/* Array in which the filestore keyword stores file id and tx id. If the
* full signature matches, these are processed by a post-match filestore

Loading…
Cancel
Save