[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:41 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit 9fbb5465556e46754a560d9f9c43fc2ba0945132
Merge: 6223810ba08e585371e458d6389dc8148b27c428 15f413d157bb0835c674f086da52fcd09b851c22
Author: aCaB <acab at clamav.net>
Date:   Thu Jan 14 23:18:30 2010 +0100

    Merge branch 'master' into cache

diff --combined libclamav/matcher.c
index c4a2d52,e7eaaa6..0dc0c6b
--- a/libclamav/matcher.c
+++ b/libclamav/matcher.c
@@@ -47,6 -47,7 +47,7 @@@
  #include "macho.h"
  #include "fmap.h"
  #include "pe_icons.h"
+ #include "regex/regex.h"
  
  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)
  {
@@@ -344,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;
@@@ -352,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;
@@@ -420,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) {
@@@ -459,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));
  	}
  
@@@ -534,13 -535,55 +535,58 @@@
  
      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)
+ {
+ 	const struct cli_cdb *cdb;
+ 
+     if(!(cdb = ctx->engine->cdb))
+ 	return CL_CLEAN;
+ 
+     do {
+ 	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;
+ 
+ 	if(cdb->res1 && (cdb->ctype == CL_TYPE_ZIP || cdb->ctype == CL_TYPE_RAR) && cdb->res1 != res1)
+ 	    continue;
+ 
+ #define CDBRANGE(field, val)						    \
+ 	if(field[0] != CLI_OFF_ANY) {					    \
+ 	    if(field[0] == field[1] && field[0] != val)			    \
+ 		continue;						    \
+ 	    else if(field[0] != field[1] && ((field[0] && field[0] > val) ||\
+ 	      (field[1] && field[1] < val)))				    \
+ 		continue;						    \
+ 	}
+ 
+ 	CDBRANGE(cdb->csize, ctx->container_size);
+ 	CDBRANGE(cdb->fsizec, fsizec);
+ 	CDBRANGE(cdb->fsizer, fsizer);
+ 	CDBRANGE(cdb->filepos, filepos);
+ 
+ 	if(cdb->name.re_magic && (!fname || cli_regexec(&cdb->name, fname, 0, NULL, 0) == REG_NOMATCH))
+ 	    continue;
+ 
+ 	*ctx->virname = cdb->virname;
+ 	return CL_VIRUS;
+ 
+     } while((cdb = cdb->next));
+ 
+     return CL_CLEAN;
+ }
diff --combined libclamav/matcher.h
index f6ebae4,61c54e5..5a07262
--- a/libclamav/matcher.h
+++ b/libclamav/matcher.h
@@@ -99,11 -99,23 +99,23 @@@ struct cli_matcher 
  #endif
  };
  
- struct cli_meta_node {
-     char *filename, *virname;
-     struct cli_meta_node *next;
-     int csize, size, method;
-     unsigned int crc32, fileno, encrypted, maxdepth;
+ struct cli_cdb
+ {
+     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
+ 			     */
+     size_t	fsizec[2];  /* file size in container */
+     size_t	fsizer[2];  /* real file size */
+     int		encrypted;  /* file is encrypted; 2 == ignore */
+     int		filepos[2]; /* file position in container */
+     int		res1;	    /* reserved / format specific */
+     void	*res2;	    /* reserved / format specific */
+ 
+     struct cli_cdb *next;
  };
  
  struct cli_mtarget {
@@@ -146,9 -158,12 +158,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);
+ 
  #endif
diff --combined libclamav/others.h
index 24eaaf4,aa1708d..99274b2
--- a/libclamav/others.h
+++ b/libclamav/others.h
@@@ -111,6 -111,7 +111,7 @@@ typedef struct 
      unsigned int scannedfiles;
      unsigned int found_possibly_unwanted;
      cli_file_t container_type; /* FIXME: to be made into a stack or array - see bb#1579 & bb#1293 */
+     size_t container_size;
      struct cli_dconf *dconf;
      fmap_t **fmap;
  } cli_ctx;
@@@ -193,11 -194,8 +194,8 @@@ struct cl_engine 
      /* B-M matcher for whitelist db */
      struct cli_matcher *md5_fp;
  
-     /* Zip metadata */
-     struct cli_meta_node *zip_mlist;
- 
-     /* RAR metadata */
-     struct cli_meta_node *rar_mlist;
+     /* Container metadata */
+     struct cli_cdb *cdb;
  
      /* Phishing .pdb and .wdb databases*/
      struct regex_matcher *whitelist_matcher;
@@@ -219,9 -217,6 +217,9 @@@
      /* Icon reference storage */
      struct icon_matcher *iconcheck;
  
 +    /* Negative cache storage */
 +    struct CACHE *cache;
 +
      /* Used for memory pools */
      mpool_t *mempool;
  
diff --combined libclamav/readdb.c
index 53cb8a1,8ab279f..9f7b599
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@@ -1718,7 -1718,7 +1718,7 @@@ static int cli_loadmd(FILE *fs, struct 
  	char buffer[FILEBUFF], *buffer_cpy;
  	unsigned int line = 0, sigs = 0, tokens_count;
  	int ret = CL_SUCCESS, crc;
- 	struct cli_meta_node *new;
+ 	struct cli_cdb *new;
  
  
      if(engine->ignored)
@@@ -1771,7 -1771,7 +1771,7 @@@
  	    break;
  	}
  
- 	new = (struct cli_meta_node *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_meta_node));
+ 	new = (struct cli_cdb *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_cdb));
  	if(!new) {
  	    ret = CL_EMEM;
  	    break;
@@@ -1783,6 -1783,8 +1783,8 @@@
  	    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);
@@@ -1791,63 -1793,228 +1793,228 @@@
  	}
  
  	new->encrypted = atoi(tokens[1]);
- 	new->filename = cli_mpool_strdup(engine->mempool, tokens[2]);
- 	if(!new->filename) {
+ 
+ 	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]);
  	    mpool_free(engine->mempool, new->virname);
  	    mpool_free(engine->mempool, new);
- 	    ret = CL_EMALFDB;
+ 	    ret = CL_EMEM;
  	    break;
- 	} else {
- 	    if(!strcmp(new->filename, "*")) {
- 	        mpool_free(engine->mempool, new->filename);
- 		new->filename = NULL;
- 	    }
  	}
+ 	new->csize[0] = new->csize[1] = CLI_OFF_ANY;
  
  	if(!strcmp(tokens[3], "*"))
- 	    new->size = -1;
+ 	    new->fsizer[0] = new->fsizer[1] = CLI_OFF_ANY;
  	else
- 	    new->size = atoi(tokens[3]);
+ 	    new->fsizer[0] = new->fsizer[1] = atoi(tokens[3]);
  
  	if(!strcmp(tokens[4], "*"))
- 	    new->csize = -1;
+ 	    new->fsizec[0] = new->fsizec[1] = CLI_OFF_ANY;
  	else
- 	    new->csize = atoi(tokens[4]);
+ 	    new->fsizec[0] = new->fsizec[1] = atoi(tokens[4]);
  
