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

Török Edvin edwin at clamav.net
Sun Apr 4 01:15:39 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit f4e342159210b2746277be70d1a320a95d6d1693
Author: Török Edvin <edwin at clamav.net>
Date:   Tue Jan 19 16:38:12 2010 +0200

    Support PE hook bytecodes triggered by logical signature.

diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c
index 6bf1f75..c61c739 100644
--- a/libclamav/bytecode.c
+++ b/libclamav/bytecode.c
@@ -1609,10 +1609,18 @@ int cli_bytecode_context_setfile(struct cli_bc_ctx *ctx, fmap_t *map)
     return 0;
 }
 
-int cli_bytecode_runlsig(const struct cli_all_bc *bcs, const struct cli_bc *bc, const char **virname, const uint32_t* lsigcnt, fmap_t *map)
+int cli_bytecode_runlsig(cli_ctx *cctx, const struct cli_all_bc *bcs, const struct cli_bc *bc, const char **virname, const uint32_t* lsigcnt, fmap_t *map)
 {
     int ret;
     struct cli_bc_ctx ctx;
+
+    if (bc->hook_lsig_id) {
+	/* this is a bytecode for a hook, defer running it until hook is
+	 * executed, so that it has all the info for the hook */
+	if (cctx->hook_lsig_matches)
+	    cli_bitset_set(cctx->hook_lsig_matches, bc->hook_lsig_id-1);
+	return CL_SUCCESS;
+    }
     memset(&ctx, 0, sizeof(ctx));
     cli_bytecode_context_setfuncid(&ctx, bc, 0);
     ctx.hooks.match_counts = lsigcnt;
@@ -1637,7 +1645,7 @@ int cli_bytecode_runlsig(const struct cli_all_bc *bcs, const struct cli_bc *bc,
     return CL_SUCCESS;
 }
 
-int cli_bytecode_runhook(const struct cl_engine *engine, struct cli_bc_ctx *ctx,
+int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct cli_bc_ctx *ctx,
 			 unsigned id, fmap_t *map, const char **virname)
 {
     const unsigned *hooks = engine->hooks[id - _BC_START_HOOKS];
@@ -1648,6 +1656,12 @@ int cli_bytecode_runhook(const struct cl_engine *engine, struct cli_bc_ctx *ctx,
     cli_dbgmsg("Bytecode executing hook id %u (%u hooks)\n", id, hooks_cnt);
     for (i=0;i < hooks_cnt;i++) {
 	const struct cli_bc *bc = &engine->bcs.all_bcs[hooks[i]];
+	if (bc->lsig) {
+	    if (!cctx->hook_lsig_matches ||
+		!cli_bitset_test(cctx->hook_lsig_matches, bc->hook_lsig_id-1))
+		continue;
+	    cli_dbgmsg("Bytecode: executing bytecode %u (lsig matched)" , bc->id);
+	}
 	cli_bytecode_context_setfuncid(ctx, bc, 0);
 	ret = cli_bytecode_run(&engine->bcs, bc, ctx);
 	if (ret != CL_SUCCESS) {
diff --git a/libclamav/bytecode.h b/libclamav/bytecode.h
index 5d4911d..d3be533 100644
--- a/libclamav/bytecode.h
+++ b/libclamav/bytecode.h
@@ -66,6 +66,7 @@ struct cli_bc {
   unsigned vnames_cnt;
   struct cli_bc_dbgnode *dbgnodes;
   unsigned dbgnode_cnt;
+  unsigned hook_lsig_id;
 };
 
 struct cli_all_bc {
@@ -106,8 +107,9 @@ int cli_bytecode_done(struct cli_all_bc *allbc);
 
 /* Hooks */
 struct cli_exe_info;
-int cli_bytecode_runlsig(const struct cli_all_bc *bcs, const struct cli_bc* bc, const char **virname, const uint32_t* lsigcnt, fmap_t *fmap);
-int cli_bytecode_runhook(const struct cl_engine *engine, struct cli_bc_ctx *ctx, unsigned id, fmap_t *map, const char **virname);
+struct cli_ctx_tag;
+int cli_bytecode_runlsig(struct cli_ctx_tag *ctx, const struct cli_all_bc *bcs, const struct cli_bc* bc, const char **virname, const uint32_t* lsigcnt, fmap_t *fmap);
+int cli_bytecode_runhook(struct cli_ctx_tag *cctx, const struct cl_engine *engine, struct cli_bc_ctx *ctx, unsigned id, fmap_t *map, const char **virname);
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/libclamav/bytecode_api.h b/libclamav/bytecode_api.h
index a9edc04..d81f083 100644
--- a/libclamav/bytecode_api.h
+++ b/libclamav/bytecode_api.h
@@ -71,7 +71,7 @@ extern const struct cli_exe_info __clambc_exeinfo;
 /** PE data, if this is a PE hook */
 extern const struct cli_pe_hook_data __clambc_pedata;
 /** File size (max 4G) */
-extern const uint32_t __clambc_filesize;
+extern const uint32_t __clambc_filesize[1];
 
 /** Kind of the bytecode */
 const uint16_t __clambc_kind;
diff --git a/libclamav/bytecode_api_decl.c b/libclamav/bytecode_api_decl.c
index 2ab0660..1315d1b 100644
--- a/libclamav/bytecode_api_decl.c
+++ b/libclamav/bytecode_api_decl.c
@@ -54,9 +54,9 @@ const struct cli_apiglobal cli_globals[] = {
 /* Bytecode globals BEGIN */
 	{"__clambc_kind", GLOBAL_KIND, 16,
 	 ((char*)&((struct cli_bc_ctx*)0)->hooks.kind - (char*)NULL)},
-	{"__clambc_match_counts", GLOBAL_MATCH_COUNTS, 82,
+	{"__clambc_match_counts", GLOBAL_MATCH_COUNTS, 83,
 	 ((char*)&((struct cli_bc_ctx*)0)->hooks.match_counts - (char*)NULL)},
-	{"__clambc_filesize", GLOBAL_FILESIZE, 32,
+	{"__clambc_filesize", GLOBAL_FILESIZE, 82,
 	 ((char*)&((struct cli_bc_ctx*)0)->hooks.filesize - (char*)NULL)},
 	{"__clambc_exeinfo", GLOBAL_EXEINFO, 79,
 	 ((char*)&((struct cli_bc_ctx*)0)->hooks.exeinfo - (char*)NULL)},
@@ -79,17 +79,18 @@ static uint16_t cli_tmp10[]={80, 32, 32, 16};
 static uint16_t cli_tmp11[]={81};
 static uint16_t cli_tmp12[]={32, 32, 32, 32, 32, 32, 32, 32, 32};
 static uint16_t cli_tmp13[]={32};
-static uint16_t cli_tmp14[]={32, 32, 32};
-static uint16_t cli_tmp15[]={32, 65, 32};
-static uint16_t cli_tmp16[]={32, 86, 32};
-static uint16_t cli_tmp17[]={87};
-static uint16_t cli_tmp18[]={16, 8, 8, 8, 89, 88};
-static uint16_t cli_tmp19[]={8};
-static uint16_t cli_tmp20[]={90};
-static uint16_t cli_tmp21[]={8};
-static uint16_t cli_tmp22[]={32, 92, 32};
-static uint16_t cli_tmp23[]={93};
-static uint16_t cli_tmp24[]={92};
+static uint16_t cli_tmp14[]={32};
+static uint16_t cli_tmp15[]={32, 32, 32};
+static uint16_t cli_tmp16[]={32, 65, 32};
+static uint16_t cli_tmp17[]={32, 87, 32};
+static uint16_t cli_tmp18[]={88};
+static uint16_t cli_tmp19[]={16, 8, 8, 8, 90, 89};
+static uint16_t cli_tmp20[]={8};
+static uint16_t cli_tmp21[]={91};
+static uint16_t cli_tmp22[]={8};
+static uint16_t cli_tmp23[]={32, 93, 32};
+static uint16_t cli_tmp24[]={94};
+static uint16_t cli_tmp25[]={93};
 
 const struct cli_bc_type cli_apicall_types[]={
 	{DStructType, cli_tmp0, 10, 0, 0},
@@ -105,39 +106,40 @@ const struct cli_bc_type cli_apicall_types[]={
 	{DStructType, cli_tmp10, 4, 0, 0},
 	{DPointerType, cli_tmp11, 1, 0, 0},
 	{DStructType, cli_tmp12, 9, 0, 0},
-	{DArrayType, cli_tmp13, 64, 0, 0},
-	{DFunctionType, cli_tmp14, 3, 0, 0},
+	{DArrayType, cli_tmp13, 1, 0, 0},
+	{DArrayType, cli_tmp14, 64, 0, 0},
 	{DFunctionType, cli_tmp15, 3, 0, 0},
 	{DFunctionType, cli_tmp16, 3, 0, 0},
-	{DPointerType, cli_tmp17, 1, 0, 0},
-	{DStructType, cli_tmp18, 6, 0, 0},
-	{DArrayType, cli_tmp19, 29, 0, 0},
-	{DArrayType, cli_tmp20, 10, 0, 0},
-	{DArrayType, cli_tmp21, 3, 0, 0},
-	{DFunctionType, cli_tmp22, 3, 0, 0},
-	{DPointerType, cli_tmp23, 1, 0, 0},
-	{DStructType, cli_tmp24, 1, 0, 0}
+	{DFunctionType, cli_tmp17, 3, 0, 0},
+	{DPointerType, cli_tmp18, 1, 0, 0},
+	{DStructType, cli_tmp19, 6, 0, 0},
+	{DArrayType, cli_tmp20, 29, 0, 0},
+	{DArrayType, cli_tmp21, 10, 0, 0},
+	{DArrayType, cli_tmp22, 3, 0, 0},
+	{DFunctionType, cli_tmp23, 3, 0, 0},
+	{DPointerType, cli_tmp24, 1, 0, 0},
+	{DStructType, cli_tmp25, 1, 0, 0}
 };
 
 const unsigned cli_apicall_maxtypes=sizeof(cli_apicall_types)/sizeof(cli_apicall_types[0]);
 const struct cli_apicall cli_apicalls[]={
 /* Bytecode APIcalls BEGIN */
-	{"test0", 22, 0, 1},
-	{"test1", 14, 0, 0},
-	{"read", 15, 1, 1},
-	{"write", 15, 2, 1},
-	{"seek", 14, 1, 0},
-	{"setvirusname", 15, 3, 1},
-	{"debug_print_str", 15, 4, 1},
-	{"debug_print_uint", 14, 2, 0},
-	{"disasm_x86", 16, 5, 1},
-	{"trace_directory", 15, 6, 1},
-	{"trace_scope", 15, 7, 1},
-	{"trace_source", 15, 8, 1},
-	{"trace_op", 15, 9, 1},
-	{"trace_value", 15, 10, 1},
-	{"trace_ptr", 15, 11, 1},
-	{"pe_rawaddr", 14, 3, 0}
+	{"test0", 23, 0, 1},
+	{"test1", 15, 0, 0},
+	{"read", 16, 1, 1},
+	{"write", 16, 2, 1},
+	{"seek", 15, 1, 0},
+	{"setvirusname", 16, 3, 1},
+	{"debug_print_str", 16, 4, 1},
+	{"debug_print_uint", 15, 2, 0},
+	{"disasm_x86", 17, 5, 1},
+	{"trace_directory", 16, 6, 1},
+	{"trace_scope", 16, 7, 1},
+	{"trace_source", 16, 8, 1},
+	{"trace_op", 16, 9, 1},
+	{"trace_value", 16, 10, 1},
+	{"trace_ptr", 16, 11, 1},
+	{"pe_rawaddr", 15, 3, 0}
 /* Bytecode APIcalls END */
 };
 const cli_apicall_int2 cli_apicalls0[] = {
diff --git a/libclamav/matcher.c b/libclamav/matcher.c
index f9e761f..ffd17d3 100644
--- a/libclamav/matcher.c
+++ b/libclamav/matcher.c
@@ -512,7 +512,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
 		ret = CL_VIRUS; \
 		break; \
 	    } \
-	    if(cli_bytecode_runlsig(&ctx->engine->bcs, xroot->ac_lsigtable[i]->bc, ctx->virname, xdata.lsigcnt[i], map) == CL_VIRUS) { \
+	    if(cli_bytecode_runlsig(ctx, &ctx->engine->bcs, xroot->ac_lsigtable[i]->bc, ctx->virname, xdata.lsigcnt[i], map) == CL_VIRUS) { \
 		ret = CL_VIRUS; \
 		break; \
 	    } \
diff --git a/libclamav/others.h b/libclamav/others.h
index 99274b2..47a8dc2 100644
--- a/libclamav/others.h
+++ b/libclamav/others.h
@@ -99,8 +99,14 @@ extern uint8_t cli_debug_flag;
 #define NAME_MAX 256
 #endif
 
+typedef struct bitset_tag
+{
+        unsigned char *bitset;
+        unsigned long length;
+} bitset_t;
+
 /* internal clamav context */
-typedef struct {
+typedef struct cli_ctx_tag {
     const char **virname;
     unsigned long int *scanned;
     const struct cli_matcher *root;
@@ -114,6 +120,7 @@ typedef struct {
     size_t container_size;
     struct cli_dconf *dconf;
     fmap_t **fmap;
+    bitset_t* hook_lsig_matches;
 } cli_ctx;
 
 
@@ -227,6 +234,7 @@ struct cl_engine {
     struct cli_all_bc bcs;
     unsigned *hooks[_BC_LAST_HOOK - _BC_START_HOOKS];
     unsigned hooks_cnt[_BC_LAST_HOOK - _BC_START_HOOKS];
+    unsigned hook_lsig_ids;
 };
 
 struct cl_settings {
@@ -372,12 +380,6 @@ static inline void cli_writeint32(char *offset, uint32_t value)
 #endif
 #define CLI_SAR(n,s) n = CLI_SRS(n,s)
 
-typedef struct bitset_tag
-{
-        unsigned char *bitset;
-        unsigned long length;
-} bitset_t;
-
 #ifdef __GNUC__
 void cli_warnmsg(const char *str, ...) __attribute__((format(printf, 1, 2)));
 #else
diff --git a/libclamav/pe.c b/libclamav/pe.c
index 256a11f..2645d76 100644
--- a/libclamav/pe.c
+++ b/libclamav/pe.c
@@ -2239,7 +2239,7 @@ int cli_scanpe(cli_ctx *ctx, icon_groupset *iconset)
     pedata.hdr_size = hdr_size;
     cli_bytecode_context_setpe(bc_ctx, &pedata);
     cli_bytecode_context_setctx(bc_ctx, ctx);
-    ret = cli_bytecode_runhook(ctx->engine, bc_ctx, BC_PE_UNPACKER, map, ctx->virname);
+    ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_UNPACKER, map, ctx->virname);
     switch (ret) {
 	case CL_VIRUS:
 	    return CL_VIRUS;
diff --git a/libclamav/readdb.c b/libclamav/readdb.c
index fed0145..e2250ed 100644
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@ -1330,7 +1330,7 @@ static int cli_loadcbc(FILE *fs, struct cl_engine *engine, unsigned int *signo,
 	return rc;
     }
     sigs += 2;/* the bytecode itself and the logical sig */
-    if (bc->kind == BC_LOGICAL) {
+    if (bc->kind == BC_LOGICAL || bc->lsig) {
 	if (!bc->lsig) {
 	    cli_errmsg("Bytecode %s has logical kind, but missing logical signature!\n", dbname);
 	    return CL_EMALFDB;
@@ -1342,10 +1342,13 @@ static int cli_loadcbc(FILE *fs, struct cl_engine *engine, unsigned int *signo,
 		       bc->lsig, dbname, cl_strerror(rc));
 	    return rc;
 	}
-    } else {
+    }
+    if (bc->kind != BC_LOGICAL) {
 	if (bc->lsig) {
-	    cli_errmsg("Bytecode %s has logical signature but is not logical kind!\n", dbname);
-	    return CL_EMALFDB;
+	    /* runlsig will only flip a status bit, not report a match,
+	     * when the hooks are executed we only execute the hook if its
+	     * status bit is on */
+	    bc->hook_lsig_id = ++engine->hook_lsig_ids;
 	}
 	if (bc->kind >= _BC_START_HOOKS && bc->kind < _BC_LAST_HOOK) {
 	    unsigned hook = bc->kind - _BC_START_HOOKS;
diff --git a/libclamav/scanners.c b/libclamav/scanners.c
index ac225b1..1cdc134 100644
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@ -1815,6 +1815,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
 	cli_file_t current_container_type = ctx->container_type; /* TODO: container tracking code TBD - bb#1293 */
 	size_t current_container_size = ctx->container_size, hashed_size;
 	unsigned char hash[16];
+	bitset_t *old_hook_lsig_matches;
 
     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);
@@ -1857,6 +1858,8 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
 	return CL_CLEAN;
     }
     hashed_size = (*ctx->fmap)->len;
+    old_hook_lsig_matches = ctx->hook_lsig_matches;
+    ctx->hook_lsig_matches = NULL;
 
     if(!ctx->options || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */
 	if(ctx->recursion == ctx->engine->maxreclevel)
@@ -1883,11 +1886,17 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
     }
     lseek(desc, 0, SEEK_SET); /* FIXMEFMAP: remove ? */
 
+    ctx->hook_lsig_matches = cli_bitset_init();
+    if (!ctx->hook_lsig_matches)
+	return CL_EMEM;
+
     if(type != CL_TYPE_IGNORED && ctx->engine->sdb) {
 	if((ret = cli_scanraw(ctx, type, 0, &dettype)) == CL_VIRUS) {
 	    ret = cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
 	    funmap(*ctx->fmap);
-	    ctx->fmap--; 
+	    ctx->fmap--;
+	    cli_bitset_free(ctx->hook_lsig_matches);
+	    ctx->hook_lsig_matches = old_hook_lsig_matches;
 	    return ret;
 	}
 	lseek(desc, 0, SEEK_SET); /* FIXMEFMAP: remove ? */
@@ -2134,7 +2143,9 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
     if(ret == CL_VIRUS) {
 	ret = cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
 	funmap(*ctx->fmap);
-	ctx->fmap--; 
+	ctx->fmap--;
+	cli_bitset_free(ctx->hook_lsig_matches);
+	ctx->hook_lsig_matches = old_hook_lsig_matches;
 	return ret;
     }
 
@@ -2150,7 +2161,9 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
 	if(cli_scanraw(ctx, type, typercg, &dettype) == CL_VIRUS) {
 	    ret =  cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
 	    funmap(*ctx->fmap);
-	    ctx->fmap--; 
+	    ctx->fmap--;
+	    cli_bitset_free(ctx->hook_lsig_matches);
+	    ctx->hook_lsig_matches = old_hook_lsig_matches;
 	    return ret;
 	}
     }
@@ -2158,6 +2171,8 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
     ctx->recursion++;
     lseek(desc, 0, SEEK_SET);
     switch(type) {
+	/* bytecode hooks triggered by a lsig must be a hook
+	 * called from one of the functions here */
 	case CL_TYPE_TEXT_ASCII:
 	case CL_TYPE_TEXT_UTF16BE:
 	case CL_TYPE_TEXT_UTF16LE:
@@ -2176,13 +2191,14 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
 	    if(SCAN_PE && ctx->dconf->pe)
 		ret = cli_scanpe(ctx, NULL);
 	    break;
-
 	default:
 	    break;
     }
     ctx->recursion--;
     funmap(*ctx->fmap);
     ctx->fmap--;
+    cli_bitset_free(ctx->hook_lsig_matches);
+    ctx->hook_lsig_matches = old_hook_lsig_matches;
 
     if(ret == CL_VIRUS)
 	ret = cli_checkfp(desc, ctx) ? CL_CLEAN : CL_VIRUS;
@@ -2219,11 +2235,12 @@ int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, cons
     if(!ctx.fmap)
 	return CL_EMEM;
     ctx.fmap--;
+    ctx.hook_lsig_matches = NULL; cli_bitset_init();
 
     rc = cli_magic_scandesc(desc, &ctx);
 
     ctx.fmap++;
-    free(ctx.fmap);
+    cli_bitset_free(ctx.hook_lsig_matches);
     if(rc == CL_CLEAN && ctx.found_possibly_unwanted)
     	rc = CL_VIRUS;
     return rc;

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list