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


The following commit has been merged in the debian/unstable branch:
commit 74f5816c58e0ed465ddbbf3d3019907c624140d4
Author: Török Edvin <edwin at clamav.net>
Date:   Tue Mar 23 21:47:57 2010 +0200

    Interpreter fixes for accessing 'ctx'.
    
    This allow all cbcs in unit_tests/input to pass.
    Not yet working on bytecode.cvd though.

diff --git a/clambc/bcrun.c b/clambc/bcrun.c
index 125f3d6..4d06bdd 100644
--- a/clambc/bcrun.c
+++ b/clambc/bcrun.c
@@ -161,7 +161,72 @@ static void print_src(const char *file)
   } while (nread > 0);
   fclose(f);
 }
-
+static uint32_t deadbeefcounts[64] = {
+    0xdeadbeef,
+    0,
+    0xbeefdead,
+    0,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+    0xdeadbeef,
+};
 int main(int argc, char *argv[])
 {
     FILE *f;
@@ -315,7 +380,8 @@ int main(int argc, char *argv[])
 	    }
 	    funmap(map);
 	}
-
+	/* for testing */
+	ctx->hooks.match_counts = deadbeefcounts;
 	rc = cli_bytecode_run(&bcs, bc, ctx);
 	if (rc != CL_SUCCESS) {
 	    fprintf(stderr,"Unable to run bytecode: %s\n", cl_strerror(rc));
diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c
index 4ba984e..a0a08f7 100644
--- a/libclamav/bytecode.c
+++ b/libclamav/bytecode.c
@@ -36,9 +36,35 @@
 #include "bytecode_api_impl.h"
 #include <string.h>
 
-/* TODO: we should make sure lsigcnt is never NULL, and has at least as many
- * elements as the bytecode needs */
-static const uint32_t nomatch[64];
+/* dummy values */
+static const uint32_t nomatch[64] = {
+    0xdeadbeef, 0xdeaddead, 0xbeefdead, 0xdeaddead, 0xdeadbeef, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const uint16_t nokind;
+static const uint32_t nofilesize;
+static const struct cli_pe_hook_data nopedata;
+
+static void context_safe(struct cli_bc_ctx *ctx)
+{
+    /* make sure these are never NULL */
+    if (!ctx->hooks.kind)
+	ctx->hooks.kind = &nokind;
+    if (!ctx->hooks.match_counts)
+	ctx->hooks.match_counts = nomatch;
+    if (!ctx->hooks.filesize)
+	ctx->hooks.filesize = &nofilesize;
+    if (!ctx->hooks.pedata)
+	ctx->hooks.pedata = &nopedata;
+}
+
 struct cli_bc_ctx *cli_bytecode_context_alloc(void)
 {
     struct cli_bc_ctx *ctx = cli_calloc(1, sizeof(*ctx));
@@ -1146,8 +1172,11 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 		inst.interp_op += 2;
 	    else if (inst.type <= 32)
 		inst.interp_op += 3;
-	    else if (inst.type <= 64)
+	    else if (inst.type <= 65)
 		inst.interp_op += 4;
+	    else {
+		cli_dbgmsg("unknown inst type: %d\n", inst.type);
+	    }
 	}
 	BB->insts[BB->numInsts++] = inst;
     }
@@ -1359,6 +1388,7 @@ int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, stru
 	cli_errmsg("bytecode has to be prepared either for interpreter or JIT!\n");
 	return CL_EARG;
     }