- 	if(!strcmp(tokens[5], "*")) {
- 	    new->crc32 = 0;
- 	} else {
- 	    crc = cli_hex2num(tokens[5]);
- 	    if(crc == -1) {
+ 	if(strcmp(tokens[5], "*")) {
+ 	    new->res1 = cli_hex2num(tokens[5]);
+ 	    if(new->res1 == -1) {
+ 		mpool_free(engine->mempool, new->virname);
+ 		mpool_free(engine->mempool, new);
+ 		if(new->name.re_magic)
+ 		    cli_regfree(&new->name);
  	        ret = CL_EMALFDB;
  		break;
  	    }
- 	    new->crc32 = (unsigned int) crc;
  	}
  
- 	if(!strcmp(tokens[6], "*"))
- 	    new->method = -1;
- 	else
- 	    new->method = atoi(tokens[6]);
+ 	/* tokens[6] - not used */
  
- 	if(!strcmp(tokens[7], "*"))
- 	    new->fileno = 0;
- 	else
- 	    new->fileno = atoi(tokens[7]);
+ 	if(strcmp(tokens[7], "*"))
+ 	    new->filepos[0] = new->filepos[1] = atoi(tokens[7]);
  
- 	if(!strcmp(tokens[8], "*"))
- 	    new->maxdepth = 0;
- 	else
- 	    new->maxdepth = atoi(tokens[8]);
+ 	/* tokens[8] - not used */
+ 
+ 	new->next = engine->cdb;
+ 	engine->cdb = new;
+ 	sigs++;
+     }
+     if(engine->ignored)
+ 	free(buffer_cpy);
+ 
+     if(!line) {
+ 	cli_errmsg("Empty database file\n");
+ 	return CL_EMALFDB;
+     }
+ 
+     if(ret) {
+ 	cli_errmsg("Problem parsing database at line %d\n", line);
+ 	return ret;
+     }
+ 
+     if(signo)
+ 	*signo += sigs;
+ 
+     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]]
+  */
+ #define CDB_TOKENS 13
+ 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;
+ 	unsigned int line = 0, sigs = 0, tokens_count, n0, n1;
+ 	int ret = CL_SUCCESS;
+ 	struct cli_cdb *new;
+ 
+ 
+     if(engine->ignored)
+ 	if(!(buffer_cpy = cli_malloc(FILEBUFF)))
+ 	    return CL_EMEM;
+ 
+     while(cli_dbgets(buffer, FILEBUFF, fs, dbio)) {
+ 	line++;
+ 	if(buffer[0] == '#')
+ 	    continue;
+ 
+ 	cli_chomp(buffer);
+ 	if(engine->ignored)
+ 	    strcpy(buffer_cpy, buffer);
+ 
+ 	tokens_count = cli_strtokenize(buffer, ':', CDB_TOKENS + 1, tokens);
+ 	if(tokens_count > CDB_TOKENS || tokens_count < CDB_TOKENS - 2) {
+ 	    ret = CL_EMALFDB;
+ 	    break;
+ 	}
+ 
+ 	if(tokens_count > 11) { /* min version */
+ 	    if(!cli_isnumber(tokens[11])) {
+ 		ret = CL_EMALFDB;
+ 		break;
+ 	    }
+ 	    if((unsigned int) atoi(tokens[11]) > 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])) {
+ 		    ret = CL_EMALFDB;
+ 		    break;
+ 		}
+ 		if((unsigned int) atoi(tokens[12]) < cl_retflevel())
+ 		    continue;
+ 	    }
+ 	}
+ 
+ 	new = (struct cli_cdb *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_cdb));
+ 	if(!new) {
+ 	    ret = CL_EMEM;
+ 	    break;
+ 	}
+ 
+ 	new->virname = cli_mpool_virname(engine->mempool, (char *)tokens[0], options & CL_DB_OFFICIAL);
+ 	if(!new->virname) {
+ 	    mpool_free(engine->mempool, new);
+ 	    ret = CL_EMEM;
+ 	    break;
+ 	}
+ 
+ 	if(engine->ignored && cli_chkign(engine->ignored, new->virname, buffer/*_cpy*/)) {
+ 	    mpool_free(engine->mempool, new->virname);
+ 	    mpool_free(engine->mempool, new);
+ 	    continue;
+ 	}
+ 
+ 	if(!strcmp(tokens[1], "*")) {
+ 	    new->ctype = CL_TYPE_ANY;
+ 	} else if((new->ctype = cli_ftcode(tokens[1])) == CL_TYPE_ERROR) {
+ 	    cli_dbgmsg("cli_loadcdb: Unknown container type %s in signature for %s, skipping\n", tokens[1], tokens[0]);
+ 	    mpool_free(engine->mempool, new->virname);
+ 	    mpool_free(engine->mempool, new);
+ 	    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(type == 1) {
- 	    new->next = engine->zip_mlist;
- 	    engine->zip_mlist = new;
+ 	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);
+ 	    mpool_free(engine->mempool, new);
+ 	    ret = CL_EMEM;
+ 	    break;
+ 	}
+ 
+ #define CDBRANGE(token_str, dest)					    \
+ 	if(strcmp(token_str, "*")) {					    \
+ 	    if(strchr(token_str, '-')) {				    \
+ 		if(sscanf(token_str, "%u-%u", &n0, &n1) != 2) {		    \
+ 		    ret = CL_EMALFDB;					    \
+ 		} else {						    \
+ 		    dest[0] = n0;					    \
+ 		    dest[1] = n1;					    \
+ 		}							    \
+ 	    } else {							    \
+ 		if(!cli_isnumber(token_str))				    \
+ 		    ret = CL_EMALFDB;					    \
+ 		else							    \
+ 		    dest[0] = dest[1] = atoi(token_str);		    \
+ 	    }								    \
+ 	    if(ret != CL_SUCCESS) {					    \
+ 		cli_errmsg("cli_loadcdb: Invalid value %s in signature for %s\n",\
+ 		    token_str, tokens[0]);				    \
+ 		if(new->name.re_magic)					    \
+ 		    cli_regfree(&new->name);				    \
+ 		mpool_free(engine->mempool, new->virname);		    \
+ 		mpool_free(engine->mempool, new);			    \
+ 		ret = CL_EMEM;						    \
+ 		break;							    \
+ 	    }								    \
+ 	} else {							    \
+ 	    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);
+ 
+ 	if(!strcmp(tokens[7], "*")) {
+ 	    new->encrypted = 2;
  	} else {
- 	    new->next = engine->rar_mlist;
- 	    engine->rar_mlist = new;
+ 	    if(strcmp(tokens[7], "0") && strcmp(tokens[7], "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);
+ 		mpool_free(engine->mempool, new->virname);
+ 		mpool_free(engine->mempool, new);
+ 		ret = CL_EMEM;
+ 		break;
+ 	    }
+ 	    new->encrypted = *tokens[7] - 0x30;
+ 	}
+ 
+ 	if(strcmp(tokens[10], "*")) {
+ 	    new->res2 = cli_mpool_strdup(engine->mempool, tokens[10]);
+ 	    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)
+ 		    cli_regfree(&new->name);
+ 		mpool_free(engine->mempool, new->virname);
+ 		mpool_free(engine->mempool, new);
+ 		ret = CL_EMEM;
+ 		break;
+ 	    }
  	}
  
