コード例 #1
0
ファイル: tmqh-flow.c プロジェクト: JakeGNA/suricata
static int StoreQueueId(TmqhFlowCtx *ctx, char *name)
{
    Tmq *tmq = TmqGetQueueByName(name);
    if (tmq == NULL) {
        tmq = TmqCreateQueue(SCStrdup(name));
        if (tmq == NULL)
            return -1;
    }
    tmq->writer_cnt++;

    uint16_t id = tmq->id;

    if (ctx->queues == NULL) {
        ctx->size = 1;
        ctx->queues = SCMalloc(ctx->size * sizeof(TmqhFlowMode));
        if (ctx->queues == NULL) {
            return -1;
        }
        memset(ctx->queues, 0, ctx->size * sizeof(TmqhFlowMode));
    } else {
        ctx->size++;
        ctx->queues = SCRealloc(ctx->queues, ctx->size * sizeof(TmqhFlowMode));
        if (ctx->queues == NULL) {
            return -1;
        }
        memset(ctx->queues + (ctx->size - 1), 0, sizeof(TmqhFlowMode));
    }
    ctx->queues[ctx->size - 1].q = &trans_q[id];
    SC_ATOMIC_INIT(ctx->queues[ctx->size - 1].total_packets);
    SC_ATOMIC_INIT(ctx->queues[ctx->size - 1].total_flows);

    return 0;
}
コード例 #2
0
static inline int SMTPCreateSpace(DetectEngineThreadCtx *det_ctx, uint16_t size)
{
    void *ptmp;
    if (size > det_ctx->smtp_buffers_size) {
        ptmp = SCRealloc(det_ctx->smtp,
                         (det_ctx->smtp_buffers_size + BUFFER_STEP) * sizeof(FiledataReassembledBody));
        if (ptmp == NULL) {
            SCFree(det_ctx->smtp);
            det_ctx->smtp = NULL;
            det_ctx->smtp_buffers_size = 0;
            det_ctx->smtp_buffers_list_len = 0;
            return -1;
        }
        det_ctx->smtp = ptmp;

        memset(det_ctx->smtp + det_ctx->smtp_buffers_size, 0, BUFFER_STEP * sizeof(FiledataReassembledBody));
        det_ctx->smtp_buffers_size += BUFFER_STEP;
    }
    for (int i = det_ctx->smtp_buffers_list_len; i < (size); i++) {
        det_ctx->smtp[i].buffer_len = 0;
        det_ctx->smtp[i].offset = 0;
    }

    return 0;
}
コード例 #3
0
CUcontext CudaHandlerModuleGetContext(const char *name, int device_id)
{
    SCMutexLock(&mutex);

    CudaHandlerModule *module = cudahl_modules;
    while (module != NULL && strcasecmp(module->name, name) != 0)
        module = module->next;
    if (module != NULL) {
        if (module->device_id != device_id) {
            SCLogError(SC_ERR_CUDA_HANDLER_ERROR, "Module already "
                       "registered, but the new device_id is different "
                       "from the already registered device_id.");
            exit(EXIT_FAILURE);
        }
        SCMutexUnlock(&mutex);
        return module->context;
    }

    CudaHandlerModule *new_module = SCMalloc(sizeof(CudaHandlerModule));
    if (new_module == NULL)
        exit(EXIT_FAILURE);
    memset(new_module, 0, sizeof(CudaHandlerModule));
    new_module->device_id = device_id;
    new_module->name = SCStrdup(name);
    if (new_module->name == NULL)
        exit(EXIT_FAILURE);
    if (cudahl_modules == NULL) {
        cudahl_modules = new_module;
    } else {
        new_module->next = cudahl_modules;
        cudahl_modules = new_module;
    }

    if (no_of_cuda_contexts <= device_id) {
        cuda_contexts = SCRealloc(cuda_contexts, sizeof(CUcontext) * (device_id + 1));
        if (cuda_contexts == NULL)
            exit(EXIT_FAILURE);
        memset(cuda_contexts + no_of_cuda_contexts, 0,
               sizeof(CUcontext) * ((device_id + 1) - no_of_cuda_contexts));
        no_of_cuda_contexts = device_id + 1;
    }

    if (cuda_contexts[device_id] == 0) {
        SCCudaDevices *devices = SCCudaGetDeviceList();
        if (SCCudaCtxCreate(&cuda_contexts[device_id], CU_CTX_SCHED_BLOCKING_SYNC,
                            devices->devices[device_id]->device) == -1) {
            SCLogDebug("ctxcreate failure.");
            exit(EXIT_FAILURE);
        }
    }
    new_module->context = cuda_contexts[device_id];

    SCMutexUnlock(&mutex);
    return cuda_contexts[device_id];
}
コード例 #4
0
ファイル: app-layer-htp-mem.c プロジェクト: Jonnyliu/suricata
void *HTPRealloc(void *ptr, size_t orig_size, size_t size)
{
    void *rptr = NULL;

    if (HTPCheckMemcap((uint32_t)(size - orig_size)) == 0)
        return NULL;

    rptr = SCRealloc(ptr, size);
    if (rptr == NULL)
        return NULL;

    HTPIncrMemuse((uint64_t)(size - orig_size));

    return rptr;
}
コード例 #5
0
ファイル: detect-filestore.c プロジェクト: gozzy/suricata
/**
 * \brief match the specified filestore
 *
 * \param t thread local vars
 * \param det_ctx pattern matcher thread local data
 * \param f *LOCKED* flow
 * \param flags direction flags
 * \param file file being inspected
 * \param s signature being inspected
 * \param m sigmatch that we will cast into DetectFilestoreData
 *
 * \retval 0 no match
 * \retval 1 match
 *
 * \todo when we start supporting more protocols, the logic in this function
 *       needs to be put behind a api.
 */