+    context_safe(ctx);
     if (bc->state == bc_interp) {
 	memset(&func, 0, sizeof(func));
 	func.numInsts = 1;
@@ -1473,6 +1503,7 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
 {
     unsigned i, j, k;
     uint64_t *gmap;
+    unsigned bcglobalid = cli_apicall_maxglobal - _FIRST_GLOBAL+2;
     bc->numGlobalBytes = 0;
     gmap = cli_malloc(bc->num_globals*sizeof(*gmap));
     if (!gmap)
@@ -1499,10 +1530,47 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
 	ty = &bc->types[bc->globaltys[j]-65];
 	switch (ty->kind) {
 	    case DPointerType:
-		*(uint64_t*)&bc->globalBytes[gmap[j]] =
-		    ptr_compose(bc->globals[j][1] - _FIRST_GLOBAL + 1,
-				bc->globals[j][0]);
-		break;
+		{
+		    uint64_t ptr;
+		    if (bc->globals[j][1] >= _FIRST_GLOBAL) {
+			ptr = ptr_compose(bc->globals[j][1] - _FIRST_GLOBAL + 1,
+					    bc->globals[j][0]);
+		    } else {
+			if (bc->globals[j][1] > bc->num_globals)
+			    continue;
+			ptr = ptr_compose(bcglobalid,
+					  gmap[bc->globals[j][1]] + bc->globals[j][0]);
+		    }
+		    *(uint64_t*)&bc->globalBytes[gmap[j]] = ptr;
+		    break;
+		}
+	    case DArrayType:
+		{
+		    unsigned elsize, i, off = gmap[j];
+		    /* TODO: support other than ints in arrays */
+		    elsize = typesize(bc, ty->containedTypes[0]);
+		    switch (elsize) {
+			case 1:
+			    for(i=0;i<ty->numElements;i++)
+				bc->globalBytes[off+i] = bc->globals[j][i];
+			    break;
+			case 2:
+			    for(i=0;i<ty->numElements;i++)
+				*(uint16_t*)&bc->globalBytes[off+i*2] = bc->globals[j][i];
+			    break;
+			case 4:
+			    for(i=0;i<ty->numElements;i++)
+				*(uint32_t*)&bc->globalBytes[off+i*4] = bc->globals[j][i];
+			    break;
+			case 8:
+			    for(i=0;i<ty->numElements;i++)
+				*(uint64_t*)&bc->globalBytes[off+i*8] = bc->globals[j][i];
+			    break;
+			default:
+			    cli_dbgmsg("interpreter: unsupported elsize: %u\n", elsize);
+		    }
+		    break;
+		}
 	    default:
 		/*TODO*/
 		if (!bc->globals[j][1])
diff --git a/libclamav/bytecode_vm.c b/libclamav/bytecode_vm.c
index 8da03f5..2f42c74 100644
--- a/libclamav/bytecode_vm.c
+++ b/libclamav/bytecode_vm.c
@@ -491,8 +491,12 @@ static inline int64_t ptr_register_glob_fixedid(struct ptr_infos *infos,
 	infos->nglobs = n;
     }
     sinfos = &infos->glob_infos[n-1];
+    if (!values)
+	size = 0;
     sinfos->base = values;
     sinfos->size = size;
+    cli_dbgmsg("bytecode: registered ctx variable at %p (+%u) id %u\n", values,
+	       size, n);
     return ptr_compose(n, 0);
 }
 
@@ -584,18 +588,39 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
     char *values = ctx->values;
     char *old_values;
     struct ptr_infos ptrinfos;
+    struct timeval tv0, tv1, timeout;
 
     memset(&ptrinfos, 0, sizeof(ptrinfos));
     memset(&stack, 0, sizeof(stack));
     for (i=0;i < cli_apicall_maxglobal - _FIRST_GLOBAL; i++) {
 	const struct cli_apiglobal *g = &cli_globals[i];
-	void *apiglobal = (void*)(((char*)&ctx->hooks) + g->offset);
+	void **apiglobal = (void**)(((char*)ctx) + g->offset);
+	if (!apiglobal)
+	    continue;
+	void *apiptr = *apiglobal;
 	uint32_t size = globaltypesize(g->type);
-	ptr_register_glob_fixedid(&ptrinfos, apiglobal, size, g->globalid - _FIRST_GLOBAL+1);
+	ptr_register_glob_fixedid(&ptrinfos, apiptr, size, g->globalid - _FIRST_GLOBAL+1);
     }
+    ptr_register_glob_fixedid(&ptrinfos, bc->globalBytes, bc->numGlobalBytes,
+			      cli_apicall_maxglobal - _FIRST_GLOBAL + 2);
+
+    gettimeofday(&tv0, NULL);
+    timeout.tv_usec = tv0.tv_usec + ctx->bytecode_timeout*1000;
+    timeout.tv_sec = tv0.tv_sec + timeout.tv_usec/1000000;
+    timeout.tv_usec %= 1000000;
 
     do {
 	pc++;
+	if (!(pc % 5000)) {
+	    gettimeofday(&tv1, NULL);
+	    if (tv1.tv_sec > timeout.tv_sec ||
+		(tv1.tv_sec == timeout.tv_sec &&
+		 tv1.tv_usec > timeout.tv_usec)) {
+		cli_errmsg("Bytecode run timed out in interpreter\n");
+		stop = CL_ETIMEOUT;
+		break;
+	    }
+	}
 	switch (inst->interp_op) {
 	    DEFINE_BINOP(OP_BC_ADD, res = op0 + op1);
 	    DEFINE_BINOP(OP_BC_SUB, res = op0 - op1);
@@ -730,14 +755,13 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 			break;
 		    }
 		    case 1: {
-			cli_errmsg("bytecode: type 1 apicalls not yet implemented!\n");
-			stop = CL_EBYTECODE;
-		/*	void *p;
-			uint32_t u;
-			p = ...;
-			u = READ32(v, inst->u.ops.ops[1]);
-			res =  cli_apicalls1[api->idx](p, u);
-			break;*/
+			void* arg1;
+			unsigned arg2;
+			/* check that arg2 is size of arg1 */
+			READ32(arg2, inst->u.ops.ops[1]);
+			READP(arg1, inst->u.ops.ops[0], arg2);
+			res = cli_apicalls1[api->idx](ctx, arg1, arg2);
+			break;
 		    }
 		    case 2: {
 			int32_t a;
@@ -745,16 +769,9 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 			res = cli_apicalls2[api->idx](ctx, a);
 			break;
 		    }
-		    case 3: {
-			cli_errmsg("bytecode: type 3 apicalls not yet implemented!\n");
+		    default:
+			cli_errmsg("bytecode: type %u apicalls not yet implemented!\n", api->kind);
 			stop = CL_EBYTECODE;
-		/*	void *p;
-			uint32_t u;
-			p = ...;
-			u = READ32(v, inst->u.ops.ops[1]);
-			res =  cli_apicalls1[api->idx](p, u);
-			break;*/
-			    }
 		}
 		WRITE32(inst->dest, res);
 		break;
@@ -951,6 +968,13 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 	    CHECK_GT(bb->numInsts, bb_inst);
 	}
     } while (stop == CL_SUCCESS);
