|
|
|
@ -65,18 +65,6 @@ static uint32_t detect_siggroup_matcharray_memory = 0;
|
|
|
|
|
static uint32_t detect_siggroup_matcharray_init_cnt = 0;
|
|
|
|
|
static uint32_t detect_siggroup_matcharray_free_cnt = 0;
|
|
|
|
|
|
|
|
|
|
static SigGroupHeadInitData *SigGroupHeadInitDataAlloc(uint32_t size) {
|
|
|
|
|
SigGroupHeadInitData *sghid = SCMalloc(sizeof(SigGroupHeadInitData));
|
|
|
|
|
if (sghid == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
memset(sghid, 0x00, sizeof(SigGroupHeadInitData));
|
|
|
|
|
|
|
|
|
|
detect_siggroup_head_initdata_init_cnt++;
|
|
|
|
|
detect_siggroup_head_initdata_memory += sizeof(SigGroupHeadInitData);
|
|
|
|
|
return sghid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SigGroupHeadInitDataFree(SigGroupHeadInitData *sghid) {
|
|
|
|
|
if (sghid->content_array != NULL) {
|
|
|
|
|
SCFree(sghid->content_array);
|
|
|
|
@ -88,12 +76,59 @@ void SigGroupHeadInitDataFree(SigGroupHeadInitData *sghid) {
|
|
|
|
|
sghid->uri_content_array = NULL;
|
|
|
|
|
sghid->uri_content_size = 0;
|
|
|
|
|
}
|
|
|
|
|
if (sghid->sig_array != NULL) {
|
|
|
|
|
SCFree(sghid->sig_array);
|
|
|
|
|
sghid->sig_array = NULL;
|
|
|
|
|
|
|
|
|
|
detect_siggroup_sigarray_free_cnt++;
|
|
|
|
|
detect_siggroup_sigarray_memory -= sghid->sig_size;
|
|
|
|
|
}
|
|
|
|
|
SCFree(sghid);
|
|
|
|
|
|
|
|
|
|
detect_siggroup_head_initdata_free_cnt++;
|
|
|
|
|
detect_siggroup_head_initdata_memory -= sizeof(SigGroupHeadInitData);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static SigGroupHeadInitData *SigGroupHeadInitDataAlloc(uint32_t size) {
|
|
|
|
|
SigGroupHeadInitData *sghid = SCMalloc(sizeof(SigGroupHeadInitData));
|
|
|
|
|
if (sghid == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
memset(sghid, 0x00, sizeof(SigGroupHeadInitData));
|
|
|
|
|
|
|
|
|
|
detect_siggroup_head_initdata_init_cnt++;
|
|
|
|
|
detect_siggroup_head_initdata_memory += sizeof(SigGroupHeadInitData);
|
|
|
|
|
|
|
|
|
|
/* initialize the signature bitarray */
|
|
|
|
|
sghid->sig_size = size;
|
|
|
|
|
if ( (sghid->sig_array = SCMalloc(sghid->sig_size)) == NULL)
|
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
|
|
memset(sghid->sig_array, 0, sghid->sig_size);
|
|
|
|
|
|
|
|
|
|
detect_siggroup_sigarray_init_cnt++;
|
|
|
|
|
detect_siggroup_sigarray_memory += sghid->sig_size;
|
|
|
|
|
|
|
|
|
|
return sghid;
|
|
|
|
|
error:
|
|
|
|
|
SigGroupHeadInitDataFree(sghid);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SigGroupHeadStore(DetectEngineCtx *de_ctx, SigGroupHead *sgh) {
|
|
|
|
|
//printf("de_ctx->sgh_array_cnt %u, de_ctx->sgh_array_size %u, de_ctx->sgh_array %p\n", de_ctx->sgh_array_cnt, de_ctx->sgh_array_size, de_ctx->sgh_array);
|
|
|
|
|
if (de_ctx->sgh_array_cnt < de_ctx->sgh_array_size) {
|
|
|
|
|
de_ctx->sgh_array[de_ctx->sgh_array_cnt] = sgh;
|
|
|
|
|
} else {
|
|
|
|
|
de_ctx->sgh_array = SCRealloc(de_ctx->sgh_array, sizeof(SigGroupHead *) * (16 + de_ctx->sgh_array_size));
|
|
|
|
|
if (de_ctx->sgh_array == NULL)
|
|
|
|
|
return;
|
|
|
|
|
de_ctx->sgh_array_size += 10;
|
|
|
|
|
de_ctx->sgh_array[de_ctx->sgh_array_cnt] = sgh;
|
|
|
|
|
}
|
|
|
|
|
de_ctx->sgh_array_cnt++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Alloc a SigGroupHead and its signature bit_array.
|
|
|
|
|
*
|
|
|
|
@ -103,7 +138,7 @@ void SigGroupHeadInitDataFree(SigGroupHeadInitData *sghid) {
|
|
|
|
|
* \retval sgh Pointer to the newly init SigGroupHead on success; or NULL in
|
|
|
|
|
* case of error.
|
|
|
|
|
*/
|
|
|
|
|
static SigGroupHead *SigGroupHeadAlloc(uint32_t size)
|
|
|
|
|
static SigGroupHead *SigGroupHeadAlloc(DetectEngineCtx *de_ctx, uint32_t size)
|
|
|
|
|
{
|
|
|
|
|
SigGroupHead *sgh = SCMalloc(sizeof(SigGroupHead));
|
|
|
|
|
if (sgh == NULL)
|
|
|
|
@ -117,15 +152,6 @@ static SigGroupHead *SigGroupHeadAlloc(uint32_t size)
|
|
|
|
|
detect_siggroup_head_init_cnt++;
|
|
|
|
|
detect_siggroup_head_memory += sizeof(SigGroupHead);
|
|
|
|
|
|
|
|
|
|
/* initialize the signature bitarray */
|
|
|
|
|
sgh->sig_size = size;
|
|
|
|
|
if ( (sgh->sig_array = SCMalloc(sgh->sig_size)) == NULL)
|
|
|
|
|
goto error;
|
|
|
|
|
memset(sgh->sig_array, 0, sgh->sig_size);
|
|
|
|
|
|
|
|
|
|
detect_siggroup_sigarray_init_cnt++;
|
|
|
|
|
detect_siggroup_sigarray_memory += sgh->sig_size;
|
|
|
|
|
|
|
|
|
|
return sgh;
|
|
|
|
|
|
|
|
|
|
error:
|
|
|
|
@ -148,14 +174,6 @@ void SigGroupHeadFree(SigGroupHead *sgh)
|
|
|
|
|
|
|
|
|
|
PatternMatchDestroyGroup(sgh);
|
|
|
|
|
|
|
|
|
|
if (sgh->sig_array != NULL) {
|
|
|
|
|
SCFree(sgh->sig_array);
|
|
|
|
|
sgh->sig_array = NULL;
|
|
|
|
|
|
|
|
|
|
detect_siggroup_sigarray_free_cnt++;
|
|
|
|
|
detect_siggroup_sigarray_memory -= sgh->sig_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sgh->match_array != NULL) {
|
|
|
|
|
detect_siggroup_matcharray_free_cnt++;
|
|
|
|
|
detect_siggroup_matcharray_memory -= (sgh->sig_cnt * sizeof(Signature *));
|
|
|
|
@ -575,11 +593,11 @@ uint32_t SigGroupHeadHashFunc(HashListTable *ht, void *data, uint16_t datalen)
|
|
|
|
|
|
|
|
|
|
SCLogDebug("hashing sgh %p (mpm_content_maxlen %u)", sgh, sgh->mpm_content_maxlen);
|
|
|
|
|
|
|
|
|
|
for (b = 0; b < sgh->sig_size; b++)
|
|
|
|
|
hash += sgh->sig_array[b];
|
|
|
|
|
for (b = 0; b < sgh->init->sig_size; b++)
|
|
|
|
|
hash += sgh->init->sig_array[b];
|
|
|
|
|
|
|
|
|
|
hash %= ht->array_size;
|
|
|
|
|
SCLogDebug("hash %"PRIu32" (sig_size %"PRIu32")", hash, sgh->sig_size);
|
|
|
|
|
SCLogDebug("hash %"PRIu32" (sig_size %"PRIu32")", hash, sgh->init->sig_size);
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -604,10 +622,10 @@ char SigGroupHeadCompareFunc(void *data1, uint16_t len1, void *data2,
|
|
|
|
|
if (data1 == NULL || data2 == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (sgh1->sig_size != sgh2->sig_size)
|
|
|
|
|
if (sgh1->init->sig_size != sgh2->init->sig_size)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (memcmp(sgh1->sig_array, sgh2->sig_array, sgh1->sig_size) != 0)
|
|
|
|
|
if (memcmp(sgh1->init->sig_array, sgh2->init->sig_array, sgh1->init->sig_size) != 0)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
@ -866,16 +884,17 @@ static void SigGroupHeadFreeSigArraysHash2(DetectEngineCtx *de_ctx,
|
|
|
|
|
|
|
|
|
|
for (htb = HashListTableGetListHead(ht);
|
|
|
|
|
htb != NULL;
|
|
|
|
|
htb = HashListTableGetListNext(htb)) {
|
|
|
|
|
htb = HashListTableGetListNext(htb))
|
|
|
|
|
{
|
|
|
|
|
sgh = (SigGroupHead *)HashListTableGetListData(htb);
|
|
|
|
|
|
|
|
|
|
if (sgh->sig_array != NULL) {
|
|
|
|
|
if (sgh->init->sig_array != NULL) {
|
|
|
|
|
detect_siggroup_sigarray_free_cnt++;
|
|
|
|
|
detect_siggroup_sigarray_memory -= sgh->sig_size;
|
|
|
|
|
detect_siggroup_sigarray_memory -= sgh->init->sig_size;
|
|
|
|
|
|
|
|
|
|
SCFree(sgh->sig_array);
|
|
|
|
|
sgh->sig_array = NULL;
|
|
|
|
|
sgh->sig_size = 0;
|
|
|
|
|
SCFree(sgh->init->sig_array);
|
|
|
|
|
sgh->init->sig_array = NULL;
|
|
|
|
|
sgh->init->sig_size = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sgh->init != NULL) {
|
|
|
|
@ -905,15 +924,6 @@ static void SigGroupHeadFreeSigArraysHash(DetectEngineCtx *de_ctx,
|
|
|
|
|
htb = HashListTableGetListNext(htb)) {
|
|
|
|
|
sgh = (SigGroupHead *)HashListTableGetListData(htb);
|
|
|
|
|
|
|
|
|
|
if (sgh->sig_array != NULL) {
|
|
|
|
|
detect_siggroup_sigarray_free_cnt++;
|
|
|
|
|
detect_siggroup_sigarray_memory -= sgh->sig_size;
|
|
|
|
|
|
|
|
|
|
SCFree(sgh->sig_array);
|
|
|
|
|
sgh->sig_array = NULL;
|
|
|
|
|
sgh->sig_size = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (sgh->init != NULL) {
|
|
|
|
|
SigGroupHeadInitDataFree(sgh->init);
|
|
|
|
|
sgh->init = NULL;
|
|
|
|
@ -987,13 +997,13 @@ int SigGroupHeadAppendSig(DetectEngineCtx *de_ctx, SigGroupHead **sgh,
|
|
|
|
|
|
|
|
|
|
/* see if we have a head already */
|
|
|
|
|
if (*sgh == NULL) {
|
|
|
|
|
*sgh = SigGroupHeadAlloc(DetectEngineGetMaxSigId(de_ctx) / 8 + 1);
|
|
|
|
|
*sgh = SigGroupHeadAlloc(de_ctx, DetectEngineGetMaxSigId(de_ctx) / 8 + 1);
|
|
|
|
|
if (*sgh == NULL)
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* enable the sig in the bitarray */
|
|
|
|
|
(*sgh)->sig_array[s->num / 8] |= 1 << (s->num % 8);
|
|
|
|
|
(*sgh)->init->sig_array[s->num / 8] |= 1 << (s->num % 8);
|
|
|
|
|
|
|
|
|
|
/* update maxlen for mpm */
|
|
|
|
|
if (s->flags & SIG_FLAG_MPM) {
|
|
|
|
@ -1037,8 +1047,8 @@ int SigGroupHeadClearSigs(SigGroupHead *sgh)
|
|
|
|
|
if (sgh == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (sgh->sig_array != NULL)
|
|
|
|
|
memset(sgh->sig_array, 0, sgh->sig_size);
|
|
|
|
|
if (sgh->init->sig_array != NULL)
|
|
|
|
|
memset(sgh->init->sig_array, 0, sgh->init->sig_size);
|
|
|
|
|
|
|
|
|
|
sgh->sig_cnt = 0;
|
|
|
|
|
|
|
|
|
@ -1064,14 +1074,14 @@ int SigGroupHeadCopySigs(DetectEngineCtx *de_ctx, SigGroupHead *src, SigGroupHea
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (*dst == NULL) {
|
|
|
|
|
*dst = SigGroupHeadAlloc(DetectEngineGetMaxSigId(de_ctx) / 8 + 1);
|
|
|
|
|
*dst = SigGroupHeadAlloc(de_ctx, DetectEngineGetMaxSigId(de_ctx) / 8 + 1);
|
|
|
|
|
if (*dst == NULL)
|
|
|
|
|
goto error;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* do the copy */
|
|
|
|
|
for (idx = 0; idx < src->sig_size; idx++)
|
|
|
|
|
(*dst)->sig_array[idx] = (*dst)->sig_array[idx] | src->sig_array[idx];
|
|
|
|
|
for (idx = 0; idx < src->init->sig_size; idx++)
|
|
|
|
|
(*dst)->init->sig_array[idx] = (*dst)->init->sig_array[idx] | src->init->sig_array[idx];
|
|
|
|
|
|
|
|
|
|
if (src->mpm_content_maxlen != 0) {
|
|
|
|
|
if ((*dst)->mpm_content_maxlen == 0)
|
|
|
|
@ -1111,7 +1121,7 @@ void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx)
|
|
|
|
|
|
|
|
|
|
sgh->sig_cnt = 0;
|
|
|
|
|
for (sig = 0; sig < max_idx + 1; sig++) {
|
|
|
|
|
if (sgh->sig_array[sig / 8] & (1 << (sig % 8)))
|
|
|
|
|
if (sgh->init->sig_array[sig / 8] & (1 << (sig % 8)))
|
|
|
|
|
sgh->sig_cnt++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -1192,8 +1202,8 @@ void SigGroupHeadPrintSigs(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
|
|
|
|
|
uint32_t u;
|
|
|
|
|
|
|
|
|
|
SCLogDebug("The Signatures present in this SigGroupHead are: ");
|
|
|
|
|
for (u = 0; u < (sgh->sig_size * 8); u++) {
|
|
|
|
|
if (sgh->sig_array[u / 8] & (1 << (u % 8))) {
|
|
|
|
|
for (u = 0; u < (sgh->init->sig_size * 8); u++) {
|
|
|
|
|
if (sgh->init->sig_array[u / 8] & (1 << (u % 8))) {
|
|
|
|
|
SCLogDebug("%" PRIu32, u);
|
|
|
|
|
printf("s->num %"PRIu16" ", u);
|
|
|
|
|
}
|
|
|
|
@ -1532,7 +1542,7 @@ int SigGroupHeadBuildMatchArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
|
|
|
|
|
detect_siggroup_matcharray_memory += (sgh->sig_cnt * sizeof(Signature *));
|
|
|
|
|
|
|
|
|
|
for (sig = 0; sig < max_idx + 1; sig++) {
|
|
|
|
|
if (!(sgh->sig_array[(sig / 8)] & (1 << (sig % 8))) )
|
|
|
|
|
if (!(sgh->init->sig_array[(sig / 8)] & (1 << (sig % 8))) )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
s = de_ctx->sig_array[sig];
|
|
|
|
@ -1546,6 +1556,49 @@ int SigGroupHeadBuildMatchArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int SigGroupHeadBuildHeadArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
|
|
|
|
|
{
|
|
|
|
|
Signature *s = NULL;
|
|
|
|
|
uint32_t idx = 0;
|
|
|
|
|
uint32_t sig = 0;
|
|
|
|
|
|
|
|
|
|
if (sgh == NULL)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
BUG_ON(sgh->head_array != NULL);
|
|
|
|
|
|
|
|
|
|
sgh->head_array = SCMalloc(sgh->sig_cnt * sizeof(SignatureHeader));
|
|
|
|
|
if (sgh->head_array == NULL)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
memset(sgh->head_array, 0, sgh->sig_cnt * sizeof(SignatureHeader));
|
|
|
|
|
|
|
|
|
|
detect_siggroup_matcharray_init_cnt++;
|
|
|
|
|
detect_siggroup_matcharray_memory += (sgh->sig_cnt * sizeof(SignatureHeader *));
|
|
|
|
|
|
|
|
|
|
for (sig = 0; sig < sgh->sig_cnt; sig++) {
|
|
|
|
|
s = sgh->match_array[sig];
|
|
|
|
|
if (s == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
sgh->head_array[idx].flags = s->flags;
|
|
|
|
|
sgh->head_array[idx].mpm_pattern_id = s->mpm_pattern_id;
|
|
|
|
|
sgh->head_array[idx].alproto = s->alproto;
|
|
|
|
|
sgh->head_array[idx].num = s->num;
|
|
|
|
|
sgh->head_array[idx].full_sig = s;
|
|
|
|
|
|
|
|
|
|
BUG_ON(s->flags != sgh->head_array[idx].flags);
|
|
|
|
|
BUG_ON(s->alproto != sgh->head_array[idx].alproto);
|
|
|
|
|
BUG_ON(s->mpm_pattern_id != sgh->head_array[idx].mpm_pattern_id);
|
|
|
|
|
BUG_ON(s->num != sgh->head_array[idx].num);
|
|
|
|
|
BUG_ON(s != sgh->head_array[idx].full_sig);
|
|
|
|
|
|
|
|
|
|
idx++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \brief Check if a SigGroupHead contains a Signature, whose sid is sent as an
|
|
|
|
|
* argument.
|
|
|
|
@ -1572,12 +1625,12 @@ int SigGroupHeadContainsSigId(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (sig = 0; sig < max_sid; sig++) {
|
|
|
|
|
if (sgh->sig_array == NULL) {
|
|
|
|
|
if (sgh->init->sig_array == NULL) {
|
|
|
|
|
SCReturnInt(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check if the SigGroupHead has an entry for the sid */
|
|
|
|
|
if ( !(sgh->sig_array[sig / 8] & (1 << (sig % 8))) )
|
|
|
|
|
if ( !(sgh->init->sig_array[sig / 8] & (1 << (sig % 8))) )
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* If we have reached here, we have an entry for sid in the SigGrouHead.
|
|
|
|
|