[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b
aCaB
acab at clamav.net
Sun Apr 4 00:59:44 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit 511c2e792cf27b0d13ba3503a3cb035bc6581d66
Author: aCaB <acab at clamav.net>
Date: Tue Aug 11 12:23:14 2009 +0200
cache
cache over 256 trees
diff --git a/clamd/clamd.c b/clamd/clamd.c
index 26e032f..8151c84 100644
--- a/clamd/clamd.c
+++ b/clamd/clamd.c
@@ -304,6 +304,8 @@ int main(int argc, char **argv)
break;
}
+ cache_init(256);
+
if(!(engine = cl_engine_new())) {
logg("!Can't initialize antivirus engine\n");
ret = 1;
diff --git a/clamscan/clamscan.c b/clamscan/clamscan.c
index c0ede1d..6cb31e6 100644
--- a/clamscan/clamscan.c
+++ b/clamscan/clamscan.c
@@ -169,6 +169,8 @@ int main(int argc, char **argv)
gettimeofday(&t1, &tz);
#endif
+ cache_init(256);
+
ret = scanmanager(opts);
if(!optget(opts, "no-summary")->enabled) {
diff --git a/libclamav/Makefile.am b/libclamav/Makefile.am
index f358bb7..1138959 100644
--- a/libclamav/Makefile.am
+++ b/libclamav/Makefile.am
@@ -323,7 +323,9 @@ libclamav_la_SOURCES = \
macho.c \
macho.h \
ishield.c \
- ishield.h
+ ishield.h \
+ cache.c \
+ cache.h
if !LINK_TOMMATH
libclamav_la_SOURCES += bignum.c \
diff --git a/libclamav/Makefile.in b/libclamav/Makefile.in
index 2a8ba22..5d1d591 100644
--- a/libclamav/Makefile.in
+++ b/libclamav/Makefile.in
@@ -131,7 +131,7 @@ am__libclamav_la_SOURCES_DIST = clamav.h matcher-ac.c matcher-ac.h \
uniq.h version.c version.h mpool.c mpool.h default.h sha256.c \
sha256.h bignum.h bytecode.c bytecode.h bytecode_vm.c \
bytecode_priv.h clambc.h cpio.c cpio.h macho.c macho.h \
- ishield.c ishield.h bignum.c bignum_class.h
+ ishield.c ishield.h cache.c cache.h bignum.c bignum_class.h
@LINK_TOMMATH_FALSE at am__objects_1 = libclamav_la-bignum.lo
am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \
libclamav_la-matcher-bm.lo libclamav_la-matcher.lo \
@@ -177,7 +177,8 @@ am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \
libclamav_la-version.lo libclamav_la-mpool.lo \
libclamav_la-sha256.lo libclamav_la-bytecode.lo \
libclamav_la-bytecode_vm.lo libclamav_la-cpio.lo \
- libclamav_la-macho.lo libclamav_la-ishield.lo $(am__objects_1)
+ libclamav_la-macho.lo libclamav_la-ishield.lo \
+ libclamav_la-cache.lo $(am__objects_1)
libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
libclamav_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(libclamav_la_CFLAGS) \
@@ -547,7 +548,7 @@ libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \
uniq.h version.c version.h mpool.c mpool.h default.h sha256.c \
sha256.h bignum.h bytecode.c bytecode.h bytecode_vm.c \
bytecode_priv.h clambc.h cpio.c cpio.h macho.c macho.h \
- ishield.c ishield.h $(am__append_7)
+ ishield.c ishield.h cache.c cache.h $(am__append_7)
noinst_LTLIBRARIES = libclamav_internal_utils.la libclamav_internal_utils_nothreads.la
COMMON_CLEANFILES = version.h version.h.tmp *.gcda *.gcno
@MAINTAINER_MODE_TRUE at BUILT_SOURCES = jsparse/generated/operators.h jsparse/generated/keywords.h jsparse-keywords.gperf
@@ -681,6 +682,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-bytecode_vm.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-bzlib.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-cab.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-cache.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-chmunpack.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-cpio.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-cvd.Plo at am__quote@
@@ -1417,6 +1419,13 @@ libclamav_la-ishield.lo: ishield.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-ishield.lo `test -f 'ishield.c' || echo '$(srcdir)/'`ishield.c
+libclamav_la-cache.lo: cache.c
+ at am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-cache.lo -MD -MP -MF $(DEPDIR)/libclamav_la-cache.Tpo -c -o libclamav_la-cache.lo `test -f 'cache.c' || echo '$(srcdir)/'`cache.c
+ at am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libclamav_la-cache.Tpo $(DEPDIR)/libclamav_la-cache.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ source='cache.c' object='libclamav_la-cache.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-cache.lo `test -f 'cache.c' || echo '$(srcdir)/'`cache.c
+
libclamav_la-bignum.lo: bignum.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-bignum.lo -MD -MP -MF $(DEPDIR)/libclamav_la-bignum.Tpo -c -o libclamav_la-bignum.lo `test -f 'bignum.c' || echo '$(srcdir)/'`bignum.c
@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libclamav_la-bignum.Tpo $(DEPDIR)/libclamav_la-bignum.Plo
diff --git a/libclamav/cache.c b/libclamav/cache.c
new file mode 100644
index 0000000..30b3a38
--- /dev/null
+++ b/libclamav/cache.c
@@ -0,0 +1,186 @@
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+
+#include "md5.h"
+#include "mpool.h"
+#include "clamav.h"
+#include "cache.h"
+
+#if HAVE_CONFIG_H
+#include "clamav-config.h"
+#endif
+
+#define CACHE_PERTURB 10
+/* 1/10th */
+
+static mpool_t *mempool = NULL;
+static struct CACHE {
+ struct CACHE_ENTRY {
+ unsigned char hash[15];
+ uint32_t dbver;
+ uint32_t hits;
+ } *items;
+ pthread_mutex_t mutex;
+ uint32_t lastdb;
+} *cache = NULL;
+static unsigned int cache_entries = 0;
+
+int cache_init(unsigned int entries) {
+ unsigned int i;
+
+ if(!(mempool = mpool_create())) {
+ cli_errmsg("mpool init fail\n");
+ return 1;
+ }
+ if(!(cache = mpool_malloc(mempool, sizeof(struct CACHE) * 256))) {
+ cli_errmsg("mpool malloc fail\n");
+ mpool_destroy(mempool);
+ return 1;
+ }
+
+ for(i=0; i<256; i++) {
+ struct CACHE_ENTRY *e = mpool_calloc(mempool, sizeof(struct CACHE_ENTRY), entries);
+ if(!e) {
+ cli_errmsg("mpool calloc fail\n");
+ mpool_destroy(mempool);
+ return 1;
+ }
+ cache[i].items = e;
+ cache[i].lastdb = 0;
+ if(pthread_mutex_init(&cache[i].mutex, NULL)) {
+ cli_errmsg("mutex init fail\n");
+ mpool_destroy(mempool);
+ return 1;
+ }
+ }
+ cache_entries = entries;
+ return 0;
+}
+
+void cache_swap(struct CACHE_ENTRY *e, unsigned int a) {
+ struct CACHE_ENTRY t;
+ unsigned int b = a-1;
+
+ if(!a || e[a].hits <= e[b].hits)
+ return;
+
+ do {
+ if(e[a].hits > e[b].hits)
+ continue;
+ break;
+ } while(b--);
+ b++;
+
+ memcpy(&t, &e[a], sizeof(t));
+ memcpy(&e[a], &e[b], sizeof(t));
+ memcpy(&e[b], &t, sizeof(t));
+}
+
+void updb(uint32_t db, unsigned int skip) {
+ unsigned int i;
+ for(i=0; i<256; i++) {
+ if(i==skip) continue;
+ if(pthread_mutex_lock(&cache[i].mutex)) {
+ cli_errmsg("mutex lock fail\n");
+ continue;
+ }
+ cache[i].lastdb = db;
+ pthread_mutex_unlock(&cache[i].mutex);
+ }
+}
+
+int cache_check(unsigned char *md5, cli_ctx *ctx) {
+ unsigned int i;
+ int ret = CL_VIRUS;
+ struct CACHE_ENTRY *e;
+ struct CACHE *c;
+
+ if(!cache) return ret;
+
+ c = &cache[*md5];
+ e = c->items;
+ if(pthread_mutex_lock(&c->mutex)) {
+ cli_errmsg("mutex lock fail\n");
+ return ret;
+ }
+ if(c->lastdb <= ctx->engine->dbversion[0]) {
+ if(c->lastdb < ctx->engine->dbversion[0]) {
+ c->lastdb = ctx->engine->dbversion[0];
+ updb(c->lastdb, *md5);
+ } else {
+ for(i=0; i<cache_entries; i++) {
+ if(!e[i].hits) break;
+ if(e[i].dbver == c->lastdb && !memcmp(e[i].hash, md5 + 1, 15)) {
+ e[i].hits++;
+ cache_swap(e, i);
+ ret = CL_CLEAN;
+ cli_warnmsg("cached\n");
+ break;
+ }
+ }
+ }
+ }
+ pthread_mutex_unlock(&c->mutex);
+ return ret;
+}
+
+void cache_add(unsigned char *md5, cli_ctx *ctx) {
+ unsigned int i, replace;
+ struct CACHE_ENTRY *e;
+ struct CACHE *c;
+
+ if(!cache) return;
+
+ c = &cache[*md5];
+ e = c->items;
+ if(pthread_mutex_lock(&c->mutex)) {
+ cli_errmsg("mutex lock fail\n");
+ return;
+ }
+ if(c->lastdb == ctx->engine->dbversion[0]) {
+ replace = cache_entries;
+ for(i=0; i<cache_entries; i++) {
+ if(!e[i].hits) break;
+ if(replace == cache_entries && e[i].dbver < c->lastdb) {
+ replace = i;
+ } else if(e[i].hits && !memcmp(e[i].hash, md5 + 1, 15)) {
+ e[i].hits++;
+ cache_swap(e, i);
+ pthread_mutex_unlock(&c->mutex);
+ return;
+ }
+ }
+ if(replace == cache_entries)
+ replace = cache_entries - 1 - (rand() % (cache_entries / CACHE_PERTURB));
+ e[replace].hits = 1;
+ e[replace].dbver = c->lastdb;
+ memcpy(e[replace].hash, md5 + 1, 15);
+ cache_swap(e, replace);
+ }
+ pthread_mutex_unlock(&c->mutex);
+ return;
+}
+
+int cache_chekdesc(int desc, size_t size, unsigned char *hash, cli_ctx *ctx) {
+ cli_md5_ctx md5;
+ unsigned char buf[8192];
+
+ off_t seekback = lseek(desc, 0, SEEK_CUR);
+
+ if(!cache) return CL_VIRUS;
+
+ cli_md5_init(&md5);
+ while(size) {
+ size_t readme = size < sizeof(buf) ? size : sizeof(buf);
+ if(cli_readn(desc, buf, readme)!=readme) {
+ lseek(desc, seekback, SEEK_SET);
+ return CL_VIRUS;
+ }
+ cli_md5_update(&md5, buf, readme);
+ size-=readme;
+ }
+ cli_md5_final(hash, &md5);
+ lseek(desc, seekback, SEEK_SET);
+ return cache_check(hash, ctx);
+}
diff --git a/libclamav/cache.h b/libclamav/cache.h
new file mode 100644
index 0000000..d70a7dc
--- /dev/null
+++ b/libclamav/cache.h
@@ -0,0 +1,11 @@
+#ifndef __CACHE_H
+#define __CACHE_H
+
+#include "others.h"
+
+int cache_init(unsigned int entries);
+int cache_check(unsigned char *md5, cli_ctx *ctx);
+void cache_add(unsigned char *md5, cli_ctx *ctx);
+int cache_chekdesc(int desc, size_t size, unsigned char *hash, cli_ctx *ctx);
+
+#endif
diff --git a/libclamav/libclamav.map b/libclamav/libclamav.map
index ea2d7be..40d1b25 100644
--- a/libclamav/libclamav.map
+++ b/libclamav/libclamav.map
@@ -154,6 +154,7 @@ CLAMAV_PRIVATE {
cli_bytecode_context_setparam_ptr;
cli_bytecode_context_getresult_int;
cli_bytecode_context_clear;
+ cache_init;
local:
*;
};
diff --git a/libclamav/matcher.c b/libclamav/matcher.c
index dd2008d..32680dc 100644
--- a/libclamav/matcher.c
+++ b/libclamav/matcher.c
@@ -445,3 +445,173 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
return (acmode & AC_SCAN_FT) ? type : CL_CLEAN;
}
+
+int cli_scandesc_hash(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, unsigned char *digest)
+{
+ unsigned char *buffer, *buff, *endbl, *upt;
+ int ret = CL_CLEAN, type = CL_CLEAN, bytes;
+ unsigned int i, evalcnt;
+ uint32_t buffersize, length, maxpatlen, shift = 0, offset = 0;
+ uint64_t evalids;
+ struct cli_ac_data gdata, tdata;
+ struct cli_matcher *groot = NULL, *troot = NULL;
+
+
+ if(!ctx->engine) {
+ cli_errmsg("cli_scandesc: engine == NULL\n");
+ return CL_ENULLARG;
+ }
+
+ if(!ftonly)
+ groot = ctx->engine->root[0]; /* generic signatures */
+
+ if(ftype) {
+ for(i = 1; i < CLI_MTARGETS; i++) {
+ if(cli_mtargets[i].target == ftype) {
+ troot = ctx->engine->root[i];
+ break;
+ }
+ }
+ }
+
+ if(ftonly) {
+ if(!troot)
+ return CL_CLEAN;
+
+ maxpatlen = troot->maxpatlen;
+ } else {
+ if(troot)
+ maxpatlen = MAX(troot->maxpatlen, groot->maxpatlen);
+ else
+ maxpatlen = groot->maxpatlen;
+ }
+
+ /* prepare the buffer */
+ buffersize = maxpatlen + SCANBUFF;
+ if(!(buffer = (unsigned char *) cli_calloc(buffersize, sizeof(unsigned char)))) {
+ cli_dbgmsg("cli_scandesc(): unable to cli_calloc(%u)\n", buffersize);
+ return CL_EMEM;
+ }
+
+ if(!ftonly && (ret = cli_ac_initdata(&gdata, groot->ac_partsigs, groot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN)))
+ return ret;
+
+ if(troot) {
+ if((ret = cli_ac_initdata(&tdata, troot->ac_partsigs, troot->ac_lsigs, CLI_DEFAULT_AC_TRACKLEN)))
+ return ret;
+ }
+
+ buff = buffer;
+ buff += maxpatlen; /* pointer to read data block */
+ endbl = buff + SCANBUFF - maxpatlen; /* pointer to the last block
+ * length of maxpatlen
+ */
+
+ upt = buff;
+ while((bytes = cli_readn(desc, buff + shift, SCANBUFF - shift)) > 0) {
+
+ if(ctx->scanned)
+ *ctx->scanned += bytes / CL_COUNT_PRECISION;
+
+ length = shift + bytes;
+ if(upt == buffer)
+ length += maxpatlen;
+
+ if(troot) {
+ if(troot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, troot, offset, ftype, desc)) != CL_VIRUS)
+ ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, NULL, troot, &tdata, offset, ftype, desc, ftoffset, acmode, NULL);
+
+ if(ret == CL_VIRUS) {
+ free(buffer);
+ if(!ftonly)
+ cli_ac_freedata(&gdata);
+ cli_ac_freedata(&tdata);
+
+ if(cli_checkfp(desc, ctx))
+ return CL_CLEAN;
+ else
+ return CL_VIRUS;
+ }
+ }
+
+ if(!ftonly) {
+ if(groot->ac_only || (ret = cli_bm_scanbuff(upt, length, ctx->virname, groot, offset, ftype, desc)) != CL_VIRUS)
+ ret = cli_ac_scanbuff(upt, length, ctx->virname, NULL, NULL, groot, &gdata, offset, ftype, desc, ftoffset, acmode, NULL);
+
+ if(ret == CL_VIRUS) {
+ free(buffer);
+ cli_ac_freedata(&gdata);
+ if(troot)
+ cli_ac_freedata(&tdata);
+ if(cli_checkfp(desc, ctx))
+ return CL_CLEAN;
+ else
+ return CL_VIRUS;
+
+ } else if((acmode & AC_SCAN_FT) && ret >= CL_TYPENO) {
+ if(ret > type)
+ type = ret;
+ }
+ }
+
+ if(bytes + shift == SCANBUFF) {
+ memmove(buffer, endbl, maxpatlen);
+ offset += SCANBUFF;
+
+ if(upt == buff) {
+ upt = buffer;
+ offset -= maxpatlen;
+ }
+
+ shift = 0;
+
+ } else {
+ shift += bytes;
+ }
+ }
+
+ free(buffer);
+
+ if(troot) {
+ for(i = 0; i < troot->ac_lsigs; i++) {
+ evalcnt = 0;
+ evalids = 0;
+ if(cli_ac_chklsig(troot->ac_lsigtable[i]->logic, troot->ac_lsigtable[i]->logic + strlen(troot->ac_lsigtable[i]->logic), tdata.lsigcnt[i], &evalcnt, &evalids, 0) == 1) {
+ if(ctx->virname)
+ *ctx->virname = troot->ac_lsigtable[i]->virname;
+ ret = CL_VIRUS;
+ break;
+ }
+ }
+ cli_ac_freedata(&tdata);
+ }
+
+ if(groot) {
+ if(ret != CL_VIRUS) for(i = 0; i < groot->ac_lsigs; i++) {
+ evalcnt = 0;
+ evalids = 0;
+ if(cli_ac_chklsig(groot->ac_lsigtable[i]->logic, groot->ac_lsigtable[i]->logic + strlen(groot->ac_lsigtable[i]->logic), gdata.lsigcnt[i], &evalcnt, &evalids, 0) == 1) {
+ if(ctx->virname)
+ *ctx->virname = groot->ac_lsigtable[i]->virname;
+ ret = CL_VIRUS;
+ break;
+ }
+ }
+ cli_ac_freedata(&gdata);
+ }
+
+ if(ret == CL_VIRUS) {
+ lseek(desc, 0, SEEK_SET);
+ if(cli_checkfp(desc, ctx))
+ return CL_CLEAN;
+ else
+ return CL_VIRUS;
+ }
+
+ if(!ftonly && ctx->engine->md5_hdb) {
+ if(cli_bm_scanbuff(digest, 16, ctx->virname, ctx->engine->md5_hdb, 0, 0, -1) == CL_VIRUS && (cli_bm_scanbuff(digest, 16, NULL, ctx->engine->md5_fp, 0, 0, -1) != CL_VIRUS))
+ return CL_VIRUS;
+ }
+
+ return (acmode & AC_SCAN_FT) ? type : CL_CLEAN;
+}
diff --git a/libclamav/matcher.h b/libclamav/matcher.h
index 82d030b..e6adc7c 100644
--- a/libclamav/matcher.h
+++ b/libclamav/matcher.h
@@ -127,6 +127,7 @@ struct cli_target_info {
int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset, cli_ctx *ctx, cli_file_t ftype, struct cli_ac_data **acdata);
int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode);
+int cli_scandesc_hash(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, unsigned char *digest);
int cli_validatesig(cli_file_t ftype, const char *offstr, off_t fileoff, struct cli_target_info *info, int desc, const char *virname);
diff --git a/libclamav/scanners.c b/libclamav/scanners.c
index 7f6a1be..085a0eb 100644
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@ -96,6 +96,7 @@
#include "macho.h"
#include "ishield.h"
#include "7z.h"
+#include "cache.h"
#ifdef HAVE_BZLIB_H
#include <bzlib.h>
@@ -1881,6 +1882,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
cli_file_t type, dettype = 0;
struct stat sb;
uint8_t typercg = 1;
+ unsigned char hash[16];
if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) {
cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel);
@@ -1910,13 +1912,17 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
if(cli_updatelimits(ctx, sb.st_size)!=CL_CLEAN)
return CL_CLEAN;
+ if(cache_chekdesc(desc, sb.st_size, hash, ctx) == CL_CLEAN)
+ return CL_CLEAN;
+
if(!ctx->options || (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_scandesc(desc, ctx, 0, 0, NULL, AC_SCAN_VIR)) == CL_VIRUS)
+ if((ret = cli_scandesc_hash(desc, ctx, 0, 0, NULL, AC_SCAN_VIR, hash)) == CL_VIRUS)
cli_dbgmsg("%s found in descriptor %d\n", *ctx->virname, desc);
+ else cache_add(hash, ctx);
return ret;
}
@@ -2177,8 +2183,10 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx)
case CL_EMAXSIZE:
case CL_EMAXFILES:
cli_dbgmsg("Descriptor[%d]: %s\n", desc, cl_strerror(ret));
+ cache_add(hash, ctx);
return CL_CLEAN;
default:
+ if(ret == CL_CLEAN) cache_add(hash, ctx);
return ret;
}
}
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list