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; }
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; }
/* 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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }