[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:14:21 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit 15f413d157bb0835c674f086da52fcd09b851c22
Author: Tomasz Kojm <tkojm at clamav.net>
Date: Fri Jan 8 15:20:33 2010 +0100
libclamav: handle zmd/rmd with cdb (bb#1579)
diff --git a/ChangeLog b/ChangeLog
index 7b440a5..6027ff0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Fri Jan 8 15:20:10 CET 2010 (tk)
+---------------------------------
+ * libclamav: handle zmd/rmd with cdb (bb#1579)
+
Thu Jan 7 18:22:39 CET 2010 (tk)
---------------------------------
* libclamav: base code for unified container metadata matcher (bb#1579)
diff --git a/libclamav/matcher.c b/libclamav/matcher.c
index 09e832a..e7eaaa6 100644
--- a/libclamav/matcher.c
+++ b/libclamav/matcher.c
@@ -543,7 +543,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
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, void *res1, void *res2)
+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;
@@ -560,26 +560,22 @@ int cli_matchmeta(cli_ctx *ctx, cli_file_t ftype, const char *fname, size_t fsiz
if(cdb->encrypted != 2 && cdb->encrypted != encrypted)
continue;
- if(cdb->csize[0] != CLI_OFF_ANY) {
- if(cdb->csize[0] == cdb->csize[1] && cdb->csize[0] != ctx->container_size)
- continue;
- else if(cdb->csize[0] != cdb->csize[1] && ((cdb->csize[0] && cdb->csize[0] > ctx->container_size) || (cdb->csize[1] && cdb->csize[1] < ctx->container_size)))
- continue;
- }
+ if(cdb->res1 && (cdb->ctype == CL_TYPE_ZIP || cdb->ctype == CL_TYPE_RAR) && cdb->res1 != res1)
+ continue;
- if(cdb->fsizec[0] != CLI_OFF_ANY) {
- if(cdb->fsizec[0] == cdb->fsizec[1] && cdb->fsizec[0] != fsizec)
- continue;
- else if(cdb->fsizec[0] != cdb->fsizec[1] && ((cdb->fsizec[0] && cdb->fsizec[0] > fsizec) || (cdb->fsizec[1] && cdb->fsizec[1] < fsizec)))
- 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; \
}
- if(cdb->fsizer[0] != CLI_OFF_ANY) {
- if(cdb->fsizer[0] == cdb->fsizer[1] && cdb->fsizer[0] != fsizer)
- continue;
- else if(cdb->fsizer[0] != cdb->fsizer[1] && ((cdb->fsizer[0] && cdb->fsizer[0] > fsizer) || (cdb->fsizer[1] && cdb->fsizer[1] < fsizer)))
- 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;
diff --git a/libclamav/matcher.h b/libclamav/matcher.h
index 096dfe2..61c54e5 100644
--- a/libclamav/matcher.h
+++ b/libclamav/matcher.h
@@ -99,13 +99,6 @@ 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 */
@@ -118,7 +111,8 @@ struct cli_cdb
size_t fsizec[2]; /* file size in container */
size_t fsizer[2]; /* real file size */
int encrypted; /* file is encrypted; 2 == ignore */
- void *res1; /* reserved / format specific */
+ int filepos[2]; /* file position in container */
+ int res1; /* reserved / format specific */
void *res2; /* reserved / format specific */
struct cli_cdb *next;
@@ -170,6 +164,6 @@ int cli_caloff(const char *offstr, struct cli_target_info *info, fmap_t *map, un
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, void *res1, void *res2);
+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 --git a/libclamav/others.h b/libclamav/others.h
index 060c0d6..aa1708d 100644
--- a/libclamav/others.h
+++ b/libclamav/others.h
@@ -194,12 +194,6 @@ 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;
diff --git a/libclamav/readdb.c b/libclamav/readdb.c
index 4328474..8ab279f 100644
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@ -1718,7 +1718,7 @@ static int cli_loadmd(FILE *fs, struct cl_engine *engine, unsigned int *signo, i
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 @@ static int cli_loadmd(FILE *fs, struct cl_engine *engine, unsigned int *signo, i
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 @@ static int cli_loadmd(FILE *fs, struct cl_engine *engine, unsigned int *signo, i
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,47 @@ static int cli_loadmd(FILE *fs, struct cl_engine *engine, unsigned int *signo, i
}
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]);
-
- if(type == 1) {
- new->next = engine->zip_mlist;
- engine->zip_mlist = new;
- } else {
- new->next = engine->rar_mlist;
- engine->rar_mlist = new;
- }
+ /* tokens[8] - not used */
+ new->next = engine->cdb;
+ engine->cdb = new;
sigs++;
}
if(engine->ignored)
@@ -1869,10 +1855,10 @@ static int cli_loadmd(FILE *fs, struct cl_engine *engine, unsigned int *signo, i
return CL_SUCCESS;
}
-/* 0 1 2 3 4 5 6 7 8 9 10 11
- * VirusName:ContainerType:FileType:FileNameREGEX:ContainerSize:FileSizeInContainer:FileSizeReal:IsEncrypted:Res1:Res2[:MinFL[:MaxFL]]
+/* 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 12
+#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];
@@ -1896,26 +1882,26 @@ static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
strcpy(buffer_cpy, buffer);
tokens_count = cli_strtokenize(buffer, ':', CDB_TOKENS + 1, tokens);
- if(tokens_count > CDB_TOKENS) {
+ if(tokens_count > CDB_TOKENS || tokens_count < CDB_TOKENS - 2) {
ret = CL_EMALFDB;
break;
}
- if(tokens_count > 10) { /* min version */
- if(!cli_isnumber(tokens[10])) {
+ if(tokens_count > 11) { /* min version */
+ if(!cli_isnumber(tokens[11])) {
ret = CL_EMALFDB;
break;
}
- if((unsigned int) atoi(tokens[10]) > cl_retflevel()) {
+ 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 == 12) { /* max version */
- if(!cli_isnumber(tokens[11])) {
+ if(tokens_count == 13) { /* max version */
+ if(!cli_isnumber(tokens[12])) {
ret = CL_EMALFDB;
break;
}
- if((unsigned int) atoi(tokens[11]) < cl_retflevel())
+ if((unsigned int) atoi(tokens[12]) < cl_retflevel())
continue;
}
}
@@ -1942,7 +1928,7 @@ static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
if(!strcmp(tokens[1], "*")) {
new->ctype = CL_TYPE_ANY;
} else if((new->ctype = cli_ftcode(tokens[1])) == CL_TYPE_ERROR) {
- cli_dbgmsg("cli_cdb: Unknown container type %s in signature for %s, skipping\n", tokens[1], tokens[0]);
+ 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;
@@ -1951,14 +1937,14 @@ static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
if(!strcmp(tokens[2], "*")) {
new->ftype = CL_TYPE_ANY;
} else if((new->ftype = cli_ftcode(tokens[2])) == CL_TYPE_ERROR) {
- cli_dbgmsg("cli_cdb: Unknown file type %s in signature for %s, skipping\n", tokens[2], tokens[0]);
+ 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_cdb: Can't compile regular expression %s in signature for %s\n", tokens[3], tokens[0]);
+ 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;
@@ -1981,7 +1967,7 @@ static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
dest[0] = dest[1] = atoi(token_str); \
} \
if(ret != CL_SUCCESS) { \
- cli_errmsg("cli_cdb: Invalid value %s in signature for %s\n",\
+ 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); \
@@ -1997,12 +1983,13 @@ static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
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 {
if(strcmp(tokens[7], "0") && strcmp(tokens[7], "1")) {
- cli_errmsg("cli_cdb: Invalid encryption flag value in signature for %s\n", tokens[0]);
+ 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);
@@ -2013,26 +2000,12 @@ static int cli_loadcdb(FILE *fs, struct cl_engine *engine, unsigned int *signo,
new->encrypted = *tokens[7] - 0x30;
}
- if(strcmp(tokens[8], "*")) {
- new->res1 = cli_mpool_strdup(engine->mempool, tokens[8]);
- if(!new->res1) {
- cli_errmsg("cli_cdb: Can't allocate memory for res1 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;
- }
- }
-
- if(strcmp(tokens[9], "*")) {
- new->res2 = cli_mpool_strdup(engine->mempool, tokens[9]);
+ if(strcmp(tokens[10], "*")) {
+ new->res2 = cli_mpool_strdup(engine->mempool, tokens[10]);
if(!new->res2) {
- cli_errmsg("cli_cdb: Can't allocate memory for res2 in signature for %s\n", tokens[0]);
+ 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->res1);
mpool_free(engine->mempool, new->virname);
mpool_free(engine->mempool, new);
ret = CL_EMEM;
@@ -2606,7 +2579,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;
@@ -2671,33 +2643,12 @@ int cl_engine_free(struct cl_engine *engine)
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->res1);
mpool_free(engine->mempool, pt->virname);
mpool_free(engine->mempool, pt);
}
diff --git a/libclamav/scanners.c b/libclamav/scanners.c
index 2c9a61f..afd74a4 100644
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@ -165,8 +165,6 @@ static int cli_scandir(const char *dirname, cli_ctx *ctx)
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)
@@ -180,41 +178,8 @@ static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx
(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");
diff --git a/libclamav/unzip.c b/libclamav/unzip.c
index 63a19c0..f881f7e 100644
--- a/libclamav/unzip.c
+++ b/libclamav/unzip.c
@@ -301,7 +301,6 @@ static unsigned int lhdr(fmap_t *map, uint32_t loff,uint32_t zsize, unsigned int
uint8_t *lh, *zip;
char name[256];
uint32_t csize, usize;
- struct cli_meta_node *meta = ctx->engine->zip_mlist;
if(!(lh = fmap_need_off(map, loff, SIZEOF_LH))) {
cli_dbgmsg("cli_unzip: lh - out of file\n");
@@ -322,7 +321,7 @@ static unsigned int lhdr(fmap_t *map, uint32_t loff,uint32_t zsize, unsigned int
fmap_unneed_off(map, loff, SIZEOF_LH);
return 0;
}
- if(meta || cli_debug_flag) {
+ if(ctx->engine->cdb || cli_debug_flag) {
uint32_t nsize = (LH_flen>=sizeof(name))?sizeof(name)-1:LH_flen;
char *src;
if(nsize && (src = fmap_need_ptr_once(map, zip, nsize))) {
@@ -337,20 +336,7 @@ static unsigned int lhdr(fmap_t *map, uint32_t loff,uint32_t zsize, unsigned int
cli_dbgmsg("cli_unzip: lh - ZMDNAME:%d:%s:%u:%u:%x:%u:%u:%u\n", ((LH_flags & F_ENCR)!=0), name, LH_usize, LH_csize, LH_crc32, LH_method, fc, ctx->recursion);
/* ZMDfmt virname:encrypted(0-1):filename(exact|*):usize(exact|*):csize(exact|*):crc32(exact|*):method(exact|*):fileno(exact|*):maxdepth(exact|*) */
- while(meta &&
- (
- meta->encrypted != ((LH_flags & F_ENCR)!=0) ||
- (meta->size>0 && (uint32_t)meta->size != LH_usize) ||
- (meta->csize>0 && (uint32_t)meta->csize != LH_csize) ||
- (meta->crc32 && meta->crc32 != LH_crc32) ||
- (meta->method>0 && meta->method != LH_method) ||
- (meta->fileno && meta->fileno != fc ) ||
- (meta->maxdepth && ctx->recursion > meta->maxdepth) ||
- (meta->filename && !cli_matchregex(name, meta->filename))
- )
- ) meta = meta->next;
- if(meta) {
- *ctx->virname = meta->virname;
+ if(cli_matchmeta(ctx, CL_TYPE_ANY, name, LH_csize, LH_usize, (LH_flags & F_ENCR)!=0, fc, LH_crc32, NULL) == CL_VIRUS) {
*ret = CL_VIRUS;
return 0;
}
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list