From 15ab5d70036249a0d251a9c936ba894ae140dfaf Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Wed, 28 Oct 2009 01:24:50 +0100 Subject: [PATCH] More engine init memleaks fixed. HashListTable remove function fixed. --- src/detect-engine-address.c | 18 ++- src/detect-engine-iponly.c | 34 +++-- src/detect-engine-iponly.h | 1 + src/detect-engine-port.c | 128 +++++----------- src/detect-engine-port.h | 1 + src/detect-engine-siggroup.c | 13 +- src/detect-engine-siggroup.h | 5 + src/detect-engine.c | 14 +- src/detect-ipproto.c | 6 + src/detect.c | 279 +++++++++++++++++++++++++++++------ src/detect.h | 4 +- src/util-hashlist.c | 31 +++- 12 files changed, 371 insertions(+), 163 deletions(-) diff --git a/src/detect-engine-address.c b/src/detect-engine-address.c index ad36d27389..565a02fccf 100644 --- a/src/detect-engine-address.c +++ b/src/detect-engine-address.c @@ -77,24 +77,34 @@ void DetectAddressGroupFree(DetectAddressGroup *ag) { if (ag == NULL) return; + SCLogDebug("ag %p", ag); + + SCLogDebug("- ag %p, ad %p", ag, ag->ad); if (ag->ad != NULL) { DetectAddressDataFree(ag->ad); } ag->ad = NULL; + SCLogDebug("- ag %p, sh %p", ag, ag->sh); /* only free the head if we have the original */ if (ag->sh != NULL && !(ag->flags & ADDRESS_GROUP_SIGGROUPHEAD_COPY)) { + SCLogDebug("- ag %p, sh %p not a copy, so call SigGroupHeadFree", ag, ag->sh); SigGroupHeadFree(ag->sh); } ag->sh = NULL; if (!(ag->flags & ADDRESS_GROUP_HAVEPORT)) { + SCLogDebug("- ag %p dst_gh %p", ag, ag->dst_gh); + if (ag->dst_gh != NULL) { DetectAddressGroupsHeadFree(ag->dst_gh); } ag->dst_gh = NULL; } else { - if (ag->port != NULL && !(ag->flags & PORT_GROUP_PORTS_COPY)) { + SCLogDebug("- ag %p port %p", ag, ag->port); + + if (ag->port != NULL && !(ag->flags & ADDRESS_GROUP_PORTS_COPY)) { + SCLogDebug("- ag %p port %p, not a copy so call DetectPortCleanupList", ag, ag->port); DetectPortCleanupList(ag->port); } ag->port = NULL; @@ -163,6 +173,8 @@ void DetectAddressGroupPrintList(DetectAddressGroup *head) { } void DetectAddressGroupCleanupList (DetectAddressGroup *head) { + //SCLogDebug("head %p", head); + if (head == NULL) return; @@ -903,6 +915,8 @@ DetectAddressGroupsHead *DetectAddressGroupsHeadInit(void) { } void DetectAddressGroupsHeadCleanup(DetectAddressGroupsHead *gh) { + //SCLogDebug("gh %p", gh); + if (gh != NULL) { DetectAddressGroupCleanupList(gh->any_head); gh->any_head = NULL; @@ -914,6 +928,8 @@ void DetectAddressGroupsHeadCleanup(DetectAddressGroupsHead *gh) { } void DetectAddressGroupsHeadFree(DetectAddressGroupsHead *gh) { + //SCLogDebug("gh %p", gh); + if (gh != NULL) { DetectAddressGroupsHeadCleanup(gh); free(gh); diff --git a/src/detect-engine-iponly.c b/src/detect-engine-iponly.c index 20eb04ba0c..c8bac581f2 100644 --- a/src/detect-engine-iponly.c +++ b/src/detect-engine-iponly.c @@ -79,7 +79,6 @@ static void IPOnlyAddSlash16(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ grtmp->cnt = 1; SigGroupHeadAppendSig(de_ctx, &grtmp->sh, s); - //printf(" -=- "); DetectAddressDataPrint(na); DetectAddressGroup *rgr = HashListTableLookup(ht,grtmp,0); if (rgr == NULL) { @@ -87,13 +86,11 @@ static void IPOnlyAddSlash16(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ HashListTableAdd(ht,grtmp,0); direction ? io_ctx->a_dst_uniq16++ : io_ctx->a_src_uniq16++; - //printf(" uniq\n"); } else { SigGroupHeadAppendSig(de_ctx, &rgr->sh, s); DetectAddressGroupFree(grtmp); direction ? io_ctx->a_dst_total16++ : io_ctx->a_src_total16++; - //printf(" dup\n"); } if (high >= 65536) @@ -101,8 +98,6 @@ static void IPOnlyAddSlash16(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ else high = 0; } - //printf(" contains %" PRIu32 " /16's\n", s16_cnt); - } else { DetectAddressGroup *grtmp = DetectAddressGroupInit(); if (grtmp == NULL) { @@ -117,8 +112,6 @@ static void IPOnlyAddSlash16(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ grtmp->ad = adtmp; grtmp->cnt = 1; - //SigGroupHeadAppendSig(de_ctx, &grtmp->sh, s); - DetectAddressGroup *rgr = HashListTableLookup(ht,grtmp,0); if (rgr == NULL) { SigGroupHeadAppendSig(de_ctx, &grtmp->sh, s); @@ -208,13 +201,22 @@ static char IPOnlyCompareFunc(void *data1, uint16_t len1, void *data2, uint16_t return 1; } + +static void IPOnlyFreeFunc(void *g) { + if (g == NULL) + return; + + DetectAddressGroup *ag = (DetectAddressGroup *)g; + DetectAddressGroupFree(ag); +} + /* XXX error checking */ void IPOnlyInit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx) { - io_ctx->ht16_src = HashListTableInit(65536, IPOnlyHashFunc16, IPOnlyCompareFunc, NULL); - io_ctx->ht16_dst = HashListTableInit(65536, IPOnlyHashFunc16, IPOnlyCompareFunc, NULL); + io_ctx->ht16_src = HashListTableInit(65536, IPOnlyHashFunc16, IPOnlyCompareFunc, IPOnlyFreeFunc); + io_ctx->ht16_dst = HashListTableInit(65536, IPOnlyHashFunc16, IPOnlyCompareFunc, IPOnlyFreeFunc); /* - io_ctx->ht24_src = HashListTableInit(65536, IPOnlyHashFunc24, IPOnlyCompareFunc, NULL); - io_ctx->ht24_dst = HashListTableInit(65536, IPOnlyHashFunc24, IPOnlyCompareFunc, NULL); + io_ctx->ht24_src = HashListTableInit(65536, IPOnlyHashFunc24, IPOnlyCompareFunc, IPOnlyFreeFunc); + io_ctx->ht24_dst = HashListTableInit(65536, IPOnlyHashFunc24, IPOnlyCompareFunc, IPOnlyFreeFunc); */ io_ctx->sig_init_size = DetectEngineGetMaxSigId(de_ctx) / 8 + 1; if ( (io_ctx->sig_init_array = malloc(io_ctx->sig_init_size)) == NULL) { @@ -272,6 +274,16 @@ void IPOnlyDeinit(DetectEngineCtx *de_ctx, DetectEngineIPOnlyCtx *io_ctx) { io_ctx->sig_init_array = NULL; } +void DetectEngineIPOnlyThreadDeinit(DetectEngineIPOnlyThreadCtx *io_tctx) { + if (io_tctx->src != NULL) { + DetectAddressGroupFree(io_tctx->src); + } + if (io_tctx->dst != NULL) { + DetectAddressGroupFree(io_tctx->dst); + } + free(io_tctx->sig_match_array); +} + DetectAddressGroup *IPOnlyLookupSrc16(DetectEngineCtx *de_ctx, DetectEngineIPOnlyThreadCtx *io_tctx, Packet *p) { io_tctx->src->ad->ip[0] = GET_IPV4_SRC_ADDR_U32(p) & 0x0000ffff; io_tctx->src->ad->ip2[0] = (GET_IPV4_SRC_ADDR_U32(p) & 0x0000ffff) | IPONLY_HTONL_65535; diff --git a/src/detect-engine-iponly.h b/src/detect-engine-iponly.h index 85db36aec9..cb36c71fb8 100644 --- a/src/detect-engine-iponly.h +++ b/src/detect-engine-iponly.h @@ -7,6 +7,7 @@ void IPOnlyPrint(DetectEngineCtx *, DetectEngineIPOnlyCtx *); void IPOnlyDeinit(DetectEngineCtx *, DetectEngineIPOnlyCtx *); void IPOnlyPrepare(DetectEngineCtx *); void DetectEngineIPOnlyThreadInit(DetectEngineCtx *, DetectEngineIPOnlyThreadCtx *); +void DetectEngineIPOnlyThreadDeinit(DetectEngineIPOnlyThreadCtx *); void IPOnlyAddSignature(DetectEngineCtx *, DetectEngineIPOnlyCtx *, Signature *); void IPOnlyRegisterTests(void); diff --git a/src/detect-engine-port.c b/src/detect-engine-port.c index 24f1012268..78862c9080 100644 --- a/src/detect-engine-port.c +++ b/src/detect-engine-port.c @@ -75,6 +75,8 @@ void DetectPortFree(DetectPort *dp) { } dp->dst_ph = NULL; + //BUG_ON(dp->next != NULL); + detect_port_memory -= sizeof(DetectPort); detect_port_free_cnt++; free(dp); @@ -109,17 +111,14 @@ void DetectPortPrintList(DetectPort *head) { DetectPort *cur; uint16_t cnt = 0; - printf("list:\n"); + SCLogDebug("= list start:"); if (head != NULL) { for (cur = head; cur != NULL; cur = cur->next) { - printf("SIGS %6u ", cur->sh ? cur->sh->sig_cnt : 0); - DetectPortPrint(cur); cnt++; - printf("\n"); } } - printf("endlist (cnt %" PRIu32 ")\n", cnt); + SCLogDebug("= list end (cnt %" PRIu32 ")", cnt); } void DetectPortCleanupList (DetectPort *head) { @@ -129,10 +128,10 @@ void DetectPortCleanupList (DetectPort *head) { DetectPort *cur, *next; for (cur = head; cur != NULL; ) { - next = cur->next; - - DetectPortFree(cur); - cur = next; + next = cur->next; + cur->next = NULL; + DetectPortFree(cur); + cur = next; } head = NULL; @@ -194,14 +193,8 @@ int DetectPortInsert(DetectEngineCtx *de_ctx, DetectPort **head, DetectPort *new if (new == NULL) return 0; -#ifdef DEBUG - SCLogDebug("head %p, new %p", head, new); - SCLogDebug("inserting (sig %" PRIu32 ")", new->sh ? new->sh->sig_cnt : 0); - if (SCLogDebugEnabled()) { - DetectPortPrint(new); - DetectPortPrintList(*head); - } -#endif + //BUG_ON(new->next != NULL); + //BUG_ON(new->prev != NULL); /* see if it already exists or overlaps with existing ag's */ if (*head != NULL) { @@ -210,14 +203,8 @@ int DetectPortInsert(DetectEngineCtx *de_ctx, DetectPort **head, DetectPort *new for (cur = *head; cur != NULL; cur = cur->next) { r = DetectPortCmp(new,cur); - if (r == PORT_ER) { - SCLogDebug("PORT_ER DetectPortCmp compared:"); - if (SCLogDebugEnabled()) { - DetectPortPrint(new); - DetectPortPrint(cur); - } - goto error; - } + BUG_ON(r == PORT_ER); + /* if so, handle that */ if (r == PORT_EQ) { SCLogDebug("PORT_EQ %p %p", cur, new); @@ -262,70 +249,27 @@ int DetectPortInsert(DetectEngineCtx *de_ctx, DetectPort **head, DetectPort *new /* alright, those were the simple cases, * lets handle the more complex ones now */ - } else if (r == PORT_ES) { - SCLogDebug("PORT_ES"); + } else { DetectPort *c = NULL; - r = DetectPortCut(de_ctx,cur,new,&c); + r = DetectPortCut(de_ctx, cur, new, &c); if (r == -1) goto error; - DetectPortInsert(de_ctx, head, new); - if (c != NULL) { - SCLogDebug("inserting C (%p)",c); - if (SCLogDebugEnabled()) { - DetectPortPrint(c); - } - DetectPortInsert(de_ctx, head, c); - } - return 1; - } else if (r == PORT_EB) { - SCLogDebug("PORT_EB"); - DetectPort *c = NULL; - r = DetectPortCut(de_ctx,cur,new,&c); + r = DetectPortInsert(de_ctx, head, new); if (r == -1) goto error; - DetectPortInsert(de_ctx, head, new); if (c != NULL) { - SCLogDebug("inserting C"); + SCLogDebug("inserting C (%p)", c); if (SCLogDebugEnabled()) { DetectPortPrint(c); } - DetectPortInsert(de_ctx, head, c); + r = DetectPortInsert(de_ctx, head, c); + if (r == -1) + goto error; } return 1; - } else if (r == PORT_LE) { - SCLogDebug("PORT_LE"); - DetectPort *c = NULL; - r = DetectPortCut(de_ctx,cur,new,&c); - if (r == -1) - goto error; - DetectPortInsert(de_ctx, head, new); - if (c != NULL) { - SCLogDebug("inserting C"); - if (SCLogDebugEnabled()) { - DetectPortPrint(c); - } - DetectPortInsert(de_ctx, head, c); - } - return 1; - } else if (r == PORT_GE) { - SCLogDebug("PORT_GE"); - DetectPort *c = NULL; - r = DetectPortCut(de_ctx,cur,new,&c); - if (r == -1) - goto error; - - DetectPortInsert(de_ctx, head, new); - if (c != NULL) { - SCLogDebug("inserting C"); - if (SCLogDebugEnabled()) { - DetectPortPrint(c); - } - DetectPortInsert(de_ctx, head, c); - } - return 1; } } @@ -389,16 +333,16 @@ static int DetectPortCut(DetectEngineCtx *de_ctx, DetectPort *a, DetectPort *b, if (tmp_c == NULL) { goto error; } + *c = tmp_c; tmp_c->port = a_port2 + 1; tmp_c->port2 = b_port2; - *c = tmp_c; SigGroupHeadCopySigs(de_ctx,b->sh,&tmp_c->sh); /* copy old b to c */ - SigGroupHeadCopySigs(de_ctx,a->sh,&b->sh); /* copy old b to a */ + SigGroupHeadCopySigs(de_ctx,a->sh,&b->sh); /* copy a to b */ tmp_c->cnt += b->cnt; - b->cnt += a->cnt; + b->cnt += a->cnt; /* we have 3 parts: [bbb[baba]aaa] * part a: b_port1 <-> a_port1 - 1 @@ -420,10 +364,10 @@ static int DetectPortCut(DetectEngineCtx *de_ctx, DetectPort *a, DetectPort *b, if (tmp_c == NULL) { goto error; } + *c = tmp_c; tmp_c->port = b_port2 + 1; tmp_c->port2 = a_port2; - *c = tmp_c; /* 'a' gets clean and then 'b' sigs * 'b' gets clean, then 'a' then 'b' sigs @@ -506,10 +450,10 @@ static int DetectPortCut(DetectEngineCtx *de_ctx, DetectPort *a, DetectPort *b, if (tmp_c == NULL) { goto error; } + *c = tmp_c; tmp_c->port = a_port2 + 1; tmp_c->port2 = b_port2; - *c = tmp_c; /* 'a' gets clean and then 'b' sigs * 'b' gets clean, then 'a' then 'b' sigs @@ -605,10 +549,10 @@ static int DetectPortCut(DetectEngineCtx *de_ctx, DetectPort *a, DetectPort *b, if (tmp_c == NULL) { goto error; } + *c = tmp_c; tmp_c->port = b_port2 + 1; tmp_c->port2 = a_port2; - *c = tmp_c; SigGroupHeadCopySigs(de_ctx,a->sh,&b->sh); SigGroupHeadCopySigs(de_ctx,a->sh,&tmp_c->sh); @@ -618,13 +562,12 @@ static int DetectPortCut(DetectEngineCtx *de_ctx, DetectPort *a, DetectPort *b, } } - /* XXX free tmp */ - if (tmp != NULL) + if (tmp != NULL) { DetectPortFree(tmp); + } return 0; error: - /* XXX free tmp */ if (tmp != NULL) DetectPortFree(tmp); return -1; @@ -779,9 +722,9 @@ void DetectPortPrint(DetectPort *dp) { return; if (dp->flags & PORT_FLAG_ANY) { - SCLogDebug("ANY"); + SCLogDebug("=> port %p: ANY", dp); } else { - SCLogDebug("%" PRIu32 "-%" PRIu32 "", dp->port, dp->port2); + SCLogDebug("=> port %p %" PRIu32 "-%" PRIu32 "", dp, dp->port, dp->port2); } } @@ -817,7 +760,7 @@ int DetectPortJoin(DetectEngineCtx *de_ctx, DetectPort *target, DetectPort *sour if (source->port2 > target->port2) target->port2 = source->port2; - return -1; + return 0; } /* parsing routines */ @@ -1102,7 +1045,7 @@ int DetectPortParse(DetectPort **head, char *str) { goto error; /* free the temp negate head */ - DetectPortFree(nhead); + DetectPortCleanupList(nhead); return 0; error: @@ -1204,10 +1147,15 @@ char DetectPortCompareFunc(void *data1, uint16_t len1, void *data2, uint16_t len return 0; } +void DetectPortFreeFunc(void *p) { + DetectPort *dp = (DetectPort *)p; + DetectPortFree(dp); +} + /* dp hash */ int DetectPortDpHashInit(DetectEngineCtx *de_ctx) { - de_ctx->dport_hash_table = HashListTableInit(PORT_HASH_SIZE, DetectPortHashFunc, DetectPortCompareFunc, NULL); + de_ctx->dport_hash_table = HashListTableInit(PORT_HASH_SIZE, DetectPortHashFunc, DetectPortCompareFunc, DetectPortFreeFunc); if (de_ctx->dport_hash_table == NULL) goto error; @@ -1241,7 +1189,7 @@ DetectPort *DetectPortDpHashLookup(DetectEngineCtx *de_ctx, DetectPort *p) { /* sp hash */ int DetectPortSpHashInit(DetectEngineCtx *de_ctx) { - de_ctx->sport_hash_table = HashListTableInit(PORT_HASH_SIZE, DetectPortHashFunc, DetectPortCompareFunc, NULL); + de_ctx->sport_hash_table = HashListTableInit(PORT_HASH_SIZE, DetectPortHashFunc, DetectPortCompareFunc, DetectPortFreeFunc); if (de_ctx->sport_hash_table == NULL) goto error; diff --git a/src/detect-engine-port.h b/src/detect-engine-port.h index 550b942a2c..cbf3908283 100644 --- a/src/detect-engine-port.h +++ b/src/detect-engine-port.h @@ -35,6 +35,7 @@ void DetectPortSpHashReset(DetectEngineCtx *); int DetectPortJoin(DetectEngineCtx *,DetectPort *target, DetectPort *source); void DetectPortPrint(DetectPort *); +void DetectPortPrintList(DetectPort *head); int DetectPortCmp(DetectPort *, DetectPort *); void DetectPortFree(DetectPort *); diff --git a/src/detect-engine-siggroup.c b/src/detect-engine-siggroup.c index 7ce1d51f72..6f20f51714 100644 --- a/src/detect-engine-siggroup.c +++ b/src/detect-engine-siggroup.c @@ -105,7 +105,7 @@ void SigGroupHeadFree(SigGroupHead *sgh) { } if (sgh->match_array != NULL) { - detect_siggroup_matcharray_init_cnt--; + detect_siggroup_matcharray_free_cnt++; detect_siggroup_matcharray_memory -= (sgh->sig_cnt * sizeof(uint32_t)); free(sgh->match_array); sgh->match_array = NULL; @@ -268,6 +268,10 @@ int SigGroupHeadHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) { return HashListTableAdd(de_ctx->sgh_hash_table, (void *)sgh, 0); } +int SigGroupHeadHashRemove(DetectEngineCtx *de_ctx, SigGroupHead *sgh) { + return HashListTableRemove(de_ctx->sgh_hash_table, (void *)sgh, 0); +} + SigGroupHead *SigGroupHeadHashLookup(DetectEngineCtx *de_ctx, SigGroupHead *sgh) { SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_hash_table, (void *)sgh, 0); return rsgh; @@ -328,6 +332,9 @@ int SigGroupHeadSPortHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh) { return HashListTableAdd(de_ctx->sgh_sport_hash_table, (void *)sgh, 0); } +int SigGroupHeadSPortHashRemove(DetectEngineCtx *de_ctx, SigGroupHead *sgh) { + return HashListTableRemove(de_ctx->sgh_sport_hash_table, (void *)sgh, 0); +} SigGroupHead *SigGroupHeadSPortHashLookup(DetectEngineCtx *de_ctx, SigGroupHead *sgh) { SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_sport_hash_table, (void *)sgh, 0); return rsgh; @@ -378,6 +385,8 @@ static void SigGroupHeadFreeSigArraysHash(DetectEngineCtx *de_ctx, HashListTable for (htb = HashListTableGetListHead(ht); htb != NULL; htb = HashListTableGetListNext(htb)) { SigGroupHead *sgh = (SigGroupHead *)HashListTableGetListData(htb); + SCLogDebug("sgh %p", sgh); + if (sgh->sig_array != NULL) { detect_siggroup_sigarray_free_cnt++; detect_siggroup_sigarray_memory -= sgh->sig_size; @@ -690,6 +699,8 @@ int SigGroupHeadBuildMatchArray (DetectEngineCtx *de_ctx, SigGroupHead *sgh, uin if (sgh == NULL) return 0; + BUG_ON(sgh->match_array != NULL); + sgh->match_array = malloc(sgh->sig_cnt * sizeof(uint32_t)); if (sgh->match_array == NULL) return -1; diff --git a/src/detect-engine-siggroup.h b/src/detect-engine-siggroup.h index 2ad0f5c3d4..ccad42a871 100644 --- a/src/detect-engine-siggroup.h +++ b/src/detect-engine-siggroup.h @@ -1,6 +1,8 @@ #ifndef __DETECT_ENGINE_SIGGROUP_H__ #define __DETECT_ENGINE_SIGGROUP_H__ +void DetectSigGroupPrintMemory(void); + int SigGroupHeadAppendSig(DetectEngineCtx *, SigGroupHead **, Signature *); int SigGroupHeadClearSigs(SigGroupHead *); int SigGroupHeadCopySigs(DetectEngineCtx *, SigGroupHead *, SigGroupHead **); @@ -38,6 +40,9 @@ int SigGroupHeadMpmUriHashInit(DetectEngineCtx *); int SigGroupHeadDPortHashInit(DetectEngineCtx *); int SigGroupHeadSPortHashInit(DetectEngineCtx *); +int SigGroupHeadHashRemove(DetectEngineCtx *, SigGroupHead *); +int SigGroupHeadSPortHashRemove(DetectEngineCtx *, SigGroupHead *); + void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx); int SigGroupHeadBuildMatchArray (DetectEngineCtx *de_ctx, SigGroupHead *sgh, uint32_t max_idx); void SigGroupHeadFreeSigArrays(DetectEngineCtx *de_ctx); diff --git a/src/detect-engine.c b/src/detect-engine.c index da7eb897d7..9f94644d8d 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -70,6 +70,10 @@ void DetectEngineCtxFree(DetectEngineCtx *de_ctx) { if (de_ctx->sig_array) free(de_ctx->sig_array); free(de_ctx); + + DetectAddressGroupPrintMemory(); + DetectSigGroupPrintMemory(); + DetectPortPrintMemory(); } /* @@ -105,8 +109,6 @@ TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data) { */ PatternMatchThreadPrepare(&det_ctx->mtc, de_ctx->mpm_matcher, DetectContentMaxId(de_ctx)); PatternMatchThreadPrepare(&det_ctx->mtcu, de_ctx->mpm_matcher, DetectUricontentMaxId(de_ctx)); - //mpm_ctx[0].InitThreadCtx(&mpm_ctx[0], &det_ctx->mtc, DetectContentMaxId(de_ctx)); - //mpm_ctx[0].InitThreadCtx(&mpm_ctx[0], &det_ctx->mtcu, DetectUricontentMaxId(de_ctx)); PmqSetup(&det_ctx->pmq, DetectEngineGetMaxSigId(de_ctx)); @@ -126,11 +128,13 @@ TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data) { TmEcode DetectEngineThreadCtxDeinit(ThreadVars *tv, void *data) { DetectEngineThreadCtx *det_ctx = (DetectEngineThreadCtx *)data; + DetectEngineIPOnlyThreadDeinit(&det_ctx->io_ctx); + /** \todo get rid of this static */ PatternMatchThreadDestroy(&det_ctx->mtc, det_ctx->de_ctx->mpm_matcher); PatternMatchThreadDestroy(&det_ctx->mtcu, det_ctx->de_ctx->mpm_matcher); - //mpm_ctx[0].DestroyThreadCtx(&mpm_ctx[0], &det_ctx->mtc); - //mpm_ctx[0].DestroyThreadCtx(&mpm_ctx[0], &det_ctx->mtcu); + + free(det_ctx); return TM_ECODE_OK; } @@ -139,7 +143,5 @@ void DetectEngineThreadCtxInfo(ThreadVars *t, DetectEngineThreadCtx *det_ctx) { /* XXX */ PatternMatchThreadPrint(&det_ctx->mtc, det_ctx->de_ctx->mpm_matcher); PatternMatchThreadPrint(&det_ctx->mtcu, det_ctx->de_ctx->mpm_matcher); - //mpm_ctx[0].PrintThreadCtx(&det_ctx->mtc); - //mpm_ctx[0].PrintThreadCtx(&det_ctx->mtcu); } diff --git a/src/detect-ipproto.c b/src/detect-ipproto.c index 594c2442d5..67109ed388 100644 --- a/src/detect-ipproto.c +++ b/src/detect-ipproto.c @@ -18,6 +18,9 @@ #include "detect-engine.h" #include "detect-engine-mpm.h" +#include "detect-engine-siggroup.h" +#include "detect-engine-address.h" + #include "util-byte.h" #include "util-unittest.h" @@ -587,6 +590,9 @@ cleanup: DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineCtxFree(de_ctx); + DetectSigGroupPrintMemory(); + DetectAddressGroupPrintMemory(); + end: return result; } diff --git a/src/detect.c b/src/detect.c index d8319e864a..1d6d480c6b 100644 --- a/src/detect.c +++ b/src/detect.c @@ -665,7 +665,7 @@ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) { uint32_t cnt_payload = 0; //DetectAddressGroupPrintMemory(); - //DetectSigGroupPrintMemory(); + DetectSigGroupPrintMemory(); //DetectPortPrintMemory(); if (!(de_ctx->flags & DE_QUIET)) { @@ -755,7 +755,7 @@ int SigAddressPrepareStage1(DetectEngineCtx *de_ctx) { } //DetectAddressGroupPrintMemory(); - //DetectSigGroupPrintMemory(); + DetectSigGroupPrintMemory(); //DetectPortPrintMemory(); if (!(de_ctx->flags & DE_QUIET)) { @@ -827,6 +827,7 @@ static int DetectEngineLookupBuildSourceAddressList(DetectEngineCtx *de_ctx, Det } } } + SCLogDebug("calling SigGroupHeadFree gr %p, gr->sh %p", gr, gr->sh); SigGroupHeadFree(gr->sh); gr->sh = NULL; } @@ -1074,6 +1075,7 @@ int CreateGroupedAddrList(DetectEngineCtx *de_ctx, DetectAddressGroup *srchead, DetectPort *port = gr->port; for ( ; port != NULL; port = port->next) { DetectPortInsertCopy(de_ctx,&newtmp->port, port); + newtmp->flags |= ADDRESS_GROUP_HAVEPORT; } /* insert it */ @@ -1127,6 +1129,7 @@ int CreateGroupedAddrList(DetectEngineCtx *de_ctx, DetectAddressGroup *srchead, DetectPort *port = gr->port; for ( ; port != NULL; port = port->next) { DetectPortInsertCopy(de_ctx,&joingr->port, port); + joingr->flags |= ADDRESS_GROUP_HAVEPORT; } } else { DetectAddressGroupJoin(de_ctx, joingr, gr); @@ -1148,6 +1151,7 @@ int CreateGroupedAddrList(DetectEngineCtx *de_ctx, DetectAddressGroup *srchead, DetectPort *port = gr->port; for ( ; port != NULL; port = port->next) { DetectPortInsertCopy(de_ctx,&newtmp->port, port); + newtmp->flags |= ADDRESS_GROUP_HAVEPORT; } if (tmplist2 == NULL) { @@ -1186,6 +1190,7 @@ int CreateGroupedAddrList(DetectEngineCtx *de_ctx, DetectAddressGroup *srchead, DetectPort *port = gr->port; for ( ; port != NULL; port = port->next) { DetectPortInsertCopy(de_ctx, &newtmp->port, port); + newtmp->flags |= ADDRESS_GROUP_HAVEPORT; } DetectAddressGroupInsert(de_ctx, newhead, newtmp); @@ -1239,19 +1244,18 @@ int CreateGroupedPortList(DetectEngineCtx *de_ctx,HashListTable *port_hash, Dete * be sorted descending on 'cnt'. */ for ( ; htb != NULL; htb = HashListTableGetListNext(htb)) { gr = (DetectPort *)HashListTableGetListData(htb); - SigGroupHeadSetMpmMaxlen(de_ctx, gr->sh); + SCLogDebug("hash list gr %p", gr); + DetectPortPrint(gr); + + SigGroupHeadSetMpmMaxlen(de_ctx, gr->sh); if (SMALL_MPM(gr->sh->mpm_content_maxlen) && unique_groups > 0) unique_groups++; groups++; -#if 0//def DEBUG - if (SCLogDebugEnabled()) { - printf(" -= 1:Port "); DetectPortPrint(gr); printf(" : "); DbgPrintSigs2(de_ctx, gr->sh); - } -#endif + /* alloc a copy */ - DetectPort *newtmp = DetectPortCopySingle(de_ctx,gr); + DetectPort *newtmp = DetectPortCopySingle(de_ctx, gr); if (newtmp == NULL) { goto error; } @@ -1265,7 +1269,6 @@ int CreateGroupedPortList(DetectEngineCtx *de_ctx,HashListTable *port_hash, Dete /* look for the place to insert */ for ( ; tmpgr != NULL&&!insert; tmpgr = tmpgr->next) { if (CompareFunc(gr, tmpgr)) { - //if (gr->cnt > tmpgr->cnt) { if (tmpgr == tmplist) { newtmp->next = tmplist; tmplist = newtmp; @@ -1294,6 +1297,9 @@ int CreateGroupedPortList(DetectEngineCtx *de_ctx,HashListTable *port_hash, Dete g_groupportlist_totgroups += unique_groups; for (gr = tmplist; gr != NULL; ) { + SCLogDebug("temp list gr %p", gr); + DetectPortPrint(gr); + if (i == 0) { if (joingr == NULL) { joingr = DetectPortCopySingle(de_ctx,gr); @@ -1319,6 +1325,7 @@ int CreateGroupedPortList(DetectEngineCtx *de_ctx,HashListTable *port_hash, Dete if (i)i--; next_gr = gr->next; + gr->next = NULL; DetectPortFree(gr); gr = next_gr; } @@ -1329,32 +1336,33 @@ int CreateGroupedPortList(DetectEngineCtx *de_ctx,HashListTable *port_hash, Dete * * Start with inserting the unique groups */ for (gr = tmplist2; gr != NULL; ) { - //printf(":-:7:-: Unique Port "); DetectPortPrint(gr); printf(" (cnt %" PRIu32 ", cost %" PRIu32 ") ", gr->cnt, gr->sh->cost); DbgSghContainsSig(de_ctx,gr->sh,2001330); + SCLogDebug("temp list2 gr %p", gr); + DetectPortPrint(gr); + DetectPort *newtmp = DetectPortCopySingle(de_ctx,gr); if (newtmp == NULL) { goto error; } - DetectPortInsert(de_ctx,newhead,newtmp); + int r = DetectPortInsert(de_ctx,newhead,newtmp); + BUG_ON(r == -1); next_gr = gr->next; + gr->next = NULL; DetectPortFree(gr); gr = next_gr; } + + DetectPortPrintList(*newhead); + /* if present, insert the joingr that covers the rest */ if (joingr != NULL) { - //printf(":-:8:-: Join Port "); DetectPortPrint(joingr); printf(" (cnt %" PRIu32 ", cost %" PRIu32 ") ", joingr->cnt, joingr->sh->cost); DbgSghContainsSig(de_ctx,joingr->sh,2001330); + SCLogDebug("inserting joingr %p", joingr); DetectPortInsert(de_ctx,newhead,joingr); + } else { + SCLogDebug("no joingr"); } -#if 0//def DEBUG - if (SCLogDebugEnabled()) { - for (gr = *newhead; gr != NULL; gr = gr->next) { - //printf(":-:9:-: Port "); DetectPortPrint(gr); printf(" (cnt %" PRIu32 "", gr->cnt); DbgSghContainsSig(de_ctx,gr->sh,489); - printf(" -= 9:Port "); DetectPortPrint(gr); printf(" : "); DbgPrintSigs2(de_ctx, gr->sh); - } - } -#endif return 0; error: return -1; @@ -1554,7 +1562,7 @@ error: return -1; } -static int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressGroupsHead *head, int family, int dsize, int flow) { +int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressGroupsHead *head, int family, int dsize, int flow) { Signature *tmp_s = NULL; DetectAddressGroup *gr = NULL, *sgr = NULL, *lookup_gr = NULL; uint32_t max_idx = 0; @@ -1708,17 +1716,20 @@ static int BuildDestinationAddressHeads(DetectEngineCtx *de_ctx, DetectAddressGr SigGroupHeadHashAdd(de_ctx, sgr->sh); de_ctx->gh_unique++; } else { + SCLogDebug("calling SigGroupHeadFree sgr %p, sgr->sh %p", sgr, sgr->sh); SigGroupHeadFree(sgr->sh); sgr->sh = sgh; de_ctx->gh_reuse++; sgr->flags |= ADDRESS_GROUP_SIGGROUPHEAD_COPY; + sgr->sh->refcnt++; } } /* free the temp list */ DetectAddressGroupCleanupList(tmp_gr_list); /* clear now unneeded sig group head */ + SCLogDebug("calling SigGroupHeadFree gr %p, gr->sh %p", gr, gr->sh); SigGroupHeadFree(gr->sh); gr->sh = NULL; } @@ -1788,6 +1799,7 @@ static int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, De lookup_gr->cnt++; } + SCLogDebug("calling SigGroupHeadFree sig_gr %p, sig_gr->sh %p", sig_gr, sig_gr->sh); SigGroupHeadFree(sig_gr->sh); sig_gr->sh = NULL; } @@ -1805,6 +1817,8 @@ static int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, De for (dst_gr = dst_gr_head; dst_gr != NULL; dst_gr = dst_gr->next) { //printf(" * Destination group: "); DetectAddressDataPrint(dst_gr->ad); printf("\n"); + dst_gr->flags |= ADDRESS_GROUP_HAVEPORT; + if (dst_gr->sh == NULL) continue; @@ -1847,7 +1861,6 @@ static int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, De int spgroups = dsize ? (flow ? MAX_UNIQ_TOSERVER_SP_GROUPS : MAX_UNIQ_TOCLIENT_SP_GROUPS) : (flow ? MAX_UNIQ_SMALL_TOSERVER_SP_GROUPS : MAX_UNIQ_SMALL_TOCLIENT_SP_GROUPS); CreateGroupedPortList(de_ctx, de_ctx->sport_hash_table, &dst_gr->port, spgroups, CreateGroupedPortListCmpMpmMaxlen, max_idx); - dst_gr->flags |= ADDRESS_GROUP_HAVEPORT; SigGroupHeadHashAdd(de_ctx, dst_gr->sh); @@ -1915,9 +1928,6 @@ static int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, De /* for each destination port we setup the siggrouphead here */ DetectPort *dp = sp->dst_ph; for ( ; dp != NULL; dp = dp->next) { - //printf(" * Dst Port(range): "); DetectPortPrint(dp); printf(" "); - //printf("\n"); - if (dp->sh == NULL) continue; @@ -1926,6 +1936,8 @@ static int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, De * another group head. */ SigGroupHead *lookup_dp_sgh = SigGroupHeadDPortHashLookup(de_ctx, dp->sh); if (lookup_dp_sgh == NULL) { + SCLogDebug("dp %p dp->sh %p is the original (sp %p, dst_gr %p, src_gr %p)", dp, dp->sh, sp, dst_gr, src_gr); + SigGroupHeadSetSigCnt(dp->sh, max_idx); SigGroupHeadBuildMatchArray(de_ctx,dp->sh, max_idx); @@ -1998,10 +2010,12 @@ static int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, De SigGroupHeadDPortHashAdd(de_ctx, dp->sh); de_ctx->gh_unique++; } else { - SigGroupHeadFree(dp->sh); + SCLogDebug("dp %p dp->sh %p is a copy", dp, dp->sh); + SigGroupHeadFree(dp->sh); dp->sh = lookup_dp_sgh; dp->flags |= PORT_SIGGROUPHEAD_COPY; + dp->sh->refcnt++; de_ctx->gh_reuse++; } @@ -2009,10 +2023,12 @@ static int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, De /* sig group head found in hash, free it and use the hashed one */ } else { SigGroupHeadFree(sp->sh); - sp->sh = lookup_sp_sgh; sp->flags |= PORT_SIGGROUPHEAD_COPY; + sp->sh->refcnt++; + SCLogDebug("replacing sp->dst_ph %p with lookup_sp_sgh->port %p", sp->dst_ph, lookup_sp_sgh->port); + DetectPortCleanupList(sp->dst_ph); sp->dst_ph = lookup_sp_sgh->port; sp->flags |= PORT_GROUP_PORTS_COPY; @@ -2021,21 +2037,54 @@ static int BuildDestinationAddressHeadsWithBothPorts(DetectEngineCtx *de_ctx, De } } else { SigGroupHeadFree(dst_gr->sh); - dst_gr->sh = lookup_sgh; dst_gr->flags |= ADDRESS_GROUP_SIGGROUPHEAD_COPY; + dst_gr->sh->refcnt++; + SCLogDebug("replacing dst_gr->port %p with lookup_sgh->port %p", dst_gr->port, lookup_sgh->port); + DetectPortCleanupList(dst_gr->port); dst_gr->port = lookup_sgh->port; - dst_gr->flags |= PORT_GROUP_PORTS_COPY; + dst_gr->flags |= ADDRESS_GROUP_PORTS_COPY; de_ctx->gh_reuse++; } + + /* free source port sgh's */ + if (!(dst_gr->flags & ADDRESS_GROUP_PORTS_COPY)) { + DetectPort *sp = dst_gr->port; + for ( ; sp != NULL; sp = sp->next) { + if (!(sp->flags & PORT_SIGGROUPHEAD_COPY)) { + if (sp->sh->refcnt == 0) { + if (SigGroupHeadHashRemove(de_ctx,sp->sh) == 0 && + SigGroupHeadSPortHashRemove(de_ctx,sp->sh) == 0) { + //printf("BothPorts: removed sgh %p\n", sp->sh); + SigGroupHeadFree(sp->sh); + sp->sh = NULL; + } + } + } + } + } } /* free the temp list */ DetectAddressGroupCleanupList(tmp_gr_list); /* clear now unneeded sig group head */ SigGroupHeadFree(src_gr->sh); src_gr->sh = NULL; + + /* free dst addr sgh's */ + dst_gr_head = GetHeadPtr(src_gr->dst_gh,family); + for (dst_gr = dst_gr_head; dst_gr != NULL; dst_gr = dst_gr->next) { + if (!(dst_gr->flags & ADDRESS_GROUP_SIGGROUPHEAD_COPY)) { + if (dst_gr->sh->refcnt == 0) { + if (SigGroupHeadHashRemove(de_ctx,dst_gr->sh) == 0) { + //printf("BothPorts: removed sgh %p\n", dst_gr->sh); + SigGroupHeadFree(dst_gr->sh); + dst_gr->sh = NULL; + } + } + } + } } return 0; @@ -2054,7 +2103,8 @@ int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) { //DetectSigGroupPrintMemory(); //DetectPortPrintMemory(); - int ds, f, proto; + int ds = 0, f = 0; + int proto; for (ds = 0; ds < DSIZE_STATES; ds++) { for (f = 0; f < FLOW_STATES; f++) { r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->dsize_gh[ds].flow_gh[f].src_gh[6],AF_INET,ds,f); @@ -2062,6 +2112,7 @@ int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) { printf ("BuildDestinationAddressHeads(src_gh[6],AF_INET) failed\n"); goto error; } +//#if 0 r = BuildDestinationAddressHeadsWithBothPorts(de_ctx, de_ctx->dsize_gh[ds].flow_gh[f].src_gh[17],AF_INET,ds,f); if (r < 0) { printf ("BuildDestinationAddressHeads(src_gh[17],AF_INET) failed\n"); @@ -2110,6 +2161,7 @@ int SigAddressPrepareStage3(DetectEngineCtx *de_ctx) { } } } +//#endif /* cleanup group head (uri)content_array's */ SigGroupHeadFreeMpmArrays(de_ctx); @@ -2531,6 +2583,7 @@ int SigGroupBuild (DetectEngineCtx *de_ctx) { int SigGroupCleanup (DetectEngineCtx *de_ctx) { SigAddressCleanupStage1(de_ctx); + return 0; } @@ -2645,7 +2698,6 @@ static int SigTest01Real (int mpm_type) { } SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, mpm_type); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, &p); @@ -2666,10 +2718,8 @@ static int SigTest01Real (int mpm_type) { } SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); DetectEngineCtxFree(de_ctx); end: return result; @@ -3331,7 +3381,6 @@ static int SigTest11Real (int mpm_type) { } SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, mpm_type); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, &p); @@ -3341,9 +3390,7 @@ static int SigTest11Real (int mpm_type) { result = 0; SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); DetectEngineCtxFree(de_ctx); end: return result; @@ -3632,7 +3679,6 @@ static int SigTest16Real (int mpm_type) { } SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, mpm_type); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, &p); @@ -3642,9 +3688,7 @@ static int SigTest16Real (int mpm_type) { printf("sid:2008284 %s: ", PacketAlertCheck(&p, 2008284) ? "OK" : "FAIL"); SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); DetectEngineCtxFree(de_ctx); end: return result; @@ -3698,7 +3742,6 @@ static int SigTest17Real (int mpm_type) { } SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, mpm_type); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, &p); @@ -3719,7 +3762,6 @@ static int SigTest17Real (int mpm_type) { SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); DetectEngineCtxFree(de_ctx); end: return result; @@ -3769,7 +3811,6 @@ static int SigTest18Real (int mpm_type) { } SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, mpm_type); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, &p); @@ -3781,7 +3822,6 @@ static int SigTest18Real (int mpm_type) { SigGroupCleanup(de_ctx); SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); DetectEngineCtxFree(de_ctx); end: return result; @@ -3834,9 +3874,7 @@ int SigTest19Real (int mpm_type) { } SigGroupBuild(de_ctx); - //PatternMatchPrepare(mpm_ctx, mpm_type); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx,(void *)&det_ctx); - //DetectEngineIPOnlyThreadInit(de_ctx,&det_ctx->io_ctx); SigMatchSignatures(&th_v, de_ctx, det_ctx, &p); if (PacketAlertCheck(&p, 999)) @@ -3845,9 +3883,7 @@ int SigTest19Real (int mpm_type) { printf("signature didn't match, but should have: "); SigGroupCleanup(de_ctx); - SigCleanSignatures(de_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); - //PatternMatchDestroy(mpm_ctx); DetectEngineCtxFree(de_ctx); end: return result; @@ -6397,6 +6433,149 @@ end: return result; } +static int SigTestMemory01 (void) { + uint8_t *buf = (uint8_t *) + "GET /one/ HTTP/1.1\r\n" + "Host: one.example.org\r\n" + "\r\n\r\n" + "GET /two/ HTTP/1.1\r\n" + "Host: two.example.org\r\n" + "\r\n\r\n"; + uint16_t buflen = strlen((char *)buf); + Packet p; + ThreadVars th_v; + DetectEngineThreadCtx *det_ctx; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + memset(&p, 0, sizeof(p)); + p.src.family = AF_INET; + p.dst.family = AF_INET; + p.payload = buf; + p.payload_len = buflen; + p.proto = IPPROTO_TCP; + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any any (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; recursive; sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + + SigGroupBuild(de_ctx); + DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); + +printf("@pre cleanup\n\n"); + DetectSigGroupPrintMemory(); + DetectAddressGroupPrintMemory(); + DetectPortPrintMemory(); + + SigGroupCleanup(de_ctx); + DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); + DetectEngineCtxFree(de_ctx); + +printf("@exit\n\n"); + DetectSigGroupPrintMemory(); + DetectAddressGroupPrintMemory(); + DetectPortPrintMemory(); + + result = 1; +end: + return result; +} + +static int SigTestMemory02 (void) { + ThreadVars th_v; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 456 (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; recursive; sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> any 1:1000 (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; recursive; sid:2;)"); + if (de_ctx->sig_list->next == NULL) { + result = 0; + goto end; + } + + SigGroupBuild(de_ctx); + +printf("@cleanup\n\n"); + SigGroupCleanup(de_ctx); + DetectEngineCtxFree(de_ctx); + +printf("@exit\n\n"); + DetectSigGroupPrintMemory(); + DetectAddressGroupPrintMemory(); + DetectPortPrintMemory(); +printf("@exit\n\n"); + DetectSigGroupPrintMemory(); + DetectAddressGroupPrintMemory(); + DetectPortPrintMemory(); + + result = 1; +end: + return result; +} + +static int SigTestMemory03 (void) { + ThreadVars th_v; + int result = 0; + + memset(&th_v, 0, sizeof(th_v)); + + DetectEngineCtx *de_ctx = DetectEngineCtxInit(); + if (de_ctx == NULL) { + goto end; + } + de_ctx->flags |= DE_QUIET; + + de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> 1.2.3.4 456 (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; recursive; sid:1;)"); + if (de_ctx->sig_list == NULL) { + result = 0; + goto end; + } + de_ctx->sig_list->next = SigInit(de_ctx,"alert tcp any any -> 1.2.3.3-1.2.3.6 1:1000 (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; recursive; sid:2;)"); + if (de_ctx->sig_list->next == NULL) { + result = 0; + goto end; + } + de_ctx->sig_list->next->next = SigInit(de_ctx,"alert tcp any any -> !1.2.3.5 1:990 (msg:\"HTTP URI cap\"; content:\"GET \"; depth:4; pcre:\"/GET (?P.*) HTTP\\/\\d\\.\\d\\r\\n/G\"; recursive; sid:3;)"); + if (de_ctx->sig_list->next->next == NULL) { + result = 0; + goto end; + } + + SigGroupBuild(de_ctx); + +printf("@cleanup\n\n"); + SigGroupCleanup(de_ctx); + DetectEngineCtxFree(de_ctx); + +printf("@exit\n\n"); + DetectSigGroupPrintMemory(); + DetectAddressGroupPrintMemory(); + DetectPortPrintMemory(); + + result = 1; +end: + return result; +} #endif /* UNITTESTS */ void SigRegisterTests(void) { @@ -6554,6 +6733,10 @@ void SigRegisterTests(void) { UtRegisterTest("SigTest40NoPacketInspection01", SigTest40NoPacketInspection01, 1); UtRegisterTest("SigTest40NoPayloadInspection02", SigTest40NoPayloadInspection02, 1); + + UtRegisterTest("SigTestMemory01", SigTestMemory01, 1); + UtRegisterTest("SigTestMemory02", SigTestMemory02, 1); + UtRegisterTest("SigTestMemory03", SigTestMemory03, 1); #endif /* UNITTESTS */ } diff --git a/src/detect.h b/src/detect.h index fb753d566b..18467a5b16 100644 --- a/src/detect.h +++ b/src/detect.h @@ -348,7 +348,7 @@ typedef struct SigGroupHead_ { uint8_t flags; /* pattern matcher instance */ - MpmCtx *mpm_ctx; /* search */ + MpmCtx *mpm_ctx; uint16_t mpm_content_maxlen; MpmCtx *mpm_uri_ctx; uint16_t mpm_uricontent_maxlen; @@ -379,6 +379,8 @@ typedef struct SigGroupHead_ { uint16_t mpm_len2; uint16_t mpm_len3; uint16_t mpm_len4; /* 4+ */ + + uint32_t refcnt; } SigGroupHead; /** sigmatch has no options, so the parser shouldn't expect any */ diff --git a/src/util-hashlist.c b/src/util-hashlist.c index 446133f724..9e06fa095a 100644 --- a/src/util-hashlist.c +++ b/src/util-hashlist.c @@ -134,14 +134,35 @@ int HashListTableRemove(HashListTable *ht, void *data, uint16_t datalen) { return -1; } + /* fast track for just one data part */ if (ht->array[hash]->bucknext == NULL) { - if (ht->Free != NULL) - ht->Free(ht->array[hash]->data); - free(ht->array[hash]); - ht->array[hash] = NULL; - return 0; + HashListTableBucket *hb = ht->array[hash]; + + if (ht->Compare(hb->data,hb->size,data,datalen) == 1) { + /* remove from the list */ + if (hb->listprev == NULL) { + ht->listhead = hb->listnext; + } else { + hb->listprev->listnext = hb->listnext; + } + if (hb->listnext == NULL) { + ht->listtail = hb->listprev; + } else { + hb->listnext->listprev = hb->listprev; + } + + if (ht->Free != NULL) + ht->Free(hb->data); + + free(ht->array[hash]); + ht->array[hash] = NULL; + return 0; + } + + return -1; } + /* more data in this bucket */ HashListTableBucket *hashbucket = ht->array[hash], *prev_hashbucket = NULL; do { if (ht->Compare(hashbucket->data,hashbucket->size,data,datalen) == 1) {