[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