+    if (cli_debug_flag) {
+	gettimeofday(&tv1, NULL);
+	tv1.tv_sec -= tv0.tv_sec;
+	tv1.tv_usec -= tv0.tv_usec;
+	cli_dbgmsg("intepreter bytecode run finished in %dus\n",
+		   tv1.tv_sec*1000000 + tv1.tv_usec);
+    }
 
     cli_stack_destroy(&stack);
     return stop == CL_BREAK ? CL_SUCCESS : stop;
diff --git a/unit_tests/check_bytecode.c b/unit_tests/check_bytecode.c
index 052488c..dd86fe4 100644
--- a/unit_tests/check_bytecode.c
+++ b/unit_tests/check_bytecode.c
@@ -120,9 +120,8 @@ END_TEST
 START_TEST (test_apicalls2)
 {
     cl_init(CL_INIT_DEFAULT);
-    if (have_clamjit)/*FIXME: should work with both */
     runtest("input/apicalls2.cbc", 0xf00d, CL_SUCCESS, 0);
-/*    runtest("input/apicalls2.cbc", 0xf00d, CL_SUCCESS, 1); */
+    runtest("input/apicalls2.cbc", 0xf00d, CL_SUCCESS, 1); 
 }
 END_TEST
 
@@ -138,20 +137,16 @@ END_TEST
 START_TEST (test_lsig)
 {
     cl_init(CL_INIT_DEFAULT);
-#if 0
-FIXME: match_counts should be initialized in clambc mode
-    if (have_clamjit)/* FIXME: should work with both */
     runtest("input/lsig.cbc", 0, 0, 0);
-  //runtest("input/lsig.cbc", 0, CL_EBYTECODE, 1);
-#endif
+    runtest("input/lsig.cbc", 0, 0, 1);
 }
 END_TEST
 
 START_TEST (test_inf)
 {
     cl_init(CL_INIT_DEFAULT);
-    if (have_clamjit)
-	runtest("input/inf.cbc", 0, CL_ETIMEOUT, 0);
+    runtest("input/inf.cbc", 0, CL_ETIMEOUT, 0);
+    runtest("input/inf.cbc", 0, CL_ETIMEOUT, 1);
 }
 END_TEST
 

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list