+ 	new->next = engine->cdb;
+ 	engine->cdb = new;
  	sigs++;
      }
      if(engine->ignored)
@@@ -1859,7 -2026,7 +2026,7 @@@
      }
  
      if(ret) {
- 	cli_errmsg("Problem parsing database at line %d\n", line);
+ 	cli_errmsg("Problem parsing database at line %u\n", line);
  	return ret;
      }
  
@@@ -1980,6 -2147,9 +2147,9 @@@ int cli_load(const char *filename, stru
      } else if(cli_strbcasestr(dbname, ".idb")) {
      	ret = cli_loadidb(fs, engine, signo, options, dbio);
  
+     } else if(cli_strbcasestr(dbname, ".cdb")) {
+     	ret = cli_loadcdb(fs, engine, signo, options, dbio);
+ 
      } else {
  	cli_dbgmsg("cli_load: unknown extension - assuming old database format\n");
  	ret = cli_loaddb(fs, engine, signo, options, dbio, dbname);
@@@ -2188,9 -2358,6 +2358,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) {
@@@ -2412,7 -2579,6 +2582,6 @@@ int cl_statfree(struct cl_stat *dbstat
  int cl_engine_free(struct cl_engine *engine)
  {
  	unsigned int i, j;
- 	struct cli_meta_node *metapt, *metah;
  	struct cli_matcher *root;
  
  
@@@ -2477,24 -2643,14 +2646,14 @@@
  	mpool_free(engine->mempool, root);
      }
  
-     metapt = engine->zip_mlist;
-     while(metapt) {
- 	metah = metapt;
- 	metapt = metapt->next;
- 	mpool_free(engine->mempool, metah->virname);
- 	if(metah->filename)
- 	    mpool_free(engine->mempool, metah->filename);
- 	mpool_free(engine->mempool, metah);
-     }
- 
-     metapt = engine->rar_mlist;
-     while(metapt) {
- 	metah = metapt;
- 	metapt = metapt->next;
- 	mpool_free(engine->mempool, metah->virname);
- 	if(metah->filename)
- 	    mpool_free(engine->mempool, metah->filename);
- 	mpool_free(engine->mempool, metah);
+     while(engine->cdb) {
+ 	struct cli_cdb *pt = engine->cdb;
+ 	engine->cdb = pt->next;
+ 	if(pt->name.re_magic)
+ 	    cli_regfree(&pt->name);
+ 	mpool_free(engine->mempool, pt->res2);
+ 	mpool_free(engine->mempool, pt->virname);
+ 	mpool_free(engine->mempool, pt);
      }
  
      if(engine->dconf->bytecode & BYTECODE_ENGINE_MASK) {
@@@ -2540,9 -2696,6 +2699,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 de6af02,afd74a4..dda93e3
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@@ -85,7 -85,6 +85,7 @@@
  #include "ishield.h"
  #include "7z.h"
  #include "fmap.h"
 +#include "cache.h"
  
  #ifdef HAVE_BZLIB_H
  #include <bzlib.h>
@@@ -166,8 -165,6 +166,6 @@@ static int cli_scandir(const char *dirn
  static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx *ctx, unsigned int files, uint32_t* sfx_check)
  {
  	int ret = CL_SUCCESS;
- 	struct cli_meta_node* mdata;
- 
  
      if(files == 1 && sfx_check) {
  	if(*sfx_check == metadata->crc)
@@@ -181,41 -178,8 +179,8 @@@
  	(unsigned int) metadata->unpack_size, metadata->method,
  	metadata->pack_size ? (unsigned int) (metadata->unpack_size / metadata->pack_size) : 0);
  
-     /* Scan metadata */
-     mdata = ctx->engine->rar_mlist;
-     if(mdata) do {
- 	if(mdata->encrypted != metadata->encrypted)
- 	    continue;
- 
- 	if(mdata->crc32 && (unsigned int) mdata->crc32 != metadata->crc)
- 	    continue;
- 
- 	if(mdata->csize > 0 && (unsigned int) mdata->csize != metadata->pack_size)
- 	    continue;
- 
- 	if(mdata->size >= 0 && (unsigned int) mdata->size != metadata->unpack_size)
- 	    continue;
- 
- 	if(mdata->method >= 0 && mdata->method != metadata->method)
- 	    continue;
- 
- 	if(mdata->fileno && mdata->fileno != files)
- 	    continue;
- 
- 	if(mdata->maxdepth && ctx->recursion > mdata->maxdepth)
- 	    continue;
- 
- 	if(mdata->filename && !cli_matchregex(metadata->filename, mdata->filename))
- 	    continue;
- 
- 	break; /* matched */
- 
-     } while((mdata = mdata->next));
- 
-     if(mdata) {
- 	*ctx->virname = mdata->virname;
+     if(cli_matchmeta(ctx, CL_TYPE_ANY, metadata->filename, metadata->pack_size, metadata->unpack_size, metadata->encrypted, files, metadata->crc, NULL) == CL_VIRUS)
  	return CL_VIRUS;
-     }
  
      if(DETECT_ENCRYPTED && metadata->encrypted) {
  	cli_dbgmsg("RAR: Encrypted files found in archive.\n");
@@@ -979,7 -943,6 +944,6 @@@ static int cli_scanscript(cli_ctx *ctx
  	unsigned char *buff;
  	unsigned char* normalized;
  	struct text_norm_state state;
- 	struct stat sb;
  	char *tmpname = NULL;
  	int ofd = -1, ret;
  	const struct cli_matcher *troot = ctx->engine->root[7];
@@@ -1530,9 -1493,7 +1494,7 @@@ static int cli_scanmail(int desc, cli_c
  	return ret;
      }
  
-     ctx->container_type = CL_TYPE_MAIL;
      ret = cli_scandir(dir, ctx);
-     ctx->container_type = 0;
  
      if(!ctx->engine->keeptmp)
  	cli_rmdirs(dir);
@@@ -1692,7 -1653,7 +1654,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++;
@@@ -1840,8 -1801,8 +1802,9 @@@ int cli_magic_scandesc(int desc, cli_ct
  	cli_file_t type, dettype = 0;
  	struct stat sb;
  	uint8_t typercg = 1;
- 	cli_file_t current_container = ctx->container_type; /* TODO: container tracking code TBD - bb#1293 */
+ 	cli_file_t current_container_type = ctx->container_type; /* TODO: container tracking code TBD - bb#1293 */
+ 	size_t current_container_size = ctx->container_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);
@@@ -1874,30 -1835,18 +1837,29 @@@
      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;
 +    }
 +    
      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, ctx);
 +
  	funmap(*ctx->fmap);
  	ctx->fmap--; 
- 
  	return ret;
      }
  
@@@ -1920,18 -1869,21 +1882,21 @@@
  	lseek(desc, 0, SEEK_SET); /* FIXMEFMAP: remove ? */
      }
  
-     ctx->container_type = 0;
      ctx->recursion++;
      switch(type) {
  	case CL_TYPE_IGNORED:
  	    break;
  
  	case CL_TYPE_RAR:
+ 	    ctx->container_type = CL_TYPE_RAR;
+ 	    ctx->container_size = sb.st_size;
  	    if(have_rar && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_RAR))
  		ret = cli_scanrar(desc, ctx, 0, NULL);
  	    break;
  
  	case CL_TYPE_ZIP:
+ 	    ctx->container_type = CL_TYPE_ZIP;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP))
  		ret = cli_unzip(ctx);
  	    break;
@@@ -1945,17 -1897,24 +1910,24 @@@
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_BZ))
  		ret = cli_scanbzip(desc, ctx);
  	    break;
