From: Victor Julien Date: Tue, 19 Aug 2014 13:09:59 +0000 (+0200) Subject: AC: use local bit array X-Git-Tag: suricata-2.1beta3~44 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=29074af9a6fc930ce772a4b70d7caff5eb59e97d;p=thirdparty%2Fsuricata.git AC: use local bit array Use a local pattern bit array to making sure we don't match more than once, in addition to the pmq bitarray that is still used for results validation higher up in the rule matching process. Why: pmq->pattern_id_bitarray is currently sometimes used in a 'stateful' way, meaning that for a single packet we run multiple MPM's on the same pmq w/o resetting it. The new bitarray is used to determine wherther we need to append the patterns associated 'sids' list to the pmq rule_id_array. It has been observed that MPM1 matches for PAT1, and MPM2 matches for PAT1 as well. However, in MPM1 PAT1 doesn't have the same sids list. In this case MPM2 would not add it's sids to the list, leading to missed detection. --- diff --git a/src/util-mpm-ac.c b/src/util-mpm-ac.c index ec16e415cf..7219542035 100644 --- a/src/util-mpm-ac.c +++ b/src/util-mpm-ac.c @@ -1307,6 +1307,9 @@ uint32_t SCACSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, /* \todo Change it for stateful MPM. Supply the state using mpm_thread_ctx */ SCACPatternList *pid_pat_list = ctx->pid_pat_list; + uint8_t bitarray[pmq->pattern_id_array_size]; + memset(&bitarray, 0, pmq->pattern_id_array_size); + if (ctx->state_count < 32767) { register SC_AC_STATE_TYPE_U16 state = 0; SC_AC_STATE_TYPE_U16 (*state_table_u16)[256] = ctx->state_table_u16; @@ -1324,10 +1327,11 @@ uint32_t SCACSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, /* inside loop */ continue; } - if (pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { + if (bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { ; } else { pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); + bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = pids[k] & 0x0000FFFF; uint32_t x; @@ -1337,12 +1341,12 @@ uint32_t SCACSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, } matches++; } else { - if (pmq->pattern_id_bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { + if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { ; } else { - pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); + pmq->pattern_id_bitarray[(pids[k]) / 8] |= (1 << ((pids[k]) % 8)); + bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = pids[k]; - uint32_t x; for (x = 0; x < pid_pat_list[pids[k]].sids_size; x++) { pmq->rule_id_array[pmq->rule_id_array_cnt++] = pid_pat_list[pids[k]].sids[x]; @@ -1373,10 +1377,11 @@ uint32_t SCACSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, /* inside loop */ continue; } - if (pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { + if (bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { ; } else { pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); + bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = pids[k] & 0x0000FFFF; uint32_t x; @@ -1386,10 +1391,11 @@ uint32_t SCACSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, } matches++; } else { - if (pmq->pattern_id_bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { + if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { ; } else { - pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); + pmq->pattern_id_bitarray[(pids[k]) / 8] |= (1 << ((pids[k]) % 8)); + bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = pids[k]; uint32_t x;