static int DetectFilestoreMatch (ThreadVars *t, DetectEngineThreadCtx *det_ctx, Flow *f,
        uint8_t flags, File *file, const Signature *s, const SigMatchCtx *m)
{
    uint32_t file_id = 0;

    SCEnter();

    if (det_ctx->filestore_cnt >= DETECT_FILESTORE_MAX) {
        SCReturnInt(1);
    }

    /* file can be NULL when a rule with filestore scope > file
     * matches. */
    if (file != NULL) {
        file_id = file->file_track_id;
        if (file->sid != NULL && s->id > 0) {
            if (file->sid_cnt >= file->sid_max) {
                void *p = SCRealloc(file->sid, sizeof(uint32_t) * (file->sid_max + 8));
                if (p == NULL) {
                    SCFree(file->sid);
                    file->sid = NULL;
                    file->sid_cnt = 0;
                    file->sid_max = 0;
                    goto continue_after_realloc_fail;
                } else {
                    file->sid = p;
                    file->sid_max += 8;
                }
            }
            file->sid[file->sid_cnt] = s->id;
            file->sid_cnt++;
        }
    }

continue_after_realloc_fail:

    det_ctx->filestore[det_ctx->filestore_cnt].file_id = file_id;
    det_ctx->filestore[det_ctx->filestore_cnt].tx_id = det_ctx->tx_id;

    SCLogDebug("%u, file %u, tx %"PRIu64, det_ctx->filestore_cnt,
        det_ctx->filestore[det_ctx->filestore_cnt].file_id,
        det_ctx->filestore[det_ctx->filestore_cnt].tx_id);

    det_ctx->filestore_cnt++;
    SCReturnInt(1);
}
コード例 #6
0
void SigGroupHeadStore(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
{
    void *ptmp;
    //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 {
        int increase = 16;
        ptmp = SCRealloc(de_ctx->sgh_array,
                         sizeof(SigGroupHead *) * (increase + de_ctx->sgh_array_size));
        if (ptmp == NULL) {
            SCFree(de_ctx->sgh_array);
            de_ctx->sgh_array = NULL;
            return;
        }
        de_ctx->sgh_array = ptmp;

        de_ctx->sgh_array_size += increase;
        de_ctx->sgh_array[de_ctx->sgh_array_cnt] = sgh;
    }
    de_ctx->sgh_array_cnt++;
}
コード例 #7
0
ファイル: util-pool-thread.c プロジェクト: nydw/suricata
int PoolThreadGrow(PoolThread *pt, uint32_t size, uint32_t prealloc_size, uint32_t elt_size,  void *(*Alloc)(), int (*Init)(void *, void *), void *InitData,  void (*Cleanup)(void *), void (*Free)(void *)) {
    void *ptmp;
    size_t newsize;
    PoolThreadElement *e = NULL;

    if (pt == NULL || pt->array == NULL) {
        SCLogError(SC_ERR_POOL_INIT, "pool grow failed");
        return -1;
    }

    newsize = pt->size + 1;
    SCLogDebug("newsize %lu", newsize);

    ptmp = SCRealloc(pt->array, (newsize * sizeof(PoolThreadElement)));
    if (ptmp == NULL) {
        SCFree(pt->array);
        pt->array = NULL;
        SCLogError(SC_ERR_POOL_INIT, "pool grow failed");
        return -1;
    }
    pt->array = ptmp;

    pt->size = newsize;

    e = &pt->array[newsize - 1];
    memset(e, 0x00, sizeof(*e));
    SCMutexInit(&e->lock, NULL);
    SCMutexLock(&e->lock);
    e->pool = PoolInit(size, prealloc_size, elt_size, Alloc, Init, InitData, Cleanup, Free);
    SCMutexUnlock(&e->lock);
    if (e->pool == NULL) {
        SCLogError(SC_ERR_POOL_INIT, "pool grow failed");
        return -1;
    }

    return (int)(newsize - 1);
}
コード例 #8
0
ファイル: util-mpm.c プロジェクト: chenglong7997/suricata
/**
 * \brief Register a new Mpm Context.
 *
 * \param name A new profile to be registered to store this MpmCtx.
 *
 * \retval id Return the id created for the new MpmCtx profile.
 */
