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


The following commit has been merged in the debian/unstable branch:
commit 9cbece5ccd636c0d3253cc280189dfe7a60b0ebd
Author: Török Edvin <edwin at clamav.net>
Date:   Sun Mar 21 19:47:25 2010 +0200

    WiP fixing globals in interpreter.

diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c
index 136161f..44cbb9a 100644
--- a/libclamav/bytecode.c
+++ b/libclamav/bytecode.c
@@ -1441,6 +1441,7 @@ void cli_bytecode_destroy(struct cli_bc *bc)
     if (bc->uses_apis)
 	cli_bitset_free(bc->uses_apis);
     free(bc->lsig);
+    free(bc->globalBytes);
 }
 
 #define MAP(val) do { operand_t o = val; \
@@ -1476,6 +1477,9 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc)
 	gmap[j] = bc->numGlobalBytes;
 	bc->numGlobalBytes += typesize(bc, ty);
     }
+    bc->globalBytes = cli_calloc(1, bc->numGlobalBytes);
+    if (!bc->globalBytes)
+	return CL_EMEM;
 
     for (i=0;i<bc->num_func;i++) {
 	struct cli_bc_func *bcfunc = &bc->funcs[i];
diff --git a/libclamav/bytecode_priv.h b/libclamav/bytecode_priv.h
index c5b6ea8..8c129b6 100644
--- a/libclamav/bytecode_priv.h
+++ b/libclamav/bytecode_priv.h
@@ -166,8 +166,6 @@ struct cli_bc_ctx {
     unsigned line;
     unsigned col;
     mpool_t *mpool;
-    uint32_t numGlobals;
-    uint8_t* globals;
     struct bc_inflate* inflates;
     unsigned ninflates;
     struct bc_buffer *buffers;
diff --git a/libclamav/bytecode_vm.c b/libclamav/bytecode_vm.c
index 416ea84..c5c121f 100644
--- a/libclamav/bytecode_vm.c
+++ b/libclamav/bytecode_vm.c
@@ -36,7 +36,7 @@
 /* These checks will also be done by the bytecode verifier, but for
  * debugging purposes we have explicit checks, these should never fail! */
 #ifdef CL_BYTECODE_DEBUG
-static int bcfail(const char *msg, long a, long b,
+static int never_inline bcfail(const char *msg, long a, long b,
 		  const char *file, unsigned line)
 {
     cli_errmsg("bytecode: check failed %s (%lx and %lx) at %s:%u\n", msg, a, b, file, line);
@@ -56,6 +56,8 @@ static int bcfail(const char *msg, long a, long b,
 #define TRACE_W(x, w, p) cli_dbgmsg("bytecode trace: %u, write%d @%u %llx\n", pc, p, w, (long long)x);
 #define TRACE_EXEC(id, dest, ty, stack) cli_dbgmsg("bytecode trace: executing %d, -> %u (%u); %u\n", id, dest, ty, stack)
 #else
+static inline int bcfail(const char *msg, long a, long b,
+			 const char *file, unsigned line) {}
 #define TRACE_R(x)
 #define TRACE_W(x, w, p)
 #define TRACE_EXEC(id, dest, ty, stack)
@@ -262,6 +264,7 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack,
 #define uint_type(n) uint##n##_t
 #define READNfrom(maxBytes, from, x, n, p)\
     CHECK_GT((maxBytes), (p)+(n/8)-1);\
+    CHECK_EQ((p)&(n-1), 0);\
     x = *(uint_type(n)*)&(from)[(p)];\
     TRACE_R(x)
 
@@ -269,7 +272,7 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack,
  do {\
      if (p&0x80000000) {\
 	 uint32_t pg = p&0x7fffffff;\
-	 READNfrom(ctx->numGlobals, ctx->globals, x, n, p);\
+	 READNfrom(bc->numGlobalBytes, bc->globals, x, n, pg);\
      } else {\
 	 READNfrom(func->numBytes, values, x, n, p);\
      }\
@@ -282,11 +285,16 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack,
 #define READ32(x, p) READN(x, 32, p)
 #define READ64(x, p) READN(x, 64, p)
 
-#define PSIZE sizeof(void*)
-#define READP(x, p) CHECK_GT(func->numBytes, p+PSIZE-1);\
-    CHECK_EQ((p)&(PSIZE-1), 0);\
-    x = *(void**)&values[p];\
-    TRACE_R(x)
+#define PSIZE sizeof(int64_t)
+#define READP(x, p, asize) { int64_t iptr__;\
+    READN(iptr__, 8, p);\
+    x = ptr_torealptr(&ptrinfos, iptr__, (asize));\
+    if (!x) {\
+	stop = CL_EBYTECODE;\
+	break;\
+    }\
+    TRACE_R(x)\
+}
 
 #define READOLD8(x, p) CHECK_GT(func->numBytes, p);\
     x = *(uint8_t*)&old_values[p];\
@@ -436,6 +444,101 @@ static always_inline struct stack_entry *pop_stack(struct stack *stack,
 		break;\
 	    }
 
+struct ptr_info {
+    uint8_t *base;
+    uint32_t size;
+};
+
+struct ptr_infos {
+    struct ptr_info *stack_infos;
+    struct ptr_info *glob_infos;
+    unsigned nstacks, nglobs;
+};
+
+static inline int64_t ptr_compose(int32_t id, uint32_t offset)
+{
+    uint64_t i = id;
+    return (i << 32) | offset;
+}
+
+static inline int32_t ptr_register_stack(struct ptr_infos *infos,
+					 unsigned char *values,
+					 uint32_t off, uint32_t size)
+{
+    int16_t id;
+    unsigned n = infos->nstacks + 1;
+    struct ptr_info *sinfos = cli_realloc(infos->stack_infos,
+					  sizeof(*sinfos)*n);
+    if (!sinfos)
+	return 0;
+    infos->stack_infos = sinfos;
+    infos->nstacks = n;
+    sinfos = &sinfos[n-1];
+    sinfos->base = values + off;
+    sinfos->size = size;
+    return ptr_compose(-(n-1), 0);
+}
+
+static inline int64_t ptr_register_glob(struct ptr_infos *infos,
+					void *values, uint32_t size)
+{
+    unsigned n = infos->nstacks + 1;
+    struct ptr_info *sinfos = cli_realloc(infos->stack_infos,
+					  sizeof(*sinfos)*n);
+    if (!sinfos)
+	return 0;
+    infos->stack_infos = sinfos;
+    infos->nstacks = n;
+    sinfos = &sinfos[n-1];
+    sinfos->base = values;
+    sinfos->size = size;
+    return ptr_compose(n, 0);
+}
+
+static inline int64_t ptr_index(int64_t ptr, uint32_t off)
+{
+    int32_t ptrid = ptr >> 32;
+    uint32_t ptroff = (uint32_t)ptr;
+    return ptr_compose(ptrid, ptroff+off);
+}
+
+static inline void* ptr_torealptr(const struct ptr_infos *infos, int64_t ptr,
+				  uint32_t read_size)
+{
+    struct ptr_info *info;
+    int32_t ptrid = ptr >> 32;
+    uint32_t ptroff = (uint32_t)ptr;
+    if (UNLIKELY(!ptrid)) {
+	bcfail("nullptr", ptrid, 0, __FILE__, __LINE__);
+	return NULL;
+    }
+    if (ptrid < 0) {
+	ptrid = -ptrid;
+	if (UNLIKELY(ptrid >= infos->nstacks)) {
+	    bcfail("ptr", ptrid, infos->nstacks, __FILE__, __LINE__);
+	    return NULL;
+	}
+	info = &infos->stack_infos[ptrid];
+    } else {
+	ptrid--;
+	if (UNLIKELY(ptrid >= infos->nglobs)) {
+	    bcfail("ptr", ptrid, infos->nglobs, __FILE__, __LINE__);
+	    return NULL;
+	}
+	info = &infos->glob_infos[ptrid];
+    }
+    if (LIKELY(ptroff < info->size &&
+	read_size < info->size &&
+	ptroff + read_size <= info->size)) {
+	return info->base+ptroff;
+    }
+
+    bcfail("ptr1", ptroff, info->size, __FILE__, __LINE__);
+    bcfail("ptr2", read_size, info->size, __FILE__, __LINE__);
+    bcfail("ptr3", ptroff+read_size, info->size, __FILE__, __LINE__);
+    return NULL;
+}
+
 static always_inline int check_sdivops(int64_t op0, int64_t op1)
 {
     return op1 == 0 || (op0 == -1 && op1 ==  (-9223372036854775807LL-1LL));
@@ -450,7 +553,9 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
     struct cli_bc_bb *bb = NULL;
     char *values = ctx->values;
     char *old_values;
+    struct ptr_infos ptrinfos;
 
+    memset(&ptrinfos, 0, sizeof(ptrinfos));
     memset(&stack, 0, sizeof(stack));
     do {
 	pc++;
@@ -721,32 +826,28 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 	    case OP_BC_LOAD*5+1:
 	    {
 		uint8_t *ptr;
-		READP(ptr, inst->u.unaryop);
+		READP(ptr, inst->u.unaryop, 1);
 		WRITE8(inst->dest, (*ptr));
 		break;
 	    }
 	    case OP_BC_LOAD*5+2:
 	    {
 		const union unaligned_16 *ptr;
-		READP(ptr, inst->u.unaryop);
+		READP(ptr, inst->u.unaryop, 2);
 		WRITE16(inst->dest, (ptr->una_u16));
 		break;
 	    }
 	    case OP_BC_LOAD*5+3:
 	    {
 		const union unaligned_32 *ptr;
-		READP(ptr, inst->u.unaryop);
-		if (!ptr) {
-		    cli_dbgmsg("Bytecode attempted to load from null pointer!\n");
-		    return CL_EBYTECODE;
-		}
+		READP(ptr, inst->u.unaryop, 4);
 		WRITE32(inst->dest, (ptr->una_u32));
 		break;
 	    }
 	    case OP_BC_LOAD*5+4:
 	    {
 		const union unaligned_64 *ptr;
-		READP(ptr, inst->u.unaryop);
+		READP(ptr, inst->u.unaryop, 8);
 		WRITE64(inst->dest, (ptr->una_u64));
 		break;
 	    }
@@ -755,7 +856,7 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 	    {
 		uint8_t *ptr;
 		uint8_t v;
-		READP(ptr, BINOP(0));
+		READP(ptr, BINOP(0), 1);
 		READ1(v, BINOP(1));
 		*ptr = v;
 		break;
@@ -764,7 +865,7 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 	    {
 		uint8_t *ptr;
 		uint8_t v;
-		READP(ptr, BINOP(0));
+		READP(ptr, BINOP(0), 1);
 		READ8(v, BINOP(1));
 		*ptr = v;
 		break;
@@ -773,7 +874,7 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 	    {
 		union unaligned_16 *ptr;
 		uint16_t v;
-		READP(ptr, BINOP(0));
+		READP(ptr, BINOP(0), 2);
 		READ16(v, BINOP(1));
 		ptr->una_s16 = v;
 		break;
@@ -782,7 +883,7 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 	    {
 		union unaligned_32 *ptr;
 		uint32_t v;
-		READP(ptr, BINOP(0));
+		READP(ptr, BINOP(0), 4);
 		READ32(v, BINOP(1));
 		ptr->una_u32 = v;
 		break;
@@ -791,7 +892,7 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
 	    {
 		union unaligned_64 *ptr;
 		uint64_t v;
-		READP(ptr, BINOP(0));
+		READP(ptr, BINOP(0), 8);
 		READ64(v, BINOP(1));
 		ptr->una_u64 = v;
 		break;
diff --git a/libclamav/others.h b/libclamav/others.h
index 44480e3..bd80f21 100644
--- a/libclamav/others.h
+++ b/libclamav/others.h
@@ -419,6 +419,7 @@ void cli_errmsg(const char *str, ...);
 
 #ifdef __GNUC__
 #define always_inline inline __attribute__((always_inline))
+#define never_inline __attribute__((noinline))
 #else
 #define always_inline inline
 #endif

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list