Example #1
0
static int cacheset_init(struct cache_set *map, mpool_t *mempool) {
    map->data = mpool_calloc(mempool, NODES, sizeof(*map->data));
    if (!map->data)
	return CL_EMEM;
    map->maxelements = 80 * NODES / 100;
    map->maxdeleted = NODES - map->maxelements - 1;
    map->elements = 0;
    map->lru_head = map->lru_tail = NULL;
    return 0;
}
Example #2
0
int cli_bm_init(struct cli_matcher *root)
{
	uint16_t i, size = HASH(255, 255, 255) + 1;
#ifdef USE_MPOOL
    assert (root->mempool && "mempool must be initialized");
#endif
    if(!(root->bm_shift = (uint8_t *) mpool_calloc(root->mempool, size, sizeof(uint8_t))))
	return CL_EMEM;

    if(!(root->bm_suffix = (struct cli_bm_patt **) mpool_calloc(root->mempool, size, sizeof(struct cli_bm_patt *)))) {
	mpool_free(root->mempool, root->bm_shift);
	return CL_EMEM;
    }

    for(i = 0; i < size; i++)
	root->bm_shift[i] = BM_MIN_LENGTH - BM_BLOCK_SIZE + 1;

    return CL_SUCCESS;
}
static void setup(void)
{
	struct cli_matcher *root;
	virname = NULL;
	thefmap = NULL;
	ctx.virname = &virname;
	ctx.fmap = &thefmap;
	ctx.engine = cl_engine_new();
	fail_unless(!!ctx.engine, "cl_engine_new() failed");
	root = (struct cli_matcher *) mpool_calloc(ctx.engine->mempool, 1, sizeof(struct cli_matcher));
	fail_unless(root != NULL, "root == NULL");
#ifdef USE_MPOOL
	root->mempool = ctx.engine->mempool;
#endif

	ctx.engine->root[0] = root;
}
Example #4
0
/* Allocates all the nodes and sets up the replacement chain */
static int cacheset_init(struct cache_set *cs, mpool_t *mempool) {
    unsigned int i;
    cs->data = mpool_calloc(mempool, NODES,  sizeof(*cs->data));
    cs->root = NULL;

    if(!cs->data)
	return 1;

    for(i=1; i<NODES; i++) {
	cs->data[i-1].next = &cs->data[i];
	cs->data[i].prev = &cs->data[i-1];
    }

    cs->first = cs->data;
    cs->last = &cs->data[NODES-1];

    return 0;
}
Example #5
0
File: mpool.c Project: OPSF/uClinux
uint16_t *cli_mpool_hex2ui(mpool_t *mp, const char *hex) {
  uint16_t *str;
  unsigned int len;
  
  len = strlen(hex);

  if(len % 2 != 0) {
    cli_errmsg("cli_hex2si(): Malformed hexstring: %s (length: %u)\n", hex, len);
    return NULL;
  }

  str = mpool_calloc(mp, (len / 2) + 1, sizeof(uint16_t));
  if(!str)
    return NULL;

  if(cli_realhex2ui(hex, str, len))
    return str;
    
  mpool_free(mp, str);
  return NULL;
}
Example #6
0
static int
sm_btl_first_time_init(mca_btl_sm_t *sm_btl,
                       int32_t my_smp_rank,
                       int n)
{
    size_t length, length_payload;
    sm_fifo_t *my_fifos;
    int my_mem_node, num_mem_nodes, i, rc;
    mca_mpool_base_resources_t *res = NULL;
    mca_btl_sm_component_t* m = &mca_btl_sm_component;

    /* Assume we don't have hwloc support and fill in dummy info */
    mca_btl_sm_component.mem_node = my_mem_node = 0;
    mca_btl_sm_component.num_mem_nodes = num_mem_nodes = 1;

#if OPAL_HAVE_HWLOC
    /* If we have hwloc support, then get accurate information */
    if (NULL != opal_hwloc_topology) {
        i = opal_hwloc_base_get_nbobjs_by_type(opal_hwloc_topology,
                                               HWLOC_OBJ_NODE, 0,
                                               OPAL_HWLOC_AVAILABLE);

        /* If we find >0 NUMA nodes, then investigate further */
        if (i > 0) {
            int numa=0, w;
            unsigned n_bound=0;
            hwloc_cpuset_t avail;
            hwloc_obj_t obj;

            /* JMS This tells me how many numa nodes are *available*,
               but it's not how many are being used *by this job*.
               Note that this is the value we've previously used (from
               the previous carto-based implementation), but it really
               should be improved to be how many NUMA nodes are being
               used *in this job*. */
            mca_btl_sm_component.num_mem_nodes = num_mem_nodes = i;

            /* if we are not bound, then there is nothing further to do */
            if (NULL != ompi_process_info.cpuset) {
                /* count the number of NUMA nodes to which we are bound */
                for (w=0; w < i; w++) {
                    if (NULL == (obj = opal_hwloc_base_get_obj_by_type(opal_hwloc_topology,
                                                                       HWLOC_OBJ_NODE, 0, w,
                                                                       OPAL_HWLOC_AVAILABLE))) {
                        continue;
                    }
                    /* get that NUMA node's available cpus */
                    avail = opal_hwloc_base_get_available_cpus(opal_hwloc_topology, obj);
                    /* see if we intersect */
                    if (hwloc_bitmap_intersects(avail, opal_hwloc_my_cpuset)) {
                        n_bound++;
                        numa = w;
                    }
                }
                /* if we are located on more than one NUMA, or we didn't find
                 * a NUMA we are on, then not much we can do
                 */
                if (1 == n_bound) {
                    mca_btl_sm_component.mem_node = my_mem_node = numa;
                } else {
                    mca_btl_sm_component.mem_node = my_mem_node = -1;
                }
            }
        }
    }
#endif

    if (NULL == (res = calloc(1, sizeof(*res)))) {
        return OMPI_ERR_OUT_OF_RESOURCE;
    }

    /* lookup shared memory pool */
    mca_btl_sm_component.sm_mpools =
        (mca_mpool_base_module_t **)calloc(num_mem_nodes,
                                           sizeof(mca_mpool_base_module_t *));

    /* Disable memory binding, because each MPI process will claim pages in the
     * mpool for their local NUMA node */
    res->mem_node = -1;

    if (OMPI_SUCCESS != (rc = setup_mpool_base_resources(m, res))) {
        free(res);
        return rc;
    }
    /* now that res is fully populated, create the thing */
    mca_btl_sm_component.sm_mpools[0] =
        mca_mpool_base_module_create(mca_btl_sm_component.sm_mpool_name,
                                     sm_btl, res);
    /* Sanity check to ensure that we found it */
    if (NULL == mca_btl_sm_component.sm_mpools[0]) {
        free(res);
        return OMPI_ERR_OUT_OF_RESOURCE;
    }

    mca_btl_sm_component.sm_mpool = mca_btl_sm_component.sm_mpools[0];

    mca_btl_sm_component.sm_mpool_base =
        mca_btl_sm_component.sm_mpools[0]->mpool_base(mca_btl_sm_component.sm_mpools[0]);

    /* create a list of peers */
    mca_btl_sm_component.sm_peers = (struct mca_btl_base_endpoint_t**)
        calloc(n, sizeof(struct mca_btl_base_endpoint_t*));
    if (NULL == mca_btl_sm_component.sm_peers) {
        free(res);
        return OMPI_ERR_OUT_OF_RESOURCE;
    }

    /* remember that node rank zero is already attached */
    if (0 != my_smp_rank) {
        if (OMPI_SUCCESS != (rc = sm_segment_attach(m))) {
            free(res);
            return rc;
        }
    }

    /* it is now safe to free the mpool resources */
    free(res);

    /* check to make sure number of local procs is within the
     * specified limits */
    if(mca_btl_sm_component.sm_max_procs > 0 &&
       mca_btl_sm_component.num_smp_procs + n >
       mca_btl_sm_component.sm_max_procs) {
        return OMPI_ERROR;
    }

    mca_btl_sm_component.shm_fifo = (volatile sm_fifo_t **)mca_btl_sm_component.sm_seg->module_data_addr;
    mca_btl_sm_component.shm_bases = (char**)(mca_btl_sm_component.shm_fifo + n);
    mca_btl_sm_component.shm_mem_nodes = (uint16_t*)(mca_btl_sm_component.shm_bases + n);

    /* set the base of the shared memory segment */
    mca_btl_sm_component.shm_bases[mca_btl_sm_component.my_smp_rank] =
        (char*)mca_btl_sm_component.sm_mpool_base;
    mca_btl_sm_component.shm_mem_nodes[mca_btl_sm_component.my_smp_rank] =
        (uint16_t)my_mem_node;

    /* initialize the array of fifo's "owned" by this process */
    if(NULL == (my_fifos = (sm_fifo_t*)mpool_calloc(FIFO_MAP_NUM(n), sizeof(sm_fifo_t))))
        return OMPI_ERR_OUT_OF_RESOURCE;

    mca_btl_sm_component.shm_fifo[mca_btl_sm_component.my_smp_rank] = my_fifos;

    /* cache the pointer to the 2d fifo array.  These addresses
     * are valid in the current process space */
    mca_btl_sm_component.fifo = (sm_fifo_t**)malloc(sizeof(sm_fifo_t*) * n);

    if(NULL == mca_btl_sm_component.fifo)
        return OMPI_ERR_OUT_OF_RESOURCE;

    mca_btl_sm_component.fifo[mca_btl_sm_component.my_smp_rank] = my_fifos;

    mca_btl_sm_component.mem_nodes = (uint16_t *) malloc(sizeof(uint16_t) * n);
    if(NULL == mca_btl_sm_component.mem_nodes)
        return OMPI_ERR_OUT_OF_RESOURCE;

    /* initialize fragment descriptor free lists */

    /* allocation will be for the fragment descriptor and payload buffer */
    length = sizeof(mca_btl_sm_frag1_t);
    length_payload =
        sizeof(mca_btl_sm_hdr_t) + mca_btl_sm_component.eager_limit;
    i = ompi_free_list_init_new(&mca_btl_sm_component.sm_frags_eager, length,
                                opal_cache_line_size, OBJ_CLASS(mca_btl_sm_frag1_t),
                                length_payload, opal_cache_line_size,
                                mca_btl_sm_component.sm_free_list_num,
                                mca_btl_sm_component.sm_free_list_max,
                                mca_btl_sm_component.sm_free_list_inc,
                                mca_btl_sm_component.sm_mpool);
    if ( OMPI_SUCCESS != i )
        return i;

    length = sizeof(mca_btl_sm_frag2_t);
    length_payload =
        sizeof(mca_btl_sm_hdr_t) + mca_btl_sm_component.max_frag_size;
    i = ompi_free_list_init_new(&mca_btl_sm_component.sm_frags_max, length,
                                opal_cache_line_size, OBJ_CLASS(mca_btl_sm_frag2_t),
                                length_payload, opal_cache_line_size,
                                mca_btl_sm_component.sm_free_list_num,
                                mca_btl_sm_component.sm_free_list_max,
                                mca_btl_sm_component.sm_free_list_inc,
                                mca_btl_sm_component.sm_mpool);
    if ( OMPI_SUCCESS != i )
        return i;

    i = ompi_free_list_init_new(&mca_btl_sm_component.sm_frags_user, 
		    sizeof(mca_btl_sm_user_t),
		    opal_cache_line_size, OBJ_CLASS(mca_btl_sm_user_t),
		    sizeof(mca_btl_sm_hdr_t), opal_cache_line_size,
		    mca_btl_sm_component.sm_free_list_num,
		    mca_btl_sm_component.sm_free_list_max,
		    mca_btl_sm_component.sm_free_list_inc,
		    mca_btl_sm_component.sm_mpool);
    if ( OMPI_SUCCESS != i )
	    return i;   

    mca_btl_sm_component.num_outstanding_frags = 0;

    mca_btl_sm_component.num_pending_sends = 0;
    i = opal_free_list_init(&mca_btl_sm_component.pending_send_fl,
                            sizeof(btl_sm_pending_send_item_t),
                            OBJ_CLASS(opal_free_list_item_t),
                            16, -1, 32);
    if ( OMPI_SUCCESS != i )
        return i;

    /* set flag indicating btl has been inited */
    sm_btl->btl_inited = true;

    return OMPI_SUCCESS;
}
Example #7
0
int cli_pcre_addpatt(struct cli_matcher *root, const char *virname, const char *trigger, const char *pattern, const char *cflags, const char *offset, const uint32_t *lsigid, unsigned int options)
{
    struct cli_pcre_meta **newmetatable = NULL, *pm = NULL;
    uint32_t pcre_count;
    const char *opt;
    int ret = CL_SUCCESS, rssigs;

    if (!root || !trigger || !pattern || !offset) {
        cli_errmsg("cli_pcre_addpatt: NULL root or NULL trigger or NULL pattern or NULL offset\n");
        return CL_ENULLARG;
    }

    /* TODO: trigger and regex checking (backreference limitations?) (control pattern limitations?) */
    /* cli_ac_chklsig will fail a empty trigger; empty patterns can cause an infinite loop */
    if (*trigger == '\0' || *pattern == '\0') {
        cli_errmsg("cli_pcre_addpatt: trigger or pattern cannot be an empty string\n");
        return CL_EMALFDB;
    }
    if (cflags && *cflags == '\0') {
        cflags = NULL;
    }

    if (lsigid)
        pm_dbgmsg("cli_pcre_addpatt: Adding /%s/%s%s triggered on (%s) as subsig %d for lsigid %d\n", 
                  pattern, cflags ? " with flags " : "", cflags ? cflags : "", trigger, lsigid[1], lsigid[0]);
    else
        pm_dbgmsg("cli_pcre_addpatt: Adding /%s/%s%s triggered on (%s) [no lsigid]\n",
                  pattern, cflags ? " with flags " : "", cflags ? cflags : "", trigger);

#ifdef PCRE_BYPASS
    /* check for trigger bypass */
    if (strcmp(trigger, PCRE_BYPASS)) {
#endif
        /* validate the lsig trigger */
        rssigs = cli_ac_chklsig(trigger, trigger + strlen(trigger), NULL, NULL, NULL, 1);
        if(rssigs == -1) {
            cli_errmsg("cli_pcre_addpatt: regex subsig /%s/ is missing a valid logical trigger\n", pattern);
            return CL_EMALFDB;
        }

        if (lsigid) {
            if (rssigs > lsigid[1]) {
                cli_errmsg("cli_pcre_addpatt: regex subsig %d logical trigger refers to subsequent subsig %d\n", lsigid[1], rssigs);
                return CL_EMALFDB;
            }
            if (rssigs == lsigid[1]) {
                cli_errmsg("cli_pcre_addpatt: regex subsig %d logical trigger is self-referential\n", lsigid[1]);
                return CL_EMALFDB;
            }
        }
        else {
            cli_dbgmsg("cli_pcre_addpatt: regex subsig is missing lsigid data\n");
        }
#ifdef PCRE_BYPASS
    }
#endif

    /* allocating entries */
    pm = (struct cli_pcre_meta *)mpool_calloc(root->mempool, 1, sizeof(*pm));
    if (!pm) {
        cli_errmsg("cli_pcre_addpatt: Unable to allocate memory for new pcre meta\n");
        return CL_EMEM;
    }

    pm->trigger = cli_mpool_strdup(root->mempool, trigger);
    if (!pm->trigger) {
        cli_errmsg("cli_pcre_addpatt: Unable to allocate memory for trigger string\n");
        cli_pcre_freemeta(root, pm);
        mpool_free(root->mempool, pm);
        return CL_EMEM;
    }

    pm->virname = (char *)cli_mpool_virname(root->mempool, virname, options & CL_DB_OFFICIAL);
    if(!pm->virname) {
        cli_errmsg("cli_pcre_addpatt: Unable to allocate memory for virname or NULL virname\n");
        cli_pcre_freemeta(root, pm);
        mpool_free(root->mempool, pm);
        return CL_EMEM;
    }

    if (lsigid) {
        root->ac_lsigtable[lsigid[0]]->virname = pm->virname;

        pm->lsigid[0] = 1;
        pm->lsigid[1] = lsigid[0];
        pm->lsigid[2] = lsigid[1];
    }
    else {
        /* sigtool */
        pm->lsigid[0] = 0;
    }

    pm->pdata.expression = strdup(pattern);
    if (!pm->pdata.expression) {
        cli_errmsg("cli_pcre_addpatt: Unable to allocate memory for expression\n");
        cli_pcre_freemeta(root, pm);
        mpool_free(root->mempool, pm);
        return CL_EMEM;
    }

    /* offset parsing and usage, similar to cli_ac_addsig */
    /* relative and type-specific offsets handled during scan */
    ret = cli_caloff(offset, NULL, root->type, pm->offdata, &(pm->offset_min), &(pm->offset_max));
    if (ret != CL_SUCCESS) {
        cli_errmsg("cli_pcre_addpatt: cannot calculate offset data: %s for pattern: %s\n", offset, pattern);
        cli_pcre_freemeta(root, pm);
        mpool_free(root->mempool, pm);
        return ret;
    }
    if(pm->offdata[0] != CLI_OFF_ANY) {
        if(pm->offdata[0] == CLI_OFF_ABSOLUTE)
            root->pcre_absoff_num++;
        else
            root->pcre_reloff_num++;
    }

    /* parse and add options, also totally not from snort */
    if (cflags) {
        opt = cflags;

        /* cli_pcre_addoptions handles pcre specific options */
        while (cli_pcre_addoptions(&(pm->pdata), &opt, 0) != CL_SUCCESS) {
            /* handle matcher specific options here */
            switch (*opt) {
            case 'g':  pm->flags |= CLI_PCRE_GLOBAL;            break;
            case 'r':  pm->flags |= CLI_PCRE_ROLLING;           break;
            case 'e':  pm->flags |= CLI_PCRE_ENCOMPASS;         break;
            default:
                cli_errmsg("cli_pcre_addpatt: unknown/extra pcre option encountered %c\n", *opt);
                cli_pcre_freemeta(root, pm);
                mpool_free(root->mempool, pm);
                return CL_EMALFDB;
            }
            opt++;
        }

        if (pm->flags) {
            pm_dbgmsg("Matcher:  %s%s%s\n",
                      pm->flags & CLI_PCRE_GLOBAL ? "CLAMAV_GLOBAL " : "",
                      pm->flags & CLI_PCRE_ROLLING ? "CLAMAV_ROLLING " : "",
                      pm->flags & CLI_PCRE_ENCOMPASS ? "CLAMAV_ENCOMPASS " : "");
        }
        else
            pm_dbgmsg("Matcher:  NONE\n");

        if (pm->pdata.options) {
#if USING_PCRE2
            pm_dbgmsg("Compiler: %s%s%s%s%s%s%s\n",
                      pm->pdata.options & PCRE2_CASELESS ? "PCRE2_CASELESS " : "",
                      pm->pdata.options & PCRE2_DOTALL ? "PCRE2_DOTALL " : "",
                      pm->pdata.options & PCRE2_MULTILINE ? "PCRE2_MULTILINE " : "",
                      pm->pdata.options & PCRE2_EXTENDED ? "PCRE2_EXTENDED " : "",

                      pm->pdata.options & PCRE2_ANCHORED ? "PCRE2_ANCHORED " : "",
                      pm->pdata.options & PCRE2_DOLLAR_ENDONLY ? "PCRE2_DOLLAR_ENDONLY " : "",
                      pm->pdata.options & PCRE2_UNGREEDY ? "PCRE2_UNGREEDY " : "");
#else
            pm_dbgmsg("Compiler: %s%s%s%s%s%s%s\n",
                      pm->pdata.options & PCRE_CASELESS ? "PCRE_CASELESS " : "",
                      pm->pdata.options & PCRE_DOTALL ? "PCRE_DOTALL " : "",
                      pm->pdata.options & PCRE_MULTILINE ? "PCRE_MULTILINE " : "",
                      pm->pdata.options & PCRE_EXTENDED ? "PCRE_EXTENDED " : "",

                      pm->pdata.options & PCRE_ANCHORED ? "PCRE_ANCHORED " : "",
                      pm->pdata.options & PCRE_DOLLAR_ENDONLY ? "PCRE_DOLLAR_ENDONLY " : "",
                      pm->pdata.options & PCRE_UNGREEDY ? "PCRE_UNGREEDY " : "");
#endif
        }
        else
            pm_dbgmsg("Compiler: NONE\n");
    }

    /* add metadata to the performance tracker */
    if (options & CL_DB_PCRE_STATS)
        pcre_perf_events_init(pm, virname);

    /* add pcre data to root after reallocation */
    pcre_count = root->pcre_metas+1;
    newmetatable = (struct cli_pcre_meta **)mpool_realloc(root->mempool, root->pcre_metatable,
                                         pcre_count * sizeof(struct cli_pcre_meta *));
    if (!newmetatable) {
        cli_errmsg("cli_pcre_addpatt: Unable to allocate memory for new pcre meta table\n");
        cli_pcre_freemeta(root, pm);
        mpool_free(root->mempool, pm);
        return CL_EMEM;
    }

    newmetatable[pcre_count-1] = pm;
    root->pcre_metatable = newmetatable;

    root->pcre_metas = pcre_count;

    return CL_SUCCESS;
}
Example #8
0
int asn1_load_mscat(fmap_t *map, struct cl_engine *engine) {
    struct cli_asn1 c;
    unsigned int size;
    struct cli_matcher *db;
    int i;

    if(asn1_parse_mscat(map, 0, map->len, &engine->cmgr, 0, &c.next, &size, engine))
        return 1;

    if(asn1_expect_objtype(map, c.next, &size, &c, 0x30))
	return 1;
    if(asn1_expect_obj(map, &c.content, &c.size, 0x06, lenof(OID_szOID_CATALOG_LIST), OID_szOID_CATALOG_LIST))
	return 1;
    if(c.size) {
	cli_dbgmsg("asn1_load_mscat: found extra data in szOID_CATALOG_LIST content\n");
	return 1;
    }
    if(asn1_expect_objtype(map, c.next, &size, &c, 0x4)) /* List ID */
	return 1;
    if(asn1_expect_objtype(map, c.next, &size, &c, 0x17)) /* Effective date - WTF?! */
	return 1;
    if(asn1_expect_algo(map, &c.next, &size, lenof(OID_szOID_CATALOG_LIST_MEMBER), OID_szOID_CATALOG_LIST_MEMBER)) /* szOID_CATALOG_LIST_MEMBER */
	return 1;
    if(asn1_expect_objtype(map, c.next, &size, &c, 0x30)) /* hashes here */
	return 1;
    /* [0] is next but we don't care as it's really descriptives stuff */

    size = c.size;
    c.next = c.content;
    while(size) {
	struct cli_asn1 tag;
	if(asn1_expect_objtype(map, c.next, &size, &c, 0x30))
	    return 1;
	if(asn1_expect_objtype(map, c.content, &c.size, &tag, 0x04)) /* TAG NAME */
	    return 1;
	if(asn1_expect_objtype(map, tag.next, &c.size, &tag, 0x31)) /* set */
	    return 1;
	if(c.size) {
	    cli_dbgmsg("asn1_load_mscat: found extra data in tag\n");
	    return 1;
	}
	while(tag.size) {
	    struct cli_asn1 tagval1, tagval2, tagval3;
	    int hashtype;

	    if(asn1_expect_objtype(map, tag.content, &tag.size, &tagval1, 0x30))
		return 1;
	    tag.content = tagval1.next;

	    if(asn1_expect_objtype(map, tagval1.content, &tagval1.size, &tagval2, 0x06))
		return 1;
	    if(tagval2.size != lenof(OID_SPC_INDIRECT_DATA_OBJID))
		continue;

	    if(!fmap_need_ptr_once(map, tagval2.content, lenof(OID_SPC_INDIRECT_DATA_OBJID))) {
		cli_dbgmsg("asn1_load_mscat: cannot read SPC_INDIRECT_DATA\n");
		return 1;
	    }
	    if(memcmp(tagval2.content, OID_SPC_INDIRECT_DATA_OBJID, lenof(OID_SPC_INDIRECT_DATA_OBJID)))
		continue; /* stuff like CAT_NAMEVALUE_OBJID(1.3.6.1.4.1.311.12.2.1) and CAT_MEMBERINFO_OBJID(.2).. */

	    if(asn1_expect_objtype(map, tagval2.next, &tagval1.size, &tagval2, 0x31))
		return 1;
	    if(tagval1.size) {
		cli_dbgmsg("asn1_load_mscat: found extra data in tag value\n");
		return 1;
	    }

	    if(asn1_expect_objtype(map, tagval2.content, &tagval2.size, &tagval1, 0x30))
		return 1;
	    if(tagval2.size) {
		cli_dbgmsg("asn1_load_mscat: found extra data in SPC_INDIRECT_DATA_OBJID tag\n");
		return 1;
	    }

	    if(asn1_expect_objtype(map, tagval1.content, &tagval1.size, &tagval2, 0x30))
		return 1;

	    if(asn1_expect_objtype(map, tagval2.content, &tagval2.size, &tagval3, 0x06)) /* shall have an obj 1.3.6.1.4.1.311.2.1.15 or 1.3.6.1.4.1.311.2.1.25 inside */
		return 1;
	    if(tagval3.size != lenof(OID_SPC_PE_IMAGE_DATA_OBJID)) { /* lenof(OID_SPC_PE_IMAGE_DATA_OBJID) = lenof(OID_SPC_CAB_DATA_OBJID) = 10*/
		cli_dbgmsg("asn1_load_mscat: bad hash type size\n");
		return 1;
	    }
	    if(!fmap_need_ptr_once(map, tagval3.content, lenof(OID_SPC_PE_IMAGE_DATA_OBJID))) {
		cli_dbgmsg("asn1_load_mscat: cannot read hash type\n");
		return 1;
	    }
	    if(!memcmp(tagval3.content, OID_SPC_PE_IMAGE_DATA_OBJID, lenof(OID_SPC_PE_IMAGE_DATA_OBJID)))
		hashtype = 2;
	    else if(!memcmp(tagval3.content, OID_SPC_CAB_DATA_OBJID, lenof(OID_SPC_CAB_DATA_OBJID)))
		hashtype = 1;
	    else {
		cli_dbgmsg("asn1_load_mscat: unexpected hash type\n");
		return 1;
	    }

	    if(asn1_expect_objtype(map, tagval2.next, &tagval1.size, &tagval2, 0x30))
		return 1;
	    if(tagval1.size) {
		cli_dbgmsg("asn1_load_mscat: found extra data after hash\n");
		return 1;
	    }

	    if(asn1_expect_algo(map, &tagval2.content, &tagval2.size, lenof(OID_sha1), OID_sha1)) /* objid 1.3.14.3.2.26 - sha1 */
		return 1;

	    if(asn1_expect_objtype(map, tagval2.content, &tagval2.size, &tagval3, 0x04))
		return 1;
	    if(tagval2.size) {
		cli_dbgmsg("asn1_load_mscat: found extra data in hash\n");
		return 1;
	    }
	    if(tagval3.size != SHA1_HASH_SIZE) {
		cli_dbgmsg("asn1_load_mscat: bad hash size %u\n", tagval3.size);
		return 1;
	    }
	    if(!fmap_need_ptr_once(map, tagval3.content, SHA1_HASH_SIZE)) {
		cli_dbgmsg("asn1_load_mscat: cannot read hash\n");
		return 1;
	    }

	    if(cli_debug_flag) {
		char sha1[SHA1_HASH_SIZE*2+1];
		for(i=0;i<SHA1_HASH_SIZE;i++)
		    sprintf(&sha1[i*2], "%02x", ((uint8_t *)(tagval3.content))[i]);
		cli_dbgmsg("asn1_load_mscat: got hash %s (%s)\n", sha1, (hashtype == 2) ? "PE" : "CAB");
	    }
	    if(!engine->hm_fp) {
		if(!(engine->hm_fp = mpool_calloc(engine->mempool, 1, sizeof(*db)))) {
		    tag.size = 1;;
		    return 1;
		}
#ifdef USE_MPOOL
		engine->hm_fp->mempool = engine->mempool;
#endif
	    }
	    if(hm_addhash_bin(engine->hm_fp, tagval3.content, CLI_HASH_SHA1, hashtype, NULL)) {
		cli_warnmsg("asn1_load_mscat: failed to add hash\n");
		return 1;
	    }
	}
    }

    return 0;
}
Example #9
0
int hm_addhash_bin(struct cli_matcher *root, const void *binhash, enum CLI_HASH_TYPE type, uint32_t size, const char *virusname) {
    const unsigned int hlen = hashlen[type];
    const struct cli_htu32_element *item;
    struct cli_sz_hash *szh;
    struct cli_htu32 *ht;
    int i;

    if (size) {
        /* size non-zero, find sz_hash element in size-driven hashtable  */
        ht = &root->hm.sizehashes[type];
        if(!root->hm.sizehashes[type].capacity) {
            i = cli_htu32_init(ht, 64, root->mempool);
            if(i) return i;
        }

        item = cli_htu32_find(ht, size);
        if(!item) {
	    struct cli_htu32_element htitem;
	    szh = mpool_calloc(root->mempool, 1, sizeof(*szh));
	    if(!szh) {
	        cli_errmsg("hm_addhash_bin: failed to allocate size hash\n");
	        return CL_EMEM;
	    }

	    htitem.key = size;
	    htitem.data.as_ptr = szh;
	    i = cli_htu32_insert(ht, &htitem, root->mempool);
	    if(i) {
	        cli_errmsg("hm_addhash_bin: failed to add item to hashtab");
	        mpool_free(root->mempool, szh);
	        return i;
	    }
        } else
	    szh = (struct cli_sz_hash *)item->data.as_ptr;
    }
    else {
        /* size 0 = wildcard */
        szh = &root->hwild.hashes[type];
    }
    szh->items++;

    szh->hash_array = mpool_realloc2(root->mempool, szh->hash_array, hlen * szh->items);
    if(!szh->hash_array) {
	cli_errmsg("hm_addhash_bin: failed to grow hash array to %u entries\n", szh->items);
	szh->items=0;
	mpool_free(root->mempool, szh->virusnames);
	szh->virusnames = NULL;
	return CL_EMEM;
    }

    szh->virusnames = mpool_realloc2(root->mempool, szh->virusnames, sizeof(*szh->virusnames) * szh->items);
    if(!szh->virusnames) {
	cli_errmsg("hm_addhash_bin: failed to grow virusname array to %u entries\n", szh->items);
	szh->items=0;
	mpool_free(root->mempool, szh->hash_array);
	szh->hash_array = NULL;
	return CL_EMEM;
    }

    memcpy(&szh->hash_array[(szh->items-1) * hlen], binhash, hlen);
    szh->virusnames[(szh->items-1)] = virusname;
    
    return 0;
}
Example #10
0
int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern)
{
	struct cli_ac_node *pt, *next;
	struct cli_ac_patt *ph;
	void *newtable;
	struct cli_ac_alt *a1, *a2;
	uint8_t i, match;
	uint16_t len = MIN(root->ac_maxdepth, pattern->length);


    for(i = 0; i < len; i++) {
	if(pattern->pattern[i] & CLI_MATCH_WILDCARD) {
	    len = i;
	    break;
	}
    }

    if(len < root->ac_mindepth) {
	/* cli_errmsg("cli_ac_addpatt: Signature for %s is too short\n", pattern->virname); */
	return CL_EMALFDB;
    }

    pt = root->ac_root;

    for(i = 0; i < len; i++) {
	if(!pt->trans) {
	    pt->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *));
	    if(!pt->trans) {
		cli_errmsg("cli_ac_addpatt: Can't allocate memory for pt->trans\n");
		return CL_EMEM;
	    }
	}

	next = pt->trans[(unsigned char) (pattern->pattern[i] & 0xff)]; 

	if(!next) {
	    next = (struct cli_ac_node *) mpool_calloc(root->mempool, 1, sizeof(struct cli_ac_node));
	    if(!next) {
		cli_errmsg("cli_ac_addpatt: Can't allocate memory for AC node\n");
		return CL_EMEM;
	    }

	    if(i != len - 1) {
		next->trans = (struct cli_ac_node **) mpool_calloc(root->mempool, 256, sizeof(struct cli_ac_node *));
		if(!next->trans) {
		    cli_errmsg("cli_ac_addpatt: Can't allocate memory for next->trans\n");
		    mpool_free(root->mempool, next);
		    return CL_EMEM;
		}
	    }

	    root->ac_nodes++;
	    newtable = mpool_realloc(root->mempool, root->ac_nodetable, root->ac_nodes * sizeof(struct cli_ac_node *));
	    if(!newtable) {
		root->ac_nodes--;
		cli_errmsg("cli_ac_addpatt: Can't realloc ac_nodetable\n");
		if(next->trans)
		    mpool_free(root->mempool, next->trans);
		mpool_free(root->mempool, next);
		return CL_EMEM;
	    }
	    root->ac_nodetable = (struct cli_ac_node **) newtable;
	    root->ac_nodetable[root->ac_nodes - 1] = next;

	    pt->trans[(unsigned char) (pattern->pattern[i] & 0xff)] = next;
	}

	pt = next;
    }

    root->ac_patterns++;
    newtable = mpool_realloc(root->mempool, root->ac_pattable, root->ac_patterns * sizeof(struct cli_ac_patt *));
    if(!newtable) {
	root->ac_patterns--;
	cli_errmsg("cli_ac_addpatt: Can't realloc ac_pattable\n");
	return CL_EMEM;
    }
    root->ac_pattable = (struct cli_ac_patt **) newtable;
    root->ac_pattable[root->ac_patterns - 1] = pattern;

    pattern->depth = i;

    ph = pt->list;
    while(ph) {
	if((ph->length == pattern->length) && (ph->prefix_length == pattern->prefix_length) && (ph->ch[0] == pattern->ch[0]) && (ph->ch[1] == pattern->ch[1])) {
	    if(!memcmp(ph->pattern, pattern->pattern, ph->length * sizeof(uint16_t)) && !memcmp(ph->prefix, pattern->prefix, ph->prefix_length * sizeof(uint16_t))) {
		if(!ph->alt && !pattern->alt) {
		    match = 1;
		} else if(ph->alt == pattern->alt) {
		    match = 1;
		    for(i = 0; i < ph->alt; i++) {
			a1 = ph->alttable[i];
			a2 = pattern->alttable[i];

			if(a1->num != a2->num) {
			    match = 0;
			    break;
			}
			if(a1->chmode != a2->chmode) {
			    match = 0;
			    break;
			} else if(a1->chmode) {
			    if(memcmp(a1->str, a2->str, a1->num)) {
				match = 0;
				break;
			    }
			} else {
			    while(a1 && a2) {
				if((a1->len != a2->len) || memcmp(a1->str, a2->str, a1->len))
				    break;
				a1 = a1->next;
				a2 = a2->next;
			    }
			    if(a1 || a2) {
				match = 0;
				break;
			    }
			}
		    }
		} else {
		    match = 0;
		}

		if(match) {
		    pattern->next_same = ph->next_same;
		    ph->next_same = pattern;
		    return CL_SUCCESS;
		}
	    }
	}
	ph = ph->next;
    }

    pattern->next = pt->list;
    pt->list = pattern;

    return CL_SUCCESS;
}
Example #11
0
int openioc_parse(const char * fname, int fd, struct cl_engine *engine, unsigned int options)
{
    int rc;
    xmlTextReaderPtr reader = NULL;
    const xmlChar * name;
    struct openioc_hash * elems = NULL, * elem = NULL;
    const char * iocp = NULL;
    uint16_t ioclen;
    char * virusname;
    int hash_count = 0;
    
    if (fname == NULL)
        return CL_ENULLARG;

    if (fd < 0)
        return CL_EARG;

    cli_dbgmsg("openioc_parse: XML parsing file %s\n", fname);

    reader = xmlReaderForFd(fd, NULL, NULL, CLAMAV_MIN_XMLREADER_FLAGS);
    if (reader == NULL) {
        cli_dbgmsg("openioc_parse: xmlReaderForFd error\n");
        return CL_EOPEN;
    }
    rc = xmlTextReaderRead(reader);
    while (rc == 1) {
        name = xmlTextReaderConstLocalName(reader);
        cli_dbgmsg("openioc_parse: xmlTextReaderRead read %s\n", name);
        if (xmlStrEqual(name, (const xmlChar *)"Indicator") && 
            xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT) {
            rc = openioc_parse_indicator(reader, &elems);
            if (rc != CL_SUCCESS) {
                xmlTextReaderClose(reader);
                xmlFreeTextReader(reader);
                return rc;
            }
        }
        if (xmlStrEqual(name, (const xmlChar *)"ioc") &&
            xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) {
            break;
        }
        rc = xmlTextReaderRead(reader);
    }

    iocp = strrchr(fname, *PATHSEP);

    if (NULL == iocp)
        iocp = fname;
    else
        iocp++;

    ioclen = strlen(fname);

    if (elems != NULL) {
        if (NULL == engine->hm_hdb) {
            engine->hm_hdb = mpool_calloc(engine->mempool, 1, sizeof(struct cli_matcher));
            if (NULL == engine->hm_hdb) {            
                xmlTextReaderClose(reader);
                xmlFreeTextReader(reader);
                return CL_EMEM;
            }
#ifdef USE_MPOOL
            engine->hm_hdb->mempool = engine->mempool;
#endif
        }
    }

    while (elems != NULL) {
        const char * sp;
        char * hash, * vp;
        int i, hashlen;

        elem = elems;
        elems = elems->next;
        hash = (char *)(elem->hash);
        while (isspace(*hash))
            hash++;
        hashlen = strlen(hash);
        if (hashlen == 0) {
            xmlFree(elem->hash);
            free(elem);
            continue;
        }
        vp = hash+hashlen-1;
        while (isspace(*vp) && vp > hash) {
            *vp-- = '\0';
            hashlen--;
        }
        virusname = calloc(1, ioclen+hashlen+2);
        if (NULL == virusname) {
            cli_dbgmsg("openioc_parse: mpool_malloc for virname memory failed.\n");
            xmlTextReaderClose(reader);
            xmlFreeTextReader(reader);
            return CL_EMEM;
        }
        sp = fname;
        vp = virusname;
        for (i=0; i<ioclen; i++, sp++, vp++) {
            switch (*sp) {
            case '\\':
            case '/':
            case '?':
            case '%':
            case '*':
            case ':':
            case '|':
            case '"':
            case '<':
            case '>':
                *vp = '_';
                break;
            default:
                if (isspace(*sp))
                    *vp = '_';
                else
                    *vp = *sp;
            }
        }
        *vp++ = '.';
        sp = hash;
        for (i=0; i<hashlen; i++, sp++) {
            if (isxdigit(*sp)) {
                *vp++ = *sp;
            }
        }

        vp = virusname;
        virusname = cli_mpool_virname(engine->mempool, virusname, options & CL_DB_OFFICIAL);
        if (!(virusname)) {
            cli_dbgmsg("openioc_parse: mpool_malloc for virname memory failed.\n");
            xmlTextReaderClose(reader);
            xmlFreeTextReader(reader);
            free(vp);
            return CL_EMEM;
        }

        free(vp);

        rc = hm_addhash_str(engine->hm_hdb, hash, 0, virusname);
        if (rc != CL_SUCCESS)
            cli_dbgmsg("openioc_parse: hm_addhash_str failed with %i hash len %i for %s.\n",
                       rc, hashlen, virusname);
        else
            hash_count++;

        xmlFree(elem->hash);
        free(elem);
    }

    if (hash_count == 0)
        cli_warnmsg("openioc_parse: No hash signatures extracted from %s.\n", fname);
    else
        cli_dbgmsg("openioc_parse: %i hash signature%s extracted from %s.\n",
                   hash_count, hash_count==1?"":"s", fname);

    xmlTextReaderClose(reader);
    xmlFreeTextReader(reader);

    return CL_SUCCESS;
}