[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b
aCaB
acab at clamav.net
Sun Apr 4 00:58:37 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit a8271e9d6ee266785d402c1596a87ab7059a80c2
Author: aCaB <acab at clamav.net>
Date: Tue Jul 14 12:39:21 2009 +0200
IS scan framework
diff --git a/libclamav/ishield.c b/libclamav/ishield.c
index 2899588..ba93c84 100644
--- a/libclamav/ishield.c
+++ b/libclamav/ishield.c
@@ -33,6 +33,7 @@
#include <unistd.h>
#endif
#include <string.h>
+#include <strings.h>
#include <zlib.h>
#include "scanners.h"
@@ -44,7 +45,6 @@
#define O_BINARY 0
#endif
-
#ifndef HAVE_ATTRIB_PACKED
#define __attribute__(x)
#endif
@@ -80,9 +80,10 @@ struct IS_FB {
#pragma pack
#endif
-static const uint8_t skey[] = { 0xec, 0xca, 0x79, 0xf8 }; /* ~0x13, ~0x35, ~0x86, ~0x07 */
+static int is_dump_and_scan(int desc, cli_ctx *ctx, off_t off, size_t fsize);
+static const uint8_t skey[] = { 0xec, 0xca, 0x79, 0xf8 }; /* ~0x13, ~0x35, ~0x86, ~0x07 */
/* Extract the content of MSI based IS */
int cli_scanishield_msi(int desc, cli_ctx *ctx, off_t off) {
@@ -200,15 +201,27 @@ int cli_scanishield_msi(int desc, cli_ctx *ctx, off_t off) {
return CL_CLEAN;
}
+struct CABSTUFF {
+ struct CABARRAY {
+ unsigned int cabno;
+ off_t off;
+ size_t sz;
+ } *cabs;
+ off_t hdr;
+ size_t hdrsz;
+ unsigned int cabcnt;
+};
+
int cli_scanishield(int desc, cli_ctx *ctx, off_t off, size_t sz) {
char *fname, *path, *version, *strsz, *eostr, *data;
char buf[2048];
- int rd;
- long int fsize;
+ int rd, ret = CL_CLEAN;
+ long fsize;
off_t coff = off;
+ struct CABSTUFF c = { NULL, -1, 0, 0 };
- while(1) {
+ while(ret == CL_CLEAN) {
rd = pread(desc, buf, sizeof(buf), coff);
if(rd <= 0)
break;
@@ -236,16 +249,108 @@ int cli_scanishield(int desc, cli_ctx *ctx, off_t off, size_t sz) {
data++;
fsize = strtol(strsz, &eostr, 10);
- if(fsize == LONG_MIN || fsize == LONG_MAX || !*strsz || !eostr || eostr == strsz || *eostr)
+ if(fsize < 0 || fsize == LONG_MAX
+ || !*strsz || !eostr || eostr == strsz || *eostr ||
+ (unsigned long)fsize >= sz ||
+ data - buf >= sz - fsize)
break;
- if((data - buf) + fsize > sz)
- break;
-
- cli_errmsg("@%x: found file %s (%s) - version %s - size %u\n", coff, fname, path, version, fsize);
+ cli_errmsg("ishield: @%lx found file %s (%s) - version %s - size %lu\n", coff, fname, path, version, fsize);
sz -= (data - buf) + fsize;
- coff += (data - buf) + fsize;
+ coff += (data - buf);
+ if(!strncasecmp(fname, "data", 4)) {
+ long cabno;
+ if(!strcasecmp(fname + 4, "1.hdr")) {
+ if(c.hdr == -1) {
+ c.hdr = coff;
+ c.hdrsz = fsize;
+ coff += fsize;
+ continue;
+ }
+ cli_warnmsg("ishield: got multiple header files\n");
+ }
+ cabno = strtol(fname + 4, &eostr, 10);
+ if(cabno > 0 && cabno < 65536 && fname[4] && eostr && eostr != &fname[4] && !strcasecmp(eostr, ".cab")) {
+ unsigned int i;
+ for(i=0; i<c.cabcnt && i!=c.cabs[i].cabno; i++) { }
+ if(i==c.cabcnt) {
+ c.cabcnt++;
+ if(!(c.cabs = cli_realloc2(c.cabs, sizeof(struct CABARRAY) * c.cabcnt))) {
+ ret = CL_EMEM;
+ break;
+ }
+ c.cabs[i].cabno = cabno;
+ c.cabs[i].off = coff;
+ c.cabs[i].sz = fsize;
+ coff += fsize;
+ continue;
+ }
+ cli_warnmsg("ishield: got multiple data%lu.cab files\n", cabno);
+ }
+ }
+
+ ret = is_dump_and_scan(desc, ctx, coff, fsize);
+ coff += fsize;
+ }
+ if(ret == CL_CLEAN && (c.cabcnt || c.hdr != -1)) {
+ if(1 /* FIXMEISHIELD */) {
+ unsigned int i;
+ if(c.hdr != -1) ret = is_dump_and_scan(desc, ctx, c.hdr, c.hdrsz);
+ for(i=0; i<c.cabcnt && ret == CL_CLEAN; i++) {
+ cli_errmsg("ishield: scanning data%u.cab\n", c.cabs[i].cabno);
+ ret = is_dump_and_scan(desc, ctx, c.cabs[i].off, c.cabs[i].sz);
+ }
+ }
}
+
+ if(c.cabs) free(c.cabs);
return CL_CLEAN;
}
+
+
+
+static int is_dump_and_scan(int desc, cli_ctx *ctx, off_t off, size_t fsize) {
+ char *fname, buf[BUFSIZ];
+ int ofd, ret = CL_CLEAN;
+
+ cli_errmsg("dumping %u bytes @%x\n", fsize, off);
+ if(!fsize) {
+ cli_errmsg("ishield: skipping empty file\n");
+ return CL_CLEAN;
+ }
+ if(!(fname = cli_gentemp(ctx->engine->tmpdir)))
+ return CL_EMEM;
+
+ if((ofd = open(fname, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR)) < 0) {
+ cli_errmsg("ishield: failed to create file %s\n", fname);
+ free(fname);
+ return CL_ECREAT;
+ }
+ while(fsize) {
+ size_t rd = fsize < sizeof(buf) ? fsize : sizeof(buf);
+ int got = pread(desc, buf, rd, off);
+ if(got <= 0) {
+ cli_errmsg("ishield: read error\n");
+ ret = CL_EREAD;
+ break;
+ }
+ if(cli_writen(ofd, buf, got) <= 0) {
+ cli_errmsg("ishield: write error\n");
+ ret = CL_EWRITE;
+ break;
+ }
+ fsize -= got;
+ off += got;
+ }
+ if(!fsize) {
+ cli_errmsg("ishield: extracted to %s\n", fname);
+ lseek(ofd, 0, SEEK_SET);
+ ret = cli_magic_scandesc(ofd, ctx);
+ }
+ close(ofd);
+ if(!ctx->engine->keeptmp)
+ if(cli_unlink(fname)) ret = CL_EUNLINK;
+ free(fname);
+ return ret;
+}
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list