[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