+ 
  	case CL_TYPE_ARJ:
+ 	    ctx->container_type = CL_TYPE_ARJ;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ARJ))
  		ret = cli_scanarj(desc, ctx, 0, NULL);
  	    break;
  
          case CL_TYPE_NULSFT:
- 	  if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_NSIS))
+ 	    ctx->container_type = CL_TYPE_NULSFT;
+ 	    ctx->container_size = sb.st_size;
+ 	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_NSIS))
  		ret = cli_scannulsft(desc, ctx, 0);
  	    break;
  
          case CL_TYPE_AUTOIT:
+ 	    ctx->container_type = CL_TYPE_AUTOIT;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_AUTOIT))
  		ret = cli_scanautoit(desc, ctx, 23);
  	    break;
@@@ -1966,6 -1925,8 +1938,8 @@@
  	    break;
  
  	case CL_TYPE_MSCAB:
+ 	    ctx->container_type = CL_TYPE_MSCAB;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CAB))
  		ret = cli_scanmscab(desc, ctx, 0);
  	    break;
@@@ -1986,11 -1947,15 +1960,15 @@@
  	    break;
  
  	case CL_TYPE_RTF:
+ 	    ctx->container_type = CL_TYPE_RTF;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_DOC & DOC_CONF_RTF))
  		ret = cli_scanrtf(desc, ctx);
  	    break;
  
  	case CL_TYPE_MAIL:
+ 	    ctx->container_type = CL_TYPE_MAIL;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX))
  		ret = cli_scanmail(desc, ctx);
  	    break;
@@@ -2006,46 -1971,64 +1984,64 @@@
  	    break;
  
  	case CL_TYPE_MSCHM:
+ 	    ctx->container_type = CL_TYPE_MSCHM;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CHM))
  		ret = cli_scanmschm(desc, ctx);
  	    break;
  
  	case CL_TYPE_MSOLE2:
+ 	    ctx->container_type = CL_TYPE_MSOLE2;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_OLE2 && (DCONF_ARCH & ARCH_CONF_OLE2))
  		ret = cli_scanole2(ctx);
  	    break;
  
  	case CL_TYPE_7Z:
+ 	    ctx->container_type = CL_TYPE_7Z;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_7Z))
  		ret = cli_7unz(desc, ctx);
  	    break;
  
  	case CL_TYPE_POSIX_TAR:
+ 	    ctx->container_type = CL_TYPE_POSIX_TAR;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR))
  		ret = cli_scantar(desc, ctx, 1);
  	    break;
  
  	case CL_TYPE_OLD_TAR:
+ 	    ctx->container_type = CL_TYPE_OLD_TAR;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_TAR))
  		ret = cli_scantar(desc, ctx, 0);
  	    break;
  
  	case CL_TYPE_CPIO_OLD:
+ 	    ctx->container_type = CL_TYPE_CPIO_OLD;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO))
  		ret = cli_scancpio_old(desc, ctx);
  	    break;
  
  	case CL_TYPE_CPIO_ODC:
+ 	    ctx->container_type = CL_TYPE_CPIO_ODC;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO))
  		ret = cli_scancpio_odc(desc, ctx);
  	    break;
  
  	case CL_TYPE_CPIO_NEWC:
+ 	    ctx->container_type = CL_TYPE_CPIO_NEWC;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO))
  		ret = cli_scancpio_newc(desc, ctx, 0);
  	    break;
  
  	case CL_TYPE_CPIO_CRC:
+ 	    ctx->container_type = CL_TYPE_CPIO_CRC;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_CPIO))
  		ret = cli_scancpio_newc(desc, ctx, 1);
  	    break;
@@@ -2071,6 -2054,8 +2067,8 @@@
  	    break;
  
          case CL_TYPE_PDF: /* FIXMELIMITS: pdf should be an archive! */
+ 	    ctx->container_type = CL_TYPE_PDF;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_PDF && (DCONF_DOC & DOC_CONF_PDF))
  		ret = cli_scanpdf(ctx, 0);
  	    break;
@@@ -2096,6 -2081,8 +2094,8 @@@
  	    break;
  
  	case CL_TYPE_SIS:
+ 	    ctx->container_type = CL_TYPE_SIS;
+ 	    ctx->container_size = sb.st_size;
  	    if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_SIS))
  		ret = cli_scansis(desc, ctx);
  	    break;
@@@ -2117,7 -2104,8 +2117,8 @@@
  	    break;
      }
      ctx->recursion--;
-     ctx->container_type = current_container;
+     ctx->container_type = current_container_type;
+     ctx->container_size = current_container_size;
  
      if(ret == CL_VIRUS) {
  	ret = cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
@@@ -2173,7 -2161,7 +2174,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:
@@@ -2181,8 -2169,6 +2182,8 @@@
  	case CL_EMAXSIZE:
  	case CL_EMAXFILES:
  	    cli_dbgmsg("Descriptor[%d]: %s\n", desc, cl_strerror(ret));
 +	case CL_CLEAN:
 +	    cache_add(hash, ctx);
  	    return CL_CLEAN;
  	default:
  	    return ret;
@@@ -2200,7 -2186,8 +2201,8 @@@ int cl_scandesc(int desc, const char **
      ctx.scanned = scanned;
      ctx.options = scanoptions;
      ctx.found_possibly_unwanted = 0;
-     ctx.container_type = 0;
+     ctx.container_type = CL_TYPE_ANY;
+     ctx.container_size = 0;
      ctx.dconf = (struct cli_dconf *) engine->dconf;
      ctx.fmap = cli_calloc(sizeof(fmap_t *), ctx.engine->maxreclevel + 1);
      if(!ctx.fmap)

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list