int32_t MpmFactoryRegisterMpmCtxProfile(DetectEngineCtx *de_ctx, const char *name, uint8_t flags)
{
    void *ptmp;
    /* the very first entry */
    if (de_ctx->mpm_ctx_factory_container == NULL) {
        de_ctx->mpm_ctx_factory_container = SCMalloc(sizeof(MpmCtxFactoryContainer));
        if (de_ctx->mpm_ctx_factory_container == NULL) {
            SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
            exit(EXIT_FAILURE);
        }
        memset(de_ctx->mpm_ctx_factory_container, 0, sizeof(MpmCtxFactoryContainer));

        MpmCtxFactoryItem *item = SCMalloc(sizeof(MpmCtxFactoryItem));
        if (unlikely(item == NULL)) {
            SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
            exit(EXIT_FAILURE);
        }

        item[0].name = SCStrdup(name);
        if (item[0].name == NULL) {
            SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
            exit(EXIT_FAILURE);
        }

        /* toserver */
        item[0].mpm_ctx_ts = SCMalloc(sizeof(MpmCtx));
        if (item[0].mpm_ctx_ts == NULL) {
            SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
            exit(EXIT_FAILURE);
        }
        memset(item[0].mpm_ctx_ts, 0, sizeof(MpmCtx));
        item[0].mpm_ctx_ts->global = 1;

        /* toclient */
        item[0].mpm_ctx_tc = SCMalloc(sizeof(MpmCtx));
        if (item[0].mpm_ctx_tc == NULL) {
            SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
            exit(EXIT_FAILURE);
        }
        memset(item[0].mpm_ctx_tc, 0, sizeof(MpmCtx));
        item[0].mpm_ctx_tc->global = 1;

        /* our id starts from 0 always.  Helps us with the ctx retrieval from
         * the array */
        item[0].id = 0;

        /* store the flag */
        item[0].flags = flags;

        /* store the newly created item */
        de_ctx->mpm_ctx_factory_container->items = item;
        de_ctx->mpm_ctx_factory_container->no_of_items++;

        /* the first id is always 0 */
        return item[0].id;
    } else {
        int i;
        MpmCtxFactoryItem *items = de_ctx->mpm_ctx_factory_container->items;
        for (i = 0; i < de_ctx->mpm_ctx_factory_container->no_of_items; i++) {
            if (items[i].name != NULL && strcmp(items[i].name, name) == 0) {
                /* looks like we have this mpm_ctx freed */
                if (items[i].mpm_ctx_ts == NULL) {
                    items[i].mpm_ctx_ts = SCMalloc(sizeof(MpmCtx));
                    if (items[i].mpm_ctx_ts == NULL) {
                        SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
                        exit(EXIT_FAILURE);
                    }
                    memset(items[i].mpm_ctx_ts, 0, sizeof(MpmCtx));
                    items[i].mpm_ctx_ts->global = 1;
                }
                if (items[i].mpm_ctx_tc == NULL) {
                    items[i].mpm_ctx_tc = SCMalloc(sizeof(MpmCtx));
                    if (items[i].mpm_ctx_tc == NULL) {
                        SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
                        exit(EXIT_FAILURE);
                    }
                    memset(items[i].mpm_ctx_tc, 0, sizeof(MpmCtx));
                    items[i].mpm_ctx_tc->global = 1;
                }
                items[i].flags = flags;
                return items[i].id;
            }
        }

        /* let's make the new entry */
        ptmp = SCRealloc(items,
                         (de_ctx->mpm_ctx_factory_container->no_of_items + 1) * sizeof(MpmCtxFactoryItem));
        if (unlikely(ptmp == NULL)) {
            SCFree(items);
            items = NULL;
            SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
            exit(EXIT_FAILURE);
        }
        items = ptmp;

        de_ctx->mpm_ctx_factory_container->items = items;

        MpmCtxFactoryItem *new_item = &items[de_ctx->mpm_ctx_factory_container->no_of_items];
        new_item[0].name = SCStrdup(name);
        if (new_item[0].name == NULL) {
            SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
            exit(EXIT_FAILURE);
        }

        /* toserver */
        new_item[0].mpm_ctx_ts = SCMalloc(sizeof(MpmCtx));
        if (new_item[0].mpm_ctx_ts == NULL) {
            SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
            exit(EXIT_FAILURE);
        }
        memset(new_item[0].mpm_ctx_ts, 0, sizeof(MpmCtx));
        new_item[0].mpm_ctx_ts->global = 1;

        /* toclient */
        new_item[0].mpm_ctx_tc = SCMalloc(sizeof(MpmCtx));
        if (new_item[0].mpm_ctx_tc == NULL) {
            SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
            exit(EXIT_FAILURE);
        }
        memset(new_item[0].mpm_ctx_tc, 0, sizeof(MpmCtx));
        new_item[0].mpm_ctx_tc->global = 1;

        new_item[0].id = de_ctx->mpm_ctx_factory_container->no_of_items;
        new_item[0].flags = flags;
        de_ctx->mpm_ctx_factory_container->no_of_items++;

        /* the newly created id */
        return new_item[0].id;
    }
}
コード例 #9
0
static uint8_t *DetectEngineSMTPGetBufferForTX(uint64_t tx_id,
                                               DetectEngineCtx *de_ctx,
                                               DetectEngineThreadCtx *det_ctx,
                                               Flow *f, File *curr_file,
                                               uint8_t flags,
                                               uint32_t *buffer_len,
                                               uint32_t *stream_start_offset)
{
    SCEnter();
    int index = 0;
    uint8_t *buffer = NULL;
    *buffer_len = 0;
    *stream_start_offset = 0;
    FileData *curr_chunk = NULL;

    if (det_ctx->smtp_buffers_list_len == 0) {
        if (SMTPCreateSpace(det_ctx, 1) < 0)
            goto end;
        index = 0;

        if (det_ctx->smtp_buffers_list_len == 0) {
            det_ctx->smtp_start_tx_id = tx_id;
        }
        det_ctx->smtp_buffers_list_len++;
    } else {
        if ((tx_id - det_ctx->smtp_start_tx_id) < det_ctx->smtp_buffers_list_len) {
            if (det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer_len != 0) {
                *buffer_len = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer_len;
                *stream_start_offset = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].offset;
                buffer = det_ctx->smtp[(tx_id - det_ctx->smtp_start_tx_id)].buffer;

                SCReturnPtr(buffer, "uint8_t");
            }
        } else {
            if (SMTPCreateSpace(det_ctx, (tx_id - det_ctx->smtp_start_tx_id) + 1) < 0)
                goto end;

            if (det_ctx->smtp_buffers_list_len == 0) {
                det_ctx->smtp_start_tx_id = tx_id;
            }
            det_ctx->smtp_buffers_list_len++;
        }
        index = (tx_id - det_ctx->smtp_start_tx_id);
    }

    SCLogDebug("smtp_config.content_limit %u, smtp_config.content_inspect_min_size %u",
                smtp_config.content_limit, smtp_config.content_inspect_min_size);

    SCLogDebug("file %p size %"PRIu64", state %d", curr_file, curr_file->content_len_so_far, curr_file->state);

    /* no new data */
    if (curr_file->content_inspected == curr_file->content_len_so_far) {
        SCLogDebug("no new data");
        goto end;
    }

    curr_chunk = curr_file->chunks_head;
    if (curr_chunk == NULL) {
        SCLogDebug("no data chunks to inspect for this transaction");
        goto end;
    }

    if ((smtp_config.content_limit == 0 ||
         curr_file->content_len_so_far < smtp_config.content_limit) &&
        curr_file->content_len_so_far < smtp_config.content_inspect_min_size &&
        !(flags & STREAM_EOF) && !(curr_file->state > FILE_STATE_OPENED)) {
        SCLogDebug("we still haven't seen the entire content. "
                   "Let's defer content inspection till we see the "
                   "entire content.");
        goto end;
    }

    int first = 1;
    curr_chunk = curr_file->chunks_head;
    while (curr_chunk != NULL) {
        /* see if we can filter out chunks */
        if (curr_file->content_inspected > 0) {
            if (curr_chunk->stream_offset < curr_file->content_inspected) {
                if ((curr_file->content_inspected - curr_chunk->stream_offset) > smtp_config.content_inspect_window) {
                    curr_chunk = curr_chunk->next;
                    continue;
                } else {
                    /* include this one */
                }
            } else {
                /* include this one */
            }
        }

        if (first) {
            det_ctx->smtp[index].offset = curr_chunk->stream_offset;
            first = 0;
        }

        /* see if we need to grow the buffer */
        if (det_ctx->smtp[index].buffer == NULL || (det_ctx->smtp[index].buffer_len + curr_chunk->len) > det_ctx->smtp[index].buffer_size) {
            void *ptmp;
            det_ctx->smtp[index].buffer_size += curr_chunk->len * 2;

            if ((ptmp = SCRealloc(det_ctx->smtp[index].buffer, det_ctx->smtp[index].buffer_size)) == NULL) {
                SCFree(det_ctx->smtp[index].buffer);
                det_ctx->smtp[index].buffer = NULL;
                det_ctx->smtp[index].buffer_size = 0;
                det_ctx->smtp[index].buffer_len = 0;
                goto end;
            }
            det_ctx->smtp[index].buffer = ptmp;
        }
        memcpy(det_ctx->smtp[index].buffer + det_ctx->smtp[index].buffer_len, curr_chunk->data, curr_chunk->len);
        det_ctx->smtp[index].buffer_len += curr_chunk->len;

        curr_chunk = curr_chunk->next;
    }

    /* updat inspected tracker */
    curr_file->content_inspected = curr_file->chunks_tail->stream_offset + curr_file->chunks_tail->len;
    SCLogDebug("curr_file->content_inspected now %"PRIu64, curr_file->content_inspected);

    buffer = det_ctx->smtp[index].buffer;
    *buffer_len = det_ctx->smtp[index].buffer_len;
    *stream_start_offset = det_ctx->smtp[index].offset;

