From 5111aa2ec02089e1cbdd095d311610acd06cf638 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Fri, 20 Mar 2015 15:47:39 +0100 Subject: [PATCH] detect-state: handle 'post match' locking The post match list was called with an unlocked flow until now. However, recent de_state handling updates changed this. The stateful detection code can now call the post match functions while keeping the flow locked. The normal detection code still calls it with an unlocked flow. This patch adds a hint to the DetectEngineThreadCtx called 'flow_locked' that is set to true if the caller has already locked the flow. --- src/detect-engine-state.c | 4 ++++ src/detect-filestore.c | 7 +++++-- src/detect-flowvar.c | 13 ++++++++++--- src/detect-flowvar.h | 5 +++-- src/detect.h | 6 +++++- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index a78a3b6243..143551be86 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -731,7 +731,9 @@ static int DoInspectItem(ThreadVars *tv, RULE_PROFILING_END(det_ctx, s, (alert == 1), p); if (alert) { + det_ctx->flow_locked = 1; SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s); + det_ctx->flow_locked = 0; if (!(s->flags & SIG_FLAG_NOALERT)) { PacketAlertAppend(det_ctx, s, p, inspect_tx_id, @@ -826,7 +828,9 @@ static int DoInspectFlowRule(ThreadVars *tv, item->nm = sm; if (alert) { + det_ctx->flow_locked = 1; SigMatchSignaturesRunPostMatch(tv, de_ctx, det_ctx, p, s); + det_ctx->flow_locked = 0; if (!(s->flags & SIG_FLAG_NOALERT)) { PacketAlertAppend(det_ctx, s, p, 0, diff --git a/src/detect-filestore.c b/src/detect-filestore.c index 42bb74faf6..00e8aacc8f 100644 --- a/src/detect-filestore.c +++ b/src/detect-filestore.c @@ -224,7 +224,8 @@ int DetectFilestorePostMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Pack else flags |= STREAM_TOSERVER; - FLOWLOCK_WRLOCK(p->flow); + if (det_ctx->flow_locked == 0) + FLOWLOCK_WRLOCK(p->flow); FileContainer *ffc = AppLayerParserGetFiles(p->flow->proto, p->flow->alproto, p->flow->alstate, flags); @@ -245,7 +246,9 @@ int DetectFilestorePostMatch(ThreadVars *t, DetectEngineThreadCtx *det_ctx, Pack } } - FLOWLOCK_UNLOCK(p->flow); + if (det_ctx->flow_locked == 0) + FLOWLOCK_UNLOCK(p->flow); + SCReturnInt(0); } diff --git a/src/detect-flowvar.c b/src/detect-flowvar.c index 0746393e63..8e8fddee0b 100644 --- a/src/detect-flowvar.c +++ b/src/detect-flowvar.c @@ -288,6 +288,7 @@ static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx { DetectFlowvarList *fs, *prev; const DetectFlowvarData *fd; + const int flow_locked = det_ctx->flow_locked; if (det_ctx->flowvarlist == NULL || p->flow == NULL) return 1; @@ -301,7 +302,10 @@ static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx SCLogDebug("adding to the flow %u:", fs->idx); //PrintRawDataFp(stdout, fs->buffer, fs->len); - FlowVarAddStr(p->flow, fs->idx, fs->buffer, fs->len); + if (flow_locked) + FlowVarAddStrNoLock(p->flow, fs->idx, fs->buffer, fs->len); + else + FlowVarAddStr(p->flow, fs->idx, fs->buffer, fs->len); /* memory at fs->buffer is now the responsibility of * the flowvar code. */ @@ -327,7 +331,7 @@ static int DetectFlowvarPostMatch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx * - enforce storage for type ALWAYS (luajit) * Only called from DetectFlowvarProcessList() when flowvarlist is not NULL . */ -void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f) +void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f, const int flow_locked) { DetectFlowvarList *next; @@ -339,7 +343,10 @@ void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f) SCLogDebug("adding to the flow %u:", fs->idx); //PrintRawDataFp(stdout, fs->buffer, fs->len); - FlowVarAddStr(f, fs->idx, fs->buffer, fs->len); + if (flow_locked) + FlowVarAddStrNoLock(f, fs->idx, fs->buffer, fs->len); + else + FlowVarAddStr(f, fs->idx, fs->buffer, fs->len); /* memory at fs->buffer is now the responsibility of * the flowvar code. */ } else diff --git a/src/detect-flowvar.h b/src/detect-flowvar.h index 7ee12f02cc..9e72a5bcb5 100644 --- a/src/detect-flowvar.h +++ b/src/detect-flowvar.h @@ -39,16 +39,17 @@ int DetectFlowvarPostMatchSetup(Signature *s, uint16_t idx); int DetectFlowvarStoreMatch(DetectEngineThreadCtx *, uint16_t, uint8_t *, uint16_t, int); /* For use only by DetectFlowvarProcessList() */ -void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f); +void DetectFlowvarProcessListInternal(DetectFlowvarList *fs, Flow *f, const int flow_locked); static inline void DetectFlowvarProcessList(DetectEngineThreadCtx *det_ctx, Flow *f) { DetectFlowvarList *fs = det_ctx->flowvarlist; + const int flow_locked = det_ctx->flow_locked; SCLogDebug("det_ctx->flowvarlist %p", fs); if (fs != NULL) { det_ctx->flowvarlist = NULL; - DetectFlowvarProcessListInternal(fs, f); + DetectFlowvarProcessListInternal(fs, f, flow_locked); } } diff --git a/src/detect.h b/src/detect.h index 973f7f87cf..80d6d6a97d 100644 --- a/src/detect.h +++ b/src/detect.h @@ -774,7 +774,7 @@ typedef struct HttpReassembledBody_ { /** * Detection engine thread data. */ -typedef struct DetectionEngineThreadCtx_ { +typedef struct DetectEngineThreadCtx_ { /* the thread to which this detection engine thread belongs */ ThreadVars *tv; @@ -792,6 +792,10 @@ typedef struct DetectionEngineThreadCtx_ { /* counter for the filestore array below -- up here for cache reasons. */ uint16_t filestore_cnt; + /* bool to hint the POSTMATCH list members about the lock status of the + * flow. If locked this is TRUE, unlocked or no-flow: FALSE */ + uint8_t flow_locked; + HttpReassembledBody *hsbd; uint64_t hsbd_start_tx_id; uint16_t hsbd_buffers_size;