[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b

Tomasz Kojm tkojm at clamav.net
Sun Apr 4 01:19:46 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit 8d278b95eb5043f5fac968764917954053890f80
Merge: 2c652ed7e993a58c74d1bfb6c7e362eac281f26f f6d4d6e769d753939e3e5f8daa918573aa7ecee0
Author: Tomasz Kojm <tkojm at clamav.net>
Date:   Thu Feb 11 19:31:32 2010 +0100

    Merge branch 'master' of ssh://git.clam.sourcefire.com/var/lib/git/clamav-devel

diff --combined libclamav/matcher-ac.c
index e75c652,b0904a7..d1f8a62
--- a/libclamav/matcher-ac.c
+++ b/libclamav/matcher-ac.c
@@@ -42,6 -42,7 +42,7 @@@
  #include "str.h"
  #include "readdb.h"
  #include "default.h"
+ #include "filtering.h"
  
  #include "mpool.h"
  
@@@ -333,7 -334,7 +334,7 @@@ static int ac_maketrans(struct cli_matc
  	    continue;
  	for(i = 0; i < 256; i++) {
  	    child = node->trans[i];
- 	    if(!child) {
+ 	    if (!child || (!IS_FINAL(child) && IS_LEAF(child))) {
  		struct cli_ac_node *failtarget = node->fail;
  		while(IS_LEAF(failtarget) || !failtarget->trans[i])
  		    failtarget = failtarget->fail;
@@@ -358,6 -359,8 +359,8 @@@ int cli_ac_buildtrie(struct cli_matche
  	return CL_SUCCESS;
      }
  
+     if (root->filter)
+ 	cli_warnmsg("Using filter for trie %d\n", root->type);
      return ac_maketrans(root);
  }
  
@@@ -383,6 -386,18 +386,18 @@@ int cli_ac_init(struct cli_matcher *roo
      root->ac_mindepth = mindepth;
      root->ac_maxdepth = maxdepth;
  
+     /* TODO: dconf here ?*/
+     if (cli_mtargets[root->type].enable_prefiltering && 0) {/* Disabled for now */
+ 	root->filter = mpool_malloc(root->mempool, sizeof(*root->filter));
+ 	if (!root->filter) {
+ 	    cli_errmsg("cli_ac_init: Can't allocate memory for ac_root->filter\n");
+ 	    mpool_free(root->mempool, root->ac_root->trans);
+ 	    mpool_free(root->mempool, root->ac_root);
+ 	    return CL_EMEM;
+ 	}
+ 	filter_init(root->filter);
+     }
+ 
      return CL_SUCCESS;
  }
  
@@@ -446,6 -461,8 +461,8 @@@ void cli_ac_free(struct cli_matcher *ro
  	mpool_free(root->mempool, root->ac_root->trans);
  	mpool_free(root->mempool, root->ac_root);
      }
+     if (root->filter)
+ 	mpool_free(root->mempool, root->filter);
  }
  
  /*
@@@ -864,7 -881,7 +881,7 @@@ inline static int ac_findmatch(const un
  
  int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs, uint32_t reloffsigs, uint8_t tracklen)
  {
- 	unsigned int i;
+ 	unsigned int i, j;
  
  
      if(!data) {
@@@ -872,6 -889,8 +889,8 @@@
  	return CL_ENULLARG;
      }
  
+     cli_hashset_init_noalloc(&data->vinfo);
+ 
      data->reloffsigs = reloffsigs;
      if(reloffsigs) {
  	data->offset = (uint32_t *) cli_malloc(reloffsigs * 2 * sizeof(uint32_t));
@@@ -917,7 -936,41 +936,41 @@@
  	}
  	for(i = 1; i < lsigs; i++)
  	    data->lsigcnt[i] = data->lsigcnt[0] + 64 * i;
+ 
+ 	/* subsig offsets */
+ 	data->lsigsuboff = (uint32_t **) cli_malloc(lsigs * sizeof(uint32_t *));
+ 	if(!data->lsigsuboff) {
+ 	    free(data->lsigcnt[0]);
+ 	    free(data->lsigcnt);
+ 	    if(partsigs)
+ 		free(data->offmatrix);
+ 	    if(reloffsigs)
+ 		free(data->offset);
+ 	    cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigsuboff\n");
+ 	    return CL_EMEM;
+ 	}
+ 	data->lsigsuboff[0] = (uint32_t *) cli_calloc(lsigs * 64, sizeof(uint32_t));
+ 	if(!data->lsigsuboff[0]) {
+ 	    free(data->lsigsuboff);
+ 	    free(data->lsigcnt[0]);
+ 	    free(data->lsigcnt);
+ 	    if(partsigs)
+ 		free(data->offmatrix);
+ 	    if(reloffsigs)
+ 		free(data->offset);
+ 	    cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigsuboff[0]\n");
+ 	    return CL_EMEM;
+ 	}
+ 	for(j = 0; j < 64; j++)
+ 	    data->lsigsuboff[0][j] = CLI_OFF_NONE;
+ 	for(i = 1; i < lsigs; i++) {
+ 	    data->lsigsuboff[i] = data->lsigsuboff[0] + 64 * i;
+ 	    for(j = 0; j < 64; j++)
+ 		data->lsigsuboff[i][j] = CLI_OFF_NONE;
+ 	}
      }
+     for (i=0;i<32;i++)
+ 	data->macro_lastmatch[i] = CLI_OFF_NONE;
  
      return CL_SUCCESS;
  }
@@@ -934,6 -987,8 +987,8 @@@ int cli_ac_caloff(const struct cli_matc
  	info.fsize = map->len;
      }
  
+     info.exeinfo.vinfo = &data->vinfo;
+ 
      for(i = 0; i < root->ac_reloff_num; i++) {
  	patt = root->ac_reloff[i];
  	if(!map) {
@@@ -957,6 -1012,7 +1012,7 @@@ void cli_ac_freedata(struct cli_ac_dat
  {
  	uint32_t i;
  
+     cli_hashset_destroy(&data->vinfo);
  
      if(data && data->partsigs) {
  	for(i = 0; i < data->partsigs; i++) {
@@@ -972,6 -1028,8 +1028,8 @@@
      if(data && data->lsigs) {
  	free(data->lsigcnt[0]);
  	free(data->lsigcnt);
+ 	free(data->lsigsuboff[0]);
+ 	free(data->lsigsuboff);
  	data->lsigs = 0;
      }
  
@@@ -1013,6 -1071,62 +1071,62 @@@ inline static int ac_addtype(struct cli
      return CL_SUCCESS;
  }
  
+ static inline void lsig_sub_matched(const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t lsigid1, uint32_t lsigid2, uint32_t realoff)
+ {
+     if(mdata->lsigsuboff[lsigid1][lsigid2] == CLI_OFF_NONE)
+ 	mdata->lsigsuboff[lsigid1][lsigid2] = realoff;
+     else if (mdata->lsigcnt[lsigid1][lsigid2] == 1) {
+ 	/* Check that the previous match had a macro match following it at the 
+ 	 * correct distance. This check is only done after the 1st match.*/
+ 	const struct cli_lsig_tdb *tdb = &root->ac_lsigtable[lsigid1]->tdb;
+ 	const struct cli_ac_patt *macropt;
+ 	uint32_t id, last_macro_match, smin, smax, last_macroprev_match;
+ 	if (!tdb->macro_ptids)
+ 	    return;
+ 	id = tdb->macro_ptids[lsigid2];
+ 	if (!id)
+ 	    return;
+ 	macropt = root->ac_pattable[id];
+ 	smin = macropt->ch_mindist[0];
+ 	smax = macropt->ch_maxdist[0];
+ 	/* start of last macro match */
+ 	last_macro_match = mdata->macro_lastmatch[macropt->sigid];
+ 	/* start of previous lsig subsig match */
+ 	last_macroprev_match = mdata->lsigsuboff[lsigid1][lsigid2];
+ 	if (last_macro_match != CLI_OFF_NONE)
+ 	    cli_dbgmsg("Checking macro match: %u + (%u - %u) == %u\n",
+ 		       last_macroprev_match, smin, smax, last_macro_match);
+ 	if (last_macro_match == CLI_OFF_NONE ||
+ 	    last_macroprev_match + smin > last_macro_match ||
+ 	    last_macroprev_match + smax < last_macro_match) {
+ 	    cli_dbgmsg("Canceled false lsig macro match\n");
+ 	    /* Previous match was false, cancel it and make this match the first
+ 	     * one.*/
+ 	    mdata->lsigcnt[lsigid1][lsigid2] = 0;
+ 	    mdata->lsigsuboff[lsigid1][lsigid2] = realoff;
+ 	} else {
+ 	    /* mark the macro sig itself matched */
+ 	    mdata->lsigcnt[lsigid1][lsigid2+1]++;
+ 	    mdata->lsigsuboff[lsigid1][lsigid2+1] = last_macro_match;
+ 	}
+     }
+     if (realoff != CLI_OFF_NONE) {
+ 	mdata->lsigcnt[lsigid1][lsigid2]++;
+     }
+ }
+ 
+ void cli_ac_chkmacro(struct cli_matcher *root, struct cli_ac_data *data, unsigned lsigid1)
+ {
+     const struct cli_lsig_tdb *tdb = &root->ac_lsigtable[lsigid1]->tdb;
+     unsigned i;
+     /* Loop through all subsigs, and if they are tied to macros check that the
+      * macro matched at a correct distance */
+     for (i=0;i<tdb->subsigs;i++) {
+ 	lsig_sub_matched(root, data, lsigid1, i, CLI_OFF_NONE);
+     }
+ }
+ 
+ 
  int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, void **customdata, struct cli_ac_result **res, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, struct cli_matched_type **ftoffset, unsigned int mode, const cli_ctx *ctx)
  {
  	struct cli_ac_node *current;
@@@ -1035,17 -1149,15 +1149,15 @@@
      current = root->ac_root;
  
      for(i = 0; i < length; i++)  {
- 
- 	if(IS_LEAF(current))
- 	    current = current->fail;
- 
  	current = current->trans[buffer[i]];
  
  	if(IS_FINAL(current)) {
  	    patt = current->list;
+ 	    if (IS_LEAF(current))
+ 		current = current->fail;
  	    while(patt) {
  		bp = i + 1 - patt->depth;
- 		if(!patt->next_same && (patt->offset_min != CLI_OFF_ANY) && (!patt->sigid || patt->partno == 1)) {
+ 		if(patt->offdata[0] != CLI_OFF_VERSION && patt->offdata[0] != CLI_OFF_MACRO && !patt->next_same && (patt->offset_min != CLI_OFF_ANY) && (!patt->sigid || patt->partno == 1)) {
  		    if(patt->offset_min == CLI_OFF_NONE) {
  			patt = patt->next;
  			continue;
@@@ -1071,7 -1183,17 +1183,17 @@@
  			    continue;
  			}
  			realoff = offset + bp - pt->prefix_length;
- 			if(pt->offset_min != CLI_OFF_ANY && (!pt->sigid || pt->partno == 1)) {
+ 			if(patt->offdata[0] == CLI_OFF_VERSION) {
+ 			    if(!cli_hashset_contains_maybe_noalloc(&mdata->vinfo, realoff)) {
+ 				pt = pt->next_same;
+ 				continue;
+ 			    }
+ 			    cli_dbgmsg("cli_ac_scanbuff: VI match for offset %x\n", realoff);
+ 			} else if (patt->offdata[0] == CLI_OFF_MACRO) {
+ 			    mdata->macro_lastmatch[patt->offdata[1]] = realoff;
+ 			    pt = pt->next_same;
+ 			    continue;
+ 			} else if(pt->offset_min != CLI_OFF_ANY && (!pt->sigid || pt->partno == 1)) {
  			    if(pt->offset_min == CLI_OFF_NONE) {
  				pt = pt->next_same;
  				continue;
@@@ -1165,7 -1287,7 +1287,7 @@@
  
  				} else { /* !pt->type */
  				    if(pt->lsigid[0]) {
- 					mdata->lsigcnt[pt->lsigid[1]][pt->lsigid[2]]++;
+ 					lsig_sub_matched(root, mdata, pt->lsigid[1], pt->lsigid[2], realoff);
  					pt = pt->next_same;
  					continue;
  				    }
@@@ -1177,6 -1299,7 +1299,7 @@@
  					newres->virname = pt->virname;
  					newres->customdata = pt->customdata;
  					newres->next = *res;
+ 					newres->offset = realoff;
  					*res = newres;
  
  					pt = pt->next_same;
@@@ -1207,7 -1330,7 +1330,7 @@@
  				}
  			    } else {
  				if(pt->lsigid[0]) {
- 				    mdata->lsigcnt[pt->lsigid[1]][pt->lsigid[2]]++;
+ 				    lsig_sub_matched(root, mdata, pt->lsigid[1], pt->lsigid[2], realoff);
  				    pt = pt->next_same;
  				    continue;
  				}
@@@ -1218,6 -1341,7 +1341,7 @@@
  					return CL_EMEM;
  				    newres->virname = pt->virname;
  				    newres->customdata = pt->customdata;
+ 				    newres->offset = realoff;
  				    newres->next = *res;
  				    *res = newres;
  
@@@ -1245,7 -1369,7 +1369,7 @@@
  
  static int qcompare(const void *a, const void *b)
  {
-     return *(unsigned char *)a - *(unsigned char *)b;
+     return *(const unsigned char *)a - *(const unsigned char *)b;
  }
  
  /* FIXME: clean up the code */
@@@ -1563,6 -1687,17 +1687,17 @@@ int cli_ac_addsig(struct cli_matcher *r
      new->length = strlen(hex ? hex : hexsig) / 2;
      free(hex);
  
+     if (root->filter) {
+ 	/* so that we can show meaningful messages */
+ 	new->virname = (char*)virname;
+ 	if (filter_add_acpatt(root->filter, new) == -1) {
+ 	    cli_warnmsg("cli_ac_addpatt: cannot use filter for trie\n");
+ 	    mpool_free(root->mempool, root->filter);
+ 	    root->filter = NULL;
+ 	}
+ 	/* TODO: should this affect maxpatlen? */
+     }
+ 
      for(i = 0; i < root->ac_maxdepth && i < new->length; i++) {
  	if(new->pattern[i] & CLI_MATCH_WILDCARD) {
  	    wprefix = 1;
@@@ -1620,9 -1755,9 +1755,9 @@@
      }
  
      if(new->length > root->maxpatlen)
 -	root->maxpatlen = new->length;
 +	root->maxpatlen = new->length + new->prefix_length;
  
-     new->virname = cli_mpool_virname(root->mempool, (char *) virname, options & CL_DB_OFFICIAL);
+     new->virname = cli_mpool_virname(root->mempool, virname, options & CL_DB_OFFICIAL);
      if(!new->virname) {
  	mpool_free(root->mempool, new->prefix ? new->prefix : new->pattern);
  	mpool_ac_free_special(root->mempool, new);
@@@ -1650,7 -1785,7 +1785,7 @@@
  	return ret;
      }
  
-     if(new->offdata[0] != CLI_OFF_ANY && new->offdata[0] != CLI_OFF_ABSOLUTE) {
+     if(new->offdata[0] != CLI_OFF_ANY && new->offdata[0] != CLI_OFF_ABSOLUTE && new->offdata[0] != CLI_OFF_MACRO) {
  	root->ac_reloff = (struct cli_ac_patt **) mpool_realloc2(root->mempool, root->ac_reloff, (root->ac_reloff_num + 1) * sizeof(struct cli_ac_patt *));
  	if(!root->ac_reloff) {
  	    cli_errmsg("cli_ac_addsig: Can't allocate memory for root->ac_reloff\n");

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list