bb#11269 - bm matcher no longer sets scanning window offset

reason: certain segments could be hashed multiple times
remotes/push_mirror/klin/msxml
Kevin Lin 10 years ago
parent 05fa78fd04
commit 38dc186fb9
  1. 28
      libclamav/matcher-bm.c
  2. 3
      libclamav/matcher-bm.h
  3. 36
      libclamav/matcher.c

@ -245,7 +245,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_bm_patt **patt, const struct cli_matcher *root, uint32_t offset, const struct cli_target_info *info, struct cli_bm_off *offdata, uint32_t *viroffset)
int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_bm_patt **patt, const struct cli_matcher *root, uint32_t offset, const struct cli_target_info *info, struct cli_bm_off *offdata, cli_ctx *ctx)
{
uint32_t i, j, off, off_min, off_max;
uint8_t found, pchain, shift;
@ -253,7 +253,7 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
struct cli_bm_patt *p;
const unsigned char *bp, *pt;
unsigned char prefix;
int ret;
int ret, viruses_found = 0;
if(!root || !root->bm_shift)
return CL_CLEAN;
@ -285,8 +285,11 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
if(offdata) {
off = offset + i - BM_MIN_LENGTH + BM_BLOCK_SIZE;
for(; offdata->pos < offdata->cnt && off >= offdata->offtab[offdata->pos]; offdata->pos++);
if(offdata->pos == offdata->cnt || off >= offdata->offtab[offdata->pos])
if(offdata->pos == offdata->cnt || off >= offdata->offtab[offdata->pos]) {
if (viruses_found)
return CL_VIRUS;
return CL_CLEAN;
}
i += offdata->offtab[offdata->pos] - off;
} else {
i++;
@ -377,12 +380,18 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
}
if(virname) {
*virname = p->virname;
if(viroffset)
*viroffset = offset + i + j - BM_MIN_LENGTH + BM_BLOCK_SIZE;
if(SCAN_ALL) {
cli_append_virus(ctx, *virname);
//*viroffset = offset + i + j - BM_MIN_LENGTH + BM_BLOCK_SIZE;
}
}
if(patt)
*patt = p;
return CL_VIRUS;
viruses_found = 1;
if(!SCAN_ALL)
return CL_VIRUS;
}
p = p->next;
}
@ -392,8 +401,11 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
if(offdata) {
off = offset + i - BM_MIN_LENGTH + BM_BLOCK_SIZE;
for(; offdata->pos < offdata->cnt && off >= offdata->offtab[offdata->pos]; offdata->pos++);
if(offdata->pos == offdata->cnt || off >= offdata->offtab[offdata->pos])
if(offdata->pos == offdata->cnt || off >= offdata->offtab[offdata->pos]) {
if (viruses_found)
return CL_VIRUS;
return CL_CLEAN;
}
i += offdata->offtab[offdata->pos] - off;
} else {
i += shift;
@ -401,5 +413,7 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
}
if (viruses_found)
return CL_VIRUS;
return CL_CLEAN;
}

@ -25,6 +25,7 @@
#include "filetypes.h"
#include "cltypes.h"
#include "fmap.h"
#include "others.h"
#define BM_BOUNDARY_EOL 1
@ -47,7 +48,7 @@ int cli_bm_addpatt(struct cli_matcher *root, struct cli_bm_patt *pattern, const
int cli_bm_init(struct cli_matcher *root);
int cli_bm_initoff(const struct cli_matcher *root, struct cli_bm_off *data, const struct cli_target_info *info);
void cli_bm_freeoff(struct cli_bm_off *data);
int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_bm_patt **patt, const struct cli_matcher *root, uint32_t offset, const struct cli_target_info *info, struct cli_bm_off *offdata, uint32_t *viroffset);
int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **virname, const struct cli_bm_patt **patt, const struct cli_matcher *root, uint32_t offset, const struct cli_target_info *info, struct cli_bm_off *offdata, cli_ctx *ctx);
void cli_bm_free(struct cli_matcher *root);
#endif

@ -98,7 +98,6 @@ static inline int matcher_run(const struct cli_matcher *root,
struct cli_ac_result **acres,
fmap_t *map,
struct cli_bm_off *offdata,
uint32_t *viroffset,
cli_ctx *ctx)
{
int ret;
@ -139,17 +138,20 @@ static inline int matcher_run(const struct cli_matcher *root,
/* Don't use prefiltering for BM offset mode, since BM keeps tracks
* of offsets itself, and doesn't work if we skip chunks of input
* data */
ret = cli_bm_scanbuff(orig_buffer, orig_length, virname, NULL, root, orig_offset, tinfo, offdata, viroffset);
ret = cli_bm_scanbuff(orig_buffer, orig_length, virname, NULL, root, orig_offset, tinfo, offdata, ctx);
} else {
ret = cli_bm_scanbuff(buffer, length, virname, NULL, root, offset, tinfo, offdata, viroffset);
ret = cli_bm_scanbuff(buffer, length, virname, NULL, root, offset, tinfo, offdata, ctx);
}
if (ret == CL_VIRUS) {
if (ctx) {
if (ret != CL_CLEAN) {
if (ret != CL_VIRUS)
return ret;
/* else (ret == CL_VIRUS) */
if (SCAN_ALL)
viruses_found = 1;
else {
cli_append_virus(ctx, *virname);
if (SCAN_ALL)
viruses_found++;
else
return ret;
return ret;
}
}
}
@ -197,7 +199,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
if(!acdata && (ret = cli_ac_initdata(&mdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)))
return ret;
ret = matcher_run(troot, buffer, length, &virname, acdata ? (acdata[0]): (&mdata), offset, NULL, ftype, NULL, AC_SCAN_VIR, NULL, *ctx->fmap, NULL, NULL, ctx);
ret = matcher_run(troot, buffer, length, &virname, acdata ? (acdata[0]): (&mdata), offset, NULL, ftype, NULL, AC_SCAN_VIR, NULL, *ctx->fmap, NULL, ctx);
if(!acdata)
cli_ac_freedata(&mdata);
@ -217,7 +219,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
if(!acdata && (ret = cli_ac_initdata(&mdata, groot->ac_partsigs, groot->ac_lsigs, groot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)))
return ret;
ret = matcher_run(groot, buffer, length, &virname, acdata ? (acdata[1]): (&mdata), offset, NULL, ftype, NULL, AC_SCAN_VIR, NULL, *ctx->fmap, NULL, NULL, ctx);
ret = matcher_run(groot, buffer, length, &virname, acdata ? (acdata[1]): (&mdata), offset, NULL, ftype, NULL, AC_SCAN_VIR, NULL, *ctx->fmap, NULL, ctx);
if(!acdata)
cli_ac_freedata(&mdata);
@ -731,7 +733,6 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
fmap_t *map = *ctx->fmap;
struct cli_matcher *hdb, *fp;
const char *virname = NULL;
uint32_t viroffset = 0;
uint32_t viruses_found = 0;
void *md5ctx, *sha1ctx, *sha256ctx;
@ -877,8 +878,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
if(troot) {
virname = NULL;
viroffset = 0;
ret = matcher_run(troot, buff, bytes, &virname, &tdata, offset, &info, ftype, ftoffset, acmode, acres, map, bm_offmode ? &toff : NULL, &viroffset, ctx);
ret = matcher_run(troot, buff, bytes, &virname, &tdata, offset, &info, ftype, ftoffset, acmode, acres, map, bm_offmode ? &toff : NULL, ctx);
if (virname) {
/* virname already appended by matcher_run */
@ -905,8 +905,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
if(!ftonly) {
virname = NULL;
viroffset = 0;
ret = matcher_run(groot, buff, bytes, &virname, &gdata, offset, &info, ftype, ftoffset, acmode, acres, map, NULL, &viroffset, ctx);
ret = matcher_run(groot, buff, bytes, &virname, &gdata, offset, &info, ftype, ftoffset, acmode, acres, map, NULL, ctx);
if (virname) {
/* virname already appended by matcher_run */
@ -948,11 +947,6 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
}
}
if(SCAN_ALL && viroffset) {
offset = viroffset;
continue;
}
if(bytes < SCANBUFF)
break;

Loading…
Cancel
Save