From 841161e0d61bed916dbc22b72904ea11da0336cd Mon Sep 17 00:00:00 2001 From: Tomasz Kojm Date: Mon, 20 Nov 2006 00:03:16 +0000 Subject: [PATCH] cache target file info in pattern matchers git-svn: trunk@2511 --- clamav-devel/ChangeLog | 4 + clamav-devel/libclamav/elf.c | 3 + clamav-devel/libclamav/matcher-ac.c | 15 +- clamav-devel/libclamav/matcher-bm.c | 13 +- clamav-devel/libclamav/matcher.c | 214 +++++++++++++++++----------- clamav-devel/libclamav/matcher.h | 12 +- clamav-devel/libclamav/pe.c | 4 + 7 files changed, 175 insertions(+), 90 deletions(-) diff --git a/clamav-devel/ChangeLog b/clamav-devel/ChangeLog index 86f10ad60..eb4973594 100644 --- a/clamav-devel/ChangeLog +++ b/clamav-devel/ChangeLog @@ -1,3 +1,7 @@ +Mon Nov 20 00:58:57 CET 2006 (tk) +--------------------------------- + * libclamav: cache target file info in pattern matchers + Sat Nov 18 22:44:37 GMT 2006 (njh) ---------------------------------- * libclamav: Don't implement the sleep function diff --git a/clamav-devel/libclamav/elf.c b/clamav-devel/libclamav/elf.c index b0d6180cf..6cfb56035 100644 --- a/clamav-devel/libclamav/elf.c +++ b/clamav-devel/libclamav/elf.c @@ -513,6 +513,8 @@ int cli_elfheader(int desc, struct cli_exe_info *elfinfo) section_hdr = (struct elf_section_hdr32 *) cli_calloc(shnum, shentsize); if(!section_hdr) { cli_errmsg("ELF: Can't allocate memory for section headers\n"); + free(elfinfo->section); + elfinfo->section = NULL; return -1; } @@ -521,6 +523,7 @@ int cli_elfheader(int desc, struct cli_exe_info *elfinfo) if(read(desc, §ion_hdr[i], sizeof(struct elf_section_hdr32)) != sizeof(struct elf_section_hdr32)) { free(section_hdr); free(elfinfo->section); + elfinfo->section = NULL; return -1; } diff --git a/clamav-devel/libclamav/matcher-ac.c b/clamav-devel/libclamav/matcher-ac.c index 182c4d4aa..8c56373ea 100644 --- a/clamav-devel/libclamav/matcher-ac.c +++ b/clamav-devel/libclamav/matcher-ac.c @@ -412,6 +412,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char unsigned int i, position, curroff; uint8_t offnum, found; struct cli_matched_type *tnode; + struct cli_target_info info; if(!root->ac_root) @@ -422,6 +423,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char return CL_ENULLARG; } + memset(&info, 0, sizeof(info)); current = root->ac_root; for(i = 0; i < length; i++) { @@ -441,7 +443,7 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char else t = ftype; - if((fd == -1 && !t) || !cli_validatesig(t, pt->offset, curroff, fd, pt->virname)) { + if((fd == -1 && !t) || !cli_validatesig(t, pt->offset, curroff, &info, fd, pt->virname)) { pt = pt->next; continue; } @@ -497,6 +499,8 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char if(ftoffset && (!*ftoffset || (*ftoffset)->cnt < SFX_MAX_TESTS) && ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) { if(!(tnode = cli_calloc(1, sizeof(struct cli_matched_type)))) { cli_errmsg("cli_ac_scanbuff(): Can't allocate memory for new type node\n"); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_EMEM; } @@ -517,6 +521,8 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char if(virname) *virname = pt->virname; + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_VIRUS; } } @@ -532,6 +538,8 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char if(ftoffset && (!*ftoffset ||(*ftoffset)->cnt < SFX_MAX_TESTS) && ftype == CL_TYPE_MSEXE && type >= CL_TYPE_SFX) { if(!(tnode = cli_calloc(1, sizeof(struct cli_matched_type)))) { cli_errmsg("cli_ac_scanbuff(): Can't allocate memory for new type node\n"); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_EMEM; } tnode->type = type; @@ -551,6 +559,8 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char if(virname) *virname = pt->virname; + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_VIRUS; } } @@ -563,6 +573,9 @@ int cli_ac_scanbuff(const unsigned char *buffer, unsigned int length, const char } } + if(info.exeinfo.section) + free(info.exeinfo.section); + return otfrec ? type : CL_CLEAN; } diff --git a/clamav-devel/libclamav/matcher-bm.c b/clamav-devel/libclamav/matcher-bm.c index c6539b06d..48ef0eb0d 100644 --- a/clamav-devel/libclamav/matcher-bm.c +++ b/clamav-devel/libclamav/matcher-bm.c @@ -136,6 +136,7 @@ int cli_bm_scanbuff(const unsigned char *buffer, unsigned int length, const char struct cli_bm_patt *p; const unsigned char *bp; unsigned char prefix; + struct cli_target_info info; if(!root->bm_shift) @@ -144,6 +145,8 @@ int cli_bm_scanbuff(const unsigned char *buffer, unsigned int length, const char if(length < BM_MIN_LENGTH) return CL_CLEAN; + memset(&info, 0, sizeof(info)); + for(i = BM_MIN_LENGTH - BM_BLOCK_SIZE; i < length - BM_BLOCK_SIZE + 1; ) { idx = HASH(buffer[i], buffer[i + 1], buffer[i + 2]); @@ -189,7 +192,7 @@ int cli_bm_scanbuff(const unsigned char *buffer, unsigned int length, const char if(p->target || p->offset) { off = offset + i - BM_MIN_LENGTH + BM_BLOCK_SIZE; - if((fd == -1 && !ftype) || !cli_validatesig(ftype, p->offset, off, fd, p->virname)) { + if((fd == -1 && !ftype) || !cli_validatesig(ftype, p->offset, off, &info, fd, p->virname)) { p = p->next; continue; } @@ -198,6 +201,9 @@ int cli_bm_scanbuff(const unsigned char *buffer, unsigned int length, const char if(virname) *virname = p->virname; + if(info.exeinfo.section) + free(info.exeinfo.section); + return CL_VIRUS; } @@ -210,5 +216,8 @@ int cli_bm_scanbuff(const unsigned char *buffer, unsigned int length, const char i += shift; } - return 0; + if(info.exeinfo.section) + free(info.exeinfo.section); + + return CL_CLEAN; } diff --git a/clamav-devel/libclamav/matcher.c b/clamav-devel/libclamav/matcher.c index 8ac7ea027..2bb6a2944 100644 --- a/clamav-devel/libclamav/matcher.c +++ b/clamav-devel/libclamav/matcher.c @@ -98,38 +98,38 @@ int cli_scanbuff(const unsigned char *buffer, unsigned int length, const char ** int targettype = 0; if((hret = sn_sigscan_resultget_name(resulthandle, i, &matchname) < 0)) { - cli_errmsg("cli_scanbuff: sn_sigscan_resultget_name failed for result %d: %d\n", i, hret); + cli_errmsg("cli_scanbuff: sn_sigscan_resultget_name failed for result %u: %d\n", i, hret); sn_sigscan_resultfree(resulthandle); return CL_ENCIO; } if(!matchname) { - cli_errmsg("cli_scanbuff: HW Result[%d]: Signature without name\n", i); + cli_errmsg("cli_scanbuff: HW Result[%u]: Signature without name\n", i); sn_sigscan_resultfree(resulthandle); return CL_EMALFDB; } if((hret = sn_sigscan_resultget_targettype(resulthandle, i, &targettype) < 0)) { - cli_errmsg("cli_scanbuff: sn_sigscan_resultget_targettype failed for result %d, signature %s: %d\n", i, matchname, hret); + cli_errmsg("cli_scanbuff: sn_sigscan_resultget_targettype failed for result %u, signature %s: %d\n", i, matchname, hret); sn_sigscan_resultfree(resulthandle); return CL_ENCIO; } if(targettype && targettab[targettype] != (int) ftype) { - cli_dbgmsg("cli_scanbuff: HW Result[%d]: %s: Target type: %d, expected: %d\n", i, matchname, targettab[targettype], ftype); + cli_dbgmsg("cli_scanbuff: HW Result[%u]: %s: Target type: %u, expected: %u\n", i, matchname, targettab[targettype], ftype); continue; } if((hret = sn_sigscan_resultget_offsetstring(resulthandle, i, &offsetstring) < 0)) { - cli_errmsg("cli_scanbuff: sn_sigscan_resultget_offsetstring failed for result %d, signature %s: %d\n", i, matchname, hret); + cli_errmsg("cli_scanbuff: sn_sigscan_resultget_offsetstring failed for result %u, signature %s: %d\n", i, matchname, hret); sn_sigscan_resultfree(resulthandle); return CL_ENCIO; } if(offsetstring) { - cli_dbgmsg("cli_scanbuff: HW Result[%d]: %s: Offset based signature not supported in buffer mode\n", i, matchname); + cli_dbgmsg("cli_scanbuff: HW Result[%u]: %s: Offset based signature not supported in buffer mode\n", i, matchname); continue; } if((hret = sn_sigscan_resultget_extradata(resulthandle, i, &optionalsigdata) < 0)) { - cli_errmsg("cli_scanbuff: sn_sigscan_resultget_extradata failed for result %d, signature %s: %d\n", i, matchname, hret); + cli_errmsg("cli_scanbuff: sn_sigscan_resultget_extradata failed for result %u, signature %s: %d\n", i, matchname, hret); sn_sigscan_resultfree(resulthandle); return CL_ENCIO; } @@ -137,13 +137,13 @@ int cli_scanbuff(const unsigned char *buffer, unsigned int length, const char ** if((pt = cli_strtok(optionalsigdata, 1, ":"))) { /* max version */ if(!isdigit(*pt)) { free(pt); - cli_errmsg("cli_scanbuff: HW Result[%d]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); + cli_errmsg("cli_scanbuff: HW Result[%u]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); sn_sigscan_resultfree(resulthandle); return CL_EMALFDB; } if(atoi(pt) < cl_retflevel()) { - cli_dbgmsg("cli_scanbuff: HW Result[%d]: %s: Signature max flevel: %d, current: %d\n", i, matchname, atoi(pt), cl_retflevel()); + cli_dbgmsg("cli_scanbuff: HW Result[%u]: %s: Signature max flevel: %u, current: %u\n", i, matchname, atoi(pt), cl_retflevel()); free(pt); continue; } @@ -152,13 +152,13 @@ int cli_scanbuff(const unsigned char *buffer, unsigned int length, const char ** if((pt = cli_strtok(optionalsigdata, 0, ":"))) { /* min version */ if(!isdigit(*pt)) { free(pt); - cli_errmsg("cli_scanbuff: HW Result[%d]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); + cli_errmsg("cli_scanbuff: HW Result[%u]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); sn_sigscan_resultfree(resulthandle); return CL_EMALFDB; } if(atoi(pt) > cl_retflevel()) { - cli_dbgmsg("cli_scanbuff: HW Result[%d]: %s: Signature required flevel: %d, current: %d\n", i, matchname, atoi(pt), cl_retflevel()); + cli_dbgmsg("cli_scanbuff: HW Result[%u]: %s: Signature required flevel: %u, current: %u\n", i, matchname, atoi(pt), cl_retflevel()); free(pt); continue; } @@ -167,13 +167,13 @@ int cli_scanbuff(const unsigned char *buffer, unsigned int length, const char ** } else { if(!isdigit(*optionalsigdata)) { - cli_errmsg("cli_scanbuff: HW Result[%d]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); + cli_errmsg("cli_scanbuff: HW Result[%u]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); sn_sigscan_resultfree(resulthandle); return CL_EMALFDB; } if(atoi(optionalsigdata) > cl_retflevel()) { - cli_dbgmsg("cli_scandesc: HW Result[%d]: %s: Signature required flevel: %d, current: %d\n", i, matchname, atoi(optionalsigdata), cl_retflevel()); + cli_dbgmsg("cli_scandesc: HW Result[%u]: %s: Signature required flevel: %u, current: %u\n", i, matchname, atoi(optionalsigdata), cl_retflevel()); continue; } } @@ -250,89 +250,101 @@ static struct cli_md5_node *cli_vermd5(const unsigned char *md5, const struct cl return NULL; } -static long int cli_caloff(const char *offstr, int fd, unsigned short ftype) +static off_t cli_caloff(const char *offstr, struct cli_target_info *info, int fd, unsigned short ftype, int *ret) { - struct cli_exe_info exeinfo; int (*einfo)(int, struct cli_exe_info *) = NULL; - long int offset = -1; - int n; + unsigned int n; + off_t pos, offset; - if(ftype == CL_TYPE_MSEXE) - einfo = cli_peheader; - else if(ftype == CL_TYPE_ELF) - einfo = cli_elfheader; + *ret = 0; + + if(!strncmp(offstr, "EP", 2) || offstr[0] == 'S') { + + if(info->status == -1) { + *ret = -1; + return 0; + + } else if(!info->status) { + + if(ftype == CL_TYPE_MSEXE) + einfo = cli_peheader; + else if(ftype == CL_TYPE_ELF) + einfo = cli_elfheader; + + if(einfo) { + if((pos = lseek(fd, 0, SEEK_CUR)) == -1) { + cli_dbgmsg("Invalid descriptor\n"); + info->status = *ret = -1; + return 0; + } + + lseek(fd, 0, SEEK_SET); + if(einfo(fd, &info->exeinfo)) { + lseek(fd, pos, SEEK_SET); + info->status = *ret = -1; + return 0; + } + lseek(fd, pos, SEEK_SET); + info->status = 1; + } + } + } if(isdigit(offstr[0])) { return atoi(offstr); - } else if(einfo && (!strncmp(offstr, "EP+", 3) || !strncmp(offstr, "EP-", 3))) { - if((n = lseek(fd, 0, SEEK_CUR)) == -1) { - cli_dbgmsg("Invalid descriptor\n"); - return -1; - } - lseek(fd, 0, SEEK_SET); - if(einfo(fd, &exeinfo)) { - lseek(fd, n, SEEK_SET); - return -1; - } - free(exeinfo.section); - lseek(fd, n, SEEK_SET); + } else if(info->status == 1 && (!strncmp(offstr, "EP+", 3) || !strncmp(offstr, "EP-", 3))) { if(offstr[2] == '+') - return exeinfo.ep + atoi(offstr + 3); + return info->exeinfo.ep + atoi(offstr + 3); else - return exeinfo.ep - atoi(offstr + 3); + return info->exeinfo.ep - atoi(offstr + 3); - } else if(einfo && offstr[0] == 'S') { - if((n = lseek(fd, 0, SEEK_CUR)) == -1) { - cli_dbgmsg("Invalid descriptor\n"); - return -1; - } - lseek(fd, 0, SEEK_SET); - if(einfo(fd, &exeinfo)) { - lseek(fd, n, SEEK_SET); - return -1; - } - lseek(fd, n, SEEK_SET); + } else if(info->status == 1 && offstr[0] == 'S') { if(!strncmp(offstr, "SL", 2)) { - if(sscanf(offstr, "SL+%ld", &offset) != 1) { - free(exeinfo.section); - return -1; + if(sscanf(offstr, "SL+%lu", &offset) != 1) { + *ret = -1; + return 0; } - offset += exeinfo.section[exeinfo.nsections - 1].raw; + offset += info->exeinfo.section[info->exeinfo.nsections - 1].raw; } else { - if(sscanf(offstr, "S%d+%ld", &n, &offset) != 2) { - free(exeinfo.section); - return -1; + if(sscanf(offstr, "S%u+%lu", &n, &offset) != 2) { + *ret = -1; + return 0; } - if(n >= exeinfo.nsections) { - free(exeinfo.section); - return -1; + if(n >= info->exeinfo.nsections) { + *ret = -1; + return 0; } - offset += exeinfo.section[n].raw; + offset += info->exeinfo.section[n].raw; } - free(exeinfo.section); return offset; } else if(!strncmp(offstr, "EOF-", 4)) { struct stat sb; - if(fstat(fd, &sb) == -1) - return -1; + if(!info->fsize) { + if(fstat(fd, &sb) == -1) { + info->status = *ret = -1; + return 0; + } + info->fsize = sb.st_size; + } - return sb.st_size - atoi(offstr + 4); + return info->fsize - atoi(offstr + 4); } - return -1; + *ret = -1; + return 0; } static int cli_checkfp(int fd, const struct cl_engine *engine) @@ -369,19 +381,22 @@ static int cli_checkfp(int fd, const struct cl_engine *engine) return 0; } -int cli_validatesig(unsigned short ftype, const char *offstr, unsigned long int fileoff, int desc, const char *virname) +int cli_validatesig(unsigned short ftype, const char *offstr, off_t fileoff, struct cli_target_info *info, int desc, const char *virname) { + off_t offset; + int ret; + if(offstr && desc != -1) { - long int off = cli_caloff(offstr, desc, ftype); + offset = cli_caloff(offstr, info, desc, ftype, &ret); - if(off == -1) { - cli_dbgmsg("Bad offset in signature (%s)\n", virname); + if(ret == -1) { + cli_dbgmsg("cli_validatesig: Can't calculate offset for signature %s\n", virname); return 0; } - if(fileoff != (unsigned long int) off) { - cli_dbgmsg("Virus offset: %ld, expected: %ld (%s)\n", fileoff, off, virname); + if(fileoff != offset) { + cli_dbgmsg("Signature offset: %lu, expected: %lu (%s)\n", fileoff, offset, virname); return 0; } } @@ -408,6 +423,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, unsigned short f int count, hret; off_t origoff; char *pt; + struct cli_target_info info; #endif @@ -461,74 +477,93 @@ int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, unsigned short f count = sn_sigscan_resultcount(resulthandle); + memset(&info, 0, sizeof(info)); + for(i = 0; i < count; i++) { const char *matchname = NULL, *offsetstring = NULL, *optionalsigdata = NULL; unsigned long long startoffset = 0; + off_t offset; int targettype = 0; if((hret = sn_sigscan_resultget_name(resulthandle, i, &matchname) < 0)) { - cli_errmsg("cli_scandesc: sn_sigscan_resultget_name failed for result %d: %d\n", i, hret); + cli_errmsg("cli_scandesc: sn_sigscan_resultget_name failed for result %u: %d\n", i, hret); sn_sigscan_resultfree(resulthandle); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_ENCIO; } if(!matchname) { - cli_errmsg("cli_scandesc: HW Result[%d]: Signature without name\n", i); + cli_errmsg("cli_scandesc: HW Result[%u]: Signature without name\n", i); sn_sigscan_resultfree(resulthandle); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_EMALFDB; } if((hret = sn_sigscan_resultget_targettype(resulthandle, i, &targettype) < 0)) { - cli_errmsg("cli_scandesc: sn_sigscan_resultget_targettype failed for result %d, signature %s: %d\n", i, matchname, hret); + cli_errmsg("cli_scandesc: sn_sigscan_resultget_targettype failed for result %u, signature %s: %d\n", i, matchname, hret); sn_sigscan_resultfree(resulthandle); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_ENCIO; } if(targettype && targettab[targettype] != (int) ftype) { - cli_dbgmsg("cli_scandesc: HW Result[%d]: %s: Target type: %d, expected: %d\n", i, matchname, targettab[targettype], ftype); + cli_dbgmsg("cli_scandesc: HW Result[%u]: %s: Target type: %u, expected: %u\n", i, matchname, targettab[targettype], ftype); continue; } if((hret = sn_sigscan_resultget_offsetstring(resulthandle, i, &offsetstring) < 0)) { - cli_errmsg("cli_scandesc: sn_sigscan_resultget_offsetstring failed for result %d, signature %s: %d\n", i, matchname, hret); + cli_errmsg("cli_scandesc: sn_sigscan_resultget_offsetstring failed for result %u, signature %s: %d\n", i, matchname, hret); sn_sigscan_resultfree(resulthandle); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_ENCIO; } if((hret = sn_sigscan_resultget_startoffset(resulthandle, i, &startoffset) < 0)) { - cli_errmsg("cli_scandesc: sn_sigscan_resultget_startoffset failed for result %d, signature %s: %d\n", i, matchname, hret); + cli_errmsg("cli_scandesc: sn_sigscan_resultget_startoffset failed for result %u, signature %s: %d\n", i, matchname, hret); sn_sigscan_resultfree(resulthandle); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_ENCIO; } if(offsetstring && strcmp(offsetstring, "*")) { - long int off = cli_caloff(offsetstring, desc, ftype); + off_t off = cli_caloff(offsetstring, &info, desc, ftype, &hret); - if(off == -1) { - cli_dbgmsg("cli_scandesc: HW Result[%d]: %s: Bad offset in signature\n", i, matchname); + if(hret == -1) { + cli_dbgmsg("cli_scandesc: HW Result[%u]: %s: Bad offset in signature\n", i, matchname); sn_sigscan_resultfree(resulthandle); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_EMALFDB; } if(startoffset != (unsigned long long) off) { - cli_dbgmsg("cli_scandesc: HW Result[%d]: %s: Virus offset: %Lu, expected: %ld\n", i, matchname, startoffset, off); + cli_dbgmsg("cli_scandesc: HW Result[%u]: %s: Virus offset: %lu, expected: %lu\n", i, matchname, startoffset, off); continue; } } if((hret = sn_sigscan_resultget_extradata(resulthandle, i, &optionalsigdata) < 0)) { - cli_errmsg("cli_scandesc: sn_sigscan_resultget_extradata failed for result %d, signature %s: %d\n", i, matchname, hret); + cli_errmsg("cli_scandesc: sn_sigscan_resultget_extradata failed for result %u, signature %s: %u\n", i, matchname, hret); sn_sigscan_resultfree(resulthandle); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_ENCIO; } if(optionalsigdata && strlen(optionalsigdata)) { if((pt = cli_strtok(optionalsigdata, 1, ":"))) { /* max version */ if(!isdigit(*pt)) { free(pt); - cli_errmsg("cli_scandesc: HW Result[%d]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); + cli_errmsg("cli_scandesc: HW Result[%u]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); sn_sigscan_resultfree(resulthandle); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_EMALFDB; } if(atoi(pt) < cl_retflevel()) { - cli_dbgmsg("cli_scandesc: HW Result[%d]: %s: Signature max flevel: %d, current: %d\n", i, matchname, atoi(pt), cl_retflevel()); + cli_dbgmsg("cli_scandesc: HW Result[%u]: %s: Signature max flevel: %u, current: %u\n", i, matchname, atoi(pt), cl_retflevel()); free(pt); continue; } @@ -537,13 +572,15 @@ int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, unsigned short f if((pt = cli_strtok(optionalsigdata, 0, ":"))) { /* min version */ if(!isdigit(*pt)) { free(pt); - cli_errmsg("cli_scandesc: HW Result[%d]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); + cli_errmsg("cli_scandesc: HW Result[%u]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); sn_sigscan_resultfree(resulthandle); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_EMALFDB; } if(atoi(pt) > cl_retflevel()) { - cli_dbgmsg("cli_scandesc: HW Result[%d]: %s: Signature required flevel: %d, current: %d\n", i, matchname, atoi(pt), cl_retflevel()); + cli_dbgmsg("cli_scandesc: HW Result[%u]: %s: Signature required flevel: %u, current: %u\n", i, matchname, atoi(pt), cl_retflevel()); free(pt); continue; } @@ -552,13 +589,15 @@ int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, unsigned short f } else { if(!isdigit(*optionalsigdata)) { - cli_errmsg("cli_scandesc: HW Result[%d]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); + cli_errmsg("cli_scandesc: HW Result[%u]: %s: Incorrect optional signature data: %s\n", i, matchname, optionalsigdata); sn_sigscan_resultfree(resulthandle); + if(info.exeinfo.section) + free(info.exeinfo.section); return CL_EMALFDB; } if(atoi(optionalsigdata) > cl_retflevel()) { - cli_dbgmsg("cli_scandesc: HW Result[%d]: %s: Signature required flevel: %d, current: %d\n", i, matchname, atoi(optionalsigdata), cl_retflevel()); + cli_dbgmsg("cli_scandesc: HW Result[%u]: %s: Signature required flevel: %u, current: %u\n", i, matchname, atoi(optionalsigdata), cl_retflevel()); continue; } } @@ -569,6 +608,9 @@ int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, unsigned short f break; } + if(info.exeinfo.section) + free(info.exeinfo.section); + if((hret = sn_sigscan_resultfree(resulthandle)) < 0) { cli_errmsg("cli_scandesc: can't free results: %d\n", ret); return CL_ENCIO; @@ -630,7 +672,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, unsigned short f /* prepare the buffer */ buffersize = maxpatlen + SCANBUFF; if(!(buffer = (unsigned char *) cli_calloc(buffersize, sizeof(unsigned char)))) { - cli_dbgmsg("cli_scandesc(): unable to cli_calloc(%d)\n", buffersize); + cli_dbgmsg("cli_scandesc(): unable to cli_calloc(%u)\n", buffersize); return CL_EMEM; } diff --git a/clamav-devel/libclamav/matcher.h b/clamav-devel/libclamav/matcher.h index c55f1ddd0..8b313ac59 100644 --- a/clamav-devel/libclamav/matcher.h +++ b/clamav-devel/libclamav/matcher.h @@ -20,16 +20,26 @@ #ifndef __MATCHER_H #define __MATCHER_H +#include + #include "clamav.h" #include "filetypes.h" #include "others.h" +#include "execs.h" +#include "cltypes.h" #define CL_TARGET_TABLE_SIZE 7 +struct cli_target_info { + off_t fsize; + struct cli_exe_info exeinfo; + int8_t status; /* 0 == not initialised, 1 == initialised OK, -1 == error */ +}; + int cli_scandesc(int desc, cli_ctx *ctx, unsigned short otfrec, unsigned short ftype, struct cli_matched_type **ftoffset); int cli_scanbuff(const unsigned char *buffer, unsigned int length, const char **virname, const struct cl_engine *engine, unsigned short ftype); -int cli_validatesig(unsigned short ftype, const char *offstr, unsigned long int fileoff, int desc, const char *virname); +int cli_validatesig(unsigned short ftype, const char *offstr, off_t fileoff, struct cli_target_info *info, int desc, const char *virname); #endif diff --git a/clamav-devel/libclamav/pe.c b/clamav-devel/libclamav/pe.c index 5079e6ec3..cf4a139d4 100644 --- a/clamav-devel/libclamav/pe.c +++ b/clamav-devel/libclamav/pe.c @@ -2436,6 +2436,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo) if(fstat(desc, &sb) == -1) { cli_dbgmsg("fstat failed\n"); free(peinfo->section); + peinfo->section = NULL; return -1; } @@ -2444,6 +2445,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo) if(!section_hdr) { cli_dbgmsg("Can't allocate memory for section headers\n"); free(peinfo->section); + peinfo->section = NULL; return -1; } @@ -2454,6 +2456,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo) cli_dbgmsg("Possibly broken PE file\n"); free(section_hdr); free(peinfo->section); + peinfo->section = NULL; return -1; } @@ -2483,6 +2486,7 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo) cli_dbgmsg("Possibly broken PE file\n"); free(section_hdr); free(peinfo->section); + peinfo->section = NULL; return -1; }