From a8cb8d830bbfb444dc7fa40395ceaf0db224e9dd Mon Sep 17 00:00:00 2001 From: Pablo Rincon Date: Fri, 25 Jun 2010 20:05:22 +0200 Subject: [PATCH] Fix for bug 186 and thresholding issue handling ip versions --- src/detect-engine-state.c | 54 ++++++++++++++++++++++++--------------- src/detect-engine-state.h | 1 - src/detect.c | 3 +++ src/flow-util.h | 14 ++++++++-- src/flow.h | 1 + 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index 7fd0dc67f2..dcc2abbfb3 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -105,24 +105,33 @@ DetectEngineState *DetectEngineStateAlloc(void) { } memset(d, 0x00, sizeof(DetectEngineState)); - SCMutexInit(&d->m, NULL); - SCReturnPtr(d, "DetectEngineState"); } /** * \brief Free a DetectEngineState object + * You must lock the flow mutex for de_state + * (f->de_state_m) * \param state DetectEngineState object to free */ void DetectEngineStateFree(DetectEngineState *state) { + DeStateStore *iter = NULL; + DeStateStore *aux = NULL; + if (state == NULL) return; - if (state->head != NULL) { - DeStateStoreFree(state->head); + iter = state->head; + while (iter != NULL) { + aux = iter; + iter = iter->next; + SCFree(aux); } - SCMutexDestroy(&state->m); + state->head = NULL; + state->tail = NULL; + + state->cnt = 0; SCFree(state); } @@ -134,20 +143,23 @@ void DetectEngineStateFree(DetectEngineState *state) { void DetectEngineStateReset(DetectEngineState *state) { SCEnter(); - if (state == NULL) { - SCReturn; - } + DeStateStore *iter = NULL; + DeStateStore *aux = NULL; - SCMutexLock(&state->m); + if (state == NULL) + return; - if (state->head != NULL) { - DeStateStoreFree(state->head); + iter = state->head; + while (iter != NULL) { + aux = iter; + iter = iter->next; + SCFree(aux); } + state->head = NULL; state->tail = NULL; state->cnt = 0; - SCMutexUnlock(&state->m); SCReturn; } @@ -351,6 +363,7 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, SCLogDebug("detection done, store results: sm %p, uri %d, dce %d", sm, umatch, dmatch); + SCMutexLock(&f->de_state_m); SCMutexLock(&f->m); /* match or no match, we store the state anyway * "sm" here is either NULL (complete match) or @@ -358,14 +371,13 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, if (f->de_state == NULL) { f->de_state = DetectEngineStateAlloc(); } - SCMutexUnlock(&f->m); - if (f->de_state != NULL) { - SCMutexLock(&f->de_state->m); DeStateSignatureAppend(f->de_state, s, sm, umatch, dmatch); - SCMutexUnlock(&f->de_state->m); } + SCMutexUnlock(&f->m); + SCMutexUnlock(&f->de_state_m); + SCReturnInt(r); } @@ -391,9 +403,9 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete return 0; } - SCMutexLock(&f->de_state->m); + SCMutexLock(&f->de_state_m); - if (f->de_state->cnt == 0) + if (f->de_state == NULL || f->de_state->cnt == 0) goto end; /* loop through the stores */ @@ -517,7 +529,7 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete } end: - SCMutexUnlock(&f->de_state->m); + SCMutexUnlock(&f->de_state_m); SCReturnInt(0); } @@ -532,11 +544,11 @@ int DeStateRestartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, DetectEngin /* first clear the existing state as it belongs * to the previous transaction */ SCMutexLock(&f->m); + SCMutexLock(&f->de_state_m); if (f->de_state != NULL) { - SCMutexLock(&f->de_state->m); DetectEngineStateReset(f->de_state); - SCMutexUnlock(&f->de_state->m); } + SCMutexUnlock(&f->de_state_m); SCMutexUnlock(&f->m); SCReturnInt(0); diff --git a/src/detect-engine-state.h b/src/detect-engine-state.h index 0e388b252e..1fa6843e54 100644 --- a/src/detect-engine-state.h +++ b/src/detect-engine-state.h @@ -74,7 +74,6 @@ typedef struct DetectEngineState_ { DeStateStore *head; /**< signature state storage */ DeStateStore *tail; /**< tail item of the storage list */ SigIntId cnt; /**< number of sigs in the storage */ - SCMutex m; /**< lock for the de_state object */ } DetectEngineState; void DeStateRegisterTests(void); diff --git a/src/detect.c b/src/detect.c index 6061317e77..65c734a61f 100644 --- a/src/detect.c +++ b/src/detect.c @@ -923,8 +923,11 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh int de_state_status = DeStateUpdateInspectTransactionId(p->flow, (flags & STREAM_TOSERVER) ? STREAM_TOSERVER : STREAM_TOCLIENT); SCLogDebug("de_state_status %d", de_state_status); + if (de_state_status == 2) { + SCMutexLock(&p->flow->de_state_m); DetectEngineStateReset(p->flow->de_state); + SCMutexUnlock(&p->flow->de_state_m); } } diff --git a/src/flow-util.h b/src/flow-util.h index 97536bf33b..358e51e806 100644 --- a/src/flow-util.h +++ b/src/flow-util.h @@ -28,6 +28,7 @@ #define FLOW_INITIALIZE(f) do { \ SCMutexInit(&(f)->m, NULL); \ + SCMutexInit(&(f)->de_state_m, NULL); \ (f)->lnext = NULL; \ (f)->lprev = NULL; \ (f)->hnext = NULL; \ @@ -69,8 +70,12 @@ (f)->flowvar = NULL; \ (f)->protoctx = NULL; \ SC_ATOMIC_RESET((f)->use_cnt); \ - DetectEngineStateFree((f)->de_state); \ + SCMutexLock(&(f)->de_state_m); \ + if ((f)->de_state != NULL) { \ + DetectEngineStateReset((f)->de_state); \ + } \ (f)->de_state = NULL; \ + SCMutexUnlock(&(f)->de_state_m); \ (f)->sgh_toserver = NULL; \ (f)->sgh_toclient = NULL; \ AppLayerParserCleanupState(f); \ @@ -89,8 +94,13 @@ (f)->flowvar = NULL; \ (f)->protoctx = NULL; \ SC_ATOMIC_DESTROY((f)->use_cnt); \ - DetectEngineStateFree((f)->de_state); \ + SCMutexLock(&(f)->de_state_m); \ + if ((f)->de_state != NULL) { \ + DetectEngineStateFree((f)->de_state); \ + } \ (f)->de_state = NULL; \ + SCMutexUnlock(&(f)->de_state_m); \ + SCMutexDestroy(&(f)->de_state_m); \ AppLayerParserCleanupState(f); \ FlowL7DataPtrFree(f); \ SCFree((f)->aldata); \ diff --git a/src/flow.h b/src/flow.h index 281fc9bd2e..3a697c1ee2 100644 --- a/src/flow.h +++ b/src/flow.h @@ -174,6 +174,7 @@ typedef struct Flow_ /** detection engine state */ struct DetectEngineState_ *de_state; + SCMutex de_state_m; /**< mutex lock for the de_state object */ /** toclient sgh for this flow. Only use when FLOW_SGH_TOCLIENT flow flag * has been set. */