end:
    SCLogDebug("buffer %p, len %u", buffer, *buffer_len);
    SCReturnPtr(buffer, "uint8_t");
}
コード例 #10
0
ファイル: util-mpm.c プロジェクト: P1sec/suricata
/**
 * \internal
 * \brief Add a pattern to the mpm-ac context.
 *
 * \param mpm_ctx Mpm context.
 * \param pat     Pointer to the pattern.
 * \param patlen  Length of the pattern.
 * \param pid     Pattern id
 * \param sid     Signature id (internal id).
 * \param flags   Pattern's MPM_PATTERN_* flags.
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
int MpmAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
                            uint16_t offset, uint16_t depth, uint32_t pid,
                            SigIntId sid, uint8_t flags)
{
    SCLogDebug("Adding pattern for ctx %p, patlen %"PRIu16" and pid %" PRIu32,
               mpm_ctx, patlen, pid);

    if (patlen == 0) {
        SCLogWarning(SC_ERR_INVALID_ARGUMENTS, "pattern length 0");
        return 0;
    }

    if (flags & MPM_PATTERN_CTX_OWNS_ID)
        pid = UINT_MAX;

    /* check if we have already inserted this pattern */
    MpmPattern *p = MpmInitHashLookup(mpm_ctx, pat, patlen, flags, pid);
    if (p == NULL) {
        SCLogDebug("Allocing new pattern");

        /* p will never be NULL */
        p = MpmAllocPattern(mpm_ctx);

        p->len = patlen;
        p->flags = flags;
        if (flags & MPM_PATTERN_CTX_OWNS_ID)
            p->id = mpm_ctx->max_pat_id++;
        else
            p->id = pid;

        p->original_pat = SCMalloc(patlen);
        if (p->original_pat == NULL)
            goto error;
        mpm_ctx->memory_cnt++;
        mpm_ctx->memory_size += patlen;
        memcpy(p->original_pat, pat, patlen);

        p->ci = SCMalloc(patlen);
        if (p->ci == NULL)
            goto error;
        mpm_ctx->memory_cnt++;
        mpm_ctx->memory_size += patlen;
        memcpy_tolower(p->ci, pat, patlen);

        /* setup the case sensitive part of the pattern */
        if (p->flags & MPM_PATTERN_FLAG_NOCASE) {
            /* nocase means no difference between cs and ci */
            p->cs = p->ci;
        } else {
            if (memcmp(p->ci, pat, p->len) == 0) {
                /* no diff between cs and ci: pat is lowercase */
                p->cs = p->ci;
            } else {
                p->cs = SCMalloc(patlen);
                if (p->cs == NULL)
                    goto error;
                mpm_ctx->memory_cnt++;
                mpm_ctx->memory_size += patlen;
                memcpy(p->cs, pat, patlen);
            }
        }

        /* put in the pattern hash */
        MpmInitHashAdd(mpm_ctx, p);

        mpm_ctx->pattern_cnt++;

        if (mpm_ctx->maxlen < patlen)
            mpm_ctx->maxlen = patlen;

        if (mpm_ctx->minlen == 0) {
            mpm_ctx->minlen = patlen;
        } else {
            if (mpm_ctx->minlen > patlen)
                mpm_ctx->minlen = patlen;
        }

        /* we need the max pat id */
        if (p->id > mpm_ctx->max_pat_id)
            mpm_ctx->max_pat_id = p->id;

        p->sids_size = 1;
        p->sids = SCMalloc(p->sids_size * sizeof(SigIntId));
        BUG_ON(p->sids == NULL);
        p->sids[0] = sid;
    } else {
        /* we can be called multiple times for the same sid in the case
         * of the 'single' modus. Here multiple rule groups share the
         * same mpm ctx and might be adding the same pattern to the
         * mpm_ctx */
        int found = 0;
        uint32_t x = 0;
        for (x = 0; x < p->sids_size; x++) {
            if (p->sids[x] == sid) {
                found = 1;
                break;
            }
        }

        if (!found) {
            SigIntId *sids = SCRealloc(p->sids, (sizeof(SigIntId) * (p->sids_size + 1)));
            BUG_ON(sids == NULL);
            p->sids = sids;
            p->sids[p->sids_size] = sid;
            p->sids_size++;
        }
    }

    return 0;

error:
    MpmFreePattern(mpm_ctx, p);
    return -1;
}