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


The following commit has been merged in the debian/unstable branch:
commit aca9ea82df22f4a9b00fc4fc5c3a53a6af40f0a8
Author: Tomasz Kojm <tkojm at clamav.net>
Date:   Fri Aug 21 15:55:10 2009 +0200

    libclamav: handle relative offsets with cli_ac_data; fix offset logic

diff --git a/ChangeLog b/ChangeLog
index 4fc5771..95e29ef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Fri Aug 21 15:53:35 CEST 2009 (tk)
+----------------------------------
+ * libclamav: handle relative offsets with cli_ac_data; fix offset logic
+
 Fri Aug 21 02:17:11 CEST 2009 (acab)
 ------------------------------------
  * libclamav/ishield.c: properly free() header
diff --git a/libclamav/filetypes.c b/libclamav/filetypes.c
index cad6db8..f925bd9 100644
--- a/libclamav/filetypes.c
+++ b/libclamav/filetypes.c
@@ -173,7 +173,7 @@ cli_file_t cli_filetype2(int desc, const struct cl_engine *engine)
 	if(!root)
 	    return ret;
 
-	if(cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN))
+	if(cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, root->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))
 	    return ret;
 
 	sret = cli_ac_scanbuff(buff, bread, NULL, NULL, NULL, engine->root[0], &mdata, 0, ret, NULL, AC_SCAN_FT, NULL);
@@ -183,7 +183,7 @@ cli_file_t cli_filetype2(int desc, const struct cl_engine *engine)
 	if(sret >= CL_TYPENO) {
 	    ret = sret;
 	} else {
-	    if(cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN))
+	    if(cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, root->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))
 		return ret;
 
 	    decoded = (unsigned char *) cli_utf16toascii((char *) buff, bread);
@@ -217,7 +217,7 @@ cli_file_t cli_filetype2(int desc, const struct cl_engine *engine)
 			     * However when detecting whether a file is HTML or not, we need exact conversion.
 			     * (just eliminating zeros and matching would introduce false positives */
 			    if(encoding_normalize_toascii(&in_area, encoding, &out_area) >= 0 && out_area.length > 0) {
-				    if(cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN))
+				    if(cli_ac_initdata(&mdata, root->ac_partsigs, root->ac_lsigs, root->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))
 					    return ret;
 
 				    if(out_area.length > 0) {
diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c
index 7e238e2..5e2dfbd 100644
--- a/libclamav/matcher-ac.c
+++ b/libclamav/matcher-ac.c
@@ -769,7 +769,7 @@ inline static int ac_findmatch(const unsigned char *buffer, uint32_t offset, uin
     return 1;
 }
 
-int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs, uint8_t tracklen)
+int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs, uint32_t reloffsigs, uint8_t tracklen)
 {
 	unsigned int i;
 
@@ -779,12 +779,24 @@ int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs,
 	return CL_ENULLARG;
     }
 
-    data->partsigs = partsigs;
+    data->reloffsigs = reloffsigs;
+    if(reloffsigs) {
+	data->offset = (uint32_t *) cli_malloc(reloffsigs * 2 * sizeof(uint32_t));
+	if(!data->offset) {
+	    cli_errmsg("cli_ac_init: Can't allocate memory for data->offset\n");
+	    return CL_EMEM;
+	}
+	for(i = 0; i < reloffsigs * 2; i += 2)
+	    data->offset[i] = CLI_OFF_NONE;
+    }
 
+    data->partsigs = partsigs;
     if(partsigs) {
 	data->offmatrix = (int32_t ***) cli_calloc(partsigs, sizeof(int32_t **));
 	if(!data->offmatrix) {
 	    cli_errmsg("cli_ac_init: Can't allocate memory for data->offmatrix\n");
+	    if(reloffsigs)
+		free(data->offset);
 	    return CL_EMEM;
 	}
     }
@@ -795,6 +807,8 @@ int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs,
 	if(!data->lsigcnt) {
 	    if(partsigs)
 		free(data->offmatrix);
+	    if(reloffsigs)
+		free(data->offset);
 	    cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigcnt\n");
 	    return CL_EMEM;
 	}
@@ -803,17 +817,19 @@ int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs,
 	    free(data->lsigcnt);
 	    if(partsigs)
 		free(data->offmatrix);
+	    if(reloffsigs)
+		free(data->offset);
 	    cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigcnt[0]\n");
 	    return CL_EMEM;
 	}
 	for(i = 1; i < lsigs; i++)
 	    data->lsigcnt[i] = data->lsigcnt[0] + 64 * i;
-     }
- 
+    }
+
     return CL_SUCCESS;
 }
 
-int cli_ac_caloff(struct cli_matcher *root, int fd)
+int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, int fd)
 {
 	int ret;
 	unsigned int i;
@@ -824,8 +840,8 @@ int cli_ac_caloff(struct cli_matcher *root, int fd)
     for(i = 0; i < root->ac_reloff_num; i++) {
 	patt = root->ac_reloff[i];
 	if(fd == -1) {
-	    patt->offset_min = CLI_OFF_NONE;
-	} else if((ret = cli_caloff(NULL, &info, fd, root->type, patt->offdata, &patt->offset_min, &patt->offset_max))) {
+	    data->offset[patt->offset_min] = CLI_OFF_NONE;
+	} else if((ret = cli_caloff(NULL, &info, fd, root->type, patt->offdata, &data->offset[patt->offset_min], &data->offset[patt->offset_max]))) {
 	    cli_errmsg("cli_ac_caloff: Can't calculate relative offset in signature for %s\n", patt->virname);
 	    if(info.exeinfo.section)
 		free(info.exeinfo.section);
@@ -859,6 +875,11 @@ void cli_ac_freedata(struct cli_ac_data *data)
 	free(data->lsigcnt);
 	data->lsigs = 0;
     }
+
+    if(data && data->reloffsigs) {
+	free(data->offset);
+	data->reloffsigs = 0;
+    }
 }
 
 inline static int ac_addtype(struct cli_matched_type **list, cli_file_t type, off_t offset, const cli_ctx *ctx)
@@ -926,7 +947,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
 	    while(patt) {
 		bp = i + 1 - patt->depth;
 		pt = patt;
-		/*
+	 	/*
 		while(pt) {
 		    if((pt->type && !(mode & AC_SCAN_FT)) || (!pt->type && !(mode & AC_SCAN_VIR))) {
 			pt = pt->next_same;
@@ -958,9 +979,16 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
 			}
 			realoff = offset + bp - pt->prefix_length;
 			if(pt->offset_min != CLI_OFF_ANY && (!pt->sigid || pt->partno == 1)) {
-			    if(pt->offset_max > realoff || pt->offset_min < realoff) {
-				pt = pt->next_same;
-				continue;
+			    if(pt->offdata[0] == CLI_OFF_ABSOLUTE) {
+				if(pt->offset_max < realoff || pt->offset_min > realoff) {
+				    pt = pt->next_same;
+				    continue;
+				}
+			    } else {
+				if(mdata->offset[pt->offset_min] == CLI_OFF_NONE || mdata->offset[pt->offset_max] < realoff || mdata->offset[pt->offset_min] > realoff) {
+				    pt = pt->next_same;
+				    continue;
+				}
 			    }
 			}
 			if(pt->sigid) { /* it's a partial signature */
@@ -1477,6 +1505,8 @@ int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hex
 	    return CL_EMEM;
 	}
 	root->ac_reloff[root->ac_reloff_num] = new;
+	new->offset_min = root->ac_reloff_num * 2;
+	new->offset_max = new->offset_min + 1;
 	root->ac_reloff_num++;
     }
 
diff --git a/libclamav/matcher-ac.h b/libclamav/matcher-ac.h
index ae4aeae..b28b7f5 100644
--- a/libclamav/matcher-ac.h
+++ b/libclamav/matcher-ac.h
@@ -33,8 +33,9 @@
 
 struct cli_ac_data {
     int32_t ***offmatrix;
-    uint32_t partsigs, lsigs;
+    uint32_t partsigs, lsigs, reloffsigs;
     uint32_t **lsigcnt;
+    uint32_t *offset;
 };
 
 struct cli_ac_alt {
@@ -79,13 +80,13 @@ struct cli_ac_result {
 #include "matcher.h"
 
 int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern);
-int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs, uint8_t tracklen);
+int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs, uint32_t reloffsigs, uint8_t tracklen);
 int cli_ac_chklsig(const char *expr, const char *end, uint32_t *lsigcnt, unsigned int *cnt, uint64_t *ids, unsigned int parse_only);
 void cli_ac_freedata(struct cli_ac_data *data);
 int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, void **customdata, struct cli_ac_result **res, const struct cli_matcher *root, struct cli_ac_data *mdata, uint32_t offset, cli_file_t ftype, struct cli_matched_type **ftoffset, unsigned int mode, const cli_ctx *ctx);
 int cli_ac_buildtrie(struct cli_matcher *root);
 int cli_ac_init(struct cli_matcher *root, uint8_t mindepth, uint8_t maxdepth);
-int cli_ac_caloff(struct cli_matcher *root, int fd);
+int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, int fd);
 void cli_ac_free(struct cli_matcher *root);
 int cli_ac_addsig(struct cli_matcher *root, const char *virname, const char *hexsig, uint32_t sigid, uint16_t parts, uint16_t partno, uint16_t rtype, uint16_t type, uint32_t mindist, uint32_t maxdist, const char *offset, const uint32_t *lsigid, unsigned int options);
 
diff --git a/libclamav/matcher-bm.c b/libclamav/matcher-bm.c
index f31698a..adb96cf 100644
--- a/libclamav/matcher-bm.c
+++ b/libclamav/matcher-bm.c
@@ -55,8 +55,12 @@ int cli_bm_addpatt(struct cli_matcher *root, struct cli_bm_patt *pattern, const
 	cli_errmsg("cli_bm_addpatt: Can't calculate offset for signature %s\n", pattern->virname);
 	return ret;
     }
-    if(pattern->offdata[0] != CLI_OFF_ANY && pattern->offdata[0] != CLI_OFF_ABSOLUTE)
-	root->bm_reloff_num++;
+    if(pattern->offdata[0] != CLI_OFF_ANY) {
+	if(pattern->offdata[0] == CLI_OFF_ABSOLUTE)
+	    root->bm_absoff_num++;
+	else
+	    root->bm_reloff_num++;
+    }
 
 #if BM_MIN_LENGTH == BM_BLOCK_SIZE
     /* try to load balance bm_suffix (at the cost of bm_shift) */
@@ -154,7 +158,7 @@ void cli_bm_free(struct cli_matcher *root)
 
 int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_matcher *root, uint32_t offset, int fd)
 {
-	uint32_t i, j, off;
+	uint32_t i, j, off, off_min, off_max;
 	uint8_t found, pchain, shift;
 	uint16_t idx, idxchk;
 	struct cli_bm_patt *p;
@@ -163,7 +167,6 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
         struct cli_target_info info;
         int ret;
 
-
     if(!root || !root->bm_shift)
 	return CL_CLEAN;
 
@@ -226,16 +229,19 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
 		if(found && p->length + p->prefix_length == j) {
 		    if(p->offset_min != CLI_OFF_ANY) {
 			if(p->offdata[0] != CLI_OFF_ABSOLUTE) {
-			    ret = cli_caloff(NULL, &info, fd, root->type, p->offdata, &p->offset_min, &p->offset_max);
+			    ret = cli_caloff(NULL, &info, fd, root->type, p->offdata, &off_min, &off_max);
 			    if(ret != CL_SUCCESS) {
 				cli_errmsg("cli_bm_scanbuff: Can't calculate relative offset in signature for %s\n", p->virname);
 				if(info.exeinfo.section)
 				    free(info.exeinfo.section);
 				return ret;
 			    }
+			} else {
+			    off_min = p->offset_min;
+			    off_max = p->offset_max;
 			}
 			off = offset + i - p->prefix_length - BM_MIN_LENGTH + BM_BLOCK_SIZE;
-			if(p->offset_max > off || p->offset_min < off) {
+			if(off_max < off || off_min > off) {
 			    p = p->next;
 			    continue;
 			}
diff --git a/libclamav/matcher.c b/libclamav/matcher.c
index a13fad8..e4e83b2 100644
--- a/libclamav/matcher.c
+++ b/libclamav/matcher.c
@@ -73,7 +73,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
 
     if(troot) {
 
-	if(!acdata && (ret = cli_ac_initdata(&mdata, troot->ac_partsigs, troot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN)))
+	if(!acdata && (ret = cli_ac_initdata(&mdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)))
 	    return ret;
 
 	if(troot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, troot, offset, -1)) != CL_VIRUS)
@@ -86,7 +86,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
 	    return ret;
     }
 
-    if(!acdata && (ret = cli_ac_initdata(&mdata, groot->ac_partsigs, groot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN)))
+    if(!acdata && (ret = cli_ac_initdata(&mdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)))
 	return ret;
 
     if(groot->ac_only || (ret = cli_bm_scanbuff(buffer, length, virname, groot, offset, -1)) != CL_VIRUS)
@@ -366,11 +366,11 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
     }
 
     if(!ftonly)
-	if((ret = cli_ac_caloff(groot, desc)) || (ret = cli_ac_initdata(&gdata, groot->ac_partsigs, groot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN)))
+	if((ret = cli_ac_initdata(&gdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) || (ret = cli_ac_caloff(groot, &gdata, desc)))
 	    return ret;
 
     if(troot) {
-	if((ret = cli_ac_caloff(troot, desc)) || (ret = cli_ac_initdata(&tdata, troot->ac_partsigs, troot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN))) {
+	if((ret = cli_ac_initdata(&tdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)) || (ret = cli_ac_caloff(troot, &tdata, desc))) {
 	    if(!ftonly)
 		cli_ac_freedata(&gdata);
 	    return ret;
diff --git a/libclamav/matcher.h b/libclamav/matcher.h
index e97a52f..6074263 100644
--- a/libclamav/matcher.h
+++ b/libclamav/matcher.h
@@ -76,7 +76,7 @@ struct cli_matcher {
     struct cli_bm_patt **bm_suffix;
     struct cli_hashset md5_sizes_hs;
     uint32_t *soff, soff_len; /* for PE section sigs */
-    uint32_t bm_patterns, bm_reloff_num;
+    uint32_t bm_patterns, bm_reloff_num, bm_absoff_num;
 
     /* Extended Aho-Corasick */
     uint32_t ac_partsigs, ac_nodes, ac_patterns, ac_lsigs;
@@ -84,7 +84,7 @@ struct cli_matcher {
     struct cli_ac_node *ac_root, **ac_nodetable;
     struct cli_ac_patt **ac_pattable;
     struct cli_ac_patt **ac_reloff;
-    uint32_t ac_reloff_num;
+    uint32_t ac_reloff_num, ac_absoff_num;
     uint8_t ac_mindepth, ac_maxdepth;
 
     uint16_t maxpatlen;
diff --git a/libclamav/readdb.c b/libclamav/readdb.c
index f3c696b..6aebed9 100644
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@ -2152,7 +2152,7 @@ int cl_engine_compile(struct cl_engine *engine)
 	if((root = engine->root[i])) {
 	    if((ret = cli_ac_buildtrie(root)))
 		return ret;
-	    cli_dbgmsg("matcher[%u]: %s: AC sigs: %u (reloff: %u) BM sigs: %u (reloff: %u) %s\n", i, cli_mtargets[i].name, root->ac_patterns, root->ac_reloff_num, root->bm_patterns, root->bm_reloff_num, root->ac_only ? "(ac_only mode)" : "");
+	    cli_dbgmsg("matcher[%u]: %s: AC sigs: %u (reloff: %u, absoff: %u) BM sigs: %u (reloff: %u, absoff: %u) %s\n", i, cli_mtargets[i].name, root->ac_patterns, root->ac_reloff_num, root->ac_absoff_num, root->bm_patterns, root->bm_reloff_num, root->bm_absoff_num, root->ac_only ? "(ac_only mode)" : "");
 	}
     }
 
diff --git a/libclamav/regex_list.c b/libclamav/regex_list.c
index 9a6f47d..11d6ed0 100644
--- a/libclamav/regex_list.c
+++ b/libclamav/regex_list.c
@@ -289,7 +289,7 @@ int regex_list_match(struct regex_matcher* matcher,char* real_url,const char* di
 		buffer[buffer_len]=0;
 		cli_dbgmsg("Looking up in regex_list: %s\n", buffer);
 
-		if((rc = cli_ac_initdata(&mdata, 0, 0, CLI_DEFAULT_AC_TRACKLEN)))
+		if((rc = cli_ac_initdata(&mdata, 0, 0, 0, CLI_DEFAULT_AC_TRACKLEN)))
 			return rc;
 
 		bufrev = cli_strdup(buffer);
diff --git a/libclamav/scanners.c b/libclamav/scanners.c
index 7f6a1be..0d7afe5 100644
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@ -1062,10 +1062,10 @@ static int cli_scanscript(int desc, cli_ctx *ctx)
 	text_normalize_init(&state, normalized, SCANBUFF + maxpatlen);
 	ret = CL_CLEAN;
 
-	if ((ret = cli_ac_initdata(&tmdata, troot->ac_partsigs, troot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN)))
+	if ((ret = cli_ac_initdata(&tmdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)))
 	    return ret;
 
-	if ((ret = cli_ac_initdata(&gmdata, groot->ac_partsigs, groot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN))) {
+	if ((ret = cli_ac_initdata(&gmdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN))) {
 	    cli_ac_freedata(&tmdata);
 	    return ret;
 	}
diff --git a/unit_tests/check_matchers.c b/unit_tests/check_matchers.c
index 170efb3..bc3ecc5 100644
--- a/unit_tests/check_matchers.c
+++ b/unit_tests/check_matchers.c
@@ -76,7 +76,7 @@ START_TEST (test_ac_scanbuff) {
     ret = cli_ac_buildtrie(root);
     fail_unless(ret == CL_SUCCESS, "cli_ac_buildtrie() failed");
 
-    ret = cli_ac_initdata(&mdata, root->ac_partsigs, 0, CLI_DEFAULT_AC_TRACKLEN);
+    ret = cli_ac_initdata(&mdata, root->ac_partsigs, 0, 0, CLI_DEFAULT_AC_TRACKLEN);
     fail_unless(ret == CL_SUCCESS, "cli_ac_initdata() failed");
 
     for(i = 0; ac_testdata[i].data; i++) {

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list