void fixing_test(MPOOL_T *mpool_p, void *arr_malloc[], size_t count) { int index, i, fix_bytes; assert(mpool_p && arr_malloc); memset(arr_malloc, 0, count*sizeof(void*)); index = 0; i = 0; fix_bytes = 33; while(i++ < 50) { printf("---------------------------------------------------\n"); index = i % count; printf("[%d]test: index=%d bytes=%d\n", i++, index, fix_bytes); if (arr_malloc[index]) mpool_free(*mpool_p, arr_malloc[index]); arr_malloc[index]=mpool_malloc(*mpool_p, fix_bytes); if (!arr_malloc[index]) printf("%s\n", PROMPT_FAILED); else memset(arr_malloc[index], 5, fix_bytes); mpool_print(*mpool_p); } i=0; while(i < count) { mpool_free(*mpool_p, arr_malloc[i++]); } mpool_print(*mpool_p); }
void main() { MPOOL_T mpool; int i=20; char *new_p1, *new_p2, *new_p3; void* arr_malloc[MAX_HANDLES]; char mem_1[500]; char mem_2[300]; mpool_init(&mpool, mem_1, sizeof(mem_1), 0, 4); new_p1 = mpool_malloc(mpool, 10); mpool_print(mpool); if (!new_p1) printf("%s", PROMPT_FAILED); mpool_grow(mpool,mem_2, sizeof(mem_2)); mpool_print(mpool); new_p2 = mpool_malloc(mpool, 32); if (!new_p2) printf("%s", PROMPT_FAILED); mpool_free(mpool, new_p2); mpool_print(mpool); new_p3 = mpool_malloc(mpool, 12); mpool_print(mpool); if (!new_p3) printf("%s", PROMPT_FAILED); mpool_free(mpool, new_p1); mpool_print(mpool); mpool_free(mpool, new_p2); mpool_print(mpool); mpool_free(mpool, new_p3); mpool_print(mpool); random_test(&mpool, arr_malloc, MAX_HANDLES, 10); lining_test(&mpool, arr_malloc, MAX_HANDLES); fixing_test(&mpool, arr_malloc, MAX_HANDLES); }
/* Allocates the trees for the engine cache */ int cli_cache_init(struct cl_engine *engine) { struct CACHE *cache; unsigned int i, j; if(!engine) { cli_errmsg("cli_cache_init: mpool malloc fail\n"); return 1; } if(!(cache = mpool_malloc(engine->mempool, sizeof(struct CACHE) * TREES))) { cli_errmsg("cli_cache_init: mpool malloc fail\n"); return 1; } for(i=0; i<TREES; i++) { if(pthread_mutex_init(&cache[i].mutex, NULL)) { cli_errmsg("cli_cache_init: mutex init fail\n"); for(j=0; j<i; j++) cacheset_destroy(&cache[j].cacheset, engine->mempool); for(j=0; j<i; j++) pthread_mutex_destroy(&cache[j].mutex); mpool_free(engine->mempool, cache); return 1; } if(cacheset_init(&cache[i].cacheset, engine->mempool)) { for(j=0; j<i; j++) cacheset_destroy(&cache[j].cacheset, engine->mempool); for(j=0; j<=i; j++) pthread_mutex_destroy(&cache[j].mutex); mpool_free(engine->mempool, cache); return 1; } } engine->cache = cache; return 0; }
void random_test(MPOOL_T *mpool_p, void *arr_malloc[], size_t count, int times) { int index, rand_bytes, i; assert(mpool_p && arr_malloc) memset(arr_malloc, 0, count*sizeof(void*)); srand ((unsigned)time(NULL)); i=0; while (times--) { printf("---------------------------------------------------\n"); index=rand()%count; rand_bytes = rand()%150; printf("[%d]test: index=%d rand_bytes=%d\n", i++, index, rand_bytes); if (arr_malloc[index]) mpool_free(*mpool_p, arr_malloc[index]); arr_malloc[index]=mpool_malloc(*mpool_p, rand_bytes); if (!arr_malloc[index]) printf("%s\n", PROMPT_FAILED); else memset(arr_malloc[index], 5,rand_bytes); mpool_print(*mpool_p); } i=0; while(i < count) { mpool_free(*mpool_p, arr_malloc[i++]); } mpool_print(*mpool_p); }
int phishing_init(struct cl_engine* engine) { struct phishcheck* pchk; if(!engine->phishcheck) { pchk = engine->phishcheck = mpool_malloc(engine->mempool, sizeof(struct phishcheck)); if(!pchk) { cli_errmsg("Phishcheck: Unable to allocate memory for initialization\n"); return CL_EMEM; } pchk->is_disabled=1; } else { pchk = engine->phishcheck; if(!pchk) return CL_ENULLARG; if(!pchk->is_disabled) { /* already initialized */ return CL_SUCCESS; } } cli_dbgmsg("Initializing phishcheck module\n"); if(build_regex(&pchk->preg_numeric,numeric_url_regex,1)) { mpool_free(engine->mempool, pchk); engine->phishcheck = NULL; return CL_EFORMAT; } pchk->is_disabled = 0; cli_dbgmsg("Phishcheck module initialized\n"); return CL_SUCCESS; }
void dconf_teardown(void) { mpool_free(pool, dconf); #ifdef USE_MPOOL if (pool) mpool_destroy(pool); #endif }
void cli_pcre_freetable(struct cli_matcher *root) { uint32_t i; struct cli_pcre_meta *pm = NULL; for (i = 0; i < root->pcre_metas; ++i) { /* free pcre meta */ pm = root->pcre_metatable[i]; cli_pcre_freemeta(root, pm); mpool_free(root->mempool, pm); } /* free holding structures and set count to zero */ mpool_free(root->mempool, root->pcre_metatable); root->pcre_metatable = NULL; root->pcre_metas = 0; }
void cli_bm_free(struct cli_matcher *root) { struct cli_bm_patt *patt, *prev; uint16_t i, size = HASH(255, 255, 255) + 1; if(root->bm_shift) mpool_free(root->mempool, root->bm_shift); if(root->bm_suffix) { for(i = 0; i < size; i++) { patt = root->bm_suffix[i]; while(patt) { prev = patt; patt = patt->next; if(prev->prefix) mpool_free(root->mempool, prev->prefix); else mpool_free(root->mempool, prev->pattern); if(prev->virname) mpool_free(root->mempool, prev->virname); if(prev->offset) mpool_free(root->mempool, prev->offset); mpool_free(root->mempool, prev); } } mpool_free(root->mempool, root->bm_suffix); } }
void *mpool_realloc2(struct MP *mp, void *ptr, size_t size) { struct FRAG *f = (struct FRAG *)((char *)ptr - FRAG_OVERHEAD); unsigned int csize; void *new_ptr; if (!ptr) return mpool_malloc(mp, size); spam("realloc @ %p (size %u -> %u))\n", f, from_bits(f->u.sbits), size); if(!size || !(csize = from_bits(f->u.sbits))) { cli_errmsg("mpool_realloc2(): Attempt to allocate %lu bytes. Please report to http://bugs.clamav.net\n", (unsigned long int) size); mpool_free(mp, ptr); return NULL; } csize -= FRAG_OVERHEAD; if (csize >= size && (!f->u.sbits || from_bits(f->u.sbits-1)-FRAG_OVERHEAD < size)) return ptr; if ((new_ptr = mpool_malloc(mp, size))) memcpy(new_ptr, ptr, csize); mpool_free(mp, ptr); return new_ptr; }
void cli_pcre_freemeta(struct cli_matcher *root, struct cli_pcre_meta *pm) { if (!pm) return; if (pm->trigger) { mpool_free(root->mempool, pm->trigger); pm->trigger = NULL; } if (pm->virname) { mpool_free(root->mempool, pm->virname); pm->virname = NULL; } if (pm->statname) { free(pm->statname); pm->statname = NULL; } cli_pcre_free_single(&(pm->pdata)); }
/* Frees the engine cache */ void cli_cache_destroy(struct cl_engine *engine) { struct CACHE *cache; unsigned int i; if(!engine || !(cache = engine->cache)) return; for(i=0; i<TREES; i++) { cacheset_destroy(&cache[i].cacheset, engine->mempool); pthread_mutex_destroy(&cache[i].mutex); } mpool_free(engine->mempool, cache); }
void phishing_done(struct cl_engine* engine) { struct phishcheck* pchk = engine->phishcheck; cli_dbgmsg("Cleaning up phishcheck\n"); if(pchk && !pchk->is_disabled) { free_regex(&pchk->preg_numeric); } whitelist_done(engine); domainlist_done(engine); if(pchk) { cli_dbgmsg("Freeing phishcheck struct\n"); mpool_free(engine->mempool, pchk); } cli_dbgmsg("Phishcheck cleaned up\n"); }
unsigned char *cli_mpool_hex2str(mpool_t *mp, const unsigned char *hex) { unsigned char *str; size_t len = strlen((const char*)hex); if (len&1) { cli_errmsg("cli_hex2str(): Malformed hexstring: %s (length: %u)\n", hex, (unsigned)len); return NULL; } str = mpool_malloc(mp, (len/2) + 1); if (cli_hex2str_to(hex, str, len) == -1) { mpool_free(mp, str); return NULL; } str[len/2] = '\0'; return str; }
/**************************************************************************************** * Function name - heap_reset * * Description - De-allocates memory and inits to the initial values heap, but does * not deallocate the heap itself. * * Input - *h - pointer to an initialized heap * Return Code/Output - none ****************************************************************************************/ void heap_reset (heap*const h) { if (h->heap) { free (h->heap); } if (h->ids_arr) { free (h->ids_arr); } if (h->nodes_mpool) { mpool_free (h->nodes_mpool); free (h->nodes_mpool); } memset (h, 0, sizeof (*h)); }
/* Frees the engine cache */ void cli_cache_destroy(struct cl_engine *engine) { struct CACHE *cache; unsigned int i; if(!engine || !(cache = engine->cache)) return; if (engine->engine_options & ENGINE_OPTIONS_DISABLE_CACHE) { return; } for(i=0; i<TREES; i++) { cacheset_destroy(&cache[i].cacheset, engine->mempool); pthread_mutex_destroy(&cache[i].mutex); } mpool_free(engine->mempool, cache); }
void mm_free(void *p) { #ifndef DONT_USE_POOL Memnode *n = (Memnode *)(((char *)p) - sizeof(Memnode)); int poolindex = roundsize(n->esize); if (poolindex >= 0) { mpool_free(p, general_pools[poolindex]); return; } /* more then 256 bytes, use free */ free(n); #else free(p); #endif }
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; }
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 void cacheset_rehash(struct cache_set *map, mpool_t *mempool) { unsigned i; int ret; struct cache_set tmp_set; struct cache_key *key; pthread_mutex_lock(&pool_mutex); ret = cacheset_init(&tmp_set, mempool); pthread_mutex_unlock(&pool_mutex); if (ret) return; key = map->lru_head; for (i=0;key && i < tmp_set.maxelements/2;i++) { cacheset_add(&tmp_set, (unsigned char*)&key->digest, key->size, mempool); key = key->lru_next; } pthread_mutex_lock(&pool_mutex); mpool_free(mempool, map->data); pthread_mutex_unlock(&pool_mutex); memcpy(map, &tmp_set, sizeof(tmp_set)); }
/* free both size-specific and agnostic hash sets */ void hm_free(struct cli_matcher *root) { enum CLI_HASH_TYPE type; if(!root) return; for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) { struct cli_htu32 *ht = &root->hm.sizehashes[type]; const struct cli_htu32_element *item = NULL; if(!root->hm.sizehashes[type].capacity) continue; while((item = cli_htu32_next(ht, item))) { struct cli_sz_hash *szh = (struct cli_sz_hash *)item->data.as_ptr; mpool_free(root->mempool, szh->hash_array); while(szh->items) mpool_free(root->mempool, (void *)szh->virusnames[--szh->items]); mpool_free(root->mempool, szh->virusnames); mpool_free(root->mempool, szh); } cli_htu32_free(ht, root->mempool); } for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) { struct cli_sz_hash *szh = &root->hwild.hashes[type]; if(!szh->items) continue; mpool_free(root->mempool, szh->hash_array); while(szh->items) mpool_free(root->mempool, (void *)szh->virusnames[--szh->items]); mpool_free(root->mempool, szh->virusnames); } }
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 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; }
void moto_freeEnv(MotoEnv *env) { Enumeration *e; /* Free any outstanding frames */ while(vec_size(env->frames) > 0) { moto_freeFrame(env); } /* Free all the globals */ e = stab_getKeys(env->globals); while (enum_hasNext(e)) { char* n = (char*)enum_next(e); MotoVar* var = stab_get(env->globals,n); if(env->mode != COMPILER_MODE) { moto_freeVal(env,var->vs); } else { opool_release(env->valpool,var->vs); } free(var); } enum_free(e); stab_free(env->globals); /* free all cached regular expressions */ e = stab_getKeys(env->rxcache); while (enum_hasNext(e)) { char *rx = (char *)enum_next(e); MDFA *mdfa = (MDFA *)stab_get(env->rxcache, rx); if (mdfa != NULL) { mdfa_free(mdfa); } } enum_free(e); /* free all remaining pointers */ e = hset_elements(env->ptrs); while (enum_hasNext(e)) { void *ptr = enum_next(e); if (shared_check(ptr)) { free(ptr); } } enum_free(e); /* free all errors */ e = sset_elements(env->errs); while (enum_hasNext(e)) { void *ptr = enum_next(e); if (shared_check(ptr)) { free(ptr); } } enum_free(e); /* free all scopes */ e = stack_elements(env->scope); while (enum_hasNext(e)) { free(enum_next(e)); } enum_free(e); /* free all cells */ moto_freeTreeCells(env); /* free all class defs */ stab_free(env->cdefs); /* free remainder of env struct */ hset_free(env->ptrs); buf_free(env->out); buf_free(env->err); stab_free(env->types); vec_free(env->frames); ftab_free(env->ftable); /* Free all the stuff that got put in the mpool ... this includes MotoFunctions and MotoClassDefinitions */ mpool_free(env->mpool); stack_free(env->scope); stab_free(env->rxcache); //stack_free(env->callstack); sset_free(env->errs); sset_free(env->uses); sset_free(env->includes); buf_free(env->fcodebuffer); istack_free(env->scopeIDStack); htab_free(env->fdefs); htab_free(env->adefs); buf_free(env->constantPool); moto_freeTree(env->tree); opool_free(env->valpool); opool_free(env->bufpool); opool_free(env->stkpool); e = stab_getKeys(env->fcache); while (enum_hasNext(e)) free((char *)enum_next(e)); enum_free(e); stab_free(env->fcache); free(env); }
void motopp_freeEnv(MotoPP *ppenv) { Enumeration *e; log_debug(__FILE__, ">>> motopp_freeEnv\n"); buf_free(ppenv->out); buf_free(ppenv->err); buf_free(ppenv->argbuf); istack_free(ppenv->dirstack); stack_free(ppenv->frames); /* free vals */ e = hset_elements(ppenv->vallist); while (enum_hasNext(e)) { MotoPPVal *val = enum_next(e); if (shared_check(val->sval)) { free(val->sval); hset_remove(ppenv->ptrs, val->sval); } free(val); } enum_free(e); hset_free(ppenv->vallist); /* free macros */ while (stack_size(ppenv->macrostack) > 0) { SymbolTable *macros = stack_pop(ppenv->macrostack); e = stab_getKeys(macros); while (enum_hasNext(e)) { char *name = (char *)enum_next(e); MotoMacro *m = (MotoMacro *)stab_get(macros, name); motopp_freeMacro(m); } stab_free(macros); enum_free(e); } /* free all remaining sys pointers */ e = hset_elements(ppenv->sysptrs); while (enum_hasNext(e)) { void *ptr = enum_next(e); if (ptr) { sys_free(ptr); } } enum_free(e); /* free all remaining pointers */ e = hset_elements(ppenv->ptrs); while (enum_hasNext(e)) { void *ptr = enum_next(e); if (shared_check(ptr)) { free(ptr); } } enum_free(e); /* free remaining pooled memory */ mpool_free(ppenv->mpool); /* free remainder of env struct */ hset_free(ppenv->sysptrs); hset_free(ppenv->ptrs); stack_free(ppenv->macrostack); free(ppenv); log_debug(__FILE__, "<<< motopp_freeEnv\n"); }
/* Frees all the nodes */ static inline void cacheset_destroy(struct cache_set *cs, mpool_t *mempool) { mpool_free(mempool, cs->data); cs->data = NULL; }
int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, unsigned int dbtype, const char *filename, unsigned int chkonly) { struct cl_cvd cvd, dupcvd; FILE *dupfs; int ret; time_t s_time; int cfd; struct cli_dbio dbio; struct cli_dbinfo *dbinfo = NULL; char *dupname; dbio.hashctx = NULL; cli_dbgmsg("in cli_cvdload()\n"); /* verify */ if((ret = cli_cvdverify(fs, &cvd, dbtype))) return ret; if(dbtype <= 1) { /* check for duplicate db */ dupname = cli_strdup(filename); if(!dupname) return CL_EMEM; dupname[strlen(dupname) - 2] = (dbtype == 1 ? 'v' : 'l'); if(!access(dupname, R_OK) && (dupfs = fopen(dupname, "rb"))) { if((ret = cli_cvdverify(dupfs, &dupcvd, !dbtype))) { fclose(dupfs); free(dupname); return ret; } fclose(dupfs); if(dupcvd.version > cvd.version) { cli_warnmsg("Detected duplicate databases %s and %s. The %s database is older and will not be loaded, you should manually remove it from the database directory.\n", filename, dupname, filename); free(dupname); return CL_SUCCESS; } else if(dupcvd.version == cvd.version && !dbtype) { cli_warnmsg("Detected duplicate databases %s and %s, please manually remove one of them\n", filename, dupname); free(dupname); return CL_SUCCESS; } } free(dupname); } if(strstr(filename, "daily.")) { time(&s_time); if(cvd.stime > s_time) { if(cvd.stime - (unsigned int ) s_time > 3600) { cli_warnmsg("******************************************************\n"); cli_warnmsg("*** Virus database timestamp in the future! ***\n"); cli_warnmsg("*** Please check the timezone and clock settings ***\n"); cli_warnmsg("******************************************************\n"); } } else if((unsigned int) s_time - cvd.stime > 604800) { cli_warnmsg("**************************************************\n"); cli_warnmsg("*** The virus database is older than 7 days! ***\n"); cli_warnmsg("*** Please update it as soon as possible. ***\n"); cli_warnmsg("**************************************************\n"); } engine->dbversion[0] = cvd.version; engine->dbversion[1] = cvd.stime; } if(cvd.fl > cl_retflevel()) { cli_warnmsg("***********************************************************\n"); cli_warnmsg("*** This version of the ClamAV engine is outdated. ***\n"); cli_warnmsg("*** DON'T PANIC! Read http://www.clamav.net/support/faq ***\n"); cli_warnmsg("***********************************************************\n"); } cfd = fileno(fs); dbio.chkonly = 0; if(dbtype == 2) ret = cli_tgzload(cfd, engine, signo, options | CL_DB_UNSIGNED, &dbio, NULL); else ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, NULL); if(ret != CL_SUCCESS) return ret; dbinfo = engine->dbinfo; if(!dbinfo || !dbinfo->cvd || (dbinfo->cvd->version != cvd.version) || (dbinfo->cvd->sigs != cvd.sigs) || (dbinfo->cvd->fl != cvd.fl) || (dbinfo->cvd->stime != cvd.stime)) { cli_errmsg("cli_cvdload: Corrupted CVD header\n"); return CL_EMALFDB; } dbinfo = engine->dbinfo ? engine->dbinfo->next : NULL; if(!dbinfo) { cli_errmsg("cli_cvdload: dbinfo error\n"); return CL_EMALFDB; } dbio.chkonly = chkonly; if(dbtype == 2) options |= CL_DB_UNSIGNED; else options |= CL_DB_SIGNED | CL_DB_OFFICIAL; ret = cli_tgzload(cfd, engine, signo, options, &dbio, dbinfo); while(engine->dbinfo) { dbinfo = engine->dbinfo; engine->dbinfo = dbinfo->next; mpool_free(engine->mempool, dbinfo->name); mpool_free(engine->mempool, dbinfo->hash); if(dbinfo->cvd) cl_cvdfree(dbinfo->cvd); mpool_free(engine->mempool, dbinfo); } return ret; }
int main(void) { size_t n, m; usCount start, end; size_t roundings[16]; printf("N1527lib test program\n" "-=-=-=-=-=-=-=-=-=-=-\n"); n=mpool_minimum_roundings(roundings, 16); assert(n<16); printf("Minimum roundings from available allocators:\n"); for(m=0; m<n; m++) { printf(" %u\n", roundings[m]); } { mpool pool128, pool4096, poolA; void *temp1, *temp2; size_t usagecount, *alignments, *roundings; pool128=mpool_obtain(alignment128_attributes); temp1=mpool_malloc(pool128, 1); temp2=mpool_malloc(pool128, 1); printf("128 aligned %p (%u), %p (%u)", temp1, mpool_usable_size(pool128, temp1), temp2, mpool_usable_size(pool128, temp2)); assert(!((size_t)temp1 & 127)); assert(!((size_t)temp2 & 127)); mpool_info(pool128, &usagecount, &alignments, &roundings, NULL); printf(" usagecount=%u, roundings[0]=%u\n", usagecount, roundings[0]); pool4096=mpool_obtain(alignment4096_attributes); temp1=mpool_malloc(pool4096, 1); temp2=mpool_malloc(pool4096, 1); printf("4096 aligned %p (%u), %p (%u)", temp1, mpool_usable_size(pool4096, temp1), temp2, mpool_usable_size(pool4096, temp2)); assert(!((size_t)temp1 & 4095)); assert(!((size_t)temp2 & 4095)); mpool_info(pool4096, &usagecount, &alignments, &roundings, NULL); printf(" usagecount=%u, roundings[0]=%u\n", usagecount, roundings[0]); poolA=mpool_obtain(alignment128_attributes_a); mpool_info(poolA, &usagecount, &alignments, &roundings, NULL); printf("PoolA: usagecount=%u, roundings[0]=%u\n", usagecount, roundings[0]); assert(poolA==pool128); } syspool=mpool_obtain(MPOOL_DEFAULT); srand(1); for(n=0; n<RECORDS; n++) sizes[n]=rand() & 1023; if(1) { unsigned frees=0; printf("Fragmenting free space ...\n"); start=GetUsCount(); while(GetUsCount()-start<3000000000000) { n=rand() % RECORDS; if(ptrs[n]) { mpool_free(syspool, ptrs[n]); ptrs[n]=0; frees++; } else ptrs[n]=mpool_malloc(syspool, sizes[n]); } memset(ptrs, 0, RECORDS*sizeof(void *)); printf("Did %u frees\n", frees); } if(0) { typedef void* mspace; extern mspace get_dlmalloc_mspace(mpool pool); extern void* mspace_malloc(mspace msp, size_t bytes); extern void mspace_free(mspace msp, void* mem); printf("\ndlmalloc Speed test\n" "-------------------\n"); { mspace ms=get_dlmalloc_mspace(syspool); for(m=0; m<3; m++) { size_t count=RECORDS, size=1024; for(n=0; n<RECORDS; n++) sizes[n]=rand() & 1023; start=GetUsCount(); for(n=0; n<RECORDS; n++) { ptrs[n]=mspace_malloc(ms, sizes[n]); } end=GetUsCount(); printf("mspace_malloc() does %f mallocs/sec\n", RECORDS/((end-start)/1000000000000.0)); start=GetUsCount(); for(n=0; n<RECORDS; n++) { mspace_free(ms, ptrs[n]); ptrs[n]=0; } end=GetUsCount(); printf("mspace_free() does %f frees/sec\n\n", RECORDS/((end-start)/1000000000000.0)); } } } if(1) { printf("\nMPool Speed test\n" "----------------\n"); for(m=0; m<3; m++) { size_t count=RECORDS, size=1024; for(n=0; n<RECORDS; n++) sizes[n]=rand() & 1023; start=GetUsCount(); mpool_batch(syspool, NULL, ptrs, sizes, &count, 0); end=GetUsCount(); printf("mpool_batch() does %f mallocs/sec\n", RECORDS/((end-start)/1000000000000.0)); count=RECORDS; start=GetUsCount(); mpool_batch(syspool, NULL, ptrs, NULL, &count, 0); end=GetUsCount(); printf("mpool_batch() does %f frees/sec\n", RECORDS/((end-start)/1000000000000.0)); start=GetUsCount(); for(n=0; n<RECORDS; n++) { ptrs[n]=mpool_malloc(syspool, sizes[n]); } end=GetUsCount(); printf("mpool_malloc() does %f mallocs/sec\n", RECORDS/((end-start)/1000000000000.0)); start=GetUsCount(); for(n=0; n<RECORDS; n++) { mpool_free(syspool, ptrs[n]); ptrs[n]=0; } end=GetUsCount(); printf("mpool_free() does %f frees/sec\n\n", RECORDS/((end-start)/1000000000000.0)); } } #ifdef _MSC_VER printf("Press Return to exit ...\n"); getchar(); #endif 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 cli_bm_addpatt(struct cli_matcher *root, struct cli_bm_patt *pattern, const char *offset) { uint16_t idx, i; const unsigned char *pt = pattern->pattern; struct cli_bm_patt *prev, *next = NULL; int ret; if(pattern->length < BM_MIN_LENGTH) { cli_errmsg("cli_bm_addpatt: Signature for %s is too short\n", pattern->virname); return CL_EMALFDB; } if((ret = cli_caloff(offset, NULL, root->type, pattern->offdata, &pattern->offset_min, &pattern->offset_max))) { cli_errmsg("cli_bm_addpatt: Can't calculate offset for signature %s\n", pattern->virname); return ret; } if(pattern->offdata[0] != CLI_OFF_ANY) { if(pattern->offdata[0] == CLI_OFF_ABSOLUTE) root->bm_absoff_num++; else root->bm_reloff_num++; } /* bm_offmode doesn't use the prefilter for BM signatures anyway, so * don't add these to the filter. */ if(root->filter && !root->bm_offmode) { /* the bm_suffix load balancing below can shorten the sig, * we want to see the entire signature! */ if (filter_add_static(root->filter, pattern->pattern, pattern->length, pattern->virname) == -1) { cli_warnmsg("cli_bm_addpatt: cannot use filter for trie\n"); mpool_free(root->mempool, root->filter); root->filter = NULL; } /* TODO: should this affect maxpatlen? */ } #if BM_MIN_LENGTH == BM_BLOCK_SIZE /* try to load balance bm_suffix (at the cost of bm_shift) */ for(i = 0; i < pattern->length - BM_BLOCK_SIZE + 1; i++) { idx = HASH(pt[i], pt[i + 1], pt[i + 2]); if(!root->bm_suffix[idx]) { if(i) { pattern->prefix = pattern->pattern; pattern->prefix_length = i; pattern->pattern = &pattern->pattern[i]; pattern->length -= i; pt = pattern->pattern; } break; } } #endif for(i = 0; i <= BM_MIN_LENGTH - BM_BLOCK_SIZE; i++) { idx = HASH(pt[i], pt[i + 1], pt[i + 2]); root->bm_shift[idx] = MIN(root->bm_shift[idx], BM_MIN_LENGTH - BM_BLOCK_SIZE - i); } prev = next = root->bm_suffix[idx]; while(next) { if(pt[0] >= next->pattern0) break; prev = next; next = next->next; } if(next == root->bm_suffix[idx]) { pattern->next = root->bm_suffix[idx]; if(root->bm_suffix[idx]) pattern->cnt = root->bm_suffix[idx]->cnt; root->bm_suffix[idx] = pattern; } else { pattern->next = prev->next; prev->next = pattern; } pattern->pattern0 = pattern->pattern[0]; root->bm_suffix[idx]->cnt++; if(root->bm_offmode) { root->bm_pattab = (struct cli_bm_patt **) mpool_realloc2(root->mempool, root->bm_pattab, (root->bm_patterns + 1) * sizeof(struct cli_bm_patt *)); if(!root->bm_pattab) { cli_errmsg("cli_bm_addpatt: Can't allocate memory for root->bm_pattab\n"); return CL_EMEM; } root->bm_pattab[root->bm_patterns] = pattern; if(pattern->offdata[0] != CLI_OFF_ABSOLUTE) pattern->offset_min = root->bm_patterns; } root->bm_patterns++; return CL_SUCCESS; }