[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 00:56:12 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit 3555ee75bf0c695b4a48d9e46275e0be77cb77dd
Author: Török Edvin <edwin at clamav.net>
Date:   Tue Jul 7 17:38:56 2009 +0300

    bytecode: Introduce cli_bc_value to store the result of an operation. Implement More checking.

diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c
index a871af4..e3aeeb5 100644
--- a/libclamav/bytecode.c
+++ b/libclamav/bytecode.c
@@ -31,16 +31,27 @@
 #include <string.h>
 
 typedef uint32_t operand_t;
+typedef uint16_t bbid_t;
+typedef uint16_t funcid_t;
 
-struct cli_bc_varop {
-    uint8_t numOps;
+struct cli_bc_callop {
     operand_t* ops;
+    uint8_t numOps;
+    funcid_t funcid;
 };
 
 struct branch {
     operand_t condition;
-    struct cli_bc_bb *br_true;
-    struct cli_bc_bb *br_false;
+    bbid_t br_true;
+    bbid_t br_false;
+};
+
+#define MAX_OP (operand_t)(~0u)
+#define CONSTANT_OP (MAX_OP-1)
+#define ARG_OP (MAX_OP-1)
+struct cli_bc_value {
+    uint64_t v;
+    operand_t ref;/* this has CONSTANT_OP value for constants, and ARG_op for arguments */
 };
 
 struct cli_bc_inst {
@@ -50,9 +61,9 @@ struct cli_bc_inst {
 	operand_t unaryop;
 	operand_t binop[2];
 	operand_t three[3];
-	struct cli_bc_varop ops;
+	struct cli_bc_callop ops;
 	struct branch branch;
-	struct cli_bc_bb *jump;
+	bbid_t jump;
     } u;
 };
 
@@ -64,9 +75,14 @@ struct cli_bc_bb {
 struct cli_bc_func {
     uint8_t numArgs;
     uint16_t numLocals;
+    uint32_t numInsts;
+    uint32_t numConstants;
     uint16_t numBB;
     uint16_t *types;
+    uint32_t insn_idx;
     struct cli_bc_bb *BB;
+    struct cli_bc_inst *allinsts;
+    struct cli_bc_value *values;
 };
 
 struct cli_bc_ctx {
@@ -124,15 +140,47 @@ static inline uint64_t readNumber(const unsigned char *p, unsigned *off, unsigne
     return n;
 }
 
-static inline uint64_t readOperand(unsigned char *p, unsigned *off, unsigned len, char *ok)
+static inline funcid_t readFuncID(struct cli_bc *bc, unsigned char *p,
+				  unsigned *off, unsigned len, char *ok)
 {
+    funcid_t id = readNumber(p, off, len, ok);
+    if (id >= bc->num_func) {
+	cli_errmsg("Called function out of range: %u >= %u\n", id, bc->num_func);
+	*ok = 0;
+	return ~0;
+    }
+    return id;
+}
+
+static inline operand_t readOperand(struct cli_bc_func *func, unsigned char *p,
+				    unsigned *off, unsigned len, char *ok)
+{
+    uint64_t v;
+    unsigned numValues = func->numArgs + func->numInsts + func->numConstants;
     if ((p[*off]&0xf0) == 0x40) {
 	p[*off] |= 0x20;
-	/* TODO: constant int operand needs to be added to constant table*/
-	return readNumber(p, off, len, ok);
+	/* TODO: unique constants */
+	func->values = cli_realloc2(func->values, (numValues+1)*sizeof(*func->values));
+	if (!func->values) {
+	    *ok = 0;
+	    return MAX_OP;
+	}
+	func->numConstants++;
+	func->values[numValues].v = readNumber(p, off, len, ok);
+	func->values[numValues].ref = CONSTANT_OP;
+	return numValues;
     }
-    return readNumber(p, off, len, ok);
+    v = readNumber(p, off, len, ok);
+    if (!*ok)
+	return MAX_OP;
+    if (v >= numValues) {
+	cli_errmsg("Operand index exceeds bounds: %u >= %u!\n", v, numValues);
+	*ok = 0;
+	return MAX_OP;
+    }
+    return v;
 }
+
 static inline unsigned readFixedNumber(const unsigned char *p, unsigned *off,
 				       unsigned len, char *ok, unsigned width)
 {
@@ -314,6 +362,31 @@ static int parseFunctionHeader(struct cli_bc *bc, unsigned fn, unsigned char *bu
 	return CL_EMALFDB;
     }
     offset++;
+    func->numInsts = readNumber(buffer, &offset, len, &ok);
+    if (!ok ){
+	cli_errmsg("Invalid instructions count\n");
+	return CL_EMALFDB;
+    }
+    func->insn_idx = 0;
+    func->numConstants=0;
+    func->allinsts = cli_calloc(func->numInsts, sizeof(*func->allinsts));
+    if (!func->allinsts) {
+	cli_errmsg("Out of memory allocating instructions\n");
+	return CL_EMEM;
+    }
+    func->values = cli_calloc(func->numInsts+func->numArgs, sizeof(*func->values));
+    if (!func->values) {
+	cli_errmsg("Out of memory allocating values\n");
+	return CL_EMEM;
+    }
+    for (i=0;i<func->numArgs;i++) {
+	func->values[i].v = 0xdeadbeef;
+	func->values[i].ref = ARG_OP;
+    }
+    for(;i<func->numInsts+func->numArgs;i++) {
+	func->values[i].v = 0xdeadbeef;
+	func->values[i].ref = i-func->numArgs;
+    }
     func->numBB = readNumber(buffer, &offset, len, &ok);
     if (!ok) {
 	cli_errmsg("Invalid basic block count\n");
@@ -327,15 +400,15 @@ static int parseFunctionHeader(struct cli_bc *bc, unsigned fn, unsigned char *bu
     return CL_SUCCESS;
 }
 
-static struct cli_bc_bb *readBBID(struct cli_bc_func *func, const unsigned char *buffer, unsigned *off, unsigned len, char *ok) {
+static bbid_t readBBID(struct cli_bc_func *func, const unsigned char *buffer, unsigned *off, unsigned len, char *ok) {
     unsigned id = readNumber(buffer, off, len, ok);
     if (!id || id >= func->numBB) {
 	cli_errmsg("Basic block ID out of range: %u\n", id);
 	*ok = 0;
     }
     if (!*ok)
-	return NULL;
-    return &func->BB[id];
+	return ~0;
+    return id;
 }
 
 static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char *buffer)
@@ -359,7 +432,7 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
     }
     offset = 1;
     BB->numInsts = 0;
-    BB->insts = NULL;
+    BB->insts = &bcfunc->allinsts[bcfunc->insn_idx];
     while (!last) {
 	unsigned numOp, i;
 	if (buffer[offset] == 'T') {
@@ -384,12 +457,12 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 		inst.u.jump = readBBID(bcfunc, buffer, &offset, len, &ok);
 		break;
 	    case OP_BRANCH:
-		inst.u.branch.condition = readOperand(buffer, &offset, len, &ok);
+		inst.u.branch.condition = readOperand(bcfunc, buffer, &offset, len, &ok);
 		inst.u.branch.br_true = readBBID(bcfunc, buffer, &offset, len, &ok);
 		inst.u.branch.br_false = readBBID(bcfunc, buffer, &offset, len, &ok);
 		break;
 	    case OP_CALL_DIRECT:
-		numOp = readFixedNumber(buffer, &offset, len, &ok, 1)+1;
+		numOp = readFixedNumber(buffer, &offset, len, &ok, 1);
 		if (ok) {
 		    inst.u.ops.numOps = numOp;
 		    inst.u.ops.ops = cli_calloc(numOp, sizeof(*inst.u.ops.ops));
@@ -397,8 +470,9 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 			cli_errmsg("Out of memory allocating operands\n");
 			return CL_EMALFDB;
 		    }
+		    inst.u.ops.funcid = readFuncID(bc, buffer, &offset, len, &ok);
 		    for (i=0;i<numOp;i++) {
-			inst.u.ops.ops[i] = readOperand(buffer, &offset, len, &ok);
+			inst.u.ops.ops[i] = readOperand(bcfunc, buffer, &offset, len, &ok);
 		    }
 		}
 		break;
@@ -406,16 +480,16 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 		numOp = operand_counts[inst.opcode];
 		switch (numOp) {
 		    case 1:
-			inst.u.unaryop = readOperand(buffer, &offset, len, &ok);
+			inst.u.unaryop = readOperand(bcfunc, buffer, &offset, len, &ok);
 			break;
 		    case 2:
-			inst.u.binop[0] = readOperand(buffer, &offset, len, &ok);
-			inst.u.binop[1] = readOperand(buffer, &offset, len, &ok);
+			inst.u.binop[0] = readOperand(bcfunc, buffer, &offset, len, &ok);
+			inst.u.binop[1] = readOperand(bcfunc, buffer, &offset, len, &ok);
 			break;
 		    case 3:
-			inst.u.three[0] = readOperand(buffer, &offset, len, &ok);
-			inst.u.three[1] = readOperand(buffer, &offset, len, &ok);
-			inst.u.three[2] = readOperand(buffer, &offset, len, &ok);
+			inst.u.three[0] = readOperand(bcfunc, buffer, &offset, len, &ok);
+			inst.u.three[1] = readOperand(bcfunc, buffer, &offset, len, &ok);
+			inst.u.three[2] = readOperand(bcfunc, buffer, &offset, len, &ok);
 			break;
 		    default:
 			cli_errmsg("Opcode with too many operands: %u?\n", numOp);
@@ -427,13 +501,11 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 	    cli_errmsg("Invalid instructions or operands\n");
 	    return CL_EMALFDB;
 	}
-	BB->insts = cli_realloc2(BB->insts, (++BB->numInsts)*sizeof(*BB->insts));
-	if (!BB->insts) {
-	    cli_errmsg("Unable to allocate memory for instruction %u\n", 
-		       BB->numInsts);
-	    return CL_EMEM;
+	if (bcfunc->insn_idx + BB->numInsts >= bcfunc->numInsts) {
+	    cli_errmsg("More instructions than declared in total!\n");
+	    return CL_EMALFDB;
 	}
-	BB->insts[BB->numInsts-1] = inst;
+	BB->insts[BB->numInsts++] = inst;
     }
     if (bb == bc->funcs[func].numBB-1) {
 	if (buffer[offset] != 'E') {
@@ -530,9 +602,10 @@ void cli_bytecode_destroy(struct cli_bc *bc)
 		if (operand_counts[i->opcode] > 3)
 		    free(i->u.ops.ops);
 	    }
-	    free(BB->insts);
 	}
 	free(f->BB);
+	free(f->allinsts);
+	free(f->values);
     }
     free(bc->funcs);
 }
diff --git a/libclamav/bytecode.h b/libclamav/bytecode.h
index 976f5dd..b6bd74b 100644
--- a/libclamav/bytecode.h
+++ b/libclamav/bytecode.h
@@ -26,6 +26,7 @@
 struct cli_dbio;
 struct cli_bc_ctx;
 struct cli_bc_func;
+struct cli_bc_value;
 
 struct cli_bc {
   unsigned verifier;
diff --git a/libclamav/clambc.h b/libclamav/clambc.h
index 43cd4bc..ccff495 100644
--- a/libclamav/clambc.h
+++ b/libclamav/clambc.h
@@ -80,7 +80,7 @@ static const unsigned char operand_counts[] = {
   /* ADD -> XOR */
   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
   /* TRUNC -> ZEXT */
-  2, 2, 2,
+  1, 1, 1,
   /* BRANCH, JMP, RET */
   3, 1, 1,
   /* ICMP */

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list