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

aCaB acab at clamav.net
Sun Apr 4 01:14:48 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit 4365fec1e517207594e67ee74d71bff59c39a683
Merge: 570b1d0050ebc727c069945f4dc2ee5b8816f665 52f52931a2f2153b2b47c8b8ca982182018d2b00
Author: aCaB <acab at clamav.net>
Date:   Fri Jan 15 03:02:05 2010 +0100

    Merge branch 'cache'

diff --combined libclamav/matcher.c
index b4bf352,0dc0c6b..f9e761f
--- a/libclamav/matcher.c
+++ b/libclamav/matcher.c
@@@ -345,7 -345,7 +345,7 @@@ int cli_scandesc(int desc, cli_ctx *ctx
      fmap_t *map = *ctx->fmap;
  
      if((*ctx->fmap = fmap(desc, 0, 0))) {
- 	ret = cli_fmap_scandesc(ctx, ftype, ftonly, ftoffset, acmode);
+ 	ret = cli_fmap_scandesc(ctx, ftype, ftonly, ftoffset, acmode, NULL);
  	funmap(*ctx->fmap);
      }
      *ctx->fmap = map;
@@@ -353,7 -353,7 +353,7 @@@
  }
  
  
- int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode)
+ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, unsigned char *refhash)
  {
   	unsigned char *buff;
  	int ret = CL_CLEAN, type = CL_CLEAN, bytes;
@@@ -421,7 -421,7 +421,7 @@@
  	}
      }
  
-     if(!ftonly && ctx->engine->md5_hdb)
+     if(!refhash && !ftonly && ctx->engine->md5_hdb)
  	cli_md5_init(&md5ctx);
  
      while(offset < map->len) {
@@@ -460,7 -460,7 +460,7 @@@
  		    type = ret;
  	    }
  
- 	    if(ctx->engine->md5_hdb)
+ 	    if(!refhash && ctx->engine->md5_hdb)
  		cli_md5_update(&md5ctx, buff + maxpatlen * (offset!=0), bytes - maxpatlen * (offset!=0));
  	}
  
@@@ -473,8 -473,6 +473,8 @@@
  	evalcnt = 0; \
  	evalids = 0; \
  	if(cli_ac_chklsig(xroot->ac_lsigtable[i]->logic, xroot->ac_lsigtable[i]->logic + strlen(xroot->ac_lsigtable[i]->logic), xdata.lsigcnt[i], &evalcnt, &evalids, 0) == 1) { \
 +	    if(xroot->ac_lsigtable[i]->tdb.container && xroot->ac_lsigtable[i]->tdb.container[0] != ctx->container_type) \
 +		continue; \
  	    if(xroot->ac_lsigtable[i]->tdb.filesize && (xroot->ac_lsigtable[i]->tdb.filesize[0] > map->len || xroot->ac_lsigtable[i]->tdb.filesize[1] < map->len)) \
  		continue; \
  	    \
@@@ -537,15 -535,18 +537,18 @@@
  
      if(!ftonly && ctx->engine->md5_hdb) {
  	    const struct cli_bm_patt *patt;
- 	cli_md5_final(digest, &md5ctx);
- 	if(cli_bm_scanbuff(digest, 16, ctx->virname, &patt, ctx->engine->md5_hdb, 0, NULL, NULL) == CL_VIRUS && patt->filesize == map->len && (cli_bm_scanbuff(digest, 16, NULL, &patt, ctx->engine->md5_fp, 0, NULL, NULL) != CL_VIRUS || patt->filesize != map->len))
+ 	if(!refhash) {
+ 	    cli_md5_final(digest, &md5ctx);
+ 	    refhash = digest;
+ 	}
+ 	if(cli_bm_scanbuff(refhash, 16, ctx->virname, &patt, ctx->engine->md5_hdb, 0, NULL, NULL) == CL_VIRUS && patt->filesize == map->len && (cli_bm_scanbuff(refhash, 16, NULL, &patt, ctx->engine->md5_fp, 0, NULL, NULL) != CL_VIRUS || patt->filesize != map->len))
  	    return CL_VIRUS;
      }
  
      return (acmode & AC_SCAN_FT) ? type : CL_CLEAN;
  }
  
 -int cli_matchmeta(cli_ctx *ctx, cli_file_t ftype, const char *fname, size_t fsizec, size_t fsizer, int encrypted, int filepos, int res1, void *res2)
 +int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, int filepos, int res1, void *res2)
  {
  	const struct cli_cdb *cdb;
  
@@@ -556,6 -557,9 +559,6 @@@
  	if(cdb->ctype != CL_TYPE_ANY && cdb->ctype != ctx->container_type)
  	    continue;
  
 -	if(cdb->ftype != CL_TYPE_ANY && cdb->ftype != ftype)
 -	    continue;
 -
  	if(cdb->encrypted != 2 && cdb->encrypted != encrypted)
  	    continue;
  
diff --combined libclamav/matcher.h
index 0d419d6,5a07262..d7e1ce5
--- a/libclamav/matcher.h
+++ b/libclamav/matcher.h
@@@ -48,14 -48,12 +48,14 @@@ struct cli_lsig_tdb 
  #define CLI_TDB_RANGE	1
  #define CLI_TDB_STR	2
  #define CLI_TDB_RANGE2	3
 +#define CLI_TDB_FTYPE	4
      uint32_t *val, *range;
      char *str;
      uint32_t cnt[3];
  
      const uint32_t *target;
      const uint32_t *engine, *nos, *ep, *filesize;
 +    const uint32_t *container;
      /*
      const uint32_t *sectoff, *sectrva, *sectvsz, *sectraw, *sectrsz,
  		   *secturva, *sectuvsz, *secturaw, *sectursz;
@@@ -105,6 -103,7 +105,6 @@@ struct cli_cd
  {
      char	*virname;   /* virus name */
      cli_file_t	ctype;	    /* container type */
 -    cli_file_t	ftype;	    /* file type */
      regex_t	name;	    /* filename regex */
      size_t	csize[2];   /* container size (min, max); if csize[0] != csize[1]
  			     * then value of 0 makes the field ignored
@@@ -159,12 -158,11 +159,11 @@@ struct cli_target_info 
  int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata);
  
  int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode);
- int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode);
- 
+ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, unsigned char *digest);
  int cli_caloff(const char *offstr, struct cli_target_info *info, fmap_t *map, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max);
  
  int cli_checkfp(int fd, cli_ctx *ctx);
  
 -int cli_matchmeta(cli_ctx *ctx, cli_file_t ftype, const char *fname, size_t fsizec, size_t fsizer, int encrypted, int filepos, int res1, void *res2);
 +int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, int filepos, int res1, void *res2);
  
  #endif
diff --combined libclamav/readdb.c
index 458e94c,9f7b599..8c966e9
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@@ -253,7 -253,7 +253,7 @@@ int cli_parse_add(struct cli_matcher *r
  	}
  	bm_new->length = hexlen / 2;
  
 -	bm_new->virname = cli_mpool_virname(root->mempool, (char *) virname, options & CL_DB_OFFICIAL);
 +	bm_new->virname = cli_mpool_virname(root->mempool, virname, options & CL_DB_OFFICIAL);
  	if(!bm_new->virname) {
  	    mpool_free(root->mempool, bm_new->pattern);
  	    mpool_free(root->mempool, bm_new);
@@@ -409,7 -409,7 +409,7 @@@ static int cli_chkign(const struct cli_
      if(!ignored || !signame || !entry)
  	return 0;
  
 -    if(cli_bm_scanbuff(signame, strlen(signame), &md5_expected, NULL, ignored, 0, NULL, NULL) == CL_VIRUS) {
 +    if(cli_bm_scanbuff((const unsigned char *) signame, strlen(signame), &md5_expected, NULL, ignored, 0, NULL, NULL) == CL_VIRUS) {
  	if(md5_expected) {
  	    cli_md5_init(&md5ctx);
              cli_md5_update(&md5ctx, entry, strlen(entry));
@@@ -462,7 -462,7 +462,7 @@@ static int cli_chkpua(const char *signa
  
  static int cli_loaddb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio, const char *dbname)
  {
 -	char buffer[FILEBUFF], *buffer_cpy, *pt, *start;
 +	char buffer[FILEBUFF], *buffer_cpy = NULL, *pt, *start;
  	unsigned int line = 0, sigs = 0;
  	int ret = 0;
  	struct cli_matcher *root;
@@@ -528,7 -528,7 +528,7 @@@
  static int cli_loadidb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio)
  {
          const char *tokens[ICO_TOKENS + 1];
 -	char buffer[FILEBUFF], *buffer_cpy;
 +	char buffer[FILEBUFF], *buffer_cpy = NULL;
  	uint8_t *hash;
  	int ret = CL_SUCCESS;
  	unsigned int line = 0, sigs = 0, tokens_count, i, size, enginesize;
@@@ -796,7 -796,7 +796,7 @@@ static int cli_loadpdb(FILE *fs, struc
  static int cli_loadndb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned short sdb, unsigned int options, struct cli_dbio *dbio, const char *dbname)
  {
  	const char *tokens[NDB_TOKENS + 1];
 -	char buffer[FILEBUFF], *buffer_cpy;
 +	char buffer[FILEBUFF], *buffer_cpy = NULL;
  	const char *sig, *virname, *offset, *pt;
  	struct cli_matcher *root;
  	int line = 0, sigs = 0, ret = 0, tokens_count;
@@@ -923,7 -923,7 +923,7 @@@ struct lsig_attrib 
  static int lsigattribs(char *attribs, struct cli_lsig_tdb *tdb)
  {
  	struct lsig_attrib attrtab[] = {
 -#define ATTRIB_TOKENS	7
 +#define ATTRIB_TOKENS	8
  	    { "Target",		    CLI_TDB_UINT,	(void **) &tdb->target	    },
  	    { "Engine",		    CLI_TDB_RANGE,	(void **) &tdb->engine	    },
  
@@@ -934,7 -934,6 +934,7 @@@
  	    { "IconGroup1",	    CLI_TDB_STR,	(void **) &tdb->icongrp1    },
  	    { "IconGroup2",	    CLI_TDB_STR,	(void **) &tdb->icongrp2    },
  
 +	    { "Container",	    CLI_TDB_FTYPE,	(void **) &tdb->container   },
  /*
  	    { "SectOff",    CLI_TDB_RANGE2,	(void **) &tdb->sectoff	    },
  	    { "SectRVA",    CLI_TDB_RANGE2,	(void **) &tdb->sectrva	    },
@@@ -973,7 -972,7 +973,7 @@@
  
  	if(!apt) {
  	    cli_dbgmsg("lsigattribs: Unknown attribute name '%s'\n", tokens[i]);
 -	    continue;
 +	    return 1;
  	}
  
  	switch(apt->type) {
@@@ -991,20 -990,6 +991,20 @@@
  		tdb->val[cnt] = atoi(pt);
  		break;
  
 +	    case CLI_TDB_FTYPE:
 +		if((v1 = cli_ftcode(pt)) == CL_TYPE_ERROR) {
 +		    cli_dbgmsg("lsigattribs: Unknown file type in %s\n", tokens[i]);
 +		    return 1; /* skip */
 +		}
 +		off[i] = cnt = tdb->cnt[CLI_TDB_UINT]++;
 +		tdb->val = (uint32_t *) mpool_realloc2(tdb->mempool, tdb->val, tdb->cnt[CLI_TDB_UINT] * sizeof(uint32_t));
 +		if(!tdb->val) {
 +		    tdb->cnt[CLI_TDB_UINT] = 0;
 +		    return -1;
 +		}
 +		tdb->val[cnt] = v1;
 +		break;
 +
  	    case CLI_TDB_RANGE:
  		if(!(pt2 = strchr(pt, '-'))) {
  		    cli_errmsg("lsigattribs: Incorrect parameters in '%s'\n", tokens[i]);
@@@ -1077,7 -1062,6 +1077,7 @@@
  	    continue;
  	switch(apt->type) {
  	    case CLI_TDB_UINT:
 +	    case CLI_TDB_FTYPE:
  		*apt->pt = (uint32_t *) &tdb->val[off[i]];
  		break;
  
@@@ -1105,11 -1089,11 +1105,11 @@@
    } while(0);
  
  #define LDB_TOKENS 67
 -static int load_oneldb(char *buffer, int chkpua, int chkign, struct cl_engine *engine, unsigned int options, const char *dbname, unsigned line, unsigned *sigs, struct cli_bc *bc, const char *buffer_cpy)
 +static int load_oneldb(char *buffer, int chkpua, int chkign, struct cl_engine *engine, unsigned int options, const char *dbname, unsigned int line, unsigned int *sigs, struct cli_bc *bc, const char *buffer_cpy)
  {
      const char *sig, *virname, *offset, *logic;
      struct cli_ac_lsig **newtable, *lsig;
 -    char *tokens[LDB_TOKENS], *pt;
 +    char *tokens[LDB_TOKENS+1], *pt;
      int i, subsigs, tokens_count;
      unsigned short target = 0;
      struct cli_matcher *root;
@@@ -1117,7 -1101,7 +1117,7 @@@
      uint32_t lsigid[2];
      int ret;
  
 -	tokens_count = cli_strtokenize(buffer, ';', LDB_TOKENS + 1, (const char **) tokens);
 +    tokens_count = cli_strtokenize(buffer, ';', LDB_TOKENS + 1, (const char **) tokens);
      if(tokens_count < 4) {
  	return CL_EMALFDB;
      }
@@@ -1158,24 -1142,18 +1158,24 @@@
  #ifdef USE_MPOOL
      tdb.mempool = engine->mempool;
  #endif
 -    if(lsigattribs(tokens[1], &tdb) == -1) {
 +    if((ret = lsigattribs(tokens[1], &tdb))) {
  	FREE_TDB(tdb);
 +	if(ret == 1) {
 +	    cli_dbgmsg("cli_loadldb: Not supported attribute(s) in logical signature for %s, skipping\n", virname);
 +	    (*sigs)--;
 +	    return CL_SUCCESS;
 +	}
  	return CL_EMALFDB;
      }
 +
      if(!tdb.target) {
  	cli_errmsg("cli_loadldb: No target specified in TDB\n");
  	FREE_TDB(tdb);
  	return CL_EMALFDB;
      } else if(tdb.target[0] >= CLI_MTARGETS) {
 -	cli_dbgmsg("cli_loadldb: Not supported target type in logical signature for %s\n", virname);
 +	cli_dbgmsg("cli_loadldb: Not supported target type in logical signature for %s, skipping\n", virname);
  	FREE_TDB(tdb);
 -	*sigs--;
 +	(*sigs)--;
  	return CL_SUCCESS;
      }
  
@@@ -1237,18 -1215,19 +1237,18 @@@
  	    sig = tokens[3 + i];
  	}
  
 -	if((ret = cli_parse_add(root, virname, sig, 0, 0, offset, target, lsigid, options))) {
 -	    return CL_EMALFDB;
 -	}
 +	if((ret = cli_parse_add(root, virname, sig, 0, 0, offset, target, lsigid, options)))
 +	    return ret;
  
  	if(tdb.engine) {
  	    if(tdb.engine[0] > cl_retflevel()) {
  		cli_dbgmsg("cli_loadldb: Signature for %s not loaded (required f-level: %u)\n", virname, tdb.engine[0]);
  		FREE_TDB(tdb);
 -		*sigs--;
 +		(*sigs)--;
  		return CL_SUCCESS;
  	    } else if(tdb.engine[1] < cl_retflevel()) {
  		FREE_TDB(tdb);
 -		*sigs--;
 +		(*sigs)--;
  		return CL_SUCCESS;
  	    }
  	}
@@@ -1258,7 -1237,7 +1258,7 @@@
  
  static int cli_loadldb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio, const char *dbname)
  {
 -	char buffer[CLI_DEFAULT_LSIG_BUFSIZE + 1], *buffer_cpy;
 +	char buffer[CLI_DEFAULT_LSIG_BUFSIZE + 1], *buffer_cpy = NULL;
  	unsigned int line = 0, sigs = 0;
  	int ret;
  
@@@ -1495,7 -1474,7 +1495,7 @@@ static int cli_loadign(FILE *fs, struc
  {
  	const char *tokens[IGN_MAX_TOKENS + 1], *signame, *hash = NULL;
  	char buffer[FILEBUFF];
 -	unsigned int line = 0, tokens_count, i, len;
 +	unsigned int line = 0, tokens_count, len;
          struct cli_bm_patt *new;
  	int ret = CL_SUCCESS;
  
@@@ -1541,14 -1520,14 +1541,14 @@@
  	    ret = CL_EMEM;
  	    break;
  	}
 -	new->pattern = cli_mpool_strdup(engine->mempool, signame);
 +	new->pattern = (unsigned char *) cli_mpool_strdup(engine->mempool, signame);
  	if(!new->pattern) {
  	    mpool_free(engine->mempool, new);
  	    ret = CL_EMEM;
  	    break;
  	}
  	if(hash) {
 -	    if(strlen(hash) != 32 || !(new->virname = (unsigned char *) cli_mpool_hex2str(engine->mempool, hash))) {
 +	    if(strlen(hash) != 32 || !(new->virname = (char *) cli_mpool_hex2str(engine->mempool, hash))) {
  		cli_errmsg("cli_loadign: Malformed MD5 string at line %u\n", line);
  		mpool_free(engine->mempool, new->pattern);
  		mpool_free(engine->mempool, new);
@@@ -1619,7 -1598,7 +1619,7 @@@ static int cli_md5db_init(struct cl_eng
  static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int mode, unsigned int options, struct cli_dbio *dbio, const char *dbname)
  {
  	const char *tokens[MD5_TOKENS + 1];
 -	char buffer[FILEBUFF], *buffer_cpy;
 +	char buffer[FILEBUFF], *buffer_cpy = NULL;
  	const char *pt;
  	int ret = CL_SUCCESS;
  	unsigned int size_field = 1, md5_field = 0, line = 0, sigs = 0, tokens_count;
@@@ -1678,7 -1657,7 +1678,7 @@@
  
  	new->filesize = atoi(tokens[size_field]);
  
 -	new->virname = cli_mpool_virname(engine->mempool, (char *) tokens[2], options & CL_DB_OFFICIAL);
 +	new->virname = cli_mpool_virname(engine->mempool, tokens[2], options & CL_DB_OFFICIAL);
  	if(!new->virname) {
  	    mpool_free(engine->mempool, new->pattern);
  	    mpool_free(engine->mempool, new);
@@@ -1736,9 -1715,9 +1736,9 @@@
  static int cli_loadmd(FILE *fs, struct cl_engine *engine, unsigned int *signo, int type, unsigned int options, struct cli_dbio *dbio, const char *dbname)
  {
  	const char *tokens[MD_TOKENS + 1];
 -	char buffer[FILEBUFF], *buffer_cpy;
 +	char buffer[FILEBUFF], *buffer_cpy = NULL;
  	unsigned int line = 0, sigs = 0, tokens_count;
 -	int ret = CL_SUCCESS, crc;
 +	int ret = CL_SUCCESS;
  	struct cli_cdb *new;
  
  
@@@ -1798,13 -1777,14 +1798,13 @@@
  	    break;
  	}
  
 -	new->virname = cli_mpool_virname(engine->mempool, (char *)tokens[0], options & CL_DB_OFFICIAL);
 +	new->virname = cli_mpool_virname(engine->mempool, tokens[0], options & CL_DB_OFFICIAL);
  	if(!new->virname) {
  	    mpool_free(engine->mempool, new);
  	    ret = CL_EMEM;
  	    break;
  	}
  	new->ctype = (type == 1) ? CL_TYPE_ZIP : CL_TYPE_RAR;
 -	new->ftype = CL_TYPE_ANY;
  
  	if(engine->ignored && cli_chkign(engine->ignored, new->virname, buffer/*_cpy*/)) {
  	    mpool_free(engine->mempool, new->virname);
@@@ -1812,7 -1792,7 +1812,7 @@@
  	    continue;
  	}
  
 -	new->encrypted = atoi(tokens[1]);
 +	new->encrypted = strcmp(tokens[1], "*") ? atoi(tokens[1]) : 2;
  
  	if(strcmp(tokens[2], "*") && cli_regcomp(&new->name, tokens[2], REG_EXTENDED | REG_NOSUB)) {
  	    cli_errmsg("cli_loadmd: Can't compile regular expression %s in signature for %s\n", tokens[2], tokens[0]);
@@@ -1847,7 -1827,8 +1847,7 @@@
  
  	/* tokens[6] - not used */
  
 -	if(strcmp(tokens[7], "*"))
 -	    new->filepos[0] = new->filepos[1] = atoi(tokens[7]);
 +	new->filepos[0] = new->filepos[1] = strcmp(tokens[7], "*") ? atoi(tokens[7]) : CLI_OFF_ANY;
  
  	/* tokens[8] - not used */
  
@@@ -1874,15 -1855,14 +1874,15 @@@
      return CL_SUCCESS;
  }
  
 -/*    0		1	     2		3	       4	       5		 6	     7	      8      9    10     11     12
 - * VirusName:ContainerType:FileType:FileNameREGEX:ContainerSize:FileSizeInContainer:FileSizeReal:IsEncrypted:FilePos:Res1:Res2[:MinFL[:MaxFL]]
 +/*    0		 1		2		3	         4	       5	      6	      7	      8   9    10     11
 + * VirusName:ContainerType:ContainerSize:FileNameREGEX:FileSizeInContainer:FileSizeReal:IsEncrypted:FilePos:Res1:Res2[:MinFL[:MaxFL]]
   */
 -#define CDB_TOKENS 13
 +
 +#define CDB_TOKENS 12
  static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, struct cli_dbio *dbio)
  {
  	const char *tokens[CDB_TOKENS + 1];
 -	char buffer[FILEBUFF], *buffer_cpy;
 +	char buffer[FILEBUFF], *buffer_cpy = NULL;
  	unsigned int line = 0, sigs = 0, tokens_count, n0, n1;
  	int ret = CL_SUCCESS;
  	struct cli_cdb *new;
@@@ -1907,21 -1887,21 +1907,21 @@@
  	    break;
  	}
  
 -	if(tokens_count > 11) { /* min version */
 -	    if(!cli_isnumber(tokens[11])) {
 +	if(tokens_count > 10) { /* min version */
 +	    if(!cli_isnumber(tokens[10])) {
  		ret = CL_EMALFDB;
  		break;
  	    }
 -	    if((unsigned int) atoi(tokens[11]) > cl_retflevel()) {
 +	    if((unsigned int) atoi(tokens[10]) > cl_retflevel()) {
  		cli_dbgmsg("cli_loadcdb: Container signature for %s not loaded (required f-level: %u)\n", tokens[0], atoi(tokens[10]));
  		continue;
  	    }
 -	    if(tokens_count == 13) { /* max version */
 -		if(!cli_isnumber(tokens[12])) {
 +	    if(tokens_count == CDB_TOKENS) { /* max version */
 +		if(!cli_isnumber(tokens[11])) {
  		    ret = CL_EMALFDB;
  		    break;
  		}
 -		if((unsigned int) atoi(tokens[12]) < cl_retflevel())
 +		if((unsigned int) atoi(tokens[11]) < cl_retflevel())
  		    continue;
  	    }
  	}
@@@ -1932,7 -1912,7 +1932,7 @@@
  	    break;
  	}
  
 -	new->virname = cli_mpool_virname(engine->mempool, (char *)tokens[0], options & CL_DB_OFFICIAL);
 +	new->virname = cli_mpool_virname(engine->mempool, tokens[0], options & CL_DB_OFFICIAL);
  	if(!new->virname) {
  	    mpool_free(engine->mempool, new);
  	    ret = CL_EMEM;
@@@ -1954,6 -1934,15 +1954,6 @@@
  	    continue;
  	}
  
 -	if(!strcmp(tokens[2], "*")) {
 -	    new->ftype = CL_TYPE_ANY;
 -	} else if((new->ftype = cli_ftcode(tokens[2])) == CL_TYPE_ERROR) {
 -	    cli_dbgmsg("cli_loadcdb: Unknown file type %s in signature for %s, skipping\n", tokens[2], tokens[0]);
 -	    mpool_free(engine->mempool, new->virname);
 -	    mpool_free(engine->mempool, new);
 -	    continue;
 -	}
 -
  	if(strcmp(tokens[3], "*") && cli_regcomp(&new->name, tokens[3], REG_EXTENDED | REG_NOSUB)) {
  	    cli_errmsg("cli_loadcdb: Can't compile regular expression %s in signature for %s\n", tokens[3], tokens[0]);
  	    mpool_free(engine->mempool, new->virname);
@@@ -1991,15 -1980,15 +1991,15 @@@
  	    dest[0] = dest[1] = CLI_OFF_ANY;				    \
  	}
  
 -	CDBRANGE(tokens[4], new->csize);
 -	CDBRANGE(tokens[5], new->fsizec);
 -	CDBRANGE(tokens[6], new->fsizer);
 -	CDBRANGE(tokens[8], new->filepos);
 +	CDBRANGE(tokens[2], new->csize);
 +	CDBRANGE(tokens[4], new->fsizec);
 +	CDBRANGE(tokens[5], new->fsizer);
 +	CDBRANGE(tokens[7], new->filepos);
  
 -	if(!strcmp(tokens[7], "*")) {
 +	if(!strcmp(tokens[6], "*")) {
  	    new->encrypted = 2;
  	} else {
 -	    if(strcmp(tokens[7], "0") && strcmp(tokens[7], "1")) {
 +	    if(strcmp(tokens[6], "0") && strcmp(tokens[6], "1")) {
  		cli_errmsg("cli_loadcdb: Invalid encryption flag value in signature for %s\n", tokens[0]);
  		if(new->name.re_magic)
  		    cli_regfree(&new->name);
@@@ -2008,11 -1997,11 +2008,11 @@@
  		ret = CL_EMEM;
  		break;
  	    }
 -	    new->encrypted = *tokens[7] - 0x30;
 +	    new->encrypted = *tokens[6] - 0x30;
  	}
  
 -	if(strcmp(tokens[10], "*")) {
 -	    new->res2 = cli_mpool_strdup(engine->mempool, tokens[10]);
 +	if(strcmp(tokens[9], "*")) {
 +	    new->res2 = cli_mpool_strdup(engine->mempool, tokens[9]);
  	    if(!new->res2) {
  		cli_errmsg("cli_loadcdb: Can't allocate memory for res2 in signature for %s\n", tokens[0]);
  		if(new->name.re_magic)
@@@ -2369,6 -2358,9 +2369,9 @@@ int cl_load(const char *path, struct cl
  	cli_dbgmsg("Bytecode engine disabled\n");
      }
  
+     if(cli_cache_init(engine))
+ 	return CL_EMEM;
+ 
      engine->dboptions |= dboptions;
  
      switch(sb.st_mode & S_IFMT) {
@@@ -2665,6 -2657,7 +2668,6 @@@ int cl_engine_free(struct cl_engine *en
      }
  
      if(engine->dconf->bytecode & BYTECODE_ENGINE_MASK) {
 -	unsigned i;
  	if (engine->bcs.all_bcs)
  	    for(i=0;i<engine->bcs.count;i++)
  		cli_bytecode_destroy(&engine->bcs.all_bcs[i]);
@@@ -2706,6 -2699,9 +2709,9 @@@
      if(engine->tmpdir)
  	mpool_free(engine->mempool, engine->tmpdir);
  
+     if(engine->cache)
+ 	cli_cache_destroy(engine);
+ 
      cli_ftfree(engine);
      if(engine->ignored) {
  	cli_bm_free(engine->ignored);
diff --combined libclamav/scanners.c
index 53fa5e6,d234c55..ac225b1
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@@ -85,6 -85,7 +85,7 @@@
  #include "ishield.h"
  #include "7z.h"
  #include "fmap.h"
+ #include "cache.h"
  
  #ifdef HAVE_BZLIB_H
  #include <bzlib.h>
@@@ -178,7 -179,7 +179,7 @@@ static int cli_unrar_scanmetadata(int d
  	(unsigned int) metadata->unpack_size, metadata->method,
  	metadata->pack_size ? (unsigned int) (metadata->unpack_size / metadata->pack_size) : 0);
  
 -    if(cli_matchmeta(ctx, CL_TYPE_ANY, metadata->filename, metadata->pack_size, metadata->unpack_size, metadata->encrypted, files, metadata->crc, NULL) == CL_VIRUS)
 +    if(cli_matchmeta(ctx, metadata->filename, metadata->pack_size, metadata->unpack_size, metadata->encrypted, files, metadata->crc, NULL) == CL_VIRUS)
  	return CL_VIRUS;
  
      if(DETECT_ENCRYPTED && metadata->encrypted) {
@@@ -318,7 -319,7 +319,7 @@@ static int cli_scanrar(int desc, cli_ct
  
  static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check)
  {
 -	int ret = CL_CLEAN, rc;
 +	int ret = CL_CLEAN, rc, file = 0;
  	arj_metadata_t metadata;
  	char *dir;
  
@@@ -352,10 -353,6 +353,10 @@@
  	if (ret != CL_SUCCESS) {
  	   break;
  	}
 +	file++;
 +	if(cli_matchmeta(ctx, metadata.filename, metadata.comp_size, metadata.orig_size, metadata.encrypted, file, 0, NULL) == CL_VIRUS)
 +	    return CL_VIRUS;
 +
  	if ((ret = cli_checklimits("ARJ", ctx, metadata.orig_size, metadata.comp_size, 0))!=CL_CLEAN) {
  	    ret = CL_SUCCESS;
  	    if (metadata.filename)
@@@ -647,8 -644,8 +648,8 @@@ static int cli_scanmscab(int desc, cli_
      for(file = cab.files; file; file = file->next) {
  	files++;
  
 -	if(!(tempname = cli_gentemp(ctx->engine->tmpdir))) {
 -	    ret = CL_EMEM;
 +	if(cli_matchmeta(ctx, file->name, 0, file->length, 0, files, 0, NULL) == CL_VIRUS) {
 +	    ret = CL_VIRUS;
  	    break;
  	}
  
@@@ -656,12 -653,6 +657,12 @@@
  	    ret = CL_CLEAN;
  	    break;
  	}
 +
 +	if(!(tempname = cli_gentemp(ctx->engine->tmpdir))) {
 +	    ret = CL_EMEM;
 +	    break;
 +	}
 +
  	if(ctx->engine->maxscansize && ctx->scansize + ctx->engine->maxfilesize >= ctx->engine->maxscansize)
  	    file->max_size = ctx->engine->maxscansize - ctx->scansize;
  	else
@@@ -1663,7 -1654,7 +1664,7 @@@ static int cli_scanraw(cli_ctx *ctx, cl
      if(typercg)
  	acmode |= AC_SCAN_FT;
  
-     ret = cli_fmap_scandesc(ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode);
+     ret = cli_fmap_scandesc(ctx, type == CL_TYPE_TEXT_ASCII ? 0 : type, 0, &ftoffset, acmode, NULL);
  
      if(ret >= CL_TYPENO) {
  	ctx->recursion++;
@@@ -1812,7 -1803,8 +1813,8 @@@ int cli_magic_scandesc(int desc, cli_ct
  	struct stat sb;
  	uint8_t typercg = 1;
  	cli_file_t current_container_type = ctx->container_type; /* TODO: container tracking code TBD - bb#1293 */
- 	size_t current_container_size = ctx->container_size;
+ 	size_t current_container_size = ctx->container_size, hashed_size;
+ 	unsigned char hash[16];
  
      if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) {
          cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel);
@@@ -1845,16 -1837,28 +1847,28 @@@
      ctx->fmap++;
      if(!(*ctx->fmap = fmap(desc, 0, sb.st_size))) {
  	cli_errmsg("CRITICAL: fmap() failed\n");
+ 	ctx->fmap--;
  	return CL_EMEM;
      }
  
+     if(cache_check(hash, ctx) == CL_CLEAN) {
+ 	funmap(*ctx->fmap);
+ 	ctx->fmap--;
+ 	return CL_CLEAN;
+     }
+     hashed_size = (*ctx->fmap)->len;
+ 
      if(!ctx->options || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */
  	if(ctx->recursion == ctx->engine->maxreclevel)
  	    cli_dbgmsg("cli_magic_scandesc: Hit recursion limit, only scanning raw file\n");
  	else
  	    cli_dbgmsg("Raw mode: No support for special files\n");
- 	if((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR)) == CL_VIRUS)
+ 
+ 	if((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR, hash)) == CL_VIRUS)
  	    cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, desc);
+ 	else
+ 	    cache_add(hash, hashed_size, ctx);
+ 
  	funmap(*ctx->fmap);
  	ctx->fmap--; 
  	return ret;
@@@ -2171,7 -2175,7 +2185,7 @@@
      ctx->fmap--;
  
      if(ret == CL_VIRUS)
- 	return cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
+ 	ret = cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
  
      switch(ret) {
  	case CL_EFORMAT:
@@@ -2179,6 -2183,8 +2193,8 @@@
  	case CL_EMAXSIZE:
  	case CL_EMAXFILES:
  	    cli_dbgmsg("Descriptor[%d]: %s\n", desc, cl_strerror(ret));
+ 	case CL_CLEAN:
+ 	    cache_add(hash, hashed_size, ctx);
  	    return CL_CLEAN;
  	default:
  	    return ret;

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list