Bug#703391: Reduced debdiff
diff -Nru clamav-0.97.6+dfsg/ChangeLog clamav-0.97.7+dfsg/ChangeLog
--- clamav-0.97.6+dfsg/ChangeLog 2012-09-17 11:15:12.000000000 -0400
+++ clamav-0.97.7+dfsg/ChangeLog 2013-03-11 11:23:20.000000000 -0400
@@ -1,3 +1,8 @@
+Wed Feb 20 10:05:00 EDT 2012 (multiple)
+---------------------------------
+ * Bug reported by Felix Groebert, Mateusz Jurczyk and Gynvael Coldwind of the
+ Google Security Team.
+
Mon Sep 6 12:32:00 EDT 2012 (dar)
---------------------------------
* libclamav: bb#5751 - cl_scansis() may returan a file descriptor instead
diff -Nru clamav-0.97.6+dfsg/clamd/scanner.c clamav-0.97.7+dfsg/clamd/scanner.c
--- clamav-0.97.6+dfsg/clamd/scanner.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/clamd/scanner.c 2013-03-11 11:23:20.000000000 -0400
@@ -107,6 +107,7 @@
{
struct scan_cb_data *scandata = data->data;
const char *virname;
+ const char **virpp = &virname;
int ret;
int type = scandata->type;
struct cb_context context;
@@ -228,11 +229,18 @@
type == TYPE_MULTISCAN ? "MULTISCANFILE" : NULL);
context.filename = filename;
context.virsize = 0;
- ret = cl_scanfile_callback(filename, &virname, &scandata->scanned, scandata->engine, scandata->options, &context);
+ ret = cl_scanfile_callback(filename, virpp, &scandata->scanned, scandata->engine, scandata->options, &context);
thrmgr_setactivetask(NULL, NULL);
+ if (scandata->options & CL_SCAN_ALLMATCHES) {
+ virpp = (const char **)*virpp; /* temp hack for scanall mode until api augmentation */
+ virname = virpp[0];
+ }
+
if (thrmgr_group_need_terminate(scandata->conn->group)) {
free(filename);
+ if (ret == CL_VIRUS && scandata->options & CL_SCAN_ALLMATCHES)
+ free((void *)virpp);
logg("*Client disconnected while scanjob was active\n");
return ret == CL_ETIMEOUT ? ret : CL_BREAK;
}
@@ -241,8 +249,19 @@
scandata->infected++;
if (conn_reply_virus(scandata->conn, filename, virname) == -1) {
free(filename);
+ if (scandata->options & CL_SCAN_ALLMATCHES)
+ free((void *)virpp);
return CL_ETIMEOUT;
}
+ if (scandata->options & CL_SCAN_ALLMATCHES && virpp[1] != NULL) {
+ int i = 1;
+ while (NULL != virpp[i])
+ if (conn_reply_virus(scandata->conn, filename, virpp[i++]) == -1) {
+ free(filename);
+ free((void *)virpp);
+ return CL_ETIMEOUT;
+ }
+ }
if(context.virsize)
detstats_add(virname, filename, context.virsize, context.virhash);
if(context.virsize && optget(scandata->opts, "ExtendedDetectionInfo")->enabled)
@@ -250,6 +269,11 @@
else
logg("~%s: %s FOUND\n", filename, virname);
virusaction(filename, virname, scandata->opts);
+ if (scandata->options & CL_SCAN_ALLMATCHES && virpp[1] != NULL) {
+ int i = 1;
+ while (NULL != virpp[i])
+ logg("~%s: %s FOUND\n", filename, virpp[i++]);
+ }
} else if (ret != CL_CLEAN) {
scandata->errors++;
if (conn_reply(scandata->conn, filename, cl_strerror(ret), "ERROR") == -1) {
@@ -262,6 +286,8 @@
}
free(filename);
+ if (ret == CL_VIRUS && scandata->options & CL_SCAN_ALLMATCHES)
+ free((void *)virpp);
if(ret == CL_EMEM) /* stop scanning */
return ret;
diff -Nru clamav-0.97.6+dfsg/clamd/session.c clamav-0.97.7+dfsg/clamd/session.c
--- clamav-0.97.6+dfsg/clamd/session.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/clamd/session.c 2013-03-11 11:23:20.000000000 -0400
@@ -94,7 +94,8 @@
{CMD16, sizeof(CMD16)-1, COMMAND_IDSESSION, 0, 0, 1},
{CMD17, sizeof(CMD17)-1, COMMAND_INSTREAM, 0, 0, 1},
{CMD19, sizeof(CMD19)-1, COMMAND_DETSTATSCLEAR, 0, 1, 1},
- {CMD20, sizeof(CMD20)-1, COMMAND_DETSTATS, 0, 1, 1}
+ {CMD20, sizeof(CMD20)-1, COMMAND_DETSTATS, 0, 1, 1},
+ {CMD21, sizeof(CMD21)-1, COMMAND_ALLMATCHSCAN, 1, 0, 1}
};
enum commands parse_command(const char *cmd, const char **argument, int oldstyle)
@@ -346,7 +347,11 @@
conn->scanfd = -1;
cli_unlink(conn->filename);
return ret;
- default:
+ case COMMAND_ALLMATCHSCAN:
+ thrmgr_setactivetask(NULL, "ALLMATCHSCAN");
+ scandata.options |= CL_SCAN_ALLMATCHES;
+ type = TYPE_SCAN;
+ break;default:
logg("!Invalid command distpached: %d\n", conn->cmdtype);
return 1;
}
@@ -420,6 +425,7 @@
case COMMAND_SCAN:
case COMMAND_CONTSCAN:
case COMMAND_MULTISCAN:
+ case COMMAND_ALLMATCHSCAN:
dup_conn->filename = strdup(argument);
if (!dup_conn->filename) {
logg("!Failed to allocate memory for filename\n");
@@ -591,6 +597,7 @@
case COMMAND_FILDES:
case COMMAND_SCAN:
case COMMAND_INSTREAMSCAN:
+ case COMMAND_ALLMATCHSCAN:
return dispatch_command(conn, cmd, argument);
case COMMAND_IDSESSION:
conn->group = thrmgr_group_new();
diff -Nru clamav-0.97.6+dfsg/clamd/session.h clamav-0.97.7+dfsg/clamd/session.h
--- clamav-0.97.6+dfsg/clamd/session.h 2012-06-12 09:03:26.000000000 -0400
+++ clamav-0.97.7+dfsg/clamd/session.h 2013-03-11 11:21:44.000000000 -0400
@@ -43,6 +43,8 @@
#define CMD19 "DETSTATSCLEAR"
#define CMD20 "DETSTATS"
+#define CMD21 "ALLMATCHSCAN"
+
#include "libclamav/clamav.h"
#include "shared/optparser.h"
#include "server.h"
@@ -70,7 +72,8 @@
COMMAND_DETSTATS,
/* internal commands */
COMMAND_MULTISCANFILE,
- COMMAND_INSTREAMSCAN
+ COMMAND_INSTREAMSCAN,
+ COMMAND_ALLMATCHSCAN
};
typedef struct client_conn_tag {
diff -Nru clamav-0.97.6+dfsg/clamdscan/client.c clamav-0.97.7+dfsg/clamdscan/client.c
--- clamav-0.97.6+dfsg/clamdscan/client.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/clamdscan/client.c 2013-03-11 11:23:20.000000000 -0400
@@ -232,7 +232,9 @@
if(remote || scandash) {
scantype = STREAM;
session = optget(opts, "multiscan")->enabled;
- } else if(optget(opts, "multiscan")->enabled) scantype = MULTI;
+ }
+ else if(optget(opts, "multiscan")->enabled) scantype = MULTI;
+ else if(optget(opts, "allmatch")->enabled) scantype = ALLMATCH;
else scantype = CONT;
maxrec = optget(clamdopts, "MaxDirectoryRecursion")->numarg;
diff -Nru clamav-0.97.6+dfsg/clamdscan/client.h clamav-0.97.7+dfsg/clamdscan/client.h
--- clamav-0.97.6+dfsg/clamdscan/client.h 2012-05-15 14:34:22.000000000 -0400
+++ clamav-0.97.7+dfsg/clamdscan/client.h 2013-03-11 11:21:44.000000000 -0400
@@ -27,7 +27,9 @@
CONT,
MULTI,
STREAM,
- FILDES
+ FILDES,
+ ALLMATCH,
+ MAX_SCANTYPE = ALLMATCH
};
int client(const struct optstruct *opts, int *infected, int *err);
diff -Nru clamav-0.97.6+dfsg/clamdscan/proto.c clamav-0.97.7+dfsg/clamdscan/proto.c
--- clamav-0.97.6+dfsg/clamdscan/proto.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/clamdscan/proto.c 2013-03-11 11:23:20.000000000 -0400
@@ -58,7 +58,7 @@
int printinfected;
extern struct optstruct *clamdopts;
-static const char *scancmd[] = { "CONTSCAN", "MULTISCAN" };
+static const char *scancmd[] = { "CONTSCAN", "MULTISCAN", "INSTREAM", "FILDES", "ALLMATCHSCAN" };
/* Connects to clamd
* Returns a FD or -1 on error */
@@ -202,6 +202,11 @@
switch(scantype) {
case MULTI:
case CONT:
+ case ALLMATCH:
+ if (!filename) {
+ logg("Filename cannot be NULL for MULTISCAN or CONTSCAN.\n");
+ return -1;
+ }
len = strlen(filename) + strlen(scancmd[scantype]) + 3;
if (!(bol = malloc(len))) {
logg("!Cannot allocate a command buffer: %s\n", strerror(errno));
@@ -247,7 +252,13 @@
colon = strrchr(bol, ':');
}
if(!colon) {
- logg("Failed to parse reply\n");
+ char * unkco = "UNKNOWN COMMAND";
+ if (!strncmp(bol, unkco, sizeof(unkco) - 1))
+ logg("clamd replied \"UNKNOWN COMMAND\". Command was %s\n",
+ (scantype < 0 || scantype > MAX_SCANTYPE) ? "unidentified" :
+ scancmd[scantype]);
+ else
+ logg("Failed to parse reply: \"%s\"\n", bol);
return -1;
} else if(!memcmp(eol - 7, " FOUND", 6)) {
*(eol - 7) = 0;
diff -Nru clamav-0.97.6+dfsg/clamscan/manager.c clamav-0.97.7+dfsg/clamscan/manager.c
--- clamav-0.97.6+dfsg/clamscan/manager.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/clamscan/manager.c 2013-03-11 11:23:20.000000000 -0400
@@ -125,6 +125,7 @@
int ret = 0, fd, included, printclean = 1;
const struct optstruct *opt;
const char *virname;
+ const char **virpp = &virname;
struct stat sb;
if((opt = optget(opts, "exclude"))->enabled) {
@@ -190,7 +191,16 @@
}
if((ret = cl_scandesc(fd, &virname, &info.blocks, engine, options)) == CL_VIRUS) {
- logg("~%s: %s FOUND\n", filename, virname);
+ if (options & CL_SCAN_ALLMATCHES) {
+ int i = 0;
+ virpp = (const char **)*virpp; /* temp hack for allscan until API enhancement */
+ virname = virpp[0];
+ while (virpp[i])
+ logg("~%s: %s FOUND\n", filename, virpp[i++]);
+ free((void *)virpp);
+ }
+ else
+ logg("~%s: %s FOUND\n", filename, virname);
info.files++;
info.ifiles++;
@@ -319,6 +329,8 @@
int ret;
unsigned int fsize = 0;
const char *virname, *tmpdir;
+ const char **virpp = &virname;
+
char *file, buff[FILEBUFF];
size_t bread;
FILE *fs;
@@ -358,7 +370,17 @@
info.rblocks += fsize / CL_COUNT_PRECISION;
if((ret = cl_scanfile(file, &virname, &info.blocks, engine, options)) == CL_VIRUS) {
- logg("stdin: %s FOUND\n", virname);
+ if (options & CL_SCAN_ALLMATCHES) {
+ int i = 0;
+ virpp = (const char **)*virpp; /* temp hack for scanall mode until api augmentation */
+ virname = virpp[0];
+ while (virpp[i])
+ logg("stdin: %s FOUND\n", virpp[i++]);
+ free((void *)virpp);
+ }
+ else
+ logg("stdin: %s FOUND\n", virname);
+
info.ifiles++;
if(bell)
@@ -587,6 +609,9 @@
}
/* set scan options */
+ if(optget(opts, "allmatch")->enabled)
+ options |= CL_SCAN_ALLMATCHES;
+
if(optget(opts,"phishing-ssl")->enabled)
options |= CL_SCAN_PHISHING_BLOCKSSL;
diff -Nru clamav-0.97.6+dfsg/configure.in clamav-0.97.7+dfsg/configure.in
--- clamav-0.97.6+dfsg/configure.in 2012-08-10 12:03:00.000000000 -0400
+++ clamav-0.97.7+dfsg/configure.in 2013-03-11 11:23:20.000000000 -0400
@@ -20,7 +20,7 @@
AC_PREREQ([2.59])
dnl For a release change [devel] to the real version [0.xy]
dnl also change VERSION below
-AC_INIT([ClamAV], [0.97.6], [http://bugs.clamav.net/], [clamav], [http://www.clamav.net/])
+AC_INIT([ClamAV], [0.97.7], [http://bugs.clamav.net/], [clamav], [http://www.clamav.net/])
AH_BOTTOM([#include "platform.h"])
dnl put configure auxiliary into config
@@ -43,10 +43,10 @@
dnl change this on a release
dnl VERSION="devel-`date +%Y%m%d`"
-VERSION="0.97.6"
+VERSION="0.97.7"
LC_CURRENT=7
-LC_REVISION=15
+LC_REVISION=16
LC_AGE=1
LIBCLAMAV_VERSION="$LC_CURRENT":"$LC_REVISION":"$LC_AGE"
AC_SUBST([LIBCLAMAV_VERSION])
diff -Nru clamav-0.97.6+dfsg/debian/changelog clamav-0.97.7+dfsg/debian/changelog
--- clamav-0.97.6+dfsg/debian/changelog 2013-03-18 22:36:11.000000000 -0400
+++ clamav-0.97.7+dfsg/debian/changelog 2013-03-18 22:36:12.000000000 -0400
@@ -1,3 +1,10 @@
+clamav (0.97.7+dfsg-1) unstable; urgency=medium
+
+ * New upstream release
+ * Urgency medium due to security fixes
+
+ -- Scott Kitterman <scott@kitterman.com> Mon, 18 Mar 2013 22:28:02 -0400
+
clamav (0.97.6+dfsg-1) unstable; urgency=low
* New upstream release (Closes: #689487)
diff -Nru clamav-0.97.6+dfsg/libclamav/blob.c clamav-0.97.7+dfsg/libclamav/blob.c
--- clamav-0.97.6+dfsg/libclamav/blob.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/blob.c 2013-03-11 11:23:20.000000000 -0400
@@ -575,7 +575,7 @@
fb->bytes_scanned += (unsigned long)len;
if((len > 5) && cli_updatelimits(ctx, len)==CL_CLEAN && (cli_scanbuff(data, (unsigned int)len, 0, ctx->virname, ctx->engine, CL_TYPE_BINARY_DATA, NULL) == CL_VIRUS)) {
- cli_dbgmsg("fileblobAddData: found %s\n", *ctx->virname);
+ cli_dbgmsg("fileblobAddData: found %s\n", cli_get_last_virus_str(ctx));
fb->isInfected = 1;
}
}
diff -Nru clamav-0.97.6+dfsg/libclamav/bytecode_api.c clamav-0.97.7+dfsg/libclamav/bytecode_api.c
--- clamav-0.97.6+dfsg/libclamav/bytecode_api.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/bytecode_api.c 2013-03-11 11:23:20.000000000 -0400
@@ -511,8 +511,7 @@
cctx->recursion--;
cctx->container_type = current;
if (res == CL_VIRUS) {
- if (cctx->virname)
- ctx->virname = *cctx->virname;
+ ctx->virname = cli_get_last_virus(cctx);
ctx->found = 1;
}
}
diff -Nru clamav-0.97.6+dfsg/libclamav/bytecode.c clamav-0.97.7+dfsg/libclamav/bytecode.c
--- clamav-0.97.6+dfsg/libclamav/bytecode.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/bytecode.c 2013-03-11 11:23:20.000000000 -0400
@@ -2571,7 +2571,7 @@
int cli_bytecode_runlsig(cli_ctx *cctx, struct cli_target_info *tinfo,
const struct cli_all_bc *bcs, unsigned bc_idx,
- const char **virname, const uint32_t* lsigcnt,
+ const uint32_t* lsigcnt,
const uint32_t *lsigsuboff, fmap_t *map)
{
int ret;
@@ -2618,9 +2618,8 @@
if (ctx.virname) {
int rc;
cli_dbgmsg("Bytecode found virus: %s\n", ctx.virname);
- if (virname)
- *virname = ctx.virname;
- if (!strncmp(*virname, "BC.Heuristics", 13))
+ cli_append_virus(cctx, ctx.virname);
+ if (!strncmp(ctx.virname, "BC.Heuristics", 13))
rc = cli_found_possibly_unwanted(cctx);
else
rc = CL_VIRUS;
@@ -2634,7 +2633,7 @@
}
int cli_bytecode_runhook(cli_ctx *cctx, const struct cl_engine *engine, struct cli_bc_ctx *ctx,
- unsigned id, fmap_t *map, const char **virname)
+ unsigned id, fmap_t *map)
{
const unsigned *hooks = engine->hooks[id - _BC_START_HOOKS];
unsigned i, hooks_cnt = engine->hooks_cnt[id - _BC_START_HOOKS];
@@ -2664,10 +2663,13 @@
}
if (ctx->virname) {
cli_dbgmsg("Bytecode found virus: %s\n", ctx->virname);
- if (virname)
- *virname = ctx->virname;
- cli_bytecode_context_clear(ctx);
- return CL_VIRUS;
+ cli_append_virus(cctx, ctx->virname);
+ if (!(cctx->options & CL_SCAN_ALLMATCHES)) {
+ cli_bytecode_context_clear(ctx);
+ return CL_VIRUS;
+ }
+ cli_bytecode_context_reset(ctx);
+ continue;
}
ret = cli_bytecode_context_getresult_int(ctx);
/* TODO: use prefix here */
@@ -2700,10 +2702,15 @@
}
free(tempfile);
if (ret != CL_CLEAN) {
- if (ret == CL_VIRUS)
+ if (ret == CL_VIRUS) {
cli_dbgmsg("Scanning unpacked file by bytecode %u found a virus\n", bc->id);
- cli_bytecode_context_clear(ctx);
- return ret;
+ if (cctx->options & CL_SCAN_ALLMATCHES) {
+ cli_bytecode_context_reset(ctx);
+ continue;
+ }
+ cli_bytecode_context_clear(ctx);
+ return ret;
+ }
}
cli_bytecode_context_reset(ctx);
continue;
diff -Nru clamav-0.97.6+dfsg/libclamav/bytecode.h clamav-0.97.7+dfsg/libclamav/bytecode.h
--- clamav-0.97.6+dfsg/libclamav/bytecode.h 2012-05-15 14:34:22.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/bytecode.h 2013-03-11 11:23:20.000000000 -0400
@@ -118,8 +118,8 @@
struct cli_exe_info;
struct cli_ctx_tag;
struct cli_target_info;
-int cli_bytecode_runlsig(struct cli_ctx_tag *ctx, struct cli_target_info *info, const struct cli_all_bc *bcs, unsigned bc_idx, const char **virname, const uint32_t* lsigcnt, const uint32_t *lsigsuboff, fmap_t *map);
-int cli_bytecode_runhook(struct cli_ctx_tag *cctx, const struct cl_engine *engine, struct cli_bc_ctx *ctx, unsigned id, fmap_t *map, const char **virname);
+int cli_bytecode_runlsig(struct cli_ctx_tag *ctx, struct cli_target_info *info, const struct cli_all_bc *bcs, unsigned bc_idx, const uint32_t* lsigcnt, const uint32_t *lsigsuboff, fmap_t *map);
+int cli_bytecode_runhook(struct cli_ctx_tag *cctx, const struct cl_engine *engine, struct cli_bc_ctx *ctx, unsigned id, fmap_t *map);
#ifdef __cplusplus
extern "C" {
diff -Nru clamav-0.97.6+dfsg/libclamav/clamav.h clamav-0.97.7+dfsg/libclamav/clamav.h
--- clamav-0.97.6+dfsg/libclamav/clamav.h 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/clamav.h 2013-03-11 11:23:21.000000000 -0400
@@ -119,6 +119,7 @@
#define CL_SCAN_PARTIAL_MESSAGE 0x40000
#define CL_SCAN_HEURISTIC_PRECEDENCE 0x80000
#define CL_SCAN_BLOCKMACROS 0x100000
+#define CL_SCAN_ALLMATCHES 0x200000
#define CL_SCAN_INTERNAL_COLLECT_SHA 0x80000000 /* Enables hash output in sha-collect builds - for internal use only */
diff -Nru clamav-0.97.6+dfsg/libclamav/elf.c clamav-0.97.7+dfsg/libclamav/elf.c
--- clamav-0.97.6+dfsg/libclamav/elf.c 2012-06-12 09:03:27.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/elf.c 2013-03-11 11:21:48.000000000 -0400
@@ -73,7 +73,7 @@
uint8_t conv = 0, err;
unsigned int format;
fmap_t *map = *ctx->fmap;
-
+ uint32_t viruses_found = 0;
cli_dbgmsg("in cli_scanelf\n");
@@ -214,8 +214,7 @@
if(phnum > 128) {
cli_dbgmsg("ELF: Suspicious number of program headers\n");
if(DETECT_BROKEN) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_EFORMAT;
@@ -227,8 +226,7 @@
if(phentsize != sizeof(struct elf_program_hdr32)) {
cli_dbgmsg("ELF: phentsize != sizeof(struct elf_program_hdr32)\n");
if(DETECT_BROKEN) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_EFORMAT;
@@ -275,8 +273,7 @@
cli_dbgmsg("ELF: Possibly broken ELF file\n");
free(program_hdr);
if(DETECT_BROKEN) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN;
@@ -296,8 +293,7 @@
if(err) {
cli_dbgmsg("ELF: Can't calculate file offset of entry point\n");
if(DETECT_BROKEN) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_EFORMAT;
@@ -319,8 +315,7 @@
if(shentsize != sizeof(struct elf_section_hdr32)) {
cli_dbgmsg("ELF: shentsize != sizeof(struct elf_section_hdr32)\n");
if(DETECT_BROKEN) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_EFORMAT;
@@ -369,8 +364,7 @@
cli_dbgmsg("ELF: Possibly broken ELF file\n");
free(section_hdr);
if(DETECT_BROKEN) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN;
diff -Nru clamav-0.97.6+dfsg/libclamav/macho.c clamav-0.97.7+dfsg/libclamav/macho.c
--- clamav-0.97.6+dfsg/libclamav/macho.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/macho.c 2013-03-11 11:23:21.000000000 -0400
@@ -174,8 +174,7 @@
if(matcher) \
return -1; \
if(DETECT_BROKEN) { \
- if(ctx->virname) \
- *ctx->virname = "Heuristics.Broken.Executable"; \
+ cli_append_virus(ctx, "Heuristics.Broken.Executable"); \
return CL_VIRUS; \
} \
return CL_EFORMAT
diff -Nru clamav-0.97.6+dfsg/libclamav/matcher-ac.c clamav-0.97.7+dfsg/libclamav/matcher-ac.c
--- clamav-0.97.6+dfsg/libclamav/matcher-ac.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/matcher-ac.c 2013-03-11 11:23:21.000000000 -0400
@@ -1145,7 +1145,7 @@
}
-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_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, cli_ctx *ctx)
{
struct cli_ac_node *current;
struct cli_ac_patt *patt, *pt, *faillist;
@@ -1355,11 +1355,18 @@
pt = pt->next_same;
continue;
} else {
- if(virname)
- *virname = pt->virname;
+ if(virname) {
+ if (ctx && SCAN_ALL && virname == ctx->virname)
+ cli_append_virus(ctx, (const char *)pt->virname);
+ else
+ *virname = pt->virname;
+ }
if(customdata)
*customdata = pt->customdata;
- return CL_VIRUS;
+ if (!ctx || !SCAN_ALL)
+ return CL_VIRUS;
+ pt = pt->next_same;
+ continue;
}
}
}
@@ -1398,11 +1405,18 @@
pt = pt->next_same;
continue;
} else {
- if(virname)
- *virname = pt->virname;
+ if(virname) {
+ if (ctx && SCAN_ALL && virname == ctx->virname)
+ cli_append_virus(ctx, pt->virname);
+ else
+ *virname = pt->virname;
+ }
if(customdata)
*customdata = pt->customdata;
- return CL_VIRUS;
+ if (!ctx || !SCAN_ALL)
+ return CL_VIRUS;
+ pt = pt->next_same;
+ continue;
}
}
}
diff -Nru clamav-0.97.6+dfsg/libclamav/matcher-ac.h clamav-0.97.7+dfsg/libclamav/matcher-ac.h
--- clamav-0.97.6+dfsg/libclamav/matcher-ac.h 2012-06-12 09:03:27.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/matcher-ac.h 2013-03-11 11:21:48.000000000 -0400
@@ -93,7 +93,7 @@
void cli_ac_chkmacro(struct cli_matcher *root, struct cli_ac_data *data, unsigned lsigid1);
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_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, 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, uint8_t dconf_prefiltering);
int cli_ac_caloff(const struct cli_matcher *root, struct cli_ac_data *data, const struct cli_target_info *info);
diff -Nru clamav-0.97.6+dfsg/libclamav/matcher-bm.c clamav-0.97.7+dfsg/libclamav/matcher-bm.c
--- clamav-0.97.6+dfsg/libclamav/matcher-bm.c 2012-06-12 09:03:27.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/matcher-bm.c 2013-03-11 11:21:48.000000000 -0400
@@ -244,7 +244,7 @@
}
}
-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)
+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)
{
uint32_t i, j, off, off_min, off_max;
uint8_t found, pchain, shift;
@@ -374,8 +374,11 @@
continue;
}
}
- if(virname)
+ if(virname) {
*virname = p->virname;
+ if(viroffset)
+ *viroffset = offset + i + j - BM_MIN_LENGTH + BM_BLOCK_SIZE;
+ }
if(patt)
*patt = p;
return CL_VIRUS;
diff -Nru clamav-0.97.6+dfsg/libclamav/matcher-bm.h clamav-0.97.7+dfsg/libclamav/matcher-bm.h
--- clamav-0.97.6+dfsg/libclamav/matcher-bm.h 2012-05-15 14:34:23.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/matcher-bm.h 2013-03-11 11:21:48.000000000 -0400
@@ -47,7 +47,7 @@
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);
+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);
void cli_bm_free(struct cli_matcher *root);
#endif
diff -Nru clamav-0.97.6+dfsg/libclamav/matcher.c clamav-0.97.7+dfsg/libclamav/matcher.c
--- clamav-0.97.6+dfsg/libclamav/matcher.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/matcher.c 2013-03-11 11:23:21.000000000 -0400
@@ -91,13 +91,16 @@
unsigned int acmode,
struct cli_ac_result **acres,
fmap_t *map,
- struct cli_bm_off *offdata)
+ struct cli_bm_off *offdata,
+ uint32_t *viroffset,
+ cli_ctx *ctx)
{
int ret;
int32_t pos = 0;
struct filter_match_info info;
uint32_t orig_length, orig_offset;
const unsigned char* orig_buffer;
+ unsigned int viruses_found = 0;
if (root->filter) {
if(filter_search_ext(root->filter, buffer, length, &info) == -1) {
@@ -128,15 +131,28 @@
/* 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);
+ ret = cli_bm_scanbuff(orig_buffer, orig_length, virname, NULL, root, orig_offset, tinfo, offdata, viroffset);
} else {
- ret = cli_bm_scanbuff(buffer, length, virname, NULL, root, offset, tinfo, offdata);
+ ret = cli_bm_scanbuff(buffer, length, virname, NULL, root, offset, tinfo, offdata, viroffset);
+ }
+ if (ret == CL_VIRUS) {
+ if (ctx) {
+ cli_append_virus(ctx, *virname);
+ if (SCAN_ALL)
+ viruses_found++;
+ else
+ return ret;
+ }
}
- if (ret == CL_VIRUS)
- return ret;
}
PERF_LOG_TRIES(acmode, 0, length);
ret = cli_ac_scanbuff(buffer, length, virname, NULL, acres, root, mdata, offset, ftype, ftoffset, acmode, NULL);
+
+ if (ctx && ret == CL_VIRUS)
+ cli_append_virus(ctx, *virname);
+ if (ctx && SCAN_ALL && viruses_found)
+ return CL_VIRUS;
+
return ret;
}
@@ -146,7 +162,7 @@
unsigned int i;
struct cli_ac_data mdata;
struct cli_matcher *groot, *troot = NULL;
- const char **virname=ctx->virname;
+ const char *virname = NULL;
const struct cl_engine *engine=ctx->engine;
if(!engine) {
@@ -170,7 +186,7 @@
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);
+ ret = matcher_run(troot, buffer, length, &virname, acdata ? (acdata[0]): (&mdata), offset, NULL, ftype, NULL, AC_SCAN_VIR, NULL, *ctx->fmap, NULL, NULL, ctx);
if(!acdata)
cli_ac_freedata(&mdata);
@@ -179,10 +195,12 @@
return ret;
}
+ virname = NULL;
+
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);
+ ret = matcher_run(groot, buffer, length, &virname, acdata ? (acdata[1]): (&mdata), offset, NULL, ftype, NULL, AC_SCAN_VIR, NULL, *ctx->fmap, NULL, NULL, ctx);
if(!acdata)
cli_ac_freedata(&mdata);
@@ -396,7 +414,7 @@
for(i = 0; i < 16; i++)
sprintf(md5 + i * 2, "%02x", digest[i]);
md5[32] = 0;
- cli_dbgmsg("FP SIGNATURE: %s:%u:%s\n", md5, (unsigned int) size, *ctx->virname ? *ctx->virname : "Name");
+ cli_dbgmsg("FP SIGNATURE: %s:%u:%s\n", md5, (unsigned int) size, cli_get_last_virus(ctx) ? cli_get_last_virus(ctx) : "Name");
map = *ctx->fmap;
have_sha1 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, size);
@@ -442,7 +460,7 @@
for(i=0; i<SHA1_HASH_SIZE; i++)
sprintf((char *)shash1+i*2, "%02x", shash1[SHA1_HASH_SIZE+i]);
- cli_errmsg("COLLECT:%s:%s:%u:%s:%s\n", shash256, shash1, size, *ctx->virname, ctx->entry_filename);
+ cli_errmsg("COLLECT:%s:%s:%u:%s:%s\n", shash256, shash1, size, cli_get_last_virus(ctx), ctx->entry_filename);
} else
cli_errmsg("can't compute sha\n!");
ctx->sha_collect = -1;
@@ -450,7 +468,7 @@
#endif
if (ctx->engine->cb_hash)
- ctx->engine->cb_hash(ctx->fmap[0]->fd, size, md5, ctx->virname ? *ctx->virname : NULL, ctx->cb_ctx);
+ ctx->engine->cb_hash(ctx->fmap[0]->fd, size, md5, cli_get_last_virus(ctx), ctx->cb_ctx);
return CL_VIRUS;
}
@@ -535,6 +553,7 @@
unsigned int i, evalcnt;
uint64_t evalids;
fmap_t *map = *ctx->fmap;
+ unsigned int viruses_found = 0;
for(i = 0; i < root->ac_lsigs; i++) {
evalcnt = 0;
@@ -561,6 +580,10 @@
memcpy(ctx->handlertype_hash, hash, 16);
if(cli_magic_scandesc_type(map->fd, ctx, root->ac_lsigtable[i]->tdb.handlertype[0]) == CL_VIRUS) {
ctx->recursion--;
+ if (SCAN_ALL) {
+ viruses_found++;
+ continue;
+ }
return CL_VIRUS;
}
ctx->recursion--;
@@ -573,25 +596,41 @@
continue;
if(matchicon(ctx, &target_info->exeinfo, root->ac_lsigtable[i]->tdb.icongrp1, root->ac_lsigtable[i]->tdb.icongrp2) == CL_VIRUS) {
if(!root->ac_lsigtable[i]->bc_idx) {
- if(ctx->virname)
- *ctx->virname = root->ac_lsigtable[i]->virname;
+ cli_append_virus(ctx, root->ac_lsigtable[i]->virname);
+ if (SCAN_ALL) {
+ viruses_found++;
+ continue;
+ }
return CL_VIRUS;
- } else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, ctx->virname, acdata->lsigcnt[i], acdata->lsigsuboff_first[i], map) == CL_VIRUS) {
+ } else if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, acdata->lsigcnt[i], acdata->lsigsuboff_first[i], map) == CL_VIRUS) {
+ if (SCAN_ALL) {
+ viruses_found++;
+ continue;
+ }
return CL_VIRUS;
}
}
continue;
}
if(!root->ac_lsigtable[i]->bc_idx) {
- if(ctx->virname)
- *ctx->virname = root->ac_lsigtable[i]->virname;
- return CL_VIRUS;
+ cli_append_virus(ctx, root->ac_lsigtable[i]->virname);
+ if (SCAN_ALL) {
+ viruses_found++;
+ continue;
+ }
+ return CL_VIRUS;
}
- if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, ctx->virname, acdata->lsigcnt[i], acdata->lsigsuboff_first[i], map) == CL_VIRUS) {
- return CL_VIRUS;
+ if(cli_bytecode_runlsig(ctx, target_info, &ctx->engine->bcs, root->ac_lsigtable[i]->bc_idx, acdata->lsigcnt[i], acdata->lsigsuboff_first[i], map) == CL_VIRUS) {
+ if (SCAN_ALL) {
+ viruses_found++;
+ continue;
+ }
+ return CL_VIRUS;
}
}
}
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return CL_CLEAN;
}
@@ -611,6 +650,9 @@
struct cli_target_info info;
fmap_t *map = *ctx->fmap;
struct cli_matcher *hdb, *fp;
+ const char *virname = NULL;
+ uint32_t viroffset = 0;
+ uint32_t viruses_found = 0;
if(!ctx->engine) {
cli_errmsg("cli_scandesc: engine == NULL\n");
@@ -712,9 +754,14 @@
*ctx->scanned += bytes / CL_COUNT_PRECISION;
if(troot) {
- ret = matcher_run(troot, buff, bytes, ctx->virname, &tdata, offset, &info, ftype, ftoffset, acmode, acres, map, bm_offmode ? &toff : NULL);
+ 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);
- if(ret == CL_VIRUS || ret == CL_EMEM) {
+ if (virname) {
+ viruses_found++;
+ }
+ if((ret == CL_VIRUS && !SCAN_ALL) || ret == CL_EMEM) {
if(!ftonly)
cli_ac_freedata(&gdata);
cli_ac_freedata(&tdata);
@@ -728,9 +775,14 @@
}
if(!ftonly) {
- ret = matcher_run(groot, buff, bytes, ctx->virname, &gdata, offset, &info, ftype, ftoffset, acmode, acres, map, NULL);
+ virname = NULL;
+ viroffset = 0;
+ ret = matcher_run(groot, buff, bytes, &virname, &gdata, offset, &info, ftype, ftoffset, acmode, acres, map, NULL, &viroffset, ctx);
- if(ret == CL_VIRUS || ret == CL_EMEM) {
+ if (virname) {
+ viruses_found++;
+ }
+ if((ret == CL_VIRUS && !SCAN_ALL) || ret == CL_EMEM) {
cli_ac_freedata(&gdata);
if(troot) {
cli_ac_freedata(&tdata);
@@ -746,8 +798,8 @@
type = ret;
}
- if(hdb) {
- void *data = buff + maxpatlen * (offset!=0);
+ if(hdb && !SCAN_ALL) {
+ const void *data = buff + maxpatlen * (offset!=0);
uint32_t data_len = bytes - maxpatlen * (offset!=0);
if(compute_hash[CLI_HASH_MD5])
@@ -759,12 +811,16 @@
}
}
+ if(SCAN_ALL && viroffset) {
+ offset = viroffset;
+ continue;
+ }
if(bytes < SCANBUFF) break;
offset += bytes - maxpatlen;
}
if(!ftonly && hdb) {
- enum CLI_HASH_TYPE hashtype;
+ enum CLI_HASH_TYPE hashtype, hashtype2;
if(compute_hash[CLI_HASH_MD5])
cli_md5_final(digest[CLI_HASH_MD5], &md5ctx);
@@ -775,31 +831,42 @@
if(compute_hash[CLI_HASH_SHA256])
sha256_final(&sha256ctx, digest[CLI_HASH_SHA256]);
+ virname = NULL;
for(hashtype = CLI_HASH_MD5; hashtype < CLI_HASH_AVAIL_TYPES; hashtype++) {
- if(compute_hash[hashtype] && (ret = cli_hm_scan(digest[hashtype], map->len, ctx->virname, hdb, hashtype)) == CL_VIRUS)
- break;
- }
-
- if(ret == CL_VIRUS && fp) {
- for(hashtype = CLI_HASH_MD5; hashtype < CLI_HASH_AVAIL_TYPES; hashtype++) {
- if(compute_hash[hashtype] && cli_hm_scan(digest[hashtype], map->len, ctx->virname, fp, hashtype) == CL_VIRUS) {
- ret = CL_CLEAN;
- break;
+ if(compute_hash[hashtype] &&
+ (ret = cli_hm_scan(digest[hashtype], map->len, &virname, hdb, hashtype)) == CL_VIRUS) {
+ if(fp) {
+ for(hashtype2 = CLI_HASH_MD5; hashtype2 < CLI_HASH_AVAIL_TYPES; hashtype2++) {
+ if(compute_hash[hashtype2] &&
+ cli_hm_scan(digest[hashtype2], map->len, NULL, fp, hashtype2) == CL_VIRUS) {
+ ret = CL_CLEAN;
+ break;
+ }
+ }
}
+ if (ret == CL_VIRUS) {
+ viruses_found++;
+ cli_append_virus(ctx, virname);
+ if (!SCAN_ALL)
+ break;
+ }
+ virname = NULL;
}
}
}
if(troot) {
- if(ret != CL_VIRUS)
+ if(ret != CL_VIRUS || SCAN_ALL)
ret = cli_lsig_eval(ctx, troot, &tdata, &info, refhash);
+ if (ret == CL_VIRUS)
+ viruses_found++;
cli_ac_freedata(&tdata);
if(bm_offmode)
cli_bm_freeoff(&toff);
}
if(groot) {
- if(ret != CL_VIRUS)
+ if(ret != CL_VIRUS || SCAN_ALL)
ret = cli_lsig_eval(ctx, groot, &gdata, &info, refhash);
cli_ac_freedata(&gdata);
}
@@ -808,6 +875,8 @@
free(info.exeinfo.section);
cli_hashset_destroy(&info.exeinfo.vinfo);
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
if(ret == CL_VIRUS)
return CL_VIRUS;
@@ -817,6 +886,7 @@
int cli_matchmeta(cli_ctx *ctx, const char *fname, size_t fsizec, size_t fsizer, int encrypted, unsigned int filepos, int res1, void *res2)
{
const struct cli_cdb *cdb;
+ unsigned int viruses_found = 0;
if(!(cdb = ctx->engine->cdb))
return CL_CLEAN;
@@ -848,10 +918,14 @@
if(cdb->name.re_magic && (!fname || cli_regexec(&cdb->name, fname, 0, NULL, 0) == REG_NOMATCH))
continue;
- *ctx->virname = cdb->virname;
- return CL_VIRUS;
+ cli_append_virus(ctx, cdb->virname);
+ viruses_found++;
+ if(!SCAN_ALL)
+ return CL_VIRUS;
} while((cdb = cdb->next));
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return CL_CLEAN;
}
diff -Nru clamav-0.97.6+dfsg/libclamav/mbox.c clamav-0.97.7+dfsg/libclamav/mbox.c
--- clamav-0.97.6+dfsg/libclamav/mbox.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/mbox.c 2013-03-11 11:23:21.000000000 -0400
@@ -544,10 +544,11 @@
messageDestroy(body);
}
- if((retcode == CL_CLEAN) && ctx->found_possibly_unwanted && (*ctx->virname == NULL)) {
- *ctx->virname = "Heuristics.Phishing.Email";
- ctx->found_possibly_unwanted = 0;
- retcode = CL_VIRUS;
+ if((retcode == CL_CLEAN) && ctx->found_possibly_unwanted &&
+ (*ctx->virname == NULL || SCAN_ALL)) {
+ cli_append_virus(ctx, "Heuristics.Phishing.Email");
+ ctx->found_possibly_unwanted = 0;
+ retcode = CL_VIRUS;
}
cli_dbgmsg("cli_mbox returning %d\n", retcode);
diff -Nru clamav-0.97.6+dfsg/libclamav/others.c clamav-0.97.7+dfsg/libclamav/others.c
--- clamav-0.97.6+dfsg/libclamav/others.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/others.c 2013-03-11 11:23:21.000000000 -0400
@@ -752,6 +752,51 @@
return 0;
}
+void cli_append_virus(cli_ctx * ctx, const char * virname)
+{
+ if (!ctx->virname)
+ return;
+ if (SCAN_ALL) {
+ if (ctx->size_viruses == 0) {
+ ctx->size_viruses = 2;
+ if (!(ctx->virname = malloc(ctx->size_viruses * sizeof(char *)))) {
+ cli_errmsg("cli_append_virus: fails on malloc() - virus %s virname not appended.\n", virname);
+ return;
+ }
+ } else if (ctx->num_viruses+1 == ctx->size_viruses) {
+ ctx->size_viruses *= 2;
+ if ((ctx->virname = realloc((void *)ctx->virname, ctx->size_viruses * sizeof (char *))) == NULL) {
+ cli_errmsg("cli_append_virus: fails on realloc() - virus %s virname not appended.\n", virname);
+ return;
+ }
+ }
+ ctx->virname[ctx->num_viruses++] = virname;
+ ctx->virname[ctx->num_viruses] = NULL;
+ }
+ else
+ *ctx->virname = virname;
+}
+
+const char * cli_get_last_virus(const cli_ctx * ctx)
+{
+ if (!ctx || !ctx->virname || !(*ctx->virname))
+ return NULL;
+
+ if (SCAN_ALL && ctx->num_viruses)
+ return ctx->virname[ctx->num_viruses-1];
+ else
+ return *ctx->virname;
+}
+
+const char * cli_get_last_virus_str(const cli_ctx * ctx)
+{
+ const char * ret;
+ if ((ret = cli_get_last_virus(ctx)))
+ return ret;
+ return "";
+}
+
+
#ifdef C_WINDOWS
/*
* Windows doesn't allow you to delete a directory while it is still open
@@ -955,7 +1000,7 @@
cli_dbgmsg("DUMP&SCAN: File extracted to %s\n", name);
lseek(newfd, 0, SEEK_SET);
if((ret = cli_magic_scandesc(newfd, ctx)) == CL_VIRUS)
- cli_dbgmsg("cli_dumpscan: Infected with %s\n", *ctx->virname);
+ cli_dbgmsg("cli_dumpscan: Infected with %s\n", cli_get_last_virus_str(ctx));
close(newfd);
if(!ctx->engine->keeptmp) {
diff -Nru clamav-0.97.6+dfsg/libclamav/others.h clamav-0.97.7+dfsg/libclamav/others.h
--- clamav-0.97.6+dfsg/libclamav/others.h 2012-08-10 12:02:00.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/others.h 2013-03-11 11:23:21.000000000 -0400
@@ -53,7 +53,7 @@
* in re-enabling affected modules.
*/
-#define CL_FLEVEL 67
+#define CL_FLEVEL 68
#define CL_FLEVEL_DCONF CL_FLEVEL
#define CL_FLEVEL_SIGTOOL CL_FLEVEL
@@ -109,6 +109,8 @@
/* internal clamav context */
typedef struct cli_ctx_tag {
const char **virname;
+ unsigned int num_viruses; /* manages virname when CL_SCAN_ALLMATCHES == 1 */
+ unsigned int size_viruses; /* manages virname when CL_SCAN_ALLMATCHES == 1 */
unsigned long int *scanned;
const struct cli_matcher *root;
const struct cl_engine *engine;
@@ -314,6 +316,7 @@
#define DETECT_BROKEN (ctx->options & CL_SCAN_BLOCKBROKEN)
#define BLOCK_MACROS (ctx->options & CL_SCAN_BLOCKMACROS)
#define SCAN_STRUCTURED (ctx->options & CL_SCAN_STRUCTURED)
+#define SCAN_ALL (ctx->options & CL_SCAN_ALLMATCHES)
/* based on macros from A. Melnikoff */
#define cbswap16(v) (((v & 0xff) << 8) | (((v) >> 8) & 0xff))
@@ -412,6 +415,10 @@
}
#endif
+void cli_append_virus(cli_ctx *ctx, const char *virname);
+const char *cli_get_last_virus(const cli_ctx *ctx);
+const char *cli_get_last_virus_str(const cli_ctx *ctx);
+
/* used by: spin, yc (C) aCaB */
#define __SHIFTBITS(a) (sizeof(a)<<3)
#define __SHIFTMASK(a) (__SHIFTBITS(a)-1)
diff -Nru clamav-0.97.6+dfsg/libclamav/pdf.c clamav-0.97.7+dfsg/libclamav/pdf.c
--- clamav-0.97.6+dfsg/libclamav/pdf.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/pdf.c 2013-03-11 11:23:21.000000000 -0400
@@ -550,7 +550,7 @@
cli_bytecode_context_setpdf(bc_ctx, phase, pdf->nobjs, pdf->objs,
&pdf->flags, pdf->size, pdf->startoff);
cli_bytecode_context_setctx(bc_ctx, ctx);
- ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PDF, map, ctx->virname);
+ ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PDF, map);
cli_bytecode_context_destroy(bc_ctx);
if (fd != -1) {
funmap(map);
@@ -876,6 +876,17 @@
static char *pdf_readstring(const char *q0, int len, const char *key, unsigned *slen);
static int pdf_readint(const char *q0, int len, const char *key);
static const char *pdf_getdict(const char *q0, int* len, const char *key);
+
+static void pdf_parse_trailer(struct pdf_struct *pdf, const char *s, long length)
+{
+ char *newID;
+ newID = pdf_readstring(s, length, "/ID", &pdf->fileIDlen);
+ if (newID) {
+ free(pdf->fileID);
+ pdf->fileID = newID;
+ }
+}
+
static void pdf_parseobj(struct pdf_struct *pdf, struct pdf_obj *obj)
{
/* enough to hold common pdf names, we don't need all the names */
@@ -960,9 +971,9 @@
if (trailer < 0) trailer = 0;
q2 = pdf->map + trailer;
cli_dbgmsg("cli_pdf: looking for trailer in linearized pdf: %ld - %ld\n", trailer, trailer_end);
- pdf->fileID = pdf_readstring(q2, trailer_end - trailer, "/ID", &pdf->fileIDlen);
+ pdf_parse_trailer(pdf, q2, trailer_end - trailer);
if (pdf->fileID)
- cli_dbgmsg("found fileID\n");
+ cli_dbgmsg("cli_pdf: found fileID\n");
}
}
if (objstate == STATE_LAUNCHACTION)
@@ -1281,7 +1292,7 @@
if (!pdf->key)
return;
memcpy(pdf->key, result, pdf->keylen);
- dbg_printhex("md5", result, 32);
+ dbg_printhex("md5", result, 16);
dbg_printhex("Candidate encryption key", pdf->key, pdf->keylen);
/* 7.6.3.3 Algorithm 6 */
@@ -1521,7 +1532,7 @@
pdf.flags |= 1 << ENCRYPTED_PDF;
cli_dbgmsg("cli_pdf: encrypted pdf found, stream will probably fail to decompress!\n");
pdf_parse_encrypt(&pdf, enc, eof - enc);
- pdf.fileID = pdf_readstring(eofmap, bytesleft, "/ID", &pdf.fileIDlen);
+ pdf_parse_trailer(&pdf, eofmap, bytesleft);
}
q += 9;
while (q < eof && (*q == ' ' || *q == '\n' || *q == '\r')) { q++; }
@@ -1553,7 +1564,7 @@
/* parse PDF and find obj offsets */
while ((rc = pdf_findobj(&pdf)) > 0) {
struct pdf_obj *obj = &pdf.objs[pdf.nobjs-1];
- cli_dbgmsg("found %d %d obj @%ld\n", obj->id >> 8, obj->id&0xff, obj->start + offset);
+ cli_dbgmsg("cli_pdf: found %d %d obj @%ld\n", obj->id >> 8, obj->id&0xff, obj->start + offset);
}
if (pdf.nobjs)
pdf.nobjs--;
@@ -1574,7 +1585,7 @@
/* It is encrypted, and a password/key needs to be supplied to decrypt.
* This doesn't trigger for PDFs that are encrypted but don't need
* a password to decrypt */
- *ctx->virname = "Heuristics.Encrypted.PDF";
+ cli_append_virus(ctx, "Heuristics.Encrypted.PDF");
rc = CL_VIRUS;
}
@@ -1596,7 +1607,7 @@
if (!rc && (ctx->options & CL_SCAN_ALGORITHMIC)) {
if (pdf.flags & (1 << ESCAPED_COMMON_PDFNAME)) {
/* for example /Fl#61te#44#65#63#6f#64#65 instead of /FlateDecode */
- *ctx->virname = "Heuristics.PDF.ObfuscatedNameObject";
+ cli_append_virus(ctx, "Heuristics.PDF.ObfuscatedNameObject");
rc = cli_found_possibly_unwanted(ctx);
}
}
@@ -2260,7 +2271,7 @@
while(len > 0) {
int byte = (len--) ? (int)*ptr++ : EOF;
- if((byte == '~') && (*ptr == '>'))
+ if((byte == '~') && (len > 0) && (*ptr == '>'))
byte = EOF;
if(byte >= '!' && byte <= 'u') {
@@ -2276,7 +2287,7 @@
}
} else if(byte == 'z') {
if(quintet) {
- cli_dbgmsg("ascii85decode: unexpected 'z'\n");
+ cli_dbgmsg("cli_pdf: ascii85decode: unexpected 'z'\n");
return -1;
}
*output++ = '\0';
@@ -2285,12 +2296,12 @@
*output++ = '\0';
ret += 4;
} else if(byte == EOF) {
- cli_dbgmsg("ascii85decode: quintet %d\n", quintet);
+ cli_dbgmsg("cli_pdf: ascii85decode: quintet %d\n", quintet);
if(quintet) {
int i;
if(quintet == 1) {
- cli_dbgmsg("ascii85Decode: only 1 byte in last quintet\n");
+ cli_dbgmsg("cli_pdf: ascii85Decode: only 1 byte in last quintet\n");
return -1;
}
for(i = quintet; i < 5; i++)
@@ -2304,7 +2315,7 @@
}
break;
} else if(!isspace(byte)) {
- cli_dbgmsg("ascii85Decode: invalid character 0x%x, len %lu\n",
+ cli_dbgmsg("cli_pdf: ascii85Decode: invalid character 0x%x, len %lu\n",
byte & 0xFF, (unsigned long)len);
return -1;
}
diff -Nru clamav-0.97.6+dfsg/libclamav/pe.c clamav-0.97.7+dfsg/libclamav/pe.c
--- clamav-0.97.6+dfsg/libclamav/pe.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/pe.c 2013-03-11 11:23:21.000000000 -0400
@@ -534,6 +534,8 @@
#ifdef HAVE__INTERNAL__SHA_COLLECT
int sha_collect = ctx->sha_collect;
#endif
+ const char * virname = NULL;
+ uint32_t viruses_found = 0;
if(!ctx) {
cli_errmsg("cli_scanpe: ctx == NULL\n");
@@ -554,8 +556,7 @@
cli_dbgmsg("Can't read new header address\n");
/* truncated header? */
if(DETECT_BROKEN_PE) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN;
@@ -684,8 +685,7 @@
nsections = EC16(file_hdr.NumberOfSections);
if(nsections < 1 || nsections > 96) {
if(DETECT_BROKEN_PE) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS;
}
if(!ctx->corrupted_input) {
@@ -706,8 +706,7 @@
if (EC16(file_hdr.SizeOfOptionalHeader) < sizeof(struct pe_image_optional_hdr32)) {
cli_dbgmsg("SizeOfOptionalHeader too small\n");
if(DETECT_BROKEN_PE) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN;
@@ -717,8 +716,7 @@
if(fmap_readn(map, &optional_hdr32, at, sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr32)) {
cli_dbgmsg("Can't read optional file header\n");
if(DETECT_BROKEN_PE) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN;
@@ -731,8 +729,7 @@
/* FIXME: need to play around a bit more with xp64 */
cli_dbgmsg("Incorrect SizeOfOptionalHeader for PE32+\n");
if(DETECT_BROKEN_PE) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN;
@@ -774,8 +771,7 @@
if(fmap_readn(map, &optional_hdr32 + 1, at, sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) != sizeof(struct pe_image_optional_hdr64) - sizeof(struct pe_image_optional_hdr32)) {
cli_dbgmsg("Can't read optional file header\n");
if(DETECT_BROKEN_PE) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN;
@@ -855,15 +851,13 @@
if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment)) || (pe_plus?EC32(optional_hdr64.SectionAlignment):EC32(optional_hdr32.SectionAlignment))%0x1000)) {
cli_dbgmsg("Bad virtual alignemnt\n");
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS;
}
if (DETECT_BROKEN_PE && !native && (!(pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment)) || (pe_plus?EC32(optional_hdr64.FileAlignment):EC32(optional_hdr32.FileAlignment))%0x200)) {
cli_dbgmsg("Bad file alignemnt\n");
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
@@ -893,8 +887,7 @@
free(section_hdr);
free(exe_sections);
if(DETECT_BROKEN_PE) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN;
@@ -961,8 +954,7 @@
if (DETECT_BROKEN_PE && (!valign || (exe_sections[i].urva % valign))) { /* Bad virtual alignment */
cli_dbgmsg("VirtualAddress is misaligned\n");
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
free(section_hdr);
free(exe_sections);
return CL_VIRUS;
@@ -974,8 +966,7 @@
free(section_hdr);
free(exe_sections);
if(DETECT_BROKEN_PE) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN; /* no ninjas to see here! move along! */
@@ -989,12 +980,16 @@
unsigned char md5_dig[16];
if(cli_hm_have_size(md5_sect, CLI_HASH_MD5, exe_sections[i].rsz) &&
cli_md5sect(map, &exe_sections[i], md5_dig) &&
- cli_hm_scan(md5_dig, exe_sections[i].rsz, ctx->virname, md5_sect, CLI_HASH_MD5) == CL_VIRUS) {
+ cli_hm_scan(md5_dig, exe_sections[i].rsz, &virname, md5_sect, CLI_HASH_MD5) == CL_VIRUS) {
+ cli_append_virus(ctx, virname);
if(cli_hm_scan(md5_dig, fsize, NULL, ctx->engine->hm_fp, CLI_HASH_MD5) != CL_VIRUS) {
- free(section_hdr);
- free(exe_sections);
- return CL_VIRUS;
+ if (!SCAN_ALL) {
+ free(section_hdr);
+ free(exe_sections);
+ return CL_VIRUS;
+ }
}
+ viruses_found++;
}
}
@@ -1005,8 +1000,7 @@
free(section_hdr);
free(exe_sections);
if(DETECT_BROKEN_PE) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN;
@@ -1015,8 +1009,7 @@
if(!i) {
if (DETECT_BROKEN_PE && exe_sections[i].urva!=hdr_size) { /* Bad first section RVA */
cli_dbgmsg("First section is in the wrong place\n");
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
free(section_hdr);
free(exe_sections);
return CL_VIRUS;
@@ -1026,8 +1019,7 @@
} else {
if (DETECT_BROKEN_PE && exe_sections[i].urva - exe_sections[i-1].urva != exe_sections[i-1].vsz) { /* No holes, no overlapping, no virtual disorder */
cli_dbgmsg("Virtually misplaced section (wrong order, overlapping, non contiguous)\n");
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx, "Heuristics.Broken.Executable");
free(section_hdr);
free(exe_sections);
return CL_VIRUS;
@@ -1048,8 +1040,7 @@
cli_dbgmsg("EntryPoint out of file\n");
free(exe_sections);
if(DETECT_BROKEN_PE) {
- if(ctx->virname)
- *ctx->virname = "Heuristics.Broken.Executable";
+ cli_append_virus(ctx,"Heuristics.Broken.Executable");
return CL_VIRUS;
}
return CL_CLEAN;
@@ -1109,7 +1100,7 @@
}
cli_bytecode_context_setpe(bc_ctx, &pedata, exe_sections);
cli_bytecode_context_setctx(bc_ctx, ctx);
- ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_ALL, map, ctx->virname);
+ ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_ALL, map);
if (ret == CL_VIRUS || ret == CL_BREAK) {
free(exe_sections);
cli_bytecode_context_destroy(bc_ctx);
@@ -1125,9 +1116,12 @@
if(pt) {
pt += 15;
if((((uint32_t)cli_readint32(pt) ^ (uint32_t)cli_readint32(pt + 4)) == 0x505a4f) && (((uint32_t)cli_readint32(pt + 8) ^ (uint32_t)cli_readint32(pt + 12)) == 0xffffb) && (((uint32_t)cli_readint32(pt + 16) ^ (uint32_t)cli_readint32(pt + 20)) == 0xb8)) {
- *ctx->virname = "Heuristics.W32.Parite.B";
- free(exe_sections);
- return CL_VIRUS;
+ cli_append_virus(ctx,"Heuristics.W32.Parite.B");
+ if (!SCAN_ALL) {
+ free(exe_sections);
+ return CL_VIRUS;
+ }
+ viruses_found++;
}
}
}
@@ -1208,9 +1202,11 @@
break;
case KZSLOOP:
if (op==kzdsize+0x48 && *kzcode==0x75 && kzlen-(int8_t)kzcode[1]-3<=kzinitlen && kzlen-(int8_t)kzcode[1]>=kzxorlen) {
- *ctx->virname = "Heuristics.W32.Kriz";
+ cli_append_virus(ctx,"Heuristics.W32.Kriz");
free(exe_sections);
- return CL_VIRUS;
+ if (!SCAN_ALL)
+ return CL_VIRUS;
+ viruses_found++;
}
cli_dbgmsg("kriz: loop out of bounds, corrupted sample?\n");
kzstate++;
@@ -1235,10 +1231,12 @@
if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
if(cli_memstr(tbuff, 4091, "\xe8\x2c\x61\x00\x00", 5)) {
- *ctx->virname = dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A";
+ cli_append_virus(ctx, dam ? "Heuristics.W32.Magistr.A.dam" : "Heuristics.W32.Magistr.A");
free(exe_sections);
- return CL_VIRUS;
- }
+ if (!SCAN_ALL)
+ return CL_VIRUS;
+ viruses_found++;
+ }
}
} else if(rsize >= 0x7000 && vsize >= 0x7000 && ((vsize & 0xff) == 0xed)) {
@@ -1247,9 +1245,11 @@
if((tbuff = fmap_need_off_once(map, exe_sections[nsections - 1].raw + rsize - bw, 4096))) {
if(cli_memstr(tbuff, 4091, "\xe8\x04\x72\x00\x00", 5)) {
- *ctx->virname = dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B";
+ cli_append_virus(ctx,dam ? "Heuristics.W32.Magistr.B.dam" : "Heuristics.W32.Magistr.B");
free(exe_sections);
- return CL_VIRUS;
+ if (!SCAN_ALL)
+ return CL_VIRUS;
+ viruses_found++;
}
}
}
@@ -1295,10 +1295,12 @@
for(i=0;i<xsjs;i++) {
if(!(code = fmap_need_off_once(map, jumps[i], 9))) continue;
if((jump=cli_readint32(code))==0x60ec8b55 || (code[4]==0x0ec && ((jump==0x83ec8b55 && code[6]==0x60) || (jump==0x81ec8b55 && !code[7] && !code[8])))) {
- *ctx->virname = "Heuristics.W32.Polipos.A";
+ cli_append_virus(ctx,"Heuristics.W32.Polipos.A");
free(jumps);
free(exe_sections);
- return CL_VIRUS;
+ if (!SCAN_ALL)
+ return CL_VIRUS;
+ viruses_found++;
}
}
free(jumps);
@@ -1317,13 +1319,16 @@
else {
cli_parseres_special(EC32(dirs[2].VirtualAddress), EC32(dirs[2].VirtualAddress), map, exe_sections, nsections, fsize, hdr_size, 0, 0, &m, stats);
if ((ret = cli_detect_swizz(stats)) == CL_VIRUS) {
- *ctx->virname = "Heuristics.Trojan.Swizzor.Gen";
+ cli_append_virus(ctx,"Heuristics.Trojan.Swizzor.Gen");
}
free(stats);
}
if (ret != CL_CLEAN) {
+ if (!(ret == CL_VIRUS && SCAN_ALL)) {
free(exe_sections);
return ret;
+ }
+ viruses_found++;
}
}
}
@@ -2080,23 +2085,23 @@
!memcmp(epbuff+0x63+offset, "\xaa\xe2\xcc", 3) &&
(fsize >= exe_sections[nsections-1].raw + 0xC6 + ecx + offset)) {
- char *spinned;
+ char *spinned;
- if((spinned = (char *) cli_malloc(fsize)) == NULL) {
- free(exe_sections);
- return CL_EMEM;
- }
+ if((spinned = (char *) cli_malloc(fsize)) == NULL) {
+ free(exe_sections);
+ return CL_EMEM;
+ }
- if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
- cli_dbgmsg("yC: Can't read %lu bytes\n", (unsigned long)fsize);
- free(spinned);
- free(exe_sections);
- return CL_EREAD;
- }
+ if((size_t) fmap_readn(map, spinned, 0, fsize) != fsize) {
+ cli_dbgmsg("yC: Can't read %lu bytes\n", (unsigned long)fsize);
+ free(spinned);
+ free(exe_sections);
+ return CL_EREAD;
+ }
- cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset);
- CLI_UNPTEMP("yC",(spinned,exe_sections,0));
- CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0));
+ cli_dbgmsg("%d,%d,%d,%d\n", nsections-1, e_lfanew, ecx, offset);
+ CLI_UNPTEMP("yC",(spinned,exe_sections,0));
+ CLI_UNPRESULTS("yC",(yc_decrypt(spinned, fsize, exe_sections, nsections-1, e_lfanew, ndesc, ecx, offset)),0,(spinned,0));
}
}
@@ -2271,7 +2276,7 @@
}
cli_bytecode_context_setpe(bc_ctx, &pedata, exe_sections);
cli_bytecode_context_setctx(bc_ctx, ctx);
- ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_UNPACKER, map, ctx->virname);
+ ret = cli_bytecode_runhook(ctx, ctx->engine, bc_ctx, BC_PE_UNPACKER, map);
switch (ret) {
case CL_VIRUS:
free(exe_sections);
@@ -2289,6 +2294,8 @@
}
free(exe_sections);
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return CL_CLEAN;
}
diff -Nru clamav-0.97.6+dfsg/libclamav/pe_icons.c clamav-0.97.7+dfsg/libclamav/pe_icons.c
--- clamav-0.97.6+dfsg/libclamav/pe_icons.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/pe_icons.c 2013-03-11 11:23:21.000000000 -0400
@@ -1512,8 +1512,7 @@
if(confidence >= positivematch) {
cli_dbgmsg("confidence: %u\n", confidence);
- if(ctx->virname)
- *ctx->virname = matcher->icons[enginesize][x].name;
+ cli_append_virus(ctx,matcher->icons[enginesize][x].name);
return CL_VIRUS;
}
}
diff -Nru clamav-0.97.6+dfsg/libclamav/phishcheck.c clamav-0.97.7+dfsg/libclamav/phishcheck.c
--- clamav-0.97.6+dfsg/libclamav/phishcheck.c 2012-06-12 09:03:27.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/phishcheck.c 2013-03-11 11:23:21.000000000 -0400
@@ -735,7 +735,7 @@
if(!pchk || pchk->is_disabled)
return CL_CLEAN;
- if(!ctx->found_possibly_unwanted)
+ if(!ctx->found_possibly_unwanted && !SCAN_ALL)
*ctx->virname=NULL;
#if 0
FILE *f = fopen("/home/edwin/quarantine/urls","r");
@@ -810,29 +810,29 @@
case CL_PHISH_CLEAN:
continue;
case CL_PHISH_NUMERIC_IP:
- *ctx->virname="Heuristics.Phishing.Email.Cloaked.NumericIP";
+ cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.NumericIP");
break;
case CL_PHISH_CLOAKED_NULL:
- *ctx->virname="Heuristics.Phishing.Email.Cloaked.Null";/*fakesite%01%00@fake.example.com*/
+ cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.Null");/*fakesite%01%00@fake.example.com*/
break;
case CL_PHISH_SSL_SPOOF:
- *ctx->virname="Heuristics.Phishing.Email.SSL-Spoof";
+ cli_append_virus(ctx, "Heuristics.Phishing.Email.SSL-Spoof");
break;
case CL_PHISH_CLOAKED_UIU:
- *ctx->virname="Heuristics.Phishing.Email.Cloaked.Username";/*http://banksite@fake.example.com*/
+ cli_append_virus(ctx, "Heuristics.Phishing.Email.Cloaked.Username");/*http://banksite@fake.example.com*/
break;
case CL_PHISH_HASH0:
- *ctx->virname="Heuristics.Safebrowsing.Suspected-malware_safebrowsing.clamav.net";
+ cli_append_virus(ctx, "Heuristics.Safebrowsing.Suspected-malware_safebrowsing.clamav.net");
break;
case CL_PHISH_HASH1:
- *ctx->virname="Heuristics.Phishing.URL.Blacklisted";
+ cli_append_virus(ctx, "Heuristics.Phishing.URL.Blacklisted");
break;
case CL_PHISH_HASH2:
- *ctx->virname="Heuristics.Safebrowsing.Suspected-phishing_safebrowsing.clamav.net";
+ cli_append_virus(ctx, "Heuristics.Safebrowsing.Suspected-phishing_safebrowsing.clamav.net");
break;
case CL_PHISH_NOMATCH:
default:
- *ctx->virname="Heuristics.Phishing.Email.SpoofedDomain";
+ cli_append_virus(ctx, "Heuristics.Phishing.Email.SpoofedDomain");
break;
}
return cli_found_possibly_unwanted(ctx);
@@ -1207,14 +1207,14 @@
cli_dbgmsg("Looking up hash %s for %s(%u)%s(%u)\n", h, host, (unsigned)hlen, path, (unsigned)plen);
#if 0
if (prefix_matched) {
- if (cli_bm_scanbuff(sha256_dig, 4, &virname, NULL, &rlist->hostkey_prefix,0,NULL,NULL) == CL_VIRUS) {
+ if (cli_bm_scanbuff(sha256_dig, 4, &virname, NULL, &rlist->hostkey_prefix,0,NULL,NULL,NULL) == CL_VIRUS) {
cli_dbgmsg("prefix matched\n");
*prefix_matched = 1;
} else
return CL_SUCCESS;
}
#endif
- if (cli_bm_scanbuff(sha256_dig, 32, &virname, NULL, &rlist->sha256_hashes,0,NULL,NULL) == CL_VIRUS) {
+ if (cli_bm_scanbuff(sha256_dig, 32, &virname, NULL, &rlist->sha256_hashes,0,NULL,NULL,NULL) == CL_VIRUS) {
cli_dbgmsg("This hash matched: %s\n", h);
switch(*virname) {
case 'W':
diff -Nru clamav-0.97.6+dfsg/libclamav/readdb.c clamav-0.97.7+dfsg/libclamav/readdb.c
--- clamav-0.97.6+dfsg/libclamav/readdb.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/readdb.c 2013-03-11 11:23:21.000000000 -0400
@@ -468,7 +468,7 @@
if(!ignored || !signame || !entry)
return 0;
- if(cli_bm_scanbuff((const unsigned char *) signame, strlen(signame), &md5_expected, NULL, ignored, 0, NULL, NULL) == CL_VIRUS) {
+ if(cli_bm_scanbuff((const unsigned char *) signame, strlen(signame), &md5_expected, NULL, ignored, 0, NULL, NULL,NULL) == CL_VIRUS) {
if(md5_expected) {
cli_md5_init(&md5ctx);
cli_md5_update(&md5ctx, entry, strlen(entry));
diff -Nru clamav-0.97.6+dfsg/libclamav/regex_list.c clamav-0.97.7+dfsg/libclamav/regex_list.c
--- clamav-0.97.6+dfsg/libclamav/regex_list.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/regex_list.c 2013-03-11 11:23:21.000000000 -0400
@@ -357,7 +357,7 @@
if (fl != 'W' && pat->length == 32 &&
cli_hashset_contains(&matcher->sha256_pfx_set, cli_readint32(pat->pattern)) &&
- cli_bm_scanbuff(pat->pattern, 32, &vname, NULL, &matcher->sha256_hashes,0,NULL,NULL) == CL_VIRUS) {
+ cli_bm_scanbuff(pat->pattern, 32, &vname, NULL, &matcher->sha256_hashes,0,NULL,NULL,NULL) == CL_VIRUS) {
if (*vname == 'W') {
/* hash is whitelisted in local.gdb */
cli_dbgmsg("Skipping hash %s\n", pattern);
diff -Nru clamav-0.97.6+dfsg/libclamav/scanners.c clamav-0.97.7+dfsg/libclamav/scanners.c
--- clamav-0.97.6+dfsg/libclamav/scanners.c 2012-08-06 16:26:55.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/scanners.c 2013-03-11 11:23:21.000000000 -0400
@@ -111,7 +111,7 @@
#endif
struct stat statbuf;
char *fname;
-
+ unsigned int viruses_found = 0;
if((dd = opendir(dirname)) != NULL) {
#ifdef HAVE_READDIR_R_3
@@ -138,16 +138,28 @@
if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) {
if(cli_scandir(fname, ctx) == CL_VIRUS) {
free(fname);
- closedir(dd);
- return CL_VIRUS;
- }
+
+ if (SCAN_ALL) {
+ viruses_found++;
+ continue;
+ }
+
+ closedir(dd);
+ return CL_VIRUS;
+ }
} else {
if(S_ISREG(statbuf.st_mode)) {
if(cli_scanfile(fname, ctx) == CL_VIRUS) {
free(fname);
- closedir(dd);
- return CL_VIRUS;
- }
+
+ if (SCAN_ALL) {
+ viruses_found++;
+ continue;
+ }
+
+ closedir(dd);
+ return CL_VIRUS;
+ }
}
}
}
@@ -161,6 +173,8 @@
}
closedir(dd);
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return CL_CLEAN;
}
@@ -188,7 +202,7 @@
lseek(desc, 0, SEEK_SET);
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
if(ret != CL_VIRUS) {
- *ctx->virname = "Heuristics.Encrypted.RAR";
+ cli_append_virus(ctx, "Heuristics.Encrypted.RAR");
return CL_VIRUS;
}
}
@@ -202,7 +216,7 @@
unrar_metadata_t *metadata, *metadata_tmp;
char *dir;
unrar_state_t rar_state;
-
+ unsigned int viruses_found = 0;
cli_dbgmsg("in scanrar()\n");
@@ -230,7 +244,7 @@
lseek(desc, 0, SEEK_SET);
ret = cli_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, NULL);
if(ret != CL_VIRUS)
- *ctx->virname = "Heuristics.Encrypted.RAR";
+ cli_append_virus(ctx, "Heuristics.Encrypted.RAR");
return CL_VIRUS;
}
return CL_CLEAN;
@@ -280,12 +294,19 @@
if(!ctx->engine->keeptmp)
if (cli_unlink(rar_state.filename)) ret = CL_EUNLINK;
if(rc == CL_VIRUS ) {
- cli_dbgmsg("RAR: infected with %s\n",*ctx->virname);
+ cli_dbgmsg("RAR: infected with %s\n", cli_get_last_virus(ctx));
ret = CL_VIRUS;
- break;
+ viruses_found++;
}
}
+ if(ret == CL_VIRUS) {
+ if(SCAN_ALL)
+ ret = CL_SUCCESS;
+ else
+ break;
+ }
+
if(ret == CL_SUCCESS)
ret = cli_unrar_scanmetadata(desc,rar_state.metadata_tail, ctx, rar_state.file_count, sfx_check);
@@ -315,6 +336,8 @@
}
cli_dbgmsg("RAR: Exit code: %d\n", ret);
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return ret;
}
@@ -370,7 +393,7 @@
rc = cli_magic_scandesc(metadata.ofd, ctx);
close(metadata.ofd);
if (rc == CL_VIRUS) {
- cli_dbgmsg("ARJ: infected with %s\n",*ctx->virname);
+ cli_dbgmsg("ARJ: infected with %s\n", cli_get_last_virus(ctx));
ret = CL_VIRUS;
if (metadata.filename) {
free(metadata.filename);
@@ -443,7 +466,7 @@
gzclose(gz);
if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) {
- cli_dbgmsg("GZip: Infected with %s\n", *ctx->virname);
+ cli_dbgmsg("GZip: Infected with %s\n", cli_get_last_virus(ctx));
close(fd);
if(!ctx->engine->keeptmp) {
if (cli_unlink(tmpname)) {
@@ -535,7 +558,7 @@
inflateEnd(&z);
if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS) {
- cli_dbgmsg("GZip: Infected with %s\n", *ctx->virname);
+ cli_dbgmsg("GZip: Infected with %s\n", cli_get_last_virus(ctx));
close(fd);
if(!ctx->engine->keeptmp) {
if (cli_unlink(tmpname)) {
@@ -652,7 +675,7 @@
lseek(fd, 0, SEEK_SET);
if((ret = cli_magic_scandesc(fd, ctx)) == CL_VIRUS ) {
- cli_dbgmsg("Bzip: Infected with %s\n", *ctx->virname);
+ cli_dbgmsg("Bzip: Infected with %s\n", cli_get_last_virus(ctx));
}
close(fd);
if(!ctx->engine->keeptmp)
@@ -707,7 +730,7 @@
struct cab_archive cab;
struct cab_file *file;
unsigned int corrupted_input;
-
+ unsigned int viruses_found = 0;
cli_dbgmsg("in cli_scanmscab()\n");
@@ -718,8 +741,11 @@
files++;
if(cli_matchmeta(ctx, file->name, 0, file->length, 0, files, 0, NULL) == CL_VIRUS) {
- ret = CL_VIRUS;
- break;
+ if (!SCAN_ALL) {
+ ret = CL_VIRUS;
+ break;
+ }
+ viruses_found++;
}
if(ctx->engine->maxscansize && ctx->scansize >= ctx->engine->maxscansize) {
@@ -758,11 +784,17 @@
}
}
free(tempname);
- if(ret == CL_VIRUS)
- break;
+ if(ret == CL_VIRUS) {
+ if (SCAN_ALL)
+ viruses_found++;
+ else
+ break;
+ }
}
cab_free(&cab);
+ if (viruses_found)
+ return CL_VIRUS;
return ret;
}
@@ -773,6 +805,7 @@
struct cli_ac_data gmdata, tmdata;
struct cli_ac_data *mdata[2];
int ret;
+ unsigned int viruses_found = 0;
if((ret = cli_ac_initdata(&tmdata, troot->ac_partsigs, troot->ac_lsigs, troot->ac_reloff_num, CLI_DEFAULT_AC_TRACKLEN)))
return ret;
@@ -786,14 +819,20 @@
ret = cli_scanbuff(data, len, 0, ctx, CL_TYPE_MSOLE2, mdata);
- if(ret != CL_VIRUS) {
+ if(ret != CL_VIRUS || SCAN_ALL) {
+ if (SCAN_ALL)
+ viruses_found++;
ret = cli_lsig_eval(ctx, troot, &tmdata, NULL, NULL);
- if(ret != CL_VIRUS)
+ if(ret != CL_VIRUS || SCAN_ALL)
+ if (SCAN_ALL)
+ viruses_found++;
ret = cli_lsig_eval(ctx, groot, &gmdata, NULL, NULL);
}
cli_ac_freedata(&tmdata);
cli_ac_freedata(&gmdata);
+ if (viruses_found)
+ return CL_VIRUS;
return ret;
}
@@ -814,6 +853,7 @@
unsigned char *data;
char *hash;
uint32_t hashcnt;
+ unsigned int viruses_found = 0;
cli_dbgmsg("VBADir: %s\n", dirname);
@@ -838,9 +878,13 @@
if(ctx->scanned)
*ctx->scanned += data_len / CL_COUNT_PRECISION;
if(vba_scandata(data, data_len, ctx) == CL_VIRUS) {
- free(data);
- ret = CL_VIRUS;
- break;
+ if (SCAN_ALL)
+ viruses_found++;
+ else {
+ free(data);
+ ret = CL_VIRUS;
+ break;
+ }
}
free(data);
}
@@ -852,10 +896,12 @@
free(vba_project->dir);
free(vba_project->offset);
free(vba_project);
- if (ret == CL_VIRUS) break;
+ if (ret == CL_VIRUS && !SCAN_ALL)
+ break;
}
- if(ret == CL_CLEAN && (hashcnt = uniq_get(U, "powerpoint document", 19, &hash))) {
+ if((ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) &&
+ (hashcnt = uniq_get(U, "powerpoint document", 19, &hash))) {
while(hashcnt--) {
snprintf(vbaname, 1024, "%s"PATHSEP"%s_%u", dirname, hash, hashcnt);
vbaname[sizeof(vbaname)-1] = '\0';
@@ -864,6 +910,7 @@
if ((fullname = cli_ppt_vba_read(fd, ctx))) {
if(cli_scandir(fullname, ctx) == CL_VIRUS) {
ret = CL_VIRUS;
+ viruses_found++;
}
if(!ctx->engine->keeptmp)
cli_rmdirs(fullname);
@@ -873,7 +920,8 @@
}
}
- if (ret == CL_CLEAN && (hashcnt = uniq_get(U, "worddocument", 12, &hash))) {
+ if ((ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) &&
+ (hashcnt = uniq_get(U, "worddocument", 12, &hash))) {
while(hashcnt--) {
snprintf(vbaname, sizeof(vbaname), "%s"PATHSEP"%s_%u", dirname, hash, hashcnt);
vbaname[sizeof(vbaname)-1] = '\0';
@@ -895,9 +943,13 @@
if(ctx->scanned)
*ctx->scanned += vba_project->length[i] / CL_COUNT_PRECISION;
if(vba_scandata(data, vba_project->length[i], ctx) == CL_VIRUS) {
+ if (SCAN_ALL)
+ viruses_found++;
+ else {
free(data);
ret = CL_VIRUS;
break;
+ }
}
free(data);
}
@@ -911,11 +963,16 @@
free(vba_project->key);
free(vba_project->length);
free(vba_project);
- if(ret == CL_VIRUS) break;
+ if(ret == CL_VIRUS) {
+ if (SCAN_ALL)
+ viruses_found++;
+ else
+ break;
+ }
}
}
- if(ret != CL_CLEAN)
+ if(ret != CL_CLEAN && !(ret == CL_VIRUS && SCAN_ALL))
return ret;
/* Check directory for embedded OLE objects */
@@ -928,7 +985,7 @@
if (fd >= 0) {
ret = cli_scan_ole10(fd, ctx);
close(fd);
- if(ret != CL_CLEAN)
+ if(ret != CL_CLEAN && !(ret == CL_VIRUS && SCAN_ALL))
return ret;
}
}
@@ -961,10 +1018,14 @@
if(lstat(fullname, &statbuf) != -1) {
if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode))
if (cli_vba_scandir(fullname, ctx, U) == CL_VIRUS) {
- ret = CL_VIRUS;
- free(fullname);
- break;
- }
+ if (SCAN_ALL)
+ viruses_found++;
+ else {
+ ret = CL_VIRUS;
+ free(fullname);
+ break;
+ }
+ }
}
free(fullname);
}
@@ -977,9 +1038,12 @@
closedir(dd);
if(BLOCK_MACROS && hasmacros) {
- *ctx->virname = "Heuristics.OLE2.ContainsMacros";
+ cli_append_virus(ctx, "Heuristics.OLE2.ContainsMacros");
ret = CL_VIRUS;
+ viruses_found++;
}
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return ret;
}
@@ -988,6 +1052,7 @@
char *tempname, fullname[1024];
int ret=CL_CLEAN, fd;
fmap_t *map = *ctx->fmap;
+ unsigned int viruses_found = 0;
cli_dbgmsg("in cli_scanhtml()\n");
@@ -1015,35 +1080,38 @@
snprintf(fullname, 1024, "%s"PATHSEP"nocomment.html", tempname);
fd = open(fullname, O_RDONLY|O_BINARY);
if (fd >= 0) {
- ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL);
- close(fd);
+ if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS)
+ viruses_found++;
+ close(fd);
}
- if(ret == CL_CLEAN && map->len < 2097152) {
+ if((ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) && map->len < 2097152) {
/* limit to 2 MB, we're not interesting in scanning large files in notags form */
/* TODO: don't even create notags if file is over 2 MB */
snprintf(fullname, 1024, "%s"PATHSEP"notags.html", tempname);
fd = open(fullname, O_RDONLY|O_BINARY);
if(fd >= 0) {
- ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL);
- close(fd);
+ if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS)
+ viruses_found++;
+ close(fd);
}
}
- if(ret == CL_CLEAN) {
+ if(ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) {
snprintf(fullname, 1024, "%s"PATHSEP"javascript", tempname);
fd = open(fullname, O_RDONLY|O_BINARY);
if(fd >= 0) {
- ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL);
- if (ret == CL_CLEAN) {
- lseek(fd, 0, SEEK_SET);
- ret = cli_scandesc(fd, ctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR, NULL);
- }
- close(fd);
+ if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS)
+ viruses_found++;
+ if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) {
+ if ((ret = cli_scandesc(fd, ctx, CL_TYPE_TEXT_ASCII, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS)
+ viruses_found++;
+ }
+ close(fd);
}
}
- if (ret == CL_CLEAN) {
+ if (ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) {
snprintf(fullname, 1024, "%s"PATHSEP"rfc2397", tempname);
ret = cli_scandir(fullname, ctx);
}
@@ -1052,6 +1120,8 @@
cli_rmdirs(tempname);
free(tempname);
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return ret;
}
@@ -1069,6 +1139,7 @@
struct cli_ac_data *mdata[2];
fmap_t *map = *ctx->fmap;
size_t at = 0;
+ unsigned int viruses_found = 0;
cli_dbgmsg("in cli_scanscript()\n");
@@ -1119,8 +1190,12 @@
}
/* when we flush the buffer also scan */
if(cli_scanbuff(state.out, state.out_pos, offset, ctx, CL_TYPE_TEXT_ASCII, mdata) == CL_VIRUS) {
- ret = CL_VIRUS;
- break;
+ if (SCAN_ALL)
+ viruses_found++;
+ else {
+ ret = CL_VIRUS;
+ break;
+ }
}
if(ctx->scanned)
*ctx->scanned += state.out_pos / CL_COUNT_PRECISION;
@@ -1141,14 +1216,18 @@
close(ofd);
}
free(normalized);
- if(ret != CL_VIRUS) {
- ret = cli_lsig_eval(ctx, troot, &tmdata, NULL, NULL);
- if(ret != CL_VIRUS)
- ret = cli_lsig_eval(ctx, groot, &gmdata, NULL, NULL);
+ if(ret != CL_VIRUS || SCAN_ALL) {
+ if ((ret = cli_lsig_eval(ctx, troot, &tmdata, NULL, NULL)) == CL_VIRUS)
+ viruses_found++;
+ if(ret != CL_VIRUS || SCAN_ALL)
+ if ((ret = cli_lsig_eval(ctx, groot, &gmdata, NULL, NULL)) == CL_VIRUS)
+ viruses_found++;
}
cli_ac_freedata(&tmdata);
cli_ac_freedata(&gmdata);
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return ret;
}
@@ -1293,6 +1372,7 @@
int ret = CL_CLEAN, rc;
chm_metadata_t metadata;
char *dir;
+ unsigned int viruses_found = 0;
cli_dbgmsg("in cli_scanmschm()\n");
@@ -1326,9 +1406,13 @@
rc = cli_magic_scandesc(metadata.ofd, ctx);
close(metadata.ofd);
if (rc == CL_VIRUS) {
- cli_dbgmsg("CHM: infected with %s\n",*ctx->virname);
- ret = CL_VIRUS;
- break;
+ cli_dbgmsg("CHM: infected with %s\n", cli_get_last_virus(ctx));
+ if (SCAN_ALL)
+ viruses_found++;
+ else {
+ ret = CL_VIRUS;
+ break;
+ }
}
}
@@ -1345,6 +1429,8 @@
if (ret == CL_BREAK)
ret = CL_CLEAN;
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return ret;
}
@@ -1380,7 +1466,7 @@
if(cli_check_riff_exploit(desc) == 2) {
ret = CL_VIRUS;
- *ctx->virname = "Heuristics.Exploit.W32.MS05-002";
+ cli_append_virus(ctx, "Heuristics.Exploit.W32.MS05-002");
}
return ret;
@@ -1392,7 +1478,7 @@
if(cli_check_jpeg_exploit(desc, ctx) == 1) {
ret = CL_VIRUS;
- *ctx->virname = "Heuristics.Exploit.W32.MS04-028";
+ cli_append_virus(ctx, "Heuristics.Exploit.W32.MS04-028");
}
return ret;
@@ -1470,7 +1556,7 @@
cli_dbgmsg("CryptFF: Scanning decrypted data\n");
if((ret = cli_magic_scandesc(ndesc, ctx)) == CL_VIRUS)
- cli_dbgmsg("CryptFF: Infected with %s\n", *ctx->virname);
+ cli_dbgmsg("CryptFF: Infected with %s\n", cli_get_last_virus_str(ctx));
close(ndesc);
@@ -1562,7 +1648,7 @@
{
char *dir;
int ret;
-
+ unsigned int viruses_found = 0;
cli_dbgmsg("Starting cli_scanmail(), recursion = %u\n", ctx->recursion);
@@ -1580,10 +1666,14 @@
* Extract the attachments into the temporary directory
*/
if((ret = cli_mbox(dir, desc, ctx))) {
- if(!ctx->engine->keeptmp)
- cli_rmdirs(dir);
- free(dir);
- return ret;
+ if (ret == CL_VIRUS && SCAN_ALL)
+ viruses_found++;
+ else {
+ if(!ctx->engine->keeptmp)
+ cli_rmdirs(dir);
+ free(dir);
+ return ret;
+ }
}
ret = cli_scandir(dir, ctx);
@@ -1592,6 +1682,8 @@
cli_rmdirs(dir);
free(dir);
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return ret;
}
@@ -1604,7 +1696,7 @@
int done = 0;
int (*ccfunc)(const unsigned char *buffer, int length);
int (*ssnfunc)(const unsigned char *buffer, int length);
-
+ unsigned int viruses_found = 0;
if(ctx == NULL)
return CL_ENULLARG;
@@ -1651,16 +1743,24 @@
if(cc_count != 0 && cc_count >= ctx->engine->min_cc_count) {
cli_dbgmsg("cli_scan_structured: %u credit card numbers detected\n", cc_count);
- *ctx->virname = "Heuristics.Structured.CreditCardNumber";
- return CL_VIRUS;
+ cli_append_virus(ctx,"Heuristics.Structured.CreditCardNumber");
+ if (SCAN_ALL)
+ viruses_found++;
+ else
+ return CL_VIRUS;
}
if(ssn_count != 0 && ssn_count >= ctx->engine->min_ssn_count) {
cli_dbgmsg("cli_scan_structured: %u social security numbers detected\n", ssn_count);
- *ctx->virname = "Heuristics.Structured.SSN";
- return CL_VIRUS;
+ cli_append_virus(ctx,"Heuristics.Structured.SSN");
+ if (SCAN_ALL)
+ viruses_found++;
+ else
+ return CL_VIRUS;
}
+ if (SCAN_ALL && viruses_found)
+ return CL_VIRUS;
return CL_CLEAN;
}
@@ -1727,7 +1827,7 @@
ret = cli_magic_scandesc(fd, ctx);
ctx->corrupted_input = corrupted_input;
if(ret == CL_VIRUS) {
- cli_dbgmsg("cli_scanembpe: Infected with %s\n", *ctx->virname);
+ cli_dbgmsg("cli_scanembpe: Infected with %s\n", cli_get_last_virus(ctx));
close(fd);
if(!ctx->engine->keeptmp) {
if (cli_unlink(tmpname)) {
@@ -1921,7 +2021,7 @@
}
if(ret == CL_VIRUS)
- cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, map->fd);
+ cli_dbgmsg("%s found\n", cli_get_last_virus(ctx));
return ret;
}
@@ -1945,14 +2045,13 @@
#define ret_from_magicscan(retcode) do { \
cli_dbgmsg("cli_magic_scandesc: returning %d %s\n", retcode, __AT__); \
if(ctx->engine->cb_post_scan) { \
- switch(ctx->engine->cb_post_scan(desc, retcode, retcode == CL_VIRUS && ctx->virname ? *ctx->virname : NULL, ctx->cb_ctx)) { \
+ switch(ctx->engine->cb_post_scan(desc, retcode, retcode == CL_VIRUS ? cli_get_last_virus(ctx) : NULL, ctx->cb_ctx)) { \
case CL_BREAK: \
cli_dbgmsg("cli_magic_scandesc: file whitelisted by callback\n"); \
return CL_CLEAN; \
case CL_VIRUS: \
cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n"); \
- if(ctx->virname) \
- *ctx->virname = "Detected.By.Callback"; \
+ cli_append_virus(ctx, "Detected.By.Callback"); \
return CL_VIRUS; \
case CL_CLEAN: \
break; \
@@ -1973,6 +2072,7 @@
size_t current_container_size = ctx->container_size, hashed_size;
unsigned char hash[16];
bitset_t *old_hook_lsig_matches;
+ unsigned int viruses_found = 0;
#ifdef HAVE__INTERNAL__SHA_COLLECT
if(ctx->sha_collect>0) ctx->sha_collect = 0;
@@ -2026,8 +2126,7 @@
ret_from_magicscan(CL_CLEAN);
case CL_VIRUS:
cli_dbgmsg("cli_magic_scandesc: file blacklisted by callback\n");
- if(ctx->virname)
- *ctx->virname = "Detected.By.Callback";
+ cli_append_virus(ctx, "Detected.By.Callback");
funmap(*ctx->fmap);
ctx->fmap--;
ret_from_magicscan(CL_VIRUS);
@@ -2048,14 +2147,14 @@
old_hook_lsig_matches = ctx->hook_lsig_matches;
ctx->hook_lsig_matches = NULL;
- if(!ctx->options || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */
+ if(!(ctx->options&~CL_SCAN_ALLMATCHES) || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */
if(ctx->recursion == ctx->engine->maxreclevel)
cli_dbgmsg("cli_magic_scandesc: Hit recursion limit, only scanning raw file\n");
else
cli_dbgmsg("Raw mode: No support for special files\n");
if((ret = cli_fmap_scandesc(ctx, 0, 0, NULL, AC_SCAN_VIR, NULL, hash)) == CL_VIRUS)
- cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, desc);
+ cli_dbgmsg("%s found in descriptor %d\n", cli_get_last_virus(ctx), desc);
else if(ret == CL_CLEAN) {
if(ctx->recursion != ctx->engine->maxreclevel)
cache_add(hash, hashed_size, ctx); /* Only cache if limits are not reached */
@@ -2381,6 +2480,8 @@
/* CL_VIRUS = malware found, check FP and report */
case CL_VIRUS:
ret = cli_checkfp(hash, hashed_size, ctx);
+ if (SCAN_ALL)
+ break;
funmap(*ctx->fmap);
ctx->fmap--;
cli_bitset_free(ctx->hook_lsig_matches);
@@ -2415,11 +2516,10 @@
case CL_TYPE_TEXT_UTF16BE:
case CL_TYPE_TEXT_UTF16LE:
case CL_TYPE_TEXT_UTF8:
- if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML)
+ if((DCONF_DOC & DOC_CONF_SCRIPT) && dettype != CL_TYPE_HTML && ret != CL_VIRUS)
ret = cli_scanscript(ctx);
if(SCAN_MAIL && (DCONF_MAIL & MAIL_CONF_MBOX) && ret != CL_VIRUS && (ctx->container_type == CL_TYPE_MAIL || dettype == CL_TYPE_MAIL)) {
- lseek(desc, 0, SEEK_SET);
- ret = cli_scandesc(desc, ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR, NULL);
+ ret = cli_fmap_scandesc(ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR, NULL, NULL);
}
break;
/* Due to performance reasons all executables were first scanned
@@ -2519,6 +2619,12 @@
cli_logg_setup(&ctx);
rc = cli_magic_scandesc(desc, &ctx);
+ if (ctx.options & CL_SCAN_ALLMATCHES) {
+ *virname = (char *)ctx.virname; /* temp hack for scanall mode until api augmentation */
+ if (rc == CL_CLEAN && ctx.num_viruses)
+ rc = CL_VIRUS;
+ }
+
cli_bitset_free(ctx.hook_lsig_matches);
free(ctx.fmap);
if(rc == CL_CLEAN && ctx.found_possibly_unwanted)
@@ -2529,24 +2635,24 @@
int cli_found_possibly_unwanted(cli_ctx* ctx)
{
- if(ctx->virname) {
- cli_dbgmsg("found Possibly Unwanted: %s\n",*ctx->virname);
- if(ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE) {
- /* we found a heuristic match, don't scan further,
- * but consider it a virus. */
- cli_dbgmsg("cli_found_possibly_unwanted: CL_VIRUS\n");
- return CL_VIRUS;
- }
- /* heuristic scan isn't taking precedence, keep scanning.
- * If this is part of an archive, and
- * we find a real malware we report that instead of the
- * heuristic match */
- ctx->found_possibly_unwanted = 1;
- } else {
- cli_warnmsg("cli_found_possibly_unwanted called, but virname is not set\n");
+ if(cli_get_last_virus(ctx)) {
+ cli_dbgmsg("found Possibly Unwanted: %s\n", cli_get_last_virus(ctx));
+ if(ctx->options & CL_SCAN_HEURISTIC_PRECEDENCE) {
+ /* we found a heuristic match, don't scan further,
+ * but consider it a virus. */
+ cli_dbgmsg("cli_found_possibly_unwanted: CL_VIRUS\n");
+ return CL_VIRUS;
}
- emax_reached(ctx);
- return CL_CLEAN;
+ /* heuristic scan isn't taking precedence, keep scanning.
+ * If this is part of an archive, and
+ * we find a real malware we report that instead of the
+ * heuristic match */
+ ctx->found_possibly_unwanted = 1;
+ } else {
+ cli_warnmsg("cli_found_possibly_unwanted called, but virname is not set\n");
+ }
+ emax_reached(ctx);
+ return CL_CLEAN;
}
static int cli_scanfile(const char *filename, cli_ctx *ctx)
diff -Nru clamav-0.97.6+dfsg/libclamav/special.c clamav-0.97.7+dfsg/libclamav/special.c
--- clamav-0.97.6+dfsg/libclamav/special.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/special.c 2013-03-11 11:23:21.000000000 -0400
@@ -77,7 +77,7 @@
if (j < 2) {
retval = CL_CLEAN;
} else if (retval==CL_VIRUS) {
- *ctx->virname = "Heuristics.Worm.Mydoom.M.log";
+ cli_append_virus(ctx, "Heuristics.Worm.Mydoom.M.log");
}
return retval;
diff -Nru clamav-0.97.6+dfsg/libclamav/untar.c clamav-0.97.7+dfsg/libclamav/untar.c
--- clamav-0.97.6+dfsg/libclamav/untar.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/untar.c 2013-03-11 11:23:21.000000000 -0400
@@ -128,6 +128,7 @@
unsigned int files = 0;
char fullname[NAME_MAX + 1];
size_t currsize = 0;
+ unsigned int num_viruses = 0;
cli_dbgmsg("In untar(%s, %d)\n", dir, desc);
@@ -159,8 +160,12 @@
close(fout);
if (!ctx->engine->keeptmp)
if (cli_unlink(fullname)) return CL_EUNLINK;
- if (ret==CL_VIRUS)
+ if (ret==CL_VIRUS) {
+ if (!SCAN_ALL)
return CL_VIRUS;
+ else
+ num_viruses++;
+ }
fout = -1;
}
@@ -276,8 +281,12 @@
strncpy(name, block, 100);
name[100] = '\0';
- if(cli_matchmeta(ctx, name, size, size, 0, files, 0, NULL) == CL_VIRUS)
- return CL_VIRUS;
+ if(cli_matchmeta(ctx, name, size, size, 0, files, 0, NULL) == CL_VIRUS) {
+ if (!SCAN_ALL)
+ return CL_VIRUS;
+ else
+ num_viruses++;
+ }
snprintf(fullname, sizeof(fullname)-1, "%s"PATHSEP"tar%02u", dir, files);
fullname[sizeof(fullname)-1] = '\0';
@@ -340,5 +349,7 @@
if (ret==CL_VIRUS)
return CL_VIRUS;
}
+ if (num_viruses)
+ return CL_VIRUS;
return CL_CLEAN;
}
diff -Nru clamav-0.97.6+dfsg/libclamav/unzip.c clamav-0.97.7+dfsg/libclamav/unzip.c
--- clamav-0.97.6+dfsg/libclamav/unzip.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/unzip.c 2013-03-11 11:23:21.000000000 -0400
@@ -350,7 +350,7 @@
if(detect_encrypted && (LH_flags & F_ENCR) && DETECT_ENCRYPTED) {
cli_dbgmsg("cli_unzip: Encrypted files found in archive.\n");
- *ctx->virname = "Heuristics.Encrypted.Zip";
+ cli_append_virus(ctx, "Heuristics.Encrypted.Zip");
*ret = CL_VIRUS;
fmap_unneed_off(map, loff, SIZEOF_LH);
return 0;
diff -Nru clamav-0.97.6+dfsg/libclamav/version.h clamav-0.97.7+dfsg/libclamav/version.h
--- clamav-0.97.6+dfsg/libclamav/version.h 2012-08-10 13:10:35.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/version.h 2013-03-11 12:02:27.000000000 -0400
@@ -1 +1 @@
-#define REPO_VERSION "devel-clamav-0.97.6"
+#define REPO_VERSION "devel-clamav-0.97.7"
diff -Nru clamav-0.97.6+dfsg/libclamav/wwunpack.c clamav-0.97.7+dfsg/libclamav/wwunpack.c
--- clamav-0.97.6+dfsg/libclamav/wwunpack.c 2012-05-15 14:34:23.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/wwunpack.c 2013-03-11 11:23:21.000000000 -0400
@@ -223,12 +223,22 @@
structs = &exe[(0xffff&cli_readint32(&exe[pe+0x14]))+pe+0x18];
for(i=0 ; i<scount ; i++) {
+ if (!CLI_ISCONTAINED(exe, exesz, structs, 0x28)) {
+ cli_dbgmsg("WWPack: structs pointer out of bounds\n");
+ return CL_EFORMAT;
+ }
+
cli_writeint32(structs+8, sects[i].vsz);
cli_writeint32(structs+12, sects[i].rva);
cli_writeint32(structs+16, sects[i].vsz);
cli_writeint32(structs+20, sects[i].rva);
structs+=0x28;
}
+ if (!CLI_ISCONTAINED(exe, exesz, structs, 0x28)) {
+ cli_dbgmsg("WWPack: structs pointer out of bounds\n");
+ return CL_EFORMAT;
+ }
+
memset(structs, 0, 0x28);
error = cli_writen(desc, exe, exesz)!=exesz;
}
diff -Nru clamav-0.97.6+dfsg/libclamav/yc.c clamav-0.97.7+dfsg/libclamav/yc.c
--- clamav-0.97.6+dfsg/libclamav/yc.c 2012-05-15 14:34:23.000000000 -0400
+++ clamav-0.97.7+dfsg/libclamav/yc.c 2013-03-11 11:21:48.000000000 -0400
@@ -40,7 +40,7 @@
/* ========================================================================== */
/* "Emulates" the poly decryptors */
-static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx)
+static int yc_poly_emulator(char* decryptor_offset, char* code, unsigned int ecx, uint32_t max_emu)
{
/*
@@ -64,7 +64,7 @@
unsigned char cl = ecx & 0xff;
unsigned int j,i;
- for(i=0;i<ecx;i++) /* Byte looper - Decrypts every byte and write it back */
+ for(i=0;i<ecx&&i<max_emu;i++) /* Byte looper - Decrypts every byte and write it back */
{
al = code[i];
@@ -168,7 +168,7 @@
unsigned int i;
struct pe_image_file_hdr *pe = (struct pe_image_file_hdr*) (fbuf + peoffset);
char *sname = (char *)pe + EC16(pe->SizeOfOptionalHeader) + 0x18;
-
+ uint32_t max_emu;
/*
First layer (decryptor of the section decryptor) in last section
@@ -180,7 +180,7 @@
*/
cli_dbgmsg("yC: offset: %x, length: %x\n", offset, ecx);
cli_dbgmsg("yC: decrypting decryptor on sect %d\n", sectcount);
- if (yc_poly_emulator(fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6, ecx))
+ if (yc_poly_emulator(fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6, ecx, ecx))
return 1;
filesize-=sections[sectcount].ursz;
@@ -190,31 +190,38 @@
Start offset for analyze: Start of yC Section + 0x457
End offset for analyze: Start of yC Section + 0x487
- Lenght to decrypt - ECX = Raw Size of Section
+ Length to decrypt - ECX = Raw Size of Section
*/
/* Loop through all sections and decrypt them... */
- for(i=0;i<sectcount;i++)
- {
- uint32_t name = (uint32_t) cli_readint32(sname+i*0x28);
- if (!sections[i].raw ||
- !sections[i].rsz ||
- name == 0x63727372 || /* rsrc */
- name == 0x7273722E || /* .rsr */
- name == 0x6F6C6572 || /* relo */
- name == 0x6C65722E || /* .rel */
- name == 0x6164652E || /* .eda */
- name == 0x6164722E || /* .rda */
- name == 0x6164692E || /* .ida */
- name == 0x736C742E || /* .tls */
- (name&0xffff) == 0x4379 /* yC */
+ for(i=0;i<sectcount;i++) {
+ uint32_t name = (uint32_t) cli_readint32(sname+i*0x28);
+ if (!sections[i].raw ||
+ !sections[i].rsz ||
+ name == 0x63727372 || /* rsrc */
+ name == 0x7273722E || /* .rsr */
+ name == 0x6F6C6572 || /* relo */
+ name == 0x6C65722E || /* .rel */
+ name == 0x6164652E || /* .eda */
+ name == 0x6164722E || /* .rda */
+ name == 0x6164692E || /* .ida */
+ name == 0x736C742E || /* .tls */
+ (name&0xffff) == 0x4379 /* yC */
) continue;
- cli_dbgmsg("yC: decrypting sect%d\n",i);
- if (yc_poly_emulator(fbuf + ycsect + (offset == -0x18 ? 0x3ea : 0x457), fbuf + sections[i].raw, sections[i].ursz))
- return 1;
+ cli_dbgmsg("yC: decrypting sect%d\n",i);
+ max_emu = filesize - sections[i].raw;
+ if (max_emu > filesize) {
+ cli_dbgmsg("yC: bad emulation length limit %u\n", max_emu);
+ return 1;
}
+ if (yc_poly_emulator(fbuf + ycsect + (offset == -0x18 ? 0x3ea : 0x457),
+ fbuf + sections[i].raw,
+ sections[i].ursz,
+ max_emu))
+ return 1;
+ }
/* Remove yC section */
pe->NumberOfSections=EC16(sectcount);
diff -Nru clamav-0.97.6+dfsg/NEWS clamav-0.97.7+dfsg/NEWS
--- clamav-0.97.6+dfsg/NEWS 2012-09-17 11:16:40.000000000 -0400
+++ clamav-0.97.7+dfsg/NEWS 2013-03-11 11:23:20.000000000 -0400
@@ -1,9 +1,8 @@
-0.97.6
+0.97.7
------
-
-ClamAV 0.97.6 corrects two major bugs. One is bb#5571, where an invalid return
-code was issued. The other is 5252, where an error in processing certain data
-types occured.
+ClamAV 0.97.7 addresses several reported potential security bugs. Thanks to
+Felix Groebert, Mateusz Jurczyk and Gynvael Coldwind of the Google Security
+Team for finding and reporting these issues.
--
The ClamAV team (http://www.clamav.net/team)
diff -Nru clamav-0.97.6+dfsg/README clamav-0.97.7+dfsg/README
--- clamav-0.97.6+dfsg/README 2012-09-17 11:02:22.000000000 -0400
+++ clamav-0.97.7+dfsg/README 2013-03-11 11:23:20.000000000 -0400
@@ -1,6 +1,12 @@
Note: This README/NEWS file refers to the source tarball. Some things described
here may not be available in binary packages.
--
+0.97.7
+------
+ClamAV 0.97.7 addresses several reported potential security bugs. Thanks to
+Felix Groebert, Mateusz Jurczyk and Gynvael Coldwind of the Google Security
+Team for finding and reporting these issues.
+
0.97.6
------
ClamAV 0.97.6 corrects bug 5252 "CL_EFORMAT: Bad format or broken data ERROR
diff -Nru clamav-0.97.6+dfsg/shared/optparser.c clamav-0.97.7+dfsg/shared/optparser.c
--- clamav-0.97.6+dfsg/shared/optparser.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/shared/optparser.c 2013-03-11 11:23:21.000000000 -0400
@@ -80,6 +80,7 @@
{ NULL, "multiscan", 'm', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMDSCAN, "", "" },
{ NULL, "fdpass", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMDSCAN, "", "" },
{ NULL, "stream", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMDSCAN, "", "" },
+ { NULL, "allmatch", 'z', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN | OPT_CLAMDSCAN, "", "" },
{ NULL, "database", 'd', TYPE_STRING, NULL, -1, DATADIR, FLAG_REQUIRED | FLAG_MULTIPLE, OPT_CLAMSCAN, "", "" }, /* merge it with DatabaseDirectory (and fix conflict with --datadir */
{ NULL, "recursive", 'r', TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN, "", "" },
{ NULL, "follow-dir-symlinks", 0, TYPE_NUMBER, MATCH_NUMBER, 1, NULL, 0, OPT_CLAMSCAN, "", "" },
diff -Nru clamav-0.97.6+dfsg/sigtool/sigtool.c clamav-0.97.7+dfsg/sigtool/sigtool.c
--- clamav-0.97.6+dfsg/sigtool/sigtool.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/sigtool/sigtool.c 2013-03-11 11:23:21.000000000 -0400
@@ -108,6 +108,7 @@
{ "gdb", 1 },
{ "pdb", 1 },
{ "wdb", 0 },
+ { "crb", 1 },
{ NULL, 0 }
};
diff -Nru clamav-0.97.6+dfsg/unit_tests/check_bytecode.c clamav-0.97.7+dfsg/unit_tests/check_bytecode.c
--- clamav-0.97.6+dfsg/unit_tests/check_bytecode.c 2012-08-06 16:26:49.000000000 -0400
+++ clamav-0.97.7+dfsg/unit_tests/check_bytecode.c 2013-03-11 11:23:21.000000000 -0400
@@ -58,8 +58,11 @@
uint64_t v;
struct cl_engine *engine;
int fdin = -1;
+ const char * virname = NULL;
memset(&cctx, 0, sizeof(cctx));
+ cctx.options |= CL_SCAN_ALLMATCHES;
+ cctx.virname = &virname;
cctx.engine = engine = cl_engine_new();
fail_unless(!!cctx.engine, "cannot create engine");
rc = cl_engine_compile(engine);
diff -Nru clamav-0.97.6+dfsg/unit_tests/check_matchers.c clamav-0.97.7+dfsg/unit_tests/check_matchers.c
--- clamav-0.97.6+dfsg/unit_tests/check_matchers.c 2012-05-15 14:34:23.000000000 -0400
+++ clamav-0.97.7+dfsg/unit_tests/check_matchers.c 2013-03-11 11:21:49.000000000 -0400
@@ -145,7 +145,83 @@
ret = cli_parse_add(root, "Sig3", "babedead", 0, 0, "*", 0, NULL, 0);
fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
- ret = cli_bm_scanbuff((const unsigned char*)"blah\xde\xad\xbe\xef", 12, &virname, NULL, root, 0, NULL, NULL);
+ ret = cli_bm_scanbuff((const unsigned char*)"blah\xde\xad\xbe\xef", 12, &virname, NULL, root, 0, NULL, NULL, NULL);
+ fail_unless(ret == CL_VIRUS, "cli_bm_scanbuff() failed");
+ fail_unless(!strncmp(virname, "Sig2", 4), "Incorrect signature matched in cli_bm_scanbuff()\n");
+}
+END_TEST
+
+START_TEST (test_ac_scanbuff_allscan) {
+ struct cli_ac_data mdata;
+ struct cli_matcher *root;
+ unsigned int i;
+ int ret;
+
+ root = ctx.engine->root[0];
+ fail_unless(root != NULL, "root == NULL");
+ root->ac_only = 1;
+
+#ifdef USE_MPOOL
+ root->mempool = mpool_create();
+#endif
+ ret = cli_ac_init(root, CLI_DEFAULT_AC_MINDEPTH, CLI_DEFAULT_AC_MAXDEPTH, 1);
+ fail_unless(ret == CL_SUCCESS, "cli_ac_init() failed");
+
+
+ for(i = 0; ac_testdata[i].data; i++) {
+ ret = cli_parse_add(root, ac_testdata[i].virname, ac_testdata[i].hexsig, 0, 0, "*", 0, NULL, 0);
+ fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
+ }
+
+ ret = cli_ac_buildtrie(root);
+ fail_unless(ret == CL_SUCCESS, "cli_ac_buildtrie() failed");
+
+ ret = cli_ac_initdata(&mdata, root->ac_partsigs, 0, 0, CLI_DEFAULT_AC_TRACKLEN);
+ fail_unless(ret == CL_SUCCESS, "cli_ac_initdata() failed");
+
+ ctx.options |= CL_SCAN_ALLMATCHES;
+ for(i = 0; ac_testdata[i].data; i++) {
+ ret = cli_ac_scanbuff((const unsigned char*)ac_testdata[i].data, strlen(ac_testdata[i].data), &virname, NULL, NULL, root, &mdata, 0, 0, NULL, AC_SCAN_VIR, NULL);
+ fail_unless_fmt(ret == CL_VIRUS, "cli_ac_scanbuff() failed for %s", ac_testdata[i].virname);
+ fail_unless_fmt(!strncmp(virname, ac_testdata[i].virname, strlen(ac_testdata[i].virname)), "Dataset %u matched with %s", i, virname);
+
+ ret = cli_scanbuff((const unsigned char*)ac_testdata[i].data, strlen(ac_testdata[i].data), 0, &ctx, 0, NULL);
+ fail_unless_fmt(ret == CL_VIRUS, "cli_scanbuff() failed for %s", ac_testdata[i].virname);
+ fail_unless_fmt(!strncmp(virname, ac_testdata[i].virname, strlen(ac_testdata[i].virname)), "Dataset %u matched with %s", i, virname);
+ if (ctx.num_viruses) {
+ free((void *)ctx.virname);
+ ctx.num_viruses = 0;
+ ctx.size_viruses = 0;
+ }
+ }
+
+ cli_ac_freedata(&mdata);
+}
+END_TEST
+
+START_TEST (test_bm_scanbuff_allscan) {
+ struct cli_matcher *root;
+ const char *virname = NULL;
+ int ret;
+
+
+ root = ctx.engine->root[0];
+ fail_unless(root != NULL, "root == NULL");
+
+#ifdef USE_MPOOL
+ root->mempool = mpool_create();
+#endif
+ ret = cli_bm_init(root);
+ fail_unless(ret == CL_SUCCESS, "cli_bm_init() failed");
+
+ ret = cli_parse_add(root, "Sig1", "deadbabe", 0, 0, "*", 0, NULL, 0);
+ fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
+ ret = cli_parse_add(root, "Sig2", "deadbeef", 0, 0, "*", 0, NULL, 0);
+ fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
+ ret = cli_parse_add(root, "Sig3", "babedead", 0, 0, "*", 0, NULL, 0);
+ fail_unless(ret == CL_SUCCESS, "cli_parse_add() failed");
+
+ ret = cli_bm_scanbuff((const unsigned char*)"blah\xde\xad\xbe\xef", 12, &virname, NULL, root, 0, NULL, NULL, NULL);
fail_unless(ret == CL_VIRUS, "cli_bm_scanbuff() failed");
fail_unless(!strncmp(virname, "Sig2", 4), "Incorrect signature matched in cli_bm_scanbuff()\n");
}
@@ -160,6 +236,8 @@
tcase_add_checked_fixture (tc_matchers, setup, teardown);
tcase_add_test(tc_matchers, test_ac_scanbuff);
tcase_add_test(tc_matchers, test_bm_scanbuff);
+ tcase_add_test(tc_matchers, test_ac_scanbuff_allscan);
+ tcase_add_test(tc_matchers, test_bm_scanbuff_allscan);
return s;
}
diff -Nru clamav-0.97.6+dfsg/unit_tests/check_regex.c clamav-0.97.7+dfsg/unit_tests/check_regex.c
--- clamav-0.97.6+dfsg/unit_tests/check_regex.c 2012-05-15 14:34:23.000000000 -0400
+++ clamav-0.97.7+dfsg/unit_tests/check_regex.c 2013-03-11 11:21:49.000000000 -0400
@@ -425,12 +425,85 @@
}
}
+static void do_phishing_test_allscan(const struct rtest *rtest)
+{
+ char *realurl;
+ cli_ctx ctx;
+ const char *virname = NULL;
+ tag_arguments_t hrefs;
+ int rc;
+
+ memset(&ctx, 0, sizeof(ctx));
+
+ realurl = cli_strdup(rtest->realurl);
+ fail_unless(!!realurl, "cli_strdup");
+
+ hrefs.count = 1;
+ hrefs.value = cli_malloc(sizeof(*hrefs.value));
+ fail_unless(!!hrefs.value, "cli_malloc");
+ hrefs.value[0] = (unsigned char*)realurl;
+ hrefs.contents = cli_malloc(sizeof(*hrefs.contents));
+ fail_unless(!!hrefs.contents, "cli_malloc");
+ hrefs.tag = cli_malloc(sizeof(*hrefs.tag));
+ fail_unless(!!hrefs.tag, "cli_malloc");
+ hrefs.tag[0] = (unsigned char*)cli_strdup("href");
+ hrefs.contents[0] = (unsigned char*)cli_strdup(rtest->displayurl);
+
+ ctx.engine = engine;
+ ctx.virname = &virname;
+ ctx.options |= CL_SCAN_ALLMATCHES;
+
+ rc = phishingScan(&ctx, &hrefs);
+
+ html_tag_arg_free(&hrefs);
+ fail_unless(rc == CL_CLEAN,"phishingScan");
+ switch(rtest->result) {
+ case 0:
+ fail_unless_fmt(ctx.found_possibly_unwanted,
+ "this should be phishing, realURL: %s, displayURL: %s",
+ rtest->realurl, rtest->displayurl);
+ break;
+ case 1:
+ fail_unless_fmt(!ctx.found_possibly_unwanted,
+ "this should be whitelisted, realURL: %s, displayURL: %s",
+ rtest->realurl, rtest->displayurl);
+ break;
+ case 2:
+ fail_unless_fmt(!ctx.found_possibly_unwanted,
+ "this should be clean, realURL: %s, displayURL: %s",
+ rtest->realurl, rtest->displayurl);
+ break;
+ case 3:
+ if(!loaded_2)
+ fail_unless_fmt(!ctx.found_possibly_unwanted,
+ "this should be clean, realURL: %s, displayURL: %s",
+ rtest->realurl, rtest->displayurl);
+ else {
+ fail_unless_fmt(ctx.found_possibly_unwanted,
+ "this should be blacklisted, realURL: %s, displayURL: %s",
+ rtest->realurl, rtest->displayurl);
+ if (*ctx.virname)
+ fail_unless_fmt(!strstr((const char*)*ctx.virname,"Blacklisted"),
+ "should be blacklisted, but is: %s\n", ctx.virname);
+ }
+ break;
+ }
+ if (ctx.num_viruses)
+ free((void *)ctx.virname);
+}
+
#ifdef CHECK_HAVE_LOOPS
START_TEST (phishingScan_test)
{
do_phishing_test(&rtests[_i]);
}
END_TEST
+
+START_TEST (phishingScan_test_allscan)
+{
+ do_phishing_test_allscan(&rtests[_i]);
+}
+END_TEST
#endif
#ifdef CHECK_HAVE_LOOPS
@@ -515,6 +588,27 @@
}
END_TEST
+START_TEST(phishing_fake_test_allscan)
+{
+ char buf[4096];
+ FILE *f = fdopen(open_testfile("input/daily.pdb"),"r");
+ fail_unless(!!f,"fopen daily.pdb");
+ while(fgets(buf, sizeof(buf), f)) {
+ struct rtest rtest;
+ const char *pdb = strchr(buf,':');
+ fail_unless(!!pdb, "missing : in pdb");
+ rtest.realurl = pdb;
+ rtest.displayurl = pdb;
+ rtest.result = 2;
+ do_phishing_test_allscan(&rtest);
+ rtest.realurl = "http://fake.example.com";
+ rtest.result = 0;
+ do_phishing_test_allscan(&rtest);
+ }
+ fclose(f);
+}
+END_TEST
+
Suite *test_regex_suite(void)
{
Suite *s = suite_create("regex");
@@ -539,16 +633,20 @@
tcase_add_unchecked_fixture(tc_phish, psetup, pteardown);
#ifdef CHECK_HAVE_LOOPS
tcase_add_loop_test(tc_phish, phishingScan_test, 0, sizeof(rtests)/sizeof(rtests[0]));
+ tcase_add_loop_test(tc_phish, phishingScan_test_allscan, 0, sizeof(rtests)/sizeof(rtests[0]));
#endif
tcase_add_test(tc_phish, phishing_fake_test);
+ tcase_add_test(tc_phish, phishing_fake_test_allscan);
tc_phish2 = tcase_create("phishingScan with 2 dbs");
suite_add_tcase(s, tc_phish2);
tcase_add_unchecked_fixture(tc_phish2, psetup2, pteardown);
#ifdef CHECK_HAVE_LOOPS
tcase_add_loop_test(tc_phish2, phishingScan_test, 0, sizeof(rtests)/sizeof(rtests[0]));
+ tcase_add_loop_test(tc_phish2, phishingScan_test_allscan, 0, sizeof(rtests)/sizeof(rtests[0]));
#endif
tcase_add_test(tc_phish2, phishing_fake_test);
+ tcase_add_test(tc_phish2, phishing_fake_test_allscan);
#ifdef CHECK_HAVE_LOOPS
tcase_add_loop_test(tc_phish, test_url_canon, 0, sizeof(uc)/sizeof(uc[0]));
#endif
Reply to: