[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6634-g03ef06d
aCaB
acab at clamav.net
Mon Feb 14 09:56:01 UTC 2011
The following commit has been merged in the debian/unstable branch:
commit 03ef06d4da2dfd94f5afae8db88a6ede239ab029
Author: aCaB <acab at clamav.net>
Date: Mon Feb 14 10:54:31 2011 +0100
merge --squash clamav-0.97
diff --git a/ChangeLog b/ChangeLog
index 9f127d0..e0a66f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,192 @@
+Mon Feb 7 17:45:49 CET 2011 (tk)
+---------------------------------
+ * V 0.97
+
+Mon Feb 7 17:24:52 CET 2011 (tk)
+---------------------------------
+ * libclamav/vba_extract.c: fix error path double free (bb#2486)
+
+Fri Feb 4 16:55:07 EET 2011 (edwin)
+------------------------------------
+ * libclamav/phishcheck.c: fix some missed safebrowsing URLs (bb #2514)
+
+Fri Feb 4 14:35:32 CET 2011 (tk)
+---------------------------------
+ * libclamav/matcher-bm.c: fix error message (bb#2513)
+
+Thu Feb 3 16:40:24 CET 2011 (acab)
+-----------------------------------
+ * libclamav/matcher-hash.c: stop leaking virusnames (nopool mode)
+
+Mon Jan 31 16:53:39 CET 2011 (tk)
+---------------------------------
+ * V 0.97rc
+
+Fri Jan 21 15:05:13 CET 2011 (acab)
+-----------------------------------
+ * libclamav/disasm.c: sign extend immeds, displacers and reljumps (bb#2341)
+
+Thu Jan 20 15:34:00 CET 2011 (tk)
+---------------------------------
+ * shared/optparser: when size limit is disabled set it to 4GB (bb#2471)
+
+Thu Jan 20 16:11:43 EET 2011 (edwin)
+------------------------------------
+ * shared/optparser.c: reduce BytecodeTimeout to 5s (instead of 60).
+
+Thu Jan 20 16:09:29 EET 2011 (edwin)
+-----------------------------------
+ * libclamav/bytecode_vm.c: fix memset on bigendian arch (bb #2478).
+
+Thu Jan 20 11:38:33 EET 2011 (edwin)
+------------------------------------
+ * libclamav/pdf.c: fix missed detection (bb #2455).
+
+Thu Jan 20 11:19:50 EET 2011 (edwin)
+-----------------------------------
+ * libclamav/pdf.c: fix another pdf uninit (bb #2404).
+
+Thu Jan 20 11:16:17 EET 2011 (edwin)
+------------------------------------
+ * libclamav/pdf.c: fix uninit value (bb #2455).
+
+Thu Jan 20 10:11:32 EET 2011 (edwin)
+------------------------------------
+ * libclamav/c++/llvm: port 2 upstream commits to fix bb#8723.
+
+Thu Jan 20 10:02:24 EET 2011 (edwin)
+------------------------------------
+ * unit_tests/check_bytecode.c: fix build on etch (bb #2399),
+ thanks to David F. Skoll <dfs*roaringpenguin.com>.
+
+Thu Jan 20 03:29:04 CET 2011 (acab)
+-----------------------------------
+ * win32/compat/resolv.c: fix nasty typo
+
+Wed Jan 19 12:16:23 CET 2011 (acab)
+-----------------------------------
+ * build system: add AM macro CLAMDSCAN_LIBS (bb#2400)
+
+Tue Jan 18 16:18:07 CET 2011 (tk)
+---------------------------------
+ * sigtool: handle .hs(b|u) and .ms(b|u) files
+
+Tue Jan 18 14:59:37 CET 2011 (tk)
+---------------------------------
+ * sigtool: add new options --sha1 and --sha256
+
+Mon Jan 17 19:05:25 CET 2011 (tk)
+---------------------------------
+ * freshclam: detect and fix corruptions of existing db files
+
+Fri Jan 14 23:33:25 CET 2011 (acab)
+-----------------------------------
+ * libclamav: merge multihash branch - we can now match on md5, sha1, sha256
+
+Fri Jan 14 15:52:30 CET 2011 (tk)
+---------------------------------
+ * freshclam: verify integrity of all *.cvd files during each session
+
+Mon Jan 10 23:51:08 EET 2011 (edwin)
+------------------------------------
+ * libclamav/c++/ClamBCRTChecks.cpp: fix paranoid mode crash (bb #2434).
+
+Mon Jan 10 18:43:02 CET 2011 (tk)
+---------------------------------
+ * sigtool: improve handling of spaces in cdiffs (bb#2090)
+
+Thu Jan 6 14:52:38 CET 2011 (acab)
+-----------------------------------
+ * libclamav/hashtab.c: properly clear the table
+
+Mon Jan 3 17:10:03 CET 2011 (tk)
+---------------------------------
+ * freshclam/manager.c: fix version warning (bb#2456)
+
+Mon Jan 3 16:38:46 CET 2011 (tk)
+---------------------------------
+ * libclamav: improve handling of HandlerType (bb#2298)
+
+Thu Dec 30 15:02:05 CET 2010 (tk)
+---------------------------------
+ * libclamav/filetypes.c: improve detection of tar files
+
+Wed Dec 29 14:36:46 CET 2010 (tk)
+---------------------------------
+ * libclamav/scanners.c: improve scanning of mail files in raw mode (bb#2244)
+
+Tue Dec 28 18:22:30 CET 2010 (tk)
+---------------------------------
+ * clamscan: add new options --follow-(dir|file)-symlinks (bb#1870)
+
+Tue Dec 28 13:03:14 CET 2010 (tk)
+---------------------------------
+ * libclamav/blob.c: properly scan files when LeaveTemporaryFiles
+ is enabled (bb#2447)
+
+Mon Dec 27 15:21:43 CET 2010 (acab)
+-----------------------------------
+ * libclamav/disasm.c: fix movsx/movzx disasm src size (bb#2341)
+
+Wed Dec 22 12:10:06 CET 2010 (tk)
+---------------------------------
+ * freshclam: fix again handling of relative db paths (bb#2240)
+
+Tue Dec 21 16:00:26 CET 2010 (acab)
+-----------------------------------
+ * clamav-milter: add LogClean option (bb#2442)
+
+Mon Dec 20 16:30:57 EET 2010 (edwin)
+-----------------------------------
+ * clamd: bump default MaxConnectionQueueLength to 200
+
+Fri Dec 17 17:10:46 CET 2010 (acab)
+-----------------------------------
+ * shared/cdiff.c: Fix error path double free - missed in 4bc4581d
+ thanks Michael Tautschnig <mt*debian.org>
+
+Fri Dec 17 14:21:21 CET 2010 (acab)
+-----------------------------------
+ * clamav-milter/whitelist.c, clamscan/manager.c, libclamav/sis.c:
+ error path leaks and similar - thanks Michael Tautschnig <mt*debian.org>
+
+Thu Dec 16 15:31:38 CET 2010 (acab)
+---------------------------------
+ * clamav-milter: handle EINTR during waitpid()
+
+Thu Dec 16 14:15:33 CET 2010 (tk)
+---------------------------------
+ * freshclam, clamd: handle EINTR during waitpid() (bb#2422)
+
+Tue Dec 14 19:13:53 EET 2010 (edwin)
+------------------------------------
+ * libclamav/chmunpack.c: avoid crash on fstat failure (bb #2429).
+
+Tue Dec 14 16:07:42 CET 2010 (tk)
+---------------------------------
+ * libclamav: pass array with initial matches to bytecode (bb#2397)
+
+Tue Dec 14 12:20:34 CET 2010 (tk)
+---------------------------------
+ * libclamav/msexpand.c: fix name clash on HP-UX (bb#2398)
+
+Tue Dec 14 11:33:00 CET 2010 (tk)
+---------------------------------
+ * libclamav/scanners.c: ScanMail wasn't always honored (bb#2426)
+
+Thu Dec 9 13:40:55 CET 2010 (tk)
+---------------------------------
+ * clamd: don't report file hashes to clients (bb#2409)
+
+Thu Dec 9 13:29:16 CET 2010 (tk)
+---------------------------------
+ * libclamav: preserve callbacks during db reload (bb#2418)
+
+Thu Dec 2 18:44:12 CET 2010 (tk)
+---------------------------------
+ * libclamav/matcher-ac.c: optimize handling of multi-part signatures (bb#2322)
+ Patch by finglenark <finglenark*gmail.com>
+
Tue Nov 30 14:05:34 CET 2010 (tk)
---------------------------------
* V 0.96.5
diff --git a/Makefile.in b/Makefile.in
index ecd0705..79fa8ad 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -199,6 +199,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/NEWS b/NEWS
index 477822d..2f4bf79 100644
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,23 @@
-0.96.5
-------
+0.97
+----
+
+ClamAV 0.97 brings many improvements, including complete Windows support
+(all major components compile out-of-box under Visual Studio), support for
+signatures based on SHA1 and SHA256, better error detection, as well as
+speed and memory optimizations. The complete list of changes is available
+in the ChangeLog file. For upgrade notes and tips please see:
+https://wiki.clamav.net/Main/UpgradeNotes097
+
+With Sourcefire, Inc. acquisition of Immunet Corp., ClamAV for Windows
+3.0 has been renamed Immunet 3.0, powered by ClamAV. This release
+contains the fully integrated LibClamAV 0.97 engine for offline,
+OnDemand, and OnAccess scanning. Immunet 3.0 users can now utilize
+the full power of the LibClamAV engine, all the ClamAV signatures,
+and creation of custom signatures on any platform running Immunet 3.0,
+powered by ClamAV. If you run Windows systems in your environment and
+need an AV solution to protect them, give Immunet 3.0, powered by ClamAV
+a try; you can download it from http://www.clamav.net/about/win32
-ClamAV 0.96.5 includes bugfixes and minor feature enhancements, such as
-improved handling of detection statistics, better file logging,
-and support for custom database URLs in freshclam. Please refer to the
-ChangeLog for details.
--
The ClamAV team (http://www.clamav.net/team)
diff --git a/README b/README
index fdc7be4..fef8ee3 100644
--- a/README
+++ b/README
@@ -2,6 +2,30 @@ Note: This README/NEWS file refers to the source tarball. Some things described
here may not be available in binary packages.
--
+0.97
+----
+
+ClamAV 0.97 brings many improvements, including complete Windows support
+(all major components compile out-of-box under Visual Studio), support for
+signatures based on SHA1 and SHA256, better error detection, as well as
+speed and memory optimizations. The complete list of changes is available
+in the ChangeLog file. For upgrade notes and tips please see:
+https://wiki.clamav.net/Main/UpgradeNotes097
+
+With Sourcefire, Inc. acquisition of Immunet Corp., ClamAV for Windows
+3.0 has been renamed Immunet 3.0, powered by ClamAV. This release
+contains the fully integrated LibClamAV 0.97 engine for offline,
+OnDemand, and OnAccess scanning. Immunet 3.0 users can now utilize
+the full power of the LibClamAV engine, all the ClamAV signatures,
+and creation of custom signatures on any platform running Immunet 3.0,
+powered by ClamAV. If you run Windows systems in your environment and
+need an AV solution to protect them, give Immunet 3.0, powered by ClamAV
+a try; you can download it from http://www.clamav.net/about/win32
+
+
+--
+The ClamAV team (http://www.clamav.net/team)
+
0.96.5
------
diff --git a/clamav-milter/Makefile.in b/clamav-milter/Makefile.in
index 9d37b93..161ff13 100644
--- a/clamav-milter/Makefile.in
+++ b/clamav-milter/Makefile.in
@@ -173,6 +173,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/clamav-milter/clamfi.c b/clamav-milter/clamfi.c
index 9f9573c..06e7bb7 100644
--- a/clamav-milter/clamfi.c
+++ b/clamav-milter/clamfi.c
@@ -58,11 +58,13 @@ static char *rejectfmt = NULL;
int addxvirus = 0; /* 0 - don't add | 1 - replace | 2 - add */
char xvirushdr[255];
char *viraction = NULL;
-enum {
- LOGINF_NONE,
- LOGINF_BASIC,
- LOGINF_FULL
-} loginfected;
+
+#define LOGINF_NONE 0
+#define LOGINF_BASIC 1
+#define LOGINF_FULL 2
+#define LOGCLN_BASIC 4
+#define LOGCLN_FULL 8
+int loginfected;
#define CLAMFIBUFSZ 1424
static const char *HDR_UNAVAIL = "UNKNOWN";
@@ -218,7 +220,7 @@ sfsistat clamfi_header(SMFICTX *ctx, char *headerf, char *headerv) {
if(!headerf) return SMFIS_CONTINUE; /* just in case */
- if(loginfected == LOGINF_FULL || viraction) {
+ if((loginfected & (LOGINF_FULL | LOGCLN_FULL)) || viraction) {
if(!cf->msg_subj && !strcasecmp(headerf, "Subject"))
cf->msg_subj = strdup(headerv ? headerv : "");
if(!cf->msg_date && !strcasecmp(headerf, "Date"))
@@ -317,10 +319,23 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
len = strlen(reply);
if(len>5 && !strcmp(reply + len - 5, ": OK\n")) {
if(addxvirus) add_x_header(ctx, "Clean", cf->scanned_count, cf->status_count);
+ if(loginfected & LOGCLN_FULL) {
+ const char *id = smfi_getsymval(ctx, "{i}");
+ const char *from = smfi_getsymval(ctx, "{mail_addr}");
+ const char *to = smfi_getsymval(ctx, "{rcpt_addr}");
+ const char *msg_subj = makesanehdr(cf->msg_subj);
+ const char *msg_date = makesanehdr(cf->msg_date);
+ const char *msg_id = makesanehdr(cf->msg_id);
+ logg("~Clean message %s from <%s> to <%s> with subject '%s' message-id '%s' date '%s'\n", id, from, to, msg_subj, msg_id, msg_date);
+ } else if(loginfected & LOGCLN_BASIC) {
+ const char *from = smfi_getsymval(ctx, "{mail_addr}");
+ const char *to = smfi_getsymval(ctx, "{rcpt_addr}");
+ logg("~Clean message from <%s> to <%s>\n", from, to);
+ }
ret = CleanAction(ctx);
} else if (len>7 && !strcmp(reply + len - 7, " FOUND\n")) {
cf->virusname = NULL;
- if(loginfected || addxvirus || rejectfmt || viraction) {
+ if((loginfected & (LOGINF_BASIC | LOGINF_FULL)) || addxvirus || rejectfmt || viraction) {
char *vir;
reply[len-7] = '\0';
@@ -344,7 +359,7 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
if(!from) from = HDR_UNAVAIL;
if(!to) to = HDR_UNAVAIL;
- if(loginfected == LOGINF_FULL || viraction) {
+ if((loginfected & LOGINF_FULL) || viraction) {
const char *id = smfi_getsymval(ctx, "{i}");
const char *msg_subj = makesanehdr(cf->msg_subj);
const char *msg_date = makesanehdr(cf->msg_date);
@@ -352,7 +367,7 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
if(!id) id = HDR_UNAVAIL;
- if(loginfected == LOGINF_FULL)
+ if(loginfected & LOGINF_FULL)
logg("~Message %s from <%s> to <%s> with subject '%s' message-id '%s' date '%s' infected by %s\n", id, from, to, msg_subj, msg_id, msg_date, vir);
if(viraction) {
@@ -382,8 +397,10 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
args[8] = NULL;
exit(execvp(viraction, args));
} else if(pid > 0) {
+ int wret;
pthread_mutex_unlock(&virusaction_lock);
- if(waitpid(pid, &ret, 0)<0)
+ while((wret = waitpid(pid, &ret, 0)) == -1 && errno == EINTR);
+ if(wret<0)
logg("!VirusEvent: waitpid() failed: %s\n", cli_strerror(errno, er, sizeof(er)));
else {
if(WIFEXITED(ret))
@@ -404,7 +421,7 @@ sfsistat clamfi_eom(SMFICTX *ctx) {
free(e_msg_id);
}
}
- if(loginfected == LOGINF_BASIC)
+ if(loginfected & LOGINF_BASIC)
logg("~Message from <%s> to <%s> infected by %s\n", from, to, vir);
}
}
@@ -509,6 +526,17 @@ int init_actions(struct optstruct *opts) {
return 1;
}
+ if((opt = optget(opts, "LogClean"))->enabled) {
+ if(!strcasecmp(opt->strarg, "Basic"))
+ loginfected |= LOGCLN_BASIC;
+ else if(!strcasecmp(opt->strarg, "Full"))
+ loginfected |= LOGCLN_FULL;
+ else if(strcasecmp(opt->strarg, "Off")) {
+ logg("!Invalid setting %s for option LogInfected\n", opt->strarg);
+ return 1;
+ }
+ }
+
if((opt = optget(opts, "VirusAction"))->enabled)
viraction = strdup(opt->strarg);
diff --git a/clamav-milter/whitelist.c b/clamav-milter/whitelist.c
index 66f43f4..19263d7 100644
--- a/clamav-milter/whitelist.c
+++ b/clamav-milter/whitelist.c
@@ -90,6 +90,7 @@ int whitelist_init(const char *fname) {
if (!(w = (struct WHLST *)malloc(sizeof(*w)))) {
logg("!Out of memory loading whitelist file\n");
whitelist_free();
+ fclose(f);
return 1;
}
w->next = (*addto);
@@ -97,9 +98,11 @@ int whitelist_init(const char *fname) {
if (cli_regcomp(&w->preg, ptr, REG_ICASE|REG_NOSUB)) {
logg("!Failed to compile regex '%s' in whitelist file\n", ptr);
whitelist_free();
+ fclose(f);
return 1;
}
}
+ fclose(f);
return 0;
}
diff --git a/clambc/Makefile.in b/clambc/Makefile.in
index f319777..7fd90bb 100644
--- a/clambc/Makefile.in
+++ b/clambc/Makefile.in
@@ -115,6 +115,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/clamconf/Makefile.in b/clamconf/Makefile.in
index a37d058..7322c1f 100644
--- a/clamconf/Makefile.in
+++ b/clamconf/Makefile.in
@@ -133,6 +133,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/clamd/Makefile.in b/clamd/Makefile.in
index 760da58..d16d81c 100644
--- a/clamd/Makefile.in
+++ b/clamd/Makefile.in
@@ -151,6 +151,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/clamd/others.c b/clamd/others.c
index 66a0d94..93d6c3c 100644
--- a/clamd/others.c
+++ b/clamd/others.c
@@ -146,7 +146,7 @@ void virusaction(const char *filename, const char *virname, const struct optstru
exit(execle("/bin/sh", "sh", "-c", buffer_cmd, NULL, env));
} else if(pid > 0) { /* parent */
pthread_mutex_unlock(&virusaction_lock);
- waitpid(pid, NULL, 0);
+ while(waitpid(pid, NULL, 0) == -1 && errno == EINTR);
} else {
logg("!VirusEvent: fork failed.\n");
}
diff --git a/clamd/scanner.c b/clamd/scanner.c
index 1d1c5a5..2a084b1 100644
--- a/clamd/scanner.c
+++ b/clamd/scanner.c
@@ -239,7 +239,7 @@ int scan_callback(struct stat *sb, char *filename, const char *msg, enum cli_ftw
if (ret == CL_VIRUS) {
scandata->infected++;
- if (conn_reply_virus(scandata->conn, filename, virname, context.virhash, context.virsize) == -1) {
+ if (conn_reply_virus(scandata->conn, filename, virname) == -1) {
free(filename);
return CL_ETIMEOUT;
}
@@ -337,7 +337,7 @@ int scanfd(const int fd, const client_conn_t *conn, unsigned long int *scanned,
}
if(ret == CL_VIRUS) {
- if (conn_reply_virus(conn, fdstr, virname, context.virhash, context.virsize) == -1)
+ if (conn_reply_virus(conn, fdstr, virname) == -1)
ret = CL_ETIMEOUT;
if(context.virsize)
detstats_add(virname, "NOFNAME", context.virsize, context.virhash);
diff --git a/clamd/session.c b/clamd/session.c
index f12eb22..e41c806 100644
--- a/clamd/session.c
+++ b/clamd/session.c
@@ -156,18 +156,12 @@ int conn_reply(const client_conn_t *conn, const char *path,
}
int conn_reply_virus(const client_conn_t *conn, const char *file,
- const char *virname, const char *virhash, unsigned int virsize)
+ const char *virname)
{
if (conn->id) {
- if (virsize)
- return mdprintf(conn->sd, "%u: %s: %s(%s:%u) FOUND%c", conn->id, file,
- virname, virhash, virsize, conn->term);
return mdprintf(conn->sd, "%u: %s: %s FOUND%c", conn->id, file, virname,
conn->term);
}
- if (virsize)
- return mdprintf(conn->sd, "%s: %s(%s:%u) FOUND%c", file, virname, virhash,
- virsize, conn->term);
return mdprintf(conn->sd, "%s: %s FOUND%c", file, virname, conn->term);
}
diff --git a/clamd/session.h b/clamd/session.h
index 23fe976..183542d 100644
--- a/clamd/session.h
+++ b/clamd/session.h
@@ -96,7 +96,7 @@ int execute_or_dispatch_command(client_conn_t *conn, enum commands command, cons
int conn_reply(const client_conn_t *conn, const char *path, const char *msg, const char *status);
int conn_reply_single(const client_conn_t *conn, const char *path, const char *status);
-int conn_reply_virus(const client_conn_t *conn, const char *file, const char *virname, const char *virhash, unsigned int virsize);
+int conn_reply_virus(const client_conn_t *conn, const char *file, const char *virname);
int conn_reply_error(const client_conn_t *conn, const char *msg);
int conn_reply_errno(const client_conn_t *conn, const char *path, const char *msg);
#endif
diff --git a/clamdscan/Makefile.am b/clamdscan/Makefile.am
index 5c514ab..5a0bd4e 100644
--- a/clamdscan/Makefile.am
+++ b/clamdscan/Makefile.am
@@ -43,7 +43,7 @@ endif
DEFS = @DEFS@ -DCL_NOTHREADS -DCL_NOLIBCLAMAV
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/clamscan -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav
-LIBS = $(top_builddir)/libclamav/libclamav_internal_utils_nothreads.la @FRESHCLAM_LIBS@
+LIBS = $(top_builddir)/libclamav/libclamav_internal_utils_nothreads.la @CLAMDSCAN_LIBS@
AM_INSTALLCHECK_STD_OPTIONS_EXEMPT=clamdscan$(EXEEXT)
CLEANFILES=*.gcda *.gcno
diff --git a/clamdscan/Makefile.in b/clamdscan/Makefile.in
index a95acd4..71d11fb 100644
--- a/clamdscan/Makefile.in
+++ b/clamdscan/Makefile.in
@@ -144,6 +144,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
@@ -187,7 +188,7 @@ LIBCLAMAV_VERSION = @LIBCLAMAV_VERSION@
LIBLTDL = @LIBLTDL@
LIBM = @LIBM@
LIBOBJS = @LIBOBJS@
-LIBS = $(top_builddir)/libclamav/libclamav_internal_utils_nothreads.la @FRESHCLAM_LIBS@
+LIBS = $(top_builddir)/libclamav/libclamav_internal_utils_nothreads.la @CLAMDSCAN_LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
diff --git a/clamdtop/Makefile.in b/clamdtop/Makefile.in
index 09d89d8..09c5258 100644
--- a/clamdtop/Makefile.in
+++ b/clamdtop/Makefile.in
@@ -144,6 +144,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/clamscan/Makefile.am b/clamscan/Makefile.am
index c965af4..4a8e7d0 100644
--- a/clamscan/Makefile.am
+++ b/clamscan/Makefile.am
@@ -31,8 +31,6 @@ clamscan_SOURCES = \
$(top_srcdir)/shared/misc.c \
$(top_srcdir)/shared/misc.h \
clamscan.c \
- others.c \
- others.h \
global.h \
manager.c \
manager.h
diff --git a/clamscan/Makefile.in b/clamscan/Makefile.in
index 15aa33d..07c053d 100644
--- a/clamscan/Makefile.in
+++ b/clamscan/Makefile.in
@@ -79,7 +79,7 @@ am__installdirs = "$(DESTDIR)$(bindir)"
PROGRAMS = $(bin_PROGRAMS)
am_clamscan_OBJECTS = output.$(OBJEXT) getopt.$(OBJEXT) \
optparser.$(OBJEXT) actions.$(OBJEXT) misc.$(OBJEXT) \
- clamscan.$(OBJEXT) others.$(OBJEXT) manager.$(OBJEXT)
+ clamscan.$(OBJEXT) manager.$(OBJEXT)
clamscan_OBJECTS = $(am_clamscan_OBJECTS)
clamscan_LDADD = $(LDADD)
AM_V_lt = $(am__v_lt_$(V))
@@ -135,6 +135,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
@@ -288,8 +289,6 @@ clamscan_SOURCES = \
$(top_srcdir)/shared/misc.c \
$(top_srcdir)/shared/misc.h \
clamscan.c \
- others.c \
- others.h \
global.h \
manager.c \
manager.h
@@ -405,7 +404,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/manager.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/misc.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/optparser.Po at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/others.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/output.Po at am__quote@
.c.o:
diff --git a/clamscan/clamscan.c b/clamscan/clamscan.c
index f1a1d94..b11a27e 100644
--- a/clamscan/clamscan.c
+++ b/clamscan/clamscan.c
@@ -210,6 +210,8 @@ void help(void)
mprintf(" --log=FILE -l FILE Save scan report to FILE\n");
mprintf(" --recursive[=yes/no(*)] -r Scan subdirectories recursively\n");
mprintf(" --cross-fs[=yes(*)/no] Scan files and directories on other filesystems\n");
+ mprintf(" --follow-dir-symlinks[=0/1(*)/2] Follow directory symlinks (0 = never, 1 = direct, 2 = always)\n");
+ mprintf(" --follow-file-symlinks[=0/1(*)/2] Follow file symlinks (0 = never, 1 = direct, 2 = always)\n");
mprintf(" --file-list=FILE -f FILE Scan files from FILE\n");
mprintf(" --remove[=yes/no(*)] Remove infected files. Be careful!\n");
mprintf(" --move=DIRECTORY Move infected files into DIRECTORY\n");
@@ -221,7 +223,7 @@ void help(void)
mprintf("\n");
mprintf(" --bytecode[=yes(*)/no] Load bytecode from the database\n");
mprintf(" --bytecode-trust-all[=yes/no(*)] Trust all loaded bytecode\n");
- mprintf(" --bytecode-timeout=N Set bytecode timeout (in milliseconds)\n");
+ mprintf(" --bytecode-timeout=N Set bytecode timeout (in milliseconds)\n");
mprintf(" --detect-pua[=yes/no(*)] Detect Possibly Unwanted Applications\n");
mprintf(" --exclude-pua=CAT Skip PUA sigs of category CAT\n");
mprintf(" --include-pua=CAT Load PUA sigs of category CAT\n");
diff --git a/clamscan/manager.c b/clamscan/manager.c
index b4a5794..1672fcd 100644
--- a/clamscan/manager.c
+++ b/clamscan/manager.c
@@ -29,6 +29,9 @@
#include <ctype.h>
#include <sys/stat.h>
#include <sys/types.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
#include <dirent.h>
#ifndef _WIN32
#include <sys/wait.h>
@@ -43,9 +46,9 @@
#include <sys/types.h>
#include <signal.h>
#include <errno.h>
+#include <target.h>
#include "manager.h"
-#include "others.h"
#include "global.h"
#include "shared/optparser.h"
@@ -64,25 +67,66 @@
dev_t procdev;
#endif
-void scanfile(const char *filename, struct cl_engine *engine, const struct optstruct *opts, unsigned int options)
+#ifdef _WIN32
+/* FIXME: If possible, handle users correctly */
+static int checkaccess(const char *path, const char *username, int mode)
+{
+ return !_access(path, mode);
+}
+#else
+static int checkaccess(const char *path, const char *username, int mode)
+{
+ struct passwd *user;
+ int ret = 0, status;
+
+ if(!geteuid()) {
+
+ if((user = getpwnam(username)) == NULL) {
+ return -1;
+ }
+
+ switch(fork()) {
+ case -1:
+ return -2;
+
+ case 0:
+ if(setgid(user->pw_gid)) {
+ fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
+ exit(0);
+ }
+
+ if(setuid(user->pw_uid)) {
+ fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
+ exit(0);
+ }
+
+ if(access(path, mode))
+ exit(0);
+ else
+ exit(1);
+
+ default:
+ wait(&status);
+ if(WIFEXITED(status) && WEXITSTATUS(status) == 1)
+ ret = 1;
+ }
+
+ } else {
+ if(!access(path, mode))
+ ret = 1;
+ }
+
+ return ret;
+}
+#endif
+
+static void scanfile(const char *filename, struct cl_engine *engine, const struct optstruct *opts, unsigned int options)
{
int ret = 0, fd, included, printclean = 1;
- unsigned int fsize;
const struct optstruct *opt;
const char *virname;
-#ifdef C_LINUX
struct stat sb;
- /* argh, don't scan /proc files */
- if(procdev)
- if(stat(filename, &sb) != -1)
- if(sb.st_dev == procdev) {
- if(!printinfected)
- logg("~%s: Excluded (/proc)\n", filename);
- return;
- }
-#endif
-
if((opt = optget(opts, "exclude"))->enabled) {
while(opt) {
if(match_regex(filename, opt->strarg) == 1) {
@@ -110,13 +154,23 @@ void scanfile(const char *filename, struct cl_engine *engine, const struct optst
}
}
- fsize = fileinfo(filename, 1);
- if(fsize == 0) {
- if(!printinfected)
- logg("~%s: Empty file\n", filename);
- return;
+ /* argh, don't scan /proc files */
+ if(stat(filename, &sb) != -1) {
+#ifdef C_LINUX
+ if(procdev && sb.st_dev == procdev) {
+ if(!printinfected)
+ logg("~%s: Excluded (/proc)\n", filename);
+ return;
+ }
+#endif
+ if(!sb.st_size) {
+ if(!printinfected)
+ logg("~%s: Empty file\n", filename);
+ return;
+ }
+ info.rblocks += sb.st_size / CL_COUNT_PRECISION;
}
- info.rblocks += fsize / CL_COUNT_PRECISION;
+
#ifndef _WIN32
if(geteuid())
if(checkaccess(filename, NULL, R_OK) != 1) {
@@ -159,14 +213,15 @@ void scanfile(const char *filename, struct cl_engine *engine, const struct optst
action(filename);
}
-void scandirs(const char *dirname, struct cl_engine *engine, const struct optstruct *opts, unsigned int options, unsigned int depth, dev_t dev)
+static void scandirs(const char *dirname, struct cl_engine *engine, const struct optstruct *opts, unsigned int options, unsigned int depth, dev_t dev)
{
DIR *dd;
struct dirent *dent;
- struct stat statbuf;
+ struct stat sb;
char *fname;
int included;
const struct optstruct *opt;
+ unsigned int dirlnk, filelnk;
if((opt = optget(opts, "exclude-dir"))->enabled) {
@@ -199,6 +254,9 @@ void scandirs(const char *dirname, struct cl_engine *engine, const struct optstr
if(depth > (unsigned int) optget(opts, "max-dir-recursion")->numarg)
return;
+ dirlnk = optget(opts, "follow-dir-symlinks")->numarg;
+ filelnk = optget(opts, "follow-file-symlinks")->numarg;
+
if((dd = opendir(dirname)) != NULL) {
info.dirs++;
depth++;
@@ -214,19 +272,35 @@ void scandirs(const char *dirname, struct cl_engine *engine, const struct optstr
sprintf(fname, "%s"PATHSEP"%s", dirname, dent->d_name);
/* stat the file */
- if(lstat(fname, &statbuf) != -1) {
+ if(lstat(fname, &sb) != -1) {
if(!optget(opts, "cross-fs")->enabled) {
- if(statbuf.st_dev != dev) {
+ if(sb.st_dev != dev) {
if(!printinfected)
logg("~%s: Excluded\n", fname);
free(fname);
continue;
}
}
- if(S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode) && recursion)
- scandirs(fname, engine, opts, options, depth, dev);
- else if(S_ISREG(statbuf.st_mode))
+ if(S_ISLNK(sb.st_mode)) {
+ if(dirlnk != 2 && filelnk != 2) {
+ if(!printinfected)
+ logg("%s: Symbolic link\n", fname);
+ } else if(stat(fname, &sb) != -1) {
+ if(S_ISREG(sb.st_mode) && filelnk == 2) {
+ scanfile(fname, engine, opts, options);
+ } else if(S_ISDIR(sb.st_mode) && dirlnk == 2) {
+ if(recursion)
+ scandirs(fname, engine, opts, options, depth, dev);
+ } else {
+ if(!printinfected)
+ logg("%s: Symbolic link\n", fname);
+ }
+ }
+ } else if(S_ISREG(sb.st_mode)) {
scanfile(fname, engine, opts, options);
+ } else if(S_ISDIR(sb.st_mode) && recursion) {
+ scandirs(fname, engine, opts, options, depth, dev);
+ }
}
free(fname);
}
@@ -273,6 +347,7 @@ static int scanstdin(const struct cl_engine *engine, const struct optstruct *opt
if(fwrite(buff, 1, bread, fs) < bread) {
logg("!Can't write to %s\n", file);
free(file);
+ fclose(fs);
return 2;
}
}
@@ -305,9 +380,8 @@ static int scanstdin(const struct cl_engine *engine, const struct optstruct *opt
int scanmanager(const struct optstruct *opts)
{
- mode_t fmode;
- int ret = 0, fmodeint, i;
- unsigned int options = 0, dboptions = 0;
+ int ret = 0, i;
+ unsigned int options = 0, dboptions = 0, dirlnk = 1, filelnk = 1;
struct cl_engine *engine;
struct stat sb;
char *file, cwd[1024], *pua_cats = NULL;
@@ -317,6 +391,18 @@ int scanmanager(const struct optstruct *opts)
struct rlimit rlim;
#endif
+ dirlnk = optget(opts, "follow-dir-symlinks")->numarg;
+ if(dirlnk > 2) {
+ logg("!--follow-dir-symlinks: Invalid argument\n");
+ return 2;
+ }
+
+ filelnk = optget(opts, "follow-file-symlinks")->numarg;
+ if(filelnk > 2) {
+ logg("!--follow-file-symlinks: Invalid argument\n");
+ return 2;
+ }
+
if(optget(opts, "phishing-sigs")->enabled)
dboptions |= CL_DB_PHISHING;
@@ -611,8 +697,8 @@ int scanmanager(const struct optstruct *opts)
logg("^Only scanning files from --file-list (files passed at cmdline are ignored)\n");
while((filename = filelist(opts, &ret)) && (file = strdup(filename))) {
- if((fmodeint = fileinfo(file, 2)) == -1) {
- logg("^Can't access file %s\n", file);
+ if(lstat(file, &sb) == -1) {
+ logg("^%s: Can't access file\n", file);
perror(file);
ret = 2;
} else {
@@ -623,21 +709,27 @@ int scanmanager(const struct optstruct *opts)
break;
}
- fmode = (mode_t) fmodeint;
-
- switch(fmode & S_IFMT) {
- case S_IFREG:
- scanfile(file, engine, opts, options);
- break;
-
- case S_IFDIR:
- stat(file, &sb);
- scandirs(file, engine, opts, options, 1, sb.st_dev);
- break;
-
- default:
- logg("!Not supported file type (%s)\n", file);
- ret = 2;
+ if(S_ISLNK(sb.st_mode)) {
+ if(dirlnk == 0 && filelnk == 0) {
+ if(!printinfected)
+ logg("%s: Symbolic link\n", file);
+ } else if(stat(file, &sb) != -1) {
+ if(S_ISREG(sb.st_mode) && filelnk) {
+ scanfile(file, engine, opts, options);
+ } else if(S_ISDIR(sb.st_mode) && dirlnk) {
+ scandirs(file, engine, opts, options, 1, sb.st_dev);
+ } else {
+ if(!printinfected)
+ logg("%s: Symbolic link\n", file);
+ }
+ }
+ } else if(S_ISREG(sb.st_mode)) {
+ scanfile(file, engine, opts, options);
+ } else if(S_ISDIR(sb.st_mode)) {
+ scandirs(file, engine, opts, options, 1, sb.st_dev);
+ } else {
+ logg("^%s: Not supported file type\n", file);
+ ret = 2;
}
}
free(file);
@@ -655,4 +747,3 @@ int scanmanager(const struct optstruct *opts)
return ret;
}
-
diff --git a/clamscan/others.c b/clamscan/others.c
deleted file mode 100644
index 5fb8c5e..0000000
--- a/clamscan/others.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Sourcefire, Inc.
- *
- * Authors: Tomasz Kojm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- */
-
-#if HAVE_CONFIG_H
-#include "clamav-config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <errno.h>
-#ifdef HAVE_PWD_H
-#include <pwd.h>
-#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#ifndef _WIN32
-#include <sys/wait.h>
-#include <sys/time.h>
-#endif
-#include <time.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <target.h>
-
-#include "shared/output.h"
-#include "others.h"
-
-int fileinfo(const char *filename, short i)
-{
- struct stat infostruct;
-
- if(stat(filename, &infostruct) == -1)
- return(-1);
-
- switch(i) {
-
- case 1: /* size */
- return infostruct.st_size;
- case 2: /* permissions */
- return (mode_t)infostruct.st_mode;
- case 3: /* modification time */
- return infostruct.st_mtime;
- case 4: /* UID */
- return infostruct.st_uid;
- case 5: /* GID */
- return infostruct.st_gid;
- default:
- logg("!fileinfo(): Unknown option.\n");
- exit(1);
- }
-}
-
-#ifdef _WIN32
-/* FIXME: Handle users correctly */
-int checkaccess(const char *path, const char *username, int mode)
-{
- return !_access(path, mode);
-}
-#else
-int checkaccess(const char *path, const char *username, int mode)
-{
- struct passwd *user;
- int ret = 0, status;
-
- if(!geteuid()) {
-
- if((user = getpwnam(username)) == NULL) {
- return -1;
- }
-
- switch(fork()) {
- case -1:
- return -2;
-
- case 0:
- if(setgid(user->pw_gid)) {
- fprintf(stderr, "ERROR: setgid(%d) failed.\n", (int) user->pw_gid);
- exit(0);
- }
-
- if(setuid(user->pw_uid)) {
- fprintf(stderr, "ERROR: setuid(%d) failed.\n", (int) user->pw_uid);
- exit(0);
- }
-
- if(access(path, mode))
- exit(0);
- else
- exit(1);
-
- default:
- wait(&status);
- if(WIFEXITED(status) && WEXITSTATUS(status) == 1)
- ret = 1;
- }
-
- } else {
- if(!access(path, mode))
- ret = 1;
- }
-
- return ret;
-}
-#endif
diff --git a/clamscan/others.h b/clamscan/others.h
deleted file mode 100644
index 934d838..0000000
--- a/clamscan/others.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2007-2009 Sourcefire, Inc.
- *
- * Authors: Tomasz Kojm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __OTHERS_H
-#define __OTHERS_H
-
-int fileinfo(const char *filename, short i);
-int checkaccess(const char *path, const char *username, int mode);
-
-#endif
diff --git a/configure b/configure
index 78454ac..388c33d 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.67 for ClamAV 0.96.5.
+# Generated by GNU Autoconf 2.67 for ClamAV 0.97.
#
# Report bugs to <http://bugs.clamav.net/>.
#
@@ -703,8 +703,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='ClamAV'
PACKAGE_TARNAME='clamav'
-PACKAGE_VERSION='0.96.5'
-PACKAGE_STRING='ClamAV 0.96.5'
+PACKAGE_VERSION='0.97'
+PACKAGE_STRING='ClamAV 0.97'
PACKAGE_BUGREPORT='http://bugs.clamav.net/'
PACKAGE_URL='http://www.clamav.net/'
@@ -754,8 +754,6 @@ am__EXEEXT_FALSE
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
-BUILD_SHA1_FALSE
-BUILD_SHA1_TRUE
subdirs
HAVE_CURSES_FALSE
HAVE_CURSES_TRUE
@@ -770,6 +768,7 @@ BUILD_CLAMD_FALSE
BUILD_CLAMD_TRUE
THREAD_LIBS
TH_SAFE
+CLAMDSCAN_LIBS
FRESHCLAM_LIBS
CLAMAV_MILTER_LIBS
CLAMD_LIBS
@@ -1541,7 +1540,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures ClamAV 0.96.5 to adapt to many kinds of systems.
+\`configure' configures ClamAV 0.97 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1612,7 +1611,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of ClamAV 0.96.5:";;
+ short | recursive ) echo "Configuration of ClamAV 0.97:";;
esac
cat <<\_ACEOF
@@ -1769,7 +1768,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-ClamAV configure 0.96.5
+ClamAV configure 0.97
generated by GNU Autoconf 2.67
Copyright (C) 2010 Free Software Foundation, Inc.
@@ -2238,7 +2237,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by ClamAV $as_me 0.96.5, which was
+It was created by ClamAV $as_me 0.97, which was
generated by GNU Autoconf 2.67. Invocation command line was
$ $0 $@
@@ -3359,7 +3358,7 @@ fi
# Define the identity of the package.
PACKAGE='clamav'
- VERSION='0.96.5'
+ VERSION='0.97'
# Some tools Automake needs.
@@ -3488,7 +3487,7 @@ AM_BACKSLASH='\'
$as_echo "#define PACKAGE PACKAGE_NAME" >>confdefs.h
-VERSION="0.96.5"
+VERSION="0.97"
cat >>confdefs.h <<_ACEOF
#define VERSION "$VERSION"
@@ -3496,7 +3495,7 @@ _ACEOF
LC_CURRENT=7
-LC_REVISION=7
+LC_REVISION=9
LC_AGE=1
LIBCLAMAV_VERSION="$LC_CURRENT":"$LC_REVISION":"$LC_AGE"
@@ -5183,13 +5182,13 @@ if test "${lt_cv_nm_interface+set}" = set; then :
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:5186: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:5185: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:5189: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:5188: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:5192: output\"" >&5)
+ (eval echo "\"\$as_me:5191: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -6384,7 +6383,7 @@ ia64-*-hpux*)
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 6387 "configure"' > conftest.$ac_ext
+ echo '#line 6386 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -7911,11 +7910,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7914: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7913: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7918: \$? = $ac_status" >&5
+ echo "$as_me:7917: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -8250,11 +8249,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8253: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8252: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:8257: \$? = $ac_status" >&5
+ echo "$as_me:8256: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -8355,11 +8354,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8358: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8357: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8362: \$? = $ac_status" >&5
+ echo "$as_me:8361: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -8410,11 +8409,11 @@ else
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:8413: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:8412: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:8417: \$? = $ac_status" >&5
+ echo "$as_me:8416: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -10794,7 +10793,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 10797 "configure"
+#line 10796 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -10890,7 +10889,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 10893 "configure"
+#line 10892 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11562,7 +11561,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11565 "configure"
+#line 11564 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -15002,6 +15001,8 @@ $as_echo "$ZLIB_HOME" >&6; }
fi
+CLAMDSCAN_LIBS="$FRESHCLAM_LIBS"
+
# Check whether --enable-zlib-vcheck was given.
if test "${enable_zlib_vcheck+set}" = set; then :
enableval=$enable_zlib_vcheck; zlib_check=$enableval
@@ -16845,6 +16846,7 @@ $as_echo "#define CLAMUKO 1" >>confdefs.h
fi
;;
solaris*)
+ CLAMDSCAN_LIBS="$CLAMDSCAN_LIBS -lresolv"
FRESHCLAM_LIBS="$FRESHCLAM_LIBS -lresolv"
if test "$have_pthreads" = "yes"; then
THREAD_LIBS="-lpthread"
@@ -16955,6 +16957,7 @@ $as_echo "#define BIND_8_COMPAT 1" >>confdefs.h
use_netinfo="yes"
;;
os2*)
+ CLAMDSCAN_LIBS="$CLAMDSCAN_LIBS -lsyslog"
FRESHCLAM_LIBS="$FRESHCLAM_LIBS -lsyslog"
CLAMD_LIBS="$CLAMD_LIBS -lsyslog"
CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lsyslog"
@@ -17050,6 +17053,7 @@ esac
+
if test "$have_milter" = "yes"; then
save_LIBS="$LIBS"
@@ -20038,14 +20042,6 @@ if test "$enable_sha_collector" != "no"; then
$as_echo "#define HAVE__INTERNAL__SHA_COLLECT 1" >>confdefs.h
fi
- if test "$enable_sha_collector" != "no"; then
- BUILD_SHA1_TRUE=
- BUILD_SHA1_FALSE='#'
-else
- BUILD_SHA1_TRUE='#'
- BUILD_SHA1_FALSE=
-fi
-
ac_config_files="$ac_config_files clamscan/Makefile database/Makefile docs/Makefile clamd/Makefile clamdscan/Makefile clamav-milter/Makefile freshclam/Makefile sigtool/Makefile clamconf/Makefile etc/Makefile test/Makefile unit_tests/Makefile clamdtop/Makefile clambc/Makefile Makefile clamav-config libclamav.pc platform.h docs/man/clamav-milter.8 docs/man/clamav-milter.conf.5 docs/man/clamconf.1 docs/man/clamd.8 docs/man/clamd.conf.5 docs/man/clamdscan.1 docs/man/clamscan.1 docs/man/freshclam.1 docs/man/freshclam.conf.5 docs/man/sigtool.1 docs/man/clamdtop.1"
@@ -20225,10 +20221,6 @@ if test -z "${HAVE_CURSES_TRUE}" && test -z "${HAVE_CURSES_FALSE}"; then
as_fn_error $? "conditional \"HAVE_CURSES\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
-if test -z "${BUILD_SHA1_TRUE}" && test -z "${BUILD_SHA1_FALSE}"; then
- as_fn_error $? "conditional \"BUILD_SHA1\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
: ${CONFIG_STATUS=./config.status}
ac_write_fail=0
@@ -20637,7 +20629,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by ClamAV $as_me 0.96.5, which was
+This file was extended by ClamAV $as_me 0.97, which was
generated by GNU Autoconf 2.67. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -20704,7 +20696,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-ClamAV config.status 0.96.5
+ClamAV config.status 0.97
configured by $0, generated by GNU Autoconf 2.67,
with options \\"\$ac_cs_config\\"
@@ -22820,10 +22812,6 @@ if test -z "${HAVE_CURSES_TRUE}" && test -z "${HAVE_CURSES_FALSE}"; then
as_fn_error $? "conditional \"HAVE_CURSES\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
-if test -z "${BUILD_SHA1_TRUE}" && test -z "${BUILD_SHA1_FALSE}"; then
- as_fn_error $? "conditional \"BUILD_SHA1\" was never defined.
-Usually this means the macro was only invoked conditionally." "$LINENO" 5
-fi
if test -z "${am__EXEEXT_TRUE}" && test -z "${am__EXEEXT_FALSE}"; then
as_fn_error $? "conditional \"am__EXEEXT\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@@ -23240,7 +23228,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by ClamAV $as_me 0.96.5, which was
+This file was extended by ClamAV $as_me 0.97, which was
generated by GNU Autoconf 2.67. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -23307,7 +23295,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-ClamAV config.status 0.96.5
+ClamAV config.status 0.97
configured by $0, generated by GNU Autoconf 2.67,
with options \\"\$ac_cs_config\\"
diff --git a/configure.in b/configure.in
index e5a934b..1c95648 100644
--- a/configure.in
+++ b/configure.in
@@ -20,7 +20,7 @@ dnl MA 02110-1301, USA.
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.96.5], [http://bugs.clamav.net/], [clamav], [http://www.clamav.net/])
+AC_INIT([ClamAV], [0.97], [http://bugs.clamav.net/], [clamav], [http://www.clamav.net/])
AH_BOTTOM([#include "platform.h"])
dnl put configure auxiliary into config
@@ -42,11 +42,11 @@ dnl the date in the version
AC_DEFINE([PACKAGE], PACKAGE_NAME, [Name of package])
dnl change this on a release
-VERSION="0.96.5"
+VERSION="0.97"
AC_DEFINE_UNQUOTED([VERSION],"$VERSION",[Version number of package])
LC_CURRENT=7
-LC_REVISION=7
+LC_REVISION=9
LC_AGE=1
LIBCLAMAV_VERSION="$LC_CURRENT":"$LC_REVISION":"$LC_AGE"
AC_SUBST([LIBCLAMAV_VERSION])
@@ -527,6 +527,8 @@ fi
AC_MSG_RESULT([$ZLIB_HOME])
])
+CLAMDSCAN_LIBS="$FRESHCLAM_LIBS"
+
AC_ARG_ENABLE([zlib-vcheck],
[ --disable-zlib-vcheck do not check for buggy zlib version ],
zlib_check=$enableval, zlib_check="yes")
@@ -971,6 +973,7 @@ kfreebsd*-gnu)
fi
;;
solaris*)
+ CLAMDSCAN_LIBS="$CLAMDSCAN_LIBS -lresolv"
FRESHCLAM_LIBS="$FRESHCLAM_LIBS -lresolv"
if test "$have_pthreads" = "yes"; then
THREAD_LIBS="-lpthread"
@@ -1049,6 +1052,7 @@ darwin*)
use_netinfo="yes"
;;
os2*)
+ CLAMDSCAN_LIBS="$CLAMDSCAN_LIBS -lsyslog"
FRESHCLAM_LIBS="$FRESHCLAM_LIBS -lsyslog"
CLAMD_LIBS="$CLAMD_LIBS -lsyslog"
CLAMAV_MILTER_LIBS="$CLAMAV_MILTER_LIBS -lsyslog"
@@ -1125,6 +1129,7 @@ AC_SUBST([LIBCLAMAV_LIBS])
AC_SUBST([CLAMD_LIBS])
AC_SUBST([CLAMAV_MILTER_LIBS])
AC_SUBST([FRESHCLAM_LIBS])
+AC_SUBST([CLAMDSCAN_LIBS])
AC_SUBST([TH_SAFE])
AC_SUBST([THREAD_LIBS])
@@ -1610,7 +1615,6 @@ AC_ARG_ENABLE([sha-collector-for-internal-use], [], [enable_sha_collector="yes"]
if test "$enable_sha_collector" != "no"; then
AC_DEFINE([HAVE__INTERNAL__SHA_COLLECT], 1, [For internal use only - DO NOT DEFINE])
fi
-AM_CONDITIONAL([BUILD_SHA1],[test "$enable_sha_collector" != "no"])
AC_OUTPUT([
clamscan/Makefile
diff --git a/database/Makefile.in b/database/Makefile.in
index 2a03459..2f5f1e5 100644
--- a/database/Makefile.in
+++ b/database/Makefile.in
@@ -101,6 +101,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/docs/Makefile.in b/docs/Makefile.in
index b8e857c..fb8ca38 100644
--- a/docs/Makefile.in
+++ b/docs/Makefile.in
@@ -128,6 +128,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/docs/clamdoc.pdf b/docs/clamdoc.pdf
index 9817aba..b3bd9e7 100644
Binary files a/docs/clamdoc.pdf and b/docs/clamdoc.pdf differ
diff --git a/docs/clamdoc.tex b/docs/clamdoc.tex
index b2b6133..e034494 100644
--- a/docs/clamdoc.tex
+++ b/docs/clamdoc.tex
@@ -71,7 +71,7 @@
\vspace{3cm}
\begin{flushright}
\rule[-1ex]{8cm}{3pt}\\
- \huge Clam AntiVirus 0.96.5\\
+ \huge Clam AntiVirus 0.97\\
\huge \emph{User Manual}\\
\end{flushright}
@@ -83,7 +83,7 @@
\noindent
\begin{boxedminipage}[b]{\textwidth}
ClamAV User Manual,
- \copyright \ 2007 - 2010 Sourcefire, Inc.
+ \copyright \ 2007 - 2011 Sourcefire, Inc.
Authors: Tomasz Kojm\\
This document is distributed under the terms of the GNU General
Public License v2.\\
diff --git a/docs/html/clamdoc.html b/docs/html/clamdoc.html
index e525949..7ef5637 100644
--- a/docs/html/clamdoc.html
+++ b/docs/html/clamdoc.html
@@ -56,7 +56,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds
<BR>
<BR>
<DIV ALIGN="RIGHT">
-<BR> <BIG CLASS="HUGE">Clam AntiVirus 0.96.5
+<BR> <BIG CLASS="HUGE">Clam AntiVirus 0.97
<BR> <BIG CLASS="HUGE"><SPAN CLASS="textit">User Manual</SPAN>
<BR>
</BIG></BIG></DIV>
diff --git a/docs/html/index.html b/docs/html/index.html
index e525949..7ef5637 100644
--- a/docs/html/index.html
+++ b/docs/html/index.html
@@ -56,7 +56,7 @@ original version by: Nikos Drakos, CBLU, University of Leeds
<BR>
<BR>
<DIV ALIGN="RIGHT">
-<BR> <BIG CLASS="HUGE">Clam AntiVirus 0.96.5
+<BR> <BIG CLASS="HUGE">Clam AntiVirus 0.97
<BR> <BIG CLASS="HUGE"><SPAN CLASS="textit">User Manual</SPAN>
<BR>
</BIG></BIG></DIV>
diff --git a/docs/man/clamav-milter.conf.5.in b/docs/man/clamav-milter.conf.5.in
index 4786397..abdfbfe 100644
--- a/docs/man/clamav-milter.conf.5.in
+++ b/docs/man/clamav-milter.conf.5.in
@@ -212,15 +212,22 @@ Enable verbose logging.
Default: no
.TP
\fBLogInfected STRING\fR
-Specify the type of syslog messages \- please refer to 'man syslog' for facility names.
-.br
-This option allows to tune what is logged when a message is infected. Possible values are Off (the default - nothing is logged), Basic (minimal info logged), Full (verbose info logged)
+This option allows to tune what is logged when a message is infected. Possible values are Off (the default \- nothing is logged), Basic (minimal info logged), Full (verbose info logged)
.br
Note: For this to work properly in sendmail, make sure the msg_id, mail_addr, rcpt_addr and i macroes are available in eom. In other words add a line like: Milter.macros.eom={msg_id}, {mail_addr}, {rcpt_addr}, i to your .cf file. Alternatively use the macro: define(`confMILTER_MACROS_EOM', `{msg_id}, {mail_addr}, {rcpt_addr}, i')
.br
Postfix should be working fine with the default settings.
.br
Default: disabled
+.TP
+\fBLogClean STRING\fR
+This option allows to tune what is logged when no threat is found in a scanned message.
+.br
+See LogInfected for possible values and caveats.
+.br
+Useful in debugging but drastically increases the log size.
+.br
+Default: disabled
.SH "NOTES"
.LP
All options expressing a size are limited to max 4GB. Values in excess will be resetted to the maximum.
diff --git a/docs/man/clamd.conf.5.in b/docs/man/clamd.conf.5.in
index ac8c4bb..6b9cb84 100644
--- a/docs/man/clamd.conf.5.in
+++ b/docs/man/clamd.conf.5.in
@@ -122,7 +122,7 @@ Default: no
\fBMaxConnectionQueueLength NUMBER\fR
Maximum length the queue of pending connections may grow to.
.br
-Default: 15
+Default: 200
.TP
\fBMaxThreads NUMBER\fR
Maximum number of threads running at the same time.
@@ -257,7 +257,7 @@ Default: TrustSigned
\fBBytecodeTimeout NUMBER\fR
Set bytecode timeout in milliseconds.
.br
-Default: 60000
+Default: 5000
.TP
\fBDetectPUA BOOL\fR
Detect Possibly Unwanted Applications.
diff --git a/docs/man/clamscan.1.in b/docs/man/clamscan.1.in
index 761fd48..3083131 100644
--- a/docs/man/clamscan.1.in
+++ b/docs/man/clamscan.1.in
@@ -54,6 +54,12 @@ Scan directories recursively. All the subdirectories in the given directory will
\fB\-\-cross\-fs=[yes(*)/no]\fR
Scan files and directories on other filesystems.
.TP
+\fB\-\-follow\-dir\-symlinks=[0/1(*)/2]\fR
+Follow directory symlinks. There are 3 options: 0 - never follow directory symlinks, 1 (default) - only follow directory symlinks, which are passed as direct arguments to clamscan. 2 - never follow directory symlinks.
+.TP
+\fB\-\-follow\-file\-symlinks=[0/1(*)/2]\fR
+Follow file symlinks. There are 3 options: 0 - never follow file symlinks, 1 (default) - only follow file symlinks, which are passed as direct arguments to clamscan. 2 - never follow file symlinks.
+.TP
\fB\-\-bell\fR
Sound bell on virus detection.
.TP
diff --git a/docs/man/sigtool.1.in b/docs/man/sigtool.1.in
index 684e571..75bfb00 100644
--- a/docs/man/sigtool.1.in
+++ b/docs/man/sigtool.1.in
@@ -30,6 +30,12 @@ Read data from stdin and write hex string to stdout.
\fB\-\-md5 [FILES]\fR
Generate MD5 checksum from stdin or MD5 sigs for FILES.
.TP
+\fB\-\-sha1 [FILES]\fR
+Generate SHA1 checksum from stdin or SHA1 sigs for FILES.
+.TP
+\fB\-\-sha256 [FILES]\fR
+Generate SHA256 checksum from stdin or SHA256 sigs for FILES.
+.TP
\fB\-\-mdb [FILES]\fR
Generate .mdb signatures for FILES.
.TP
diff --git a/etc/Makefile.in b/etc/Makefile.in
index 85a65ea..7158093 100644
--- a/etc/Makefile.in
+++ b/etc/Makefile.in
@@ -100,6 +100,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/etc/clamav-milter.conf b/etc/clamav-milter.conf
index e244240..c484840 100644
--- a/etc/clamav-milter.conf
+++ b/etc/clamav-milter.conf
@@ -266,3 +266,9 @@ ClamdSocket /var/run/clamav/clamd
# Default: disabled
#LogInfected Basic
+# This option allows to tune what is logged when no threat is found in a scanned message.
+# See LogInfected for possible values and caveats.
+# Useful in debugging but drastically increases the log size.
+# Default: disabled
+#LogClean Basic
+
diff --git a/etc/clamd.conf b/etc/clamd.conf
index 6cbb05e..67ebee1 100644
--- a/etc/clamd.conf
+++ b/etc/clamd.conf
@@ -103,7 +103,7 @@ Example
#TCPAddr 127.0.0.1
# Maximum length the queue of pending connections may grow to.
-# Default: 15
+# Default: 200
#MaxConnectionQueueLength 30
# Clamd uses FTP-like protocol to receive data from remote clients.
@@ -480,5 +480,5 @@ Example
# Set bytecode timeout in miliseconds.
#
-# Default: 60000
-# BytecodeTimeout 60000
+# Default: 5000
+# BytecodeTimeout 1000
diff --git a/freshclam/Makefile.in b/freshclam/Makefile.in
index f129d83..1b8cfb2 100644
--- a/freshclam/Makefile.in
+++ b/freshclam/Makefile.in
@@ -137,6 +137,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/freshclam/freshclam.c b/freshclam/freshclam.c
index 4aae243..b7d6d34 100644
--- a/freshclam/freshclam.c
+++ b/freshclam/freshclam.c
@@ -63,7 +63,7 @@ static short terminate = 0;
extern int active_children;
static short foreground = 1;
-char updtmpdir[512];
+char updtmpdir[512], dbdir[512];
int sigchld_wait = 1;
static void sighandler(int sig) {
@@ -164,7 +164,7 @@ static void help(void)
mprintf("\n");
}
-static int download(const struct optstruct *opts, const char *datadir, const char *cfgfile)
+static int download(const struct optstruct *opts, const char *cfgfile)
{
int ret = 0, try = 0, maxattempts = 0;
const struct optstruct *opt;
@@ -178,7 +178,7 @@ static int download(const struct optstruct *opts, const char *datadir, const cha
return 56;
} else {
while(opt) {
- ret = downloadmanager(opts, opt->strarg, datadir, try == maxattempts - 1);
+ ret = downloadmanager(opts, opt->strarg, try == maxattempts - 1);
#ifndef _WIN32
alarm(0);
#endif
@@ -224,7 +224,7 @@ int main(int argc, char **argv)
{
int ret = 52, retcl;
const char *cfgfile, *arg = NULL, *pidfile = NULL;
- char *pt, dbdir[512];
+ char *pt;
struct optstruct *opts;
const struct optstruct *opt;
#ifndef _WIN32
@@ -471,7 +471,7 @@ int main(int argc, char **argv)
logg("#freshclam daemon %s (OS: "TARGET_OS_TYPE", ARCH: "TARGET_ARCH_TYPE", CPU: "TARGET_CPU_TYPE")\n", get_version());
while(!terminate) {
- ret = download(opts, dbdir, cfgfile);
+ ret = download(opts, cfgfile);
if(ret <= 1) {
if((opt = optget(opts, "SubmitDetectionStats"))->enabled)
@@ -529,7 +529,7 @@ int main(int argc, char **argv)
logg(" *** Virus databases are not updated in this mode ***\n");
ret = submitstats(opt->strarg, opts);
} else {
- ret = download(opts, dbdir, cfgfile);
+ ret = download(opts, cfgfile);
if((opt = optget(opts, "SubmitDetectionStats"))->enabled)
submitstats(opt->strarg, opts);
diff --git a/freshclam/manager.c b/freshclam/manager.c
index f9a2f12..45e5137 100644
--- a/freshclam/manager.c
+++ b/freshclam/manager.c
@@ -83,7 +83,7 @@
#include "libclamav/cvd.h"
#include "libclamav/regex_list.h"
-extern char updtmpdir[512];
+extern char updtmpdir[512], dbdir[512];
#define CHDIR_ERR(x) \
if(chdir(x) == -1) \
@@ -567,6 +567,7 @@ static char *proxyauth(const char *user, const char *pass)
return auth;
}
+#if BUILD_CLAMD
int submitstats(const char *clamdcfg, const struct optstruct *opts)
{
int sd, clamsockd, bread, cnt, ret;
@@ -744,6 +745,13 @@ int submitstats(const char *clamdcfg, const struct optstruct *opts)
}
return ret;
}
+#else
+int submitstats(const char *clamdcfg, const struct optstruct *opts)
+{
+ logg("clamd not built, no statistics");
+ return 52;
+}
+#endif
static int Rfc2822DateTime(char *buf, time_t mtime)
{
@@ -1132,7 +1140,7 @@ static int getfile(const char *srcfile, const char *destfile, const char *hostna
if(mdat) {
mirman_update_sf(mdat->currip, mdat->af, mdat, 0, 1);
- mirman_write("mirrors.dat", optget(opts, "DatabaseDirectory")->strarg, mdat);
+ mirman_write("mirrors.dat", dbdir, mdat);
}
ret = getfile_mirman(srcfile, destfile, hostname, ip, localip, proxy, port, user, pass, uas, ctimeout, rtimeout, mdat, logerr, can_whitelist, ims, ipaddr, sd);
@@ -1140,7 +1148,7 @@ static int getfile(const char *srcfile, const char *destfile, const char *hostna
if(mdat) {
mirman_update_sf(mdat->currip, mdat->af, mdat, 0, -1);
- mirman_write("mirrors.dat", optget(opts, "DatabaseDirectory")->strarg, mdat);
+ mirman_write("mirrors.dat", dbdir, mdat);
}
return ret;
@@ -1476,7 +1484,7 @@ static int test_database_wrap(const char *file, const char *newdb, int bytecode)
char lastline[256];
int pipefd[2];
pid_t pid;
- int status = 0;
+ int status = 0, ret;
FILE *f;
if (pipe(pipefd) == -1) {
@@ -1513,7 +1521,8 @@ static int test_database_wrap(const char *file, const char *newdb, int bytecode)
}
fclose(f);
- if (waitpid(pid, &status, 0) == -1 && errno != ECHILD)
+ while ((ret = waitpid(pid, &status, 0)) == -1 && errno == EINTR);
+ if (ret == -1 && errno != ECHILD)
logg("^waitpid() failed: %s\n", strerror(errno));
cli_chomp(firstline);
cli_chomp(lastline);
@@ -1523,7 +1532,7 @@ static int test_database_wrap(const char *file, const char *newdb, int bytecode)
lastline);
}
if (WIFEXITED(status)) {
- int ret = WEXITSTATUS(status);
+ ret = WEXITSTATUS(status);
if (ret) {
logg("^Database load exited with status %d\n", ret);
return ret;
@@ -1556,6 +1565,43 @@ static int test_database_wrap(const char *file, const char *newdb, int bytecode)
}
#endif
+static int checkdbdir(void)
+{
+ DIR *dir;
+ struct dirent *dent;
+ char fname[512], broken[513];
+ int ret, fret = 0;
+
+ if(!(dir = opendir(dbdir))) {
+ logg("!checkdbdir: Can't open directory %s\n", dbdir);
+ return -1;
+ }
+
+ while((dent = readdir(dir))) {
+ if(dent->d_ino) {
+ if(cli_strbcasestr(dent->d_name, ".cld") || cli_strbcasestr(dent->d_name, ".cvd")) {
+ snprintf(fname, sizeof(fname), "%s"PATHSEP"%s", dbdir, dent->d_name);
+ if((ret = cl_cvdverify(fname))) {
+ fret = -1;
+ mprintf("!Corrupted database file %s: %s\n", fname, cl_strerror(ret));
+ snprintf(broken, sizeof(broken), "%s.broken", fname);
+ if(!access(broken, R_OK))
+ unlink(broken);
+ if(rename(fname, broken)) {
+ if(unlink(fname))
+ mprintf("!Can't remove broken database file %s, please delete it manually and restart freshclam\n", fname);
+ } else {
+ mprintf("Corrupted database file renamed to %s\n", broken);
+ }
+ }
+ }
+ }
+ }
+
+ closedir(dir);
+ return fret;
+}
+
extern int sigchld_wait;
static int updatedb(const char *dbname, const char *hostname, char *ip, int *signo, const struct optstruct *opts, const char *dnsreply, char *localip, int outdated, struct mirdat *mdat, int logerr, int extra)
@@ -2046,7 +2092,7 @@ static int updatecustomdb(const char *url, int *signo, const struct optstruct *o
return 0;
}
-int downloadmanager(const struct optstruct *opts, const char *hostname, const char *dbdir, int logerr)
+int downloadmanager(const struct optstruct *opts, const char *hostname, int logerr)
{
time_t currtime;
int ret, updated = 0, outdated = 0, signo = 0;
@@ -2118,11 +2164,9 @@ int downloadmanager(const struct optstruct *opts, const char *hostname, const ch
logg("*Software version from DNS: %s\n", newver);
strncpy(vstr, get_version(), 32);
vstr[31] = 0;
- if((pt = strstr(vstr, "-exp")) || (pt = strstr(vstr,"-broken")))
- *pt = 0;
-
if(vwarning && !strstr(vstr, "devel") && !strstr(vstr, "rc")) {
- if(strcmp(vstr, newver)) {
+ pt = strchr(vstr, '-');
+ if((pt && strncmp(vstr, newver, pt - vstr)) || (!pt && strcmp(vstr, newver))) {
logg("^Your ClamAV installation is OUTDATED!\n");
logg("^Local version: %s Recommended version: %s\n", vstr, newver);
logg("DON'T PANIC! Read http://www.clamav.net/support/faq\n");
@@ -2269,6 +2313,12 @@ int downloadmanager(const struct optstruct *opts, const char *hostname, const ch
cli_rmdirs(updtmpdir);
+ if(checkdbdir() < 0) {
+ if(newver)
+ free(newver);
+ return 54;
+ }
+
if(updated) {
if(optget(opts, "HTTPProxyServer")->enabled || !ipaddr[0]) {
logg("Database updated (%d signatures) from %s\n", signo, hostname);
diff --git a/freshclam/manager.h b/freshclam/manager.h
index 9390ac9..8281048 100644
--- a/freshclam/manager.h
+++ b/freshclam/manager.h
@@ -25,7 +25,7 @@
#include "shared/optparser.h"
-int downloadmanager(const struct optstruct *opts, const char *hostname, const char *dbdir, int logerr);
+int downloadmanager(const struct optstruct *opts, const char *hostname, int logerr);
int submitstats(const char *clamdcfg, const struct optstruct *opts);
diff --git a/libclamav/Makefile.am b/libclamav/Makefile.am
index 401477a..94cd1e5 100644
--- a/libclamav/Makefile.am
+++ b/libclamav/Makefile.am
@@ -142,8 +142,8 @@ libclamav_la_SOURCES = \
matcher-ac.h \
matcher-bm.c \
matcher-bm.h \
- matcher-md5.c \
- matcher-md5.h \
+ matcher-hash.c \
+ matcher-hash.h \
matcher.c \
matcher.h \
others.c \
@@ -335,6 +335,8 @@ libclamav_la_SOURCES = \
default.h\
sha256.c\
sha256.h\
+ sha1.c\
+ sha1.h\
bignum.h\
bytecode.c\
bytecode.h\
@@ -367,10 +369,6 @@ libclamav_la_SOURCES += bignum.c \
bignum_class.h
endif
-if BUILD_SHA1
-libclamav_la_SOURCES += sha1.c sha1.h
-endif
-
.PHONY: version.h.tmp
version.c: version.h
version.h: version.h.tmp
diff --git a/libclamav/Makefile.in b/libclamav/Makefile.in
index 06d7309..d66f7fb 100644
--- a/libclamav/Makefile.in
+++ b/libclamav/Makefile.in
@@ -66,7 +66,6 @@ target_triplet = @target@
@LINK_TOMMATH_FALSE at am__append_7 = bignum.c \
@LINK_TOMMATH_FALSE@ bignum_class.h
- at BUILD_SHA1_TRUE@am__append_8 = sha1.c sha1.h
subdir = libclamav
DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
@@ -115,7 +114,7 @@ LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
@ENABLE_LLVM_FALSE at am__DEPENDENCIES_2 = libclamav_nocxx.la
@ENABLE_LLVM_TRUE at am__DEPENDENCIES_2 = c++/libclamavcxx.la
am__libclamav_la_SOURCES_DIST = clamav.h matcher-ac.c matcher-ac.h \
- matcher-bm.c matcher-bm.h matcher-md5.c matcher-md5.h \
+ matcher-bm.c matcher-bm.h matcher-hash.c matcher-hash.h \
matcher.c matcher.h others.c others.h readdb.c readdb.h cvd.c \
cvd.h dsig.c dsig.h scanners.c scanners.h textdet.c textdet.h \
filetypes.c filetypes.h filetypes_int.h rtf.c rtf.h blob.c \
@@ -153,17 +152,16 @@ am__libclamav_la_SOURCES_DIST = clamav.h matcher-ac.c matcher-ac.h \
jsparse/lexglobal.h jsparse/textbuf.h uniq.c uniq.h version.c \
version.h mpool.c mpool.h filtering.h filtering.c fmap.c \
fmap.h perflogging.c perflogging.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 \
- type_desc.h bcfeatures.h bytecode_api.c bytecode_api_decl.c \
- bytecode_api.h bytecode_api_impl.h bytecode_hooks.h cache.c \
- cache.h bytecode_detect.c bytecode_detect.h \
- builtin_bytecodes.h events.c events.h bignum.c bignum_class.h \
- sha1.c sha1.h
+ sha1.c sha1.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 type_desc.h bcfeatures.h bytecode_api.c \
+ bytecode_api_decl.c bytecode_api.h bytecode_api_impl.h \
+ bytecode_hooks.h cache.c cache.h bytecode_detect.c \
+ bytecode_detect.h builtin_bytecodes.h events.c events.h \
+ bignum.c bignum_class.h
@LINK_TOMMATH_FALSE at am__objects_1 = libclamav_la-bignum.lo
- at BUILD_SHA1_TRUE@am__objects_2 = libclamav_la-sha1.lo
am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \
- libclamav_la-matcher-bm.lo libclamav_la-matcher-md5.lo \
+ libclamav_la-matcher-bm.lo libclamav_la-matcher-hash.lo \
libclamav_la-matcher.lo libclamav_la-others.lo \
libclamav_la-readdb.lo libclamav_la-cvd.lo \
libclamav_la-dsig.lo libclamav_la-scanners.lo \
@@ -206,12 +204,13 @@ am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.lo \
libclamav_la-uniq.lo libclamav_la-version.lo \
libclamav_la-mpool.lo libclamav_la-filtering.lo \
libclamav_la-fmap.lo libclamav_la-perflogging.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 \
- libclamav_la-bytecode_api.lo libclamav_la-bytecode_api_decl.lo \
- libclamav_la-cache.lo libclamav_la-bytecode_detect.lo \
- libclamav_la-events.lo $(am__objects_1) $(am__objects_2)
+ libclamav_la-sha256.lo libclamav_la-sha1.lo \
+ libclamav_la-bytecode.lo libclamav_la-bytecode_vm.lo \
+ libclamav_la-cpio.lo libclamav_la-macho.lo \
+ libclamav_la-ishield.lo libclamav_la-bytecode_api.lo \
+ libclamav_la-bytecode_api_decl.lo libclamav_la-cache.lo \
+ libclamav_la-bytecode_detect.lo libclamav_la-events.lo \
+ $(am__objects_1)
libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS)
AM_V_lt = $(am__v_lt_$(V))
am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
@@ -386,6 +385,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
@@ -620,7 +620,7 @@ libclamav_la_LDFLAGS = @TH_SAFE@ -version-info @LIBCLAMAV_VERSION@ \
-no-undefined $(am__append_6)
include_HEADERS = clamav.h
libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \
- matcher-bm.h matcher-md5.c matcher-md5.h matcher.c matcher.h \
+ matcher-bm.h matcher-hash.c matcher-hash.h matcher.c matcher.h \
others.c others.h readdb.c readdb.h cvd.c cvd.h dsig.c dsig.h \
scanners.c scanners.h textdet.c textdet.h filetypes.c \
filetypes.h filetypes_int.h rtf.c rtf.h blob.c blob.h mbox.c \
@@ -658,13 +658,13 @@ libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \
jsparse/lexglobal.h jsparse/textbuf.h uniq.c uniq.h version.c \
version.h mpool.c mpool.h filtering.h filtering.c fmap.c \
fmap.h perflogging.c perflogging.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 \
- type_desc.h bcfeatures.h bytecode_api.c bytecode_api_decl.c \
- bytecode_api.h bytecode_api_impl.h bytecode_hooks.h cache.c \
- cache.h bytecode_detect.c bytecode_detect.h \
- builtin_bytecodes.h events.c events.h $(am__append_7) \
- $(am__append_8)
+ sha1.c sha1.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 type_desc.h bcfeatures.h bytecode_api.c \
+ bytecode_api_decl.c bytecode_api.h bytecode_api_impl.h \
+ bytecode_hooks.h cache.c cache.h bytecode_detect.c \
+ bytecode_detect.h builtin_bytecodes.h events.c events.h \
+ $(am__append_7)
noinst_LTLIBRARIES = libclamav_internal_utils.la libclamav_internal_utils_nothreads.la libclamav_nocxx.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
@@ -838,7 +838,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-macho.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-matcher-ac.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-matcher-bm.Plo at am__quote@
- at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-matcher-md5.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-matcher-hash.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-matcher.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-mbox.Plo at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libclamav_la-message.Plo at am__quote@
@@ -936,13 +936,13 @@ libclamav_la-matcher-bm.lo: matcher-bm.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-matcher-bm.lo `test -f 'matcher-bm.c' || echo '$(srcdir)/'`matcher-bm.c
-libclamav_la-matcher-md5.lo: matcher-md5.c
- at am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-matcher-md5.lo -MD -MP -MF $(DEPDIR)/libclamav_la-matcher-md5.Tpo -c -o libclamav_la-matcher-md5.lo `test -f 'matcher-md5.c' || echo '$(srcdir)/'`matcher-md5.c
- at am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-matcher-md5.Tpo $(DEPDIR)/libclamav_la-matcher-md5.Plo
+libclamav_la-matcher-hash.lo: matcher-hash.c
+ at am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-matcher-hash.lo -MD -MP -MF $(DEPDIR)/libclamav_la-matcher-hash.Tpo -c -o libclamav_la-matcher-hash.lo `test -f 'matcher-hash.c' || echo '$(srcdir)/'`matcher-hash.c
+ at am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-matcher-hash.Tpo $(DEPDIR)/libclamav_la-matcher-hash.Plo
@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@ source='matcher-md5.c' object='libclamav_la-matcher-md5.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ source='matcher-hash.c' object='libclamav_la-matcher-hash.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-matcher-md5.lo `test -f 'matcher-md5.c' || echo '$(srcdir)/'`matcher-md5.c
+ at am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-matcher-hash.lo `test -f 'matcher-hash.c' || echo '$(srcdir)/'`matcher-hash.c
libclamav_la-matcher.lo: matcher.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-matcher.lo -MD -MP -MF $(DEPDIR)/libclamav_la-matcher.Tpo -c -o libclamav_la-matcher.lo `test -f 'matcher.c' || echo '$(srcdir)/'`matcher.c
@@ -1640,6 +1640,14 @@ libclamav_la-sha256.lo: sha256.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-sha256.lo `test -f 'sha256.c' || echo '$(srcdir)/'`sha256.c
+libclamav_la-sha1.lo: sha1.c
+ at am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-sha1.lo -MD -MP -MF $(DEPDIR)/libclamav_la-sha1.Tpo -c -o libclamav_la-sha1.lo `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c
+ at am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-sha1.Tpo $(DEPDIR)/libclamav_la-sha1.Plo
+ at am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sha1.c' object='libclamav_la-sha1.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-sha1.lo `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c
+
libclamav_la-bytecode.lo: bytecode.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-bytecode.lo -MD -MP -MF $(DEPDIR)/libclamav_la-bytecode.Tpo -c -o libclamav_la-bytecode.lo `test -f 'bytecode.c' || echo '$(srcdir)/'`bytecode.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-bytecode.Tpo $(DEPDIR)/libclamav_la-bytecode.Plo
@@ -1728,14 +1736,6 @@ libclamav_la-bignum.lo: bignum.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-bignum.lo `test -f 'bignum.c' || echo '$(srcdir)/'`bignum.c
-libclamav_la-sha1.lo: sha1.c
- at am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -MT libclamav_la-sha1.lo -MD -MP -MF $(DEPDIR)/libclamav_la-sha1.Tpo -c -o libclamav_la-sha1.lo `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c
- at am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-sha1.Tpo $(DEPDIR)/libclamav_la-sha1.Plo
- at am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@ source='sha1.c' object='libclamav_la-sha1.lo' libtool=yes @AMDEPBACKSLASH@
- at AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
- at am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_la_CFLAGS) $(CFLAGS) -c -o libclamav_la-sha1.lo `test -f 'sha1.c' || echo '$(srcdir)/'`sha1.c
-
libclamav_internal_utils_la-str.lo: str.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libclamav_internal_utils_la_CFLAGS) $(CFLAGS) -MT libclamav_internal_utils_la-str.lo -MD -MP -MF $(DEPDIR)/libclamav_internal_utils_la-str.Tpo -c -o libclamav_internal_utils_la-str.lo `test -f 'str.c' || echo '$(srcdir)/'`str.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_internal_utils_la-str.Tpo $(DEPDIR)/libclamav_internal_utils_la-str.Plo
diff --git a/libclamav/blob.c b/libclamav/blob.c
index 3daa648..bec7d16 100644
--- a/libclamav/blob.c
+++ b/libclamav/blob.c
@@ -396,12 +396,6 @@ fileblobCreate(void)
int
fileblobScanAndDestroy(fileblob *fb)
{
- if(fb->ctx && fb->ctx->engine->keeptmp) {
- /* Can't remove the file, the caller must scan */
- fileblobDestroy(fb);
- return CL_CLEAN;
- }
-
switch(fileblobScan(fb)) {
case CL_VIRUS:
fileblobDestructiveDestroy(fb);
@@ -424,7 +418,8 @@ fileblobDestructiveDestroy(fileblob *fb)
if(fb->fp && fb->fullname) {
fclose(fb->fp);
cli_dbgmsg("fileblobDestructiveDestroy: %s\n", fb->fullname);
- cli_unlink(fb->fullname);
+ if(!fb->ctx || !fb->ctx->engine->keeptmp)
+ cli_unlink(fb->fullname);
free(fb->fullname);
fb->fp = NULL;
fb->fullname = NULL;
diff --git a/libclamav/bytecode_vm.c b/libclamav/bytecode_vm.c
index 1691563..e3c61bd 100644
--- a/libclamav/bytecode_vm.c
+++ b/libclamav/bytecode_vm.c
@@ -226,7 +226,6 @@ static always_inline struct stack_entry *allocate_stack(struct stack *stack,
entry->bb_inst = bb_inst;
/* we allocated room for values right after stack_entry! */
entry->values = values = (char*)&entry[1];
-
memcpy(&values[func->numBytes - func->numConstants*8], func->constants,
sizeof(*values)*func->numConstants*8);
return entry;
@@ -1125,40 +1124,41 @@ int cli_vm_execute(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct
break;
}
DEFINE_OP(OP_BC_MEMCPY) {
- int32_t arg3;
+ int64_t arg3;
void *arg1, *arg2;
int64_t res=0;
READ32(arg3, inst->u.three[2]);
READPOP(arg1, inst->u.three[0], arg3);
READPOP(arg2, inst->u.three[1], arg3);
- memcpy(arg1, arg2, arg3);
+ memcpy(arg1, arg2, (int32_t)arg3);
/* READ64(res, inst->u.three[0]);*/
WRITE64(inst->dest, res);
break;
}
DEFINE_OP(OP_BC_MEMMOVE) {
- int32_t arg3;
+ int64_t arg3;
void *arg1, *arg2;
int64_t res=0;
- READ32(arg3, inst->u.three[2]);
+ READ64(arg3, inst->u.three[2]);
READPOP(arg1, inst->u.three[0], arg3);
READPOP(arg2, inst->u.three[1], arg3);
- memmove(arg1, arg2, arg3);
+ memmove(arg1, arg2, (int32_t)arg3);
/* READ64(res, inst->u.three[0]);*/
WRITE64(inst->dest, res);
break;
}
DEFINE_OP(OP_BC_MEMSET) {
- int32_t arg2, arg3;
+ int64_t arg3;
+ int32_t arg2;
void *arg1;
int64_t res=0;
- READ32(arg3, inst->u.three[2]);
+ READ64(arg3, inst->u.three[2]);
READPOP(arg1, inst->u.three[0], arg3);
READ32(arg2, inst->u.three[1]);
- memset(arg1, arg2, arg3);
+ memset(arg1, arg2, (int32_t)arg3);
/* READ64(res, inst->u.three[0]);*/
WRITE64(inst->dest, res);
break;
diff --git a/libclamav/c++/bytecode2llvm.cpp b/libclamav/c++/bytecode2llvm.cpp
index 5c19dbd..9ab263b 100644
--- a/libclamav/c++/bytecode2llvm.cpp
+++ b/libclamav/c++/bytecode2llvm.cpp
@@ -1451,6 +1451,11 @@ public:
assert(inst->u.ops.funcid < cli_apicall_maxapi && "APICall out of range");
std::vector<Value*> args;
Function *DestF = apiFuncs[inst->u.ops.funcid];
+ if (!strcmp(cli_apicalls[inst->u.ops.funcid].name, "engine_functionality_level")) {
+ Store(inst->dest,
+ ConstantInt::get(Type::getInt32Ty(Context),
+ cl_retflevel()));
+ } else {
args.push_back(&*F->arg_begin()); // pass hidden arg
for (unsigned a=0;a<inst->u.ops.numOps;a++) {
operand_t op = inst->u.ops.ops[a];
@@ -1459,6 +1464,7 @@ public:
CallInst *CI = Builder.CreateCall(DestF, args.begin(), args.end());
CI->setDoesNotThrow(true);
Store(inst->dest, CI);
+ }
break;
}
case OP_BC_GEP1:
@@ -2103,8 +2109,8 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
// TODO: only run this on the untrusted bytecodes, not all of them...
if (has_untrusted)
PM.add(createClamBCRTChecks());
- PM.add(createCFGSimplificationPass());
PM.add(createSCCPPass());
+ PM.add(createCFGSimplificationPass());
PM.add(createGlobalOptimizerPass());
PM.add(createConstantMergePass());
PM.add(new RuntimeLimits());
@@ -2121,8 +2127,9 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
// compile all functions now, not lazily!
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
Function *Fn = &*I;
- if (!Fn->isDeclaration())
+ if (!Fn->isDeclaration()) {
EE->getPointerToFunction(Fn);
+ }
}
codegenTimer.stopTimer();
}
@@ -2155,7 +2162,7 @@ int bytecode_init(void)
{
// If already initialized return
if (llvm_is_multithreaded()) {
- cli_warnmsg("bytecode_init: already initialized");
+ cli_warnmsg("bytecode_init: already initialized\n");
return CL_EARG;
}
llvm_install_error_handler(llvm_error_handler);
diff --git a/libclamav/c++/llvm/autoconf/configure.ac b/libclamav/c++/llvm/autoconf/configure.ac
index 3b1a6c0..01aba96 100644
--- a/libclamav/c++/llvm/autoconf/configure.ac
+++ b/libclamav/c++/llvm/autoconf/configure.ac
@@ -1272,9 +1272,25 @@ if test "$llvm_cv_enable_libffi" = "yes" ; then
AC_CHECK_HEADERS([ffi.h ffi/ffi.h])
fi
-dnl Try to find Darwin specific crash reporting library.
+dnl Try to find Darwin specific crash reporting libraries.
AC_CHECK_HEADERS([CrashReporterClient.h])
+dnl Try to find Darwin specific crash reporting global.
+AC_MSG_CHECKING([__crashreporter_info__])
+AC_LINK_IFELSE(
+ AC_LANG_SOURCE(
+ [[extern const char *__crashreporter_info__;
+ int main() {
+ __crashreporter_info__ = "test";
+ return 0;
+ }
+ ]]),
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_CRASHREPORTER_INFO, 1, Can use __crashreporter_info__),
+ AC_MSG_RESULT(no)
+ AC_DEFINE(HAVE_CRASHREPORTER_INFO, 0,
+ Define if __crashreporter_info__ exists.))
+
dnl===-----------------------------------------------------------------------===
dnl===
dnl=== SECTION 7: Check for types and structures
diff --git a/libclamav/c++/llvm/configure b/libclamav/c++/llvm/configure
index 0d8450f..eb53a25 100755
--- a/libclamav/c++/llvm/configure
+++ b/libclamav/c++/llvm/configure
@@ -11631,6 +11631,36 @@ fi
done
+<<<<<<< HEAD
+=======
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking __crashreporter_info__" >&5
+$as_echo_n "checking __crashreporter_info__... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+extern const char *__crashreporter_info__;
+ int main() {
+ __crashreporter_info__ = "test";
+ return 0;
+ }
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+$as_echo "#define HAVE_CRASHREPORTER_INFO 1" >>confdefs.h
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define HAVE_CRASHREPORTER_INFO 0" >>confdefs.h
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+>>>>>>> clamav-0.97
diff --git a/libclamav/c++/llvm/include/llvm/Config/config.h.in b/libclamav/c++/llvm/include/llvm/Config/config.h.in
index a4cebb3..7f858f7 100644
--- a/libclamav/c++/llvm/include/llvm/Config/config.h.in
+++ b/libclamav/c++/llvm/include/llvm/Config/config.h.in
@@ -72,6 +72,9 @@
/* Define to 1 if you have the <CrashReporterClient.h> header file. */
#undef HAVE_CRASHREPORTERCLIENT_H
+/* Define if __crashreporter_info__ exists. */
+#undef HAVE_CRASHREPORTER_INFO
+
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
diff --git a/libclamav/c++/llvm/lib/Support/PrettyStackTrace.cpp b/libclamav/c++/llvm/lib/Support/PrettyStackTrace.cpp
index 3c8a108..57a9d51 100644
--- a/libclamav/c++/llvm/lib/Support/PrettyStackTrace.cpp
+++ b/libclamav/c++/llvm/lib/Support/PrettyStackTrace.cpp
@@ -55,7 +55,7 @@ static void PrintCurStackTrace(raw_ostream &OS) {
}
// Integrate with crash reporter libraries.
-#if defined (__APPLE__) && defined (HAVE_CRASHREPORTERCLIENT_H)
+#if defined (__APPLE__) && HAVE_CRASHREPORTERCLIENT_H
// If any clients of llvm try to link to libCrashReporterClient.a themselves,
// only one crash info struct will be used.
extern "C" {
@@ -64,7 +64,7 @@ struct crashreporter_annotations_t gCRAnnotations
__attribute__((section("__DATA," CRASHREPORTER_ANNOTATIONS_SECTION)))
= { CRASHREPORTER_ANNOTATIONS_VERSION, 0, 0, 0, 0 };
}
-#elif defined (__APPLE__)
+#elif defined (__APPLE__) && HAVE_CRASHREPORTER_INFO
static const char *__crashreporter_info__ = 0;
asm(".desc ___crashreporter_info__, 0x10");
#endif
@@ -86,11 +86,11 @@ static void CrashHandler(void *) {
}
if (!TmpStr.empty()) {
-#ifndef HAVE_CRASHREPORTERCLIENT_H
- __crashreporter_info__ = strdup(std::string(TmpStr.str()).c_str());
-#else
+#ifdef HAVE_CRASHREPORTERCLIENT_H
// Cast to void to avoid warning.
(void)CRSetCrashLogMessage(std::string(TmpStr.str()).c_str());
+#elif HAVE_CRASHREPORTER_INFO
+ __crashreporter_info__ = strdup(std::string(TmpStr.str()).c_str());
#endif
errs() << TmpStr.str();
}
diff --git a/libclamav/chmunpack.c b/libclamav/chmunpack.c
index 3f4a557..2ad9796 100644
--- a/libclamav/chmunpack.c
+++ b/libclamav/chmunpack.c
@@ -32,6 +32,7 @@
#include <unistd.h>
#endif
#include <string.h>
+#include <errno.h>
#include "fmap.h"
#include "others.h"
@@ -678,6 +679,10 @@ int cli_chm_open(int fd, const char *dirname, chm_metadata_t *metadata, cli_ctx
if (!metadata->map) {
return CL_EMAP;
}
+ } else {
+ char err[128];
+ cli_warnmsg("fstat() failed: %s\n", cli_strerror(errno, err, sizeof(err)));
+ return CL_ESTAT;
}
if (!itsf_read_header(metadata)) {
diff --git a/libclamav/clamav.h b/libclamav/clamav.h
index 862562c..e0423e8 100644
--- a/libclamav/clamav.h
+++ b/libclamav/clamav.h
@@ -69,6 +69,11 @@ typedef enum {
CL_EBYTECODE,/* may be reported in testmode */
CL_EBYTECODE_TESTFAIL, /* may be reported in testmode */
+ /* c4w error codes */
+ CL_ELOCK,
+ CL_EBUSY,
+ CL_ESTATE,
+
/* no error codes below this line please */
CL_ELAST_ERROR
} cl_error_t;
diff --git a/libclamav/cvd.c b/libclamav/cvd.c
index 30dac75..564162b 100644
--- a/libclamav/cvd.c
+++ b/libclamav/cvd.c
@@ -515,7 +515,7 @@ static int cli_cvdverify(FILE *fs, struct cl_cvd *cvdpt, unsigned int cld)
return CL_SUCCESS;
}
- md5 = cli_md5stream(fs, NULL);
+ md5 = cli_hashstream(fs, NULL, 1);
cli_dbgmsg("MD5(.tar.gz) = %s\n", md5);
if(strncmp(md5, cvd->md5, 32)) {
@@ -539,6 +539,7 @@ static int cli_cvdverify(FILE *fs, struct cl_cvd *cvdpt, unsigned int cld)
int cl_cvdverify(const char *file)
{
+ struct cl_engine *engine;
FILE *fs;
int ret;
@@ -548,13 +549,20 @@ int cl_cvdverify(const char *file)
return CL_EOPEN;
}
- ret = cli_cvdverify(fs, NULL, 0);
- fclose(fs);
+ if(!(engine = cl_engine_new())) {
+ cli_errmsg("cld_cvdverify: Can't create new engine\n");
+ fclose(fs);
+ return CL_EMEM;
+ }
+
+ ret = cli_cvdload(fs, engine, NULL, CL_DB_STDOPT | CL_DB_PUA, !!cli_strbcasestr(file, ".cld"), file, 1);
+ cl_engine_free(engine);
+ fclose(fs);
return ret;
}
-int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, unsigned int cld, const char *filename)
+int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, unsigned int cld, const char *filename, unsigned int chkonly)
{
struct cl_cvd cvd, dupcvd;
FILE *dupfs;
@@ -622,6 +630,7 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
}
cfd = fileno(fs);
+ dbio.chkonly = 0;
ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, NULL);
if(ret != CL_SUCCESS)
return ret;
@@ -635,6 +644,7 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
if(!dbinfo)
return CL_EMALFDB;
+ dbio.chkonly = chkonly;
options |= CL_DB_SIGNED;
ret = cli_tgzload(cfd, engine, signo, options | CL_DB_OFFICIAL, &dbio, dbinfo);
diff --git a/libclamav/cvd.h b/libclamav/cvd.h
index e51c2b4..aee727f 100644
--- a/libclamav/cvd.h
+++ b/libclamav/cvd.h
@@ -33,10 +33,11 @@ struct cli_dbio {
unsigned int size, bread;
char *buf, *bufpt, *readpt;
unsigned int usebuf, bufsize, readsize;
+ unsigned int chkonly;
SHA256_CTX sha256ctx;
};
-int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, unsigned int cld, const char *filename);
+int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int options, unsigned int cld, const char *filename, unsigned int chkonly);
int cli_cvdunpack(const char *file, const char *dir);
#endif
diff --git a/libclamav/disasm.c b/libclamav/disasm.c
index 61bd7cf..6f72fb4 100644
--- a/libclamav/disasm.c
+++ b/libclamav/disasm.c
@@ -1092,16 +1092,16 @@ static const struct OPCODES x86ops[2][256] = {{
PUSHOP(0xb3, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BTR),
PUSHOP(0xb4, ADDR_MRM_GEN_GM, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LFS), /* FIXME: mem size is F/D */
PUSHOP(0xb5, ADDR_MRM_GEN_GM, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_LGS), /* FIXME: mem size is F/D */
- PUSHOP(0xb6, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVZX), /* FIXME: dsize is always B */
- PUSHOP(0xb7, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVZX), /* FIXME: dsize is always W */
+ PUSHOP(0xb6, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVZX),
+ PUSHOP(0xb7, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVZX),
PUSHOP(0xb8, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_INVALID),
PUSHOP(0xb9, ADDR_NOADDR, SIZE_NOSIZE, ADDR_NOADDR, SIZE_NOSIZE, OP_UNSUP),
PUSHOP(0xba, ADDR_MRM_EXTRA_1A, SIZE_WD, ADDR_IMMED, SIZE_BYTE, 24),
PUSHOP(0xbb, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BTC),
PUSHOP(0xbc, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSF),
PUSHOP(0xbd, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_BSR),
- PUSHOP(0xbe, ADDR_MRM_GEN_GE, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVSX), /* FIXME: dsize is always B */
- PUSHOP(0xbf, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVSX), /* FIXME: dsize is always W */
+ PUSHOP(0xbe, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVSX),
+ PUSHOP(0xbf, ADDR_MRM_GEN_GE, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_MOVSX),
PUSHOP(0xc0, ADDR_MRM_GEN_EG, SIZE_BYTE, ADDR_NOADDR, SIZE_NOSIZE, OP_XADD),
PUSHOP(0xc1, ADDR_MRM_GEN_EG, SIZE_WD, ADDR_NOADDR, SIZE_NOSIZE, OP_XADD),
@@ -1200,8 +1200,6 @@ static void spam_x86(struct DISASMED *s, char *hr) {
case ACCESS_NOARG:
break;
case ACCESS_IMM:
- hr += sprintf(hr, "%s %lx", comma, (long)s->args[i].arg.q);
- break;
case ACCESS_REL:
if (s->args[i].arg.rq >=0)
hr += sprintf(hr, "%s %lx", comma, (long)s->args[i].arg.q);
@@ -1418,10 +1416,10 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
GETBYTE(b);
s->args[0].arg.q+=(uint64_t)b<<(i*8);
}
- if (x86ops[table][s->table_op].dmethod==ADDR_RELJ) {
+ /* if (x86ops[table][s->table_op].dmethod==ADDR_RELJ) { */
s->args[0].arg.q<<=((8-sz)*8);
s->args[0].arg.rq>>=((8-sz)*8);
- }
+ /* } */
s->state = STATE_CHECKSTYPE;
continue;
}
@@ -1490,6 +1488,10 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
s->args[reversed^1].access = ACCESS_REG;
if ((s->args[reversed^1].reg = p[s->args[reversed].size][rop]) == REG_INVALID) INVALIDATE;
+ /* MOVZX size fixxup */
+ if(s->real_op == OP_MOVZX || s->real_op == OP_MOVSX)
+ s->args[reversed].size = SIZEB + (s->table_op & 1);
+
if(mod==3) {
if(x86ops[table][s->table_op].dmethod==ADDR_MRM_GEN_GM || x86ops[table][s->table_op].dmethod==ADDR_MRM_EXTRA_1A_M) INVALIDATE;
s->args[reversed].access = ACCESS_REG;
@@ -1623,6 +1625,8 @@ static const uint8_t *disasm_x86(const uint8_t *command, unsigned int len, struc
GETBYTE(b);
s->args[s->cur].arg.q+=b<<(i*8);
}
+ s->args[s->cur].arg.q<<=((8-sz)*8);
+ s->args[s->cur].arg.rq>>=((8-sz)*8);
s->state = STATE_FINALIZE;
continue;
}
diff --git a/libclamav/filetypes.c b/libclamav/filetypes.c
index b992d4c..a40aa39 100644
--- a/libclamav/filetypes.c
+++ b/libclamav/filetypes.c
@@ -163,6 +163,17 @@ cli_file_t cli_filetype2(fmap_t *map, const struct cl_engine *engine)
ret = cli_filetype(buff, bread, engine);
+ if(ret == CL_TYPE_BINARY_DATA) {
+ switch(is_tar(buff, bread)) {
+ case 1:
+ cli_dbgmsg("Recognized old fashioned tar file\n");
+ return CL_TYPE_OLD_TAR;
+ case 2:
+ cli_dbgmsg("Recognized POSIX tar file\n");
+ return CL_TYPE_POSIX_TAR;
+ }
+ }
+
if(ret >= CL_TYPE_TEXT_ASCII && ret <= CL_TYPE_BINARY_DATA) {
/* HTML files may contain special characters and could be
* misidentified as BINARY_DATA by cli_filetype()
@@ -234,18 +245,5 @@ cli_file_t cli_filetype2(fmap_t *map, const struct cl_engine *engine)
}
}
- if(ret == CL_TYPE_BINARY_DATA) {
- switch(is_tar(buff, bread)) {
- case 1:
- ret = CL_TYPE_OLD_TAR;
- cli_dbgmsg("Recognized old fashioned tar file\n");
- break;
- case 2:
- ret = CL_TYPE_POSIX_TAR;
- cli_dbgmsg("Recognized POSIX tar file\n");
- break;
- }
- }
-
return ret;
}
diff --git a/libclamav/hashtab.c b/libclamav/hashtab.c
index e7fa897..11275c8 100644
--- a/libclamav/hashtab.c
+++ b/libclamav/hashtab.c
@@ -33,6 +33,7 @@
#define MODULE_NAME "hashtab: "
static const char DELETED_KEY[] = "";
+#define DELETED_HTU32_KEY ((uint32_t)(-1))
static unsigned long nearest_power(unsigned long num)
{
@@ -185,6 +186,24 @@ int cli_hashtab_init(struct cli_hashtable *s,size_t capacity)
return 0;
}
+int cli_htu32_init(struct cli_htu32 *s, size_t capacity, mpool_t *mempool)
+{
+ if(!s)
+ return CL_ENULLARG;
+
+ PROFILE_INIT(s);
+
+ capacity = nearest_power(capacity);
+ s->htable = mpool_calloc(mempool, capacity, sizeof(*s->htable));
+ if(!s->htable)
+ return CL_EMEM;
+ s->capacity = capacity;
+ s->used = 0;
+ s->maxfill = 8*capacity/10;
+ return 0;
+}
+
+
static inline uint32_t hash32shift(uint32_t key)
{
key = ~key + (key << 15);
@@ -210,6 +229,14 @@ static inline size_t hash(const unsigned char* k,const size_t len,const size_t S
return Hash & (SIZE - 1);
}
+static inline size_t hash_htu32(uint32_t k, const size_t SIZE)
+{
+ /* mixing function */
+ size_t Hash = hash32shift(k);
+ /* SIZE is power of 2 */
+ return Hash & (SIZE - 1);
+}
+
/* if returned element has key==NULL, then key was not found in table */
struct cli_element* cli_hashtab_find(const struct cli_hashtable *s,const char* key,const size_t len)
{
@@ -241,6 +268,61 @@ struct cli_element* cli_hashtab_find(const struct cli_hashtable *s,const char* k
return NULL; /* not found */
}
+
+const struct cli_htu32_element *cli_htu32_find(const struct cli_htu32 *s, uint32_t key)
+{
+ struct cli_htu32_element* element;
+ size_t tries = 1;
+ size_t idx;
+
+ if(!s)
+ return NULL;
+ PROFILE_CALC_HASH(s);
+ PROFILE_FIND_ELEMENT(s);
+ idx = hash_htu32(key, s->capacity);
+ element = &s->htable[idx];
+ do {
+ if(!element->key) {
+ PROFILE_FIND_NOTFOUND(s, tries);
+ return NULL; /* element not found, place is empty */
+ }
+ else if(key == element->key) {
+ PROFILE_FIND_FOUND(s, tries);
+ return element;/* found */
+ }
+ else {
+ idx = (idx + tries++) & (s->capacity-1);
+ element = &s->htable[idx];
+ }
+ } while (tries <= s->capacity);
+ PROFILE_HASH_EXHAUSTED(s);
+ return NULL; /* not found */
+}
+
+/* linear enumeration - start with current = NULL, returns next item if present or NULL if not */
+const struct cli_htu32_element *cli_htu32_next(const struct cli_htu32 *s, const struct cli_htu32_element *current) {
+ size_t ncur;
+ if(!s || !s->capacity)
+ return NULL;
+
+ if(!current)
+ ncur = 0;
+ else {
+ ncur = current - s->htable;
+ if(ncur >= s->capacity)
+ return NULL;
+
+ ncur++;
+ }
+ for(; ncur<s->capacity; ncur++) {
+ const struct cli_htu32_element *item = &s->htable[ncur & (s->capacity - 1)];
+ if(item->key && item->key != DELETED_HTU32_KEY)
+ return item;
+ }
+ return NULL;
+}
+
+
static int cli_hashtab_grow(struct cli_hashtable *s)
{
const size_t new_capacity = nearest_power(s->capacity + 1);
@@ -262,7 +344,7 @@ static int cli_hashtab_grow(struct cli_hashtable *s)
element = &htable[idx];
while(element->key && tries <= new_capacity) {
- idx = (idx + tries++) % new_capacity;
+ idx = (idx + tries++) & (new_capacity-1);
element = &htable[idx];
}
if(!element->key) {
@@ -287,6 +369,57 @@ static int cli_hashtab_grow(struct cli_hashtable *s)
return CL_SUCCESS;
}
+#ifndef USE_MPOOL
+#define cli_htu32_grow(A, B) cli_htu32_grow(A)
+#endif
+
+static int cli_htu32_grow(struct cli_htu32 *s, mpool_t *mempool)
+{
+ const size_t new_capacity = nearest_power(s->capacity + 1);
+ struct cli_htu32_element* htable = mpool_calloc(mempool, new_capacity, sizeof(*s->htable));
+ size_t i,idx, used = 0;
+ cli_dbgmsg("hashtab.c: new capacity: %lu\n",new_capacity);
+ if(new_capacity == s->capacity || !htable)
+ return CL_EMEM;
+
+ PROFILE_GROW_START(s);
+
+ for(i=0; i < s->capacity; i++) {
+ if(s->htable[i].key && s->htable[i].key != DELETED_HTU32_KEY) {
+ struct cli_htu32_element* element;
+ size_t tries = 1;
+
+ PROFILE_CALC_HASH(s);
+ idx = hash_htu32(s->htable[i].key, new_capacity);
+ element = &htable[idx];
+
+ while(element->key && tries <= new_capacity) {
+ idx = (idx + tries++) & (new_capacity-1);
+ element = &htable[idx];
+ }
+ if(!element->key) {
+ /* copy element from old hashtable to new */
+ PROFILE_GROW_FOUND(s, tries);
+ *element = s->htable[i];
+ used++;
+ }
+ else {
+ cli_errmsg("hashtab.c: Impossible - unable to rehash table");
+ return CL_EMEM;/* this means we didn't find enough room for all elements in the new table, should never happen */
+ }
+ }
+ }
+ mpool_free(mempool, s->htable);
+ s->htable = htable;
+ s->used = used;
+ s->capacity = new_capacity;
+ s->maxfill = new_capacity*8/10;
+ cli_dbgmsg("Table %p size after grow:%ld\n",(void*)s,s->capacity);
+ PROFILE_GROW_DONE(s);
+ return CL_SUCCESS;
+}
+
+
const struct cli_element* cli_hashtab_insert(struct cli_hashtable *s, const char* key, const size_t len, const cli_element_data data)
{
struct cli_element* element;
@@ -349,6 +482,64 @@ const struct cli_element* cli_hashtab_insert(struct cli_hashtable *s, const char
return NULL;
}
+
+int cli_htu32_insert(struct cli_htu32 *s, const struct cli_htu32_element *item, mpool_t *mempool)
+{
+ struct cli_htu32_element* element;
+ struct cli_htu32_element* deleted_element = NULL;
+ size_t tries = 1;
+ size_t idx;
+ int ret;
+
+ if(!s)
+ return CL_ENULLARG;
+ if(s->used > s->maxfill) {
+ cli_dbgmsg("hashtab.c:Growing hashtable %p, because it has exceeded maxfill, old size:%ld\n",(void*)s,s->capacity);
+ cli_htu32_grow(s, mempool);
+ }
+ do {
+ PROFILE_CALC_HASH(s);
+ idx = hash_htu32(item->key, s->capacity);
+ element = &s->htable[idx];
+
+ do {
+ if(!element->key) {
+ /* element not found, place is empty, insert*/
+ if(deleted_element) {
+ /* reuse deleted elements*/
+ element = deleted_element;
+ PROFILE_DELETED_REUSE(s, tries);
+ }
+ else {
+ PROFILE_INSERT(s, tries);
+ }
+ *element = *item;
+ s->used++;
+ return 0;
+ }
+ else if(element->key == DELETED_HTU32_KEY) {
+ deleted_element = element;
+ element->key = 0;
+ }
+ else if(item->key == element->key) {
+ PROFILE_DATA_UPDATE(s, tries);
+ element->data = item->data;/* key found, update */
+ return 0;
+ }
+ else {
+ idx = (idx + tries++) % s->capacity;
+ element = &s->htable[idx];
+ }
+ } while (tries <= s->capacity);
+ /* no free place found*/
+ PROFILE_HASH_EXHAUSTED(s);
+ cli_dbgmsg("hashtab.c: Growing hashtable %p, because its full, old size:%ld.\n",(void*)s,s->capacity);
+ } while( (ret = cli_htu32_grow(s, mempool)) >= 0 );
+ cli_warnmsg("hashtab.c: Unable to grow hashtable\n");
+ return ret;
+}
+
+
void cli_hashtab_delete(struct cli_hashtable *s,const char* key,const size_t len)
{
struct cli_element *el = cli_hashtab_find(s, key, len);
@@ -358,6 +549,13 @@ void cli_hashtab_delete(struct cli_hashtable *s,const char* key,const size_t len
el->key = DELETED_KEY;
}
+void cli_htu32_delete(struct cli_htu32 *s, uint32_t key)
+{
+ struct cli_htu32_element *el = (struct cli_htu32_element *)cli_htu32_find(s, key);
+ if(el)
+ el->key = DELETED_HTU32_KEY;
+}
+
void cli_hashtab_clear(struct cli_hashtable *s)
{
size_t i;
@@ -367,7 +565,15 @@ void cli_hashtab_clear(struct cli_hashtable *s)
free((void *)s->htable[i].key);
}
if(s->htable)
- memset(s->htable, 0, s->capacity);
+ memset(s->htable, 0, s->capacity * sizeof(*s->htable));
+ s->used = 0;
+}
+
+void cli_htu32_clear(struct cli_htu32 *s)
+{
+ PROFILE_HASH_CLEAR(s);
+ if(s->htable)
+ memset(s->htable, 0, s->capacity * sizeof(struct cli_htu32_element));
s->used = 0;
}
@@ -379,6 +585,18 @@ void cli_hashtab_free(struct cli_hashtable *s)
s->capacity = 0;
}
+void cli_htu32_free(struct cli_htu32 *s, mpool_t *mempool)
+{
+ mpool_free(mempool, s->htable);
+ s->htable = NULL;
+ s->capacity = 0;
+}
+
+size_t cli_htu32_numitems(struct cli_htu32 *s) {
+ if(!s) return 0;
+ return s->capacity;
+}
+
int cli_hashtab_store(const struct cli_hashtable *s,FILE* out)
{
size_t i;
diff --git a/libclamav/hashtab.h b/libclamav/hashtab.h
index 7672f4d..97ccffc 100644
--- a/libclamav/hashtab.h
+++ b/libclamav/hashtab.h
@@ -86,6 +86,39 @@ void cli_hashtab_free(struct cli_hashtable *s);
int cli_hashtab_load(FILE* in, struct cli_hashtable *s);
int cli_hashtab_store(const struct cli_hashtable *s,FILE* out);
+
+struct cli_htu32_element {
+ uint32_t key;
+ union {
+ unsigned long as_ulong;
+ void *as_ptr;
+ } data;
+};
+
+struct cli_htu32 {
+ struct cli_htu32_element* htable;
+ size_t capacity;
+ size_t used;
+ size_t maxfill;/* 80% */
+
+ STRUCT_PROFILE
+};
+
+#ifndef USE_MPOOL
+#define cli_htu32_init(A, B, C) cli_htu32_init(A, B)
+#define cli_htu32_insert(A, B, C) cli_htu32_insert(A, B)
+#define cli_htu32_free(A, B) cli_htu32_free(A)
+#endif
+int cli_htu32_init(struct cli_htu32 *s, size_t capacity, mpool_t *mempool);
+int cli_htu32_insert(struct cli_htu32 *s, const struct cli_htu32_element *item, mpool_t *mempool);
+const struct cli_htu32_element *cli_htu32_find(const struct cli_htu32 *s, uint32_t key);
+void cli_htu32_delete(struct cli_htu32 *s, uint32_t key);
+void cli_htu32_clear(struct cli_htu32 *s);
+void cli_htu32_free(struct cli_htu32 *s, mpool_t *mempool);
+const struct cli_htu32_element *cli_htu32_next(const struct cli_htu32 *s, const struct cli_htu32_element *current);
+size_t cli_htu32_numitems(struct cli_htu32 *s);
+
+
/* a hashtable that stores the values too */
struct cli_map_value {
void *value;
diff --git a/libclamav/libclamav.map b/libclamav/libclamav.map
index 9b2c74d..3aed4c5 100644
--- a/libclamav/libclamav.map
+++ b/libclamav/libclamav.map
@@ -66,8 +66,8 @@ CLAMAV_PRIVATE {
cli_wm_decrypt_macro;
cli_readn;
cli_str2hex;
- cli_md5file;
- cli_md5stream;
+ cli_hashfile;
+ cli_hashstream;
html_normalise_map;
cli_utf16toascii;
diff --git a/libclamav/matcher-ac.c b/libclamav/matcher-ac.c
index 17b83f2..4e01f44 100644
--- a/libclamav/matcher-ac.c
+++ b/libclamav/matcher-ac.c
@@ -82,7 +82,7 @@ static char boundary[256] = {
int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern)
{
struct cli_ac_node *pt, *next;
- struct cli_ac_patt *ph;
+ struct cli_ac_patt *ph, *ph_prev, *ph_add_after;
void *newtable;
struct cli_ac_special *a1, *a2;
uint8_t i, match;
@@ -162,7 +162,10 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern)
pattern->depth = i;
ph = pt->list;
+ ph_add_after = ph_prev = NULL;
while(ph) {
+ if(!ph_add_after && ph->partno <= pattern->partno && (!ph->next || ph->next->partno > pattern->partno))
+ ph_add_after = ph;
if((ph->length == pattern->length) && (ph->prefix_length == pattern->prefix_length) && (ph->ch[0] == pattern->ch[0]) && (ph->ch[1] == pattern->ch[1])) {
if(!memcmp(ph->pattern, pattern->pattern, ph->length * sizeof(uint16_t)) && !memcmp(ph->prefix, pattern->prefix, ph->prefix_length * sizeof(uint16_t))) {
if(!ph->special && !pattern->special) {
@@ -207,17 +210,35 @@ int cli_ac_addpatt(struct cli_matcher *root, struct cli_ac_patt *pattern)
}
if(match) {
- pattern->next_same = ph->next_same;
- ph->next_same = pattern;
- return CL_SUCCESS;
+ if(pattern->partno < ph->partno) {
+ pattern->next_same = ph;
+ if(ph_prev)
+ ph_prev->next = ph->next;
+ else
+ pt->list = ph->next;
+ ph->next = NULL;
+ break;
+ } else {
+ while(ph->next_same && ph->next_same->partno < pattern->partno)
+ ph = ph->next_same;
+ pattern->next_same = ph->next_same;
+ ph->next_same = pattern;
+ return CL_SUCCESS;
+ }
}
}
}
+ ph_prev = ph;
ph = ph->next;
}
- pattern->next = pt->list;
- pt->list = pattern;
+ if(ph_add_after) {
+ pattern->next = ph_add_after->next;
+ ph_add_after->next = pattern;
+ } else {
+ pattern->next = pt->list;
+ pt->list = pattern;
+ }
return CL_SUCCESS;
}
@@ -305,16 +326,6 @@ static int ac_maketrans(struct cli_matcher *root)
child->fail = fail->trans[i];
- if(child->list) {
- patt = child->list;
- while(patt->next)
- patt = patt->next;
-
- patt->next = child->fail->list;
- } else {
- child->list = child->fail->list;
- }
-
if((ret = bfs_enqueue(&bfs, &bfs_last, child)) != 0)
return ret;
}
@@ -935,40 +946,54 @@ int cli_ac_initdata(struct cli_ac_data *data, uint32_t partsigs, uint32_t lsigs,
data->lsigcnt[i] = data->lsigcnt[0] + 64 * i;
/* subsig offsets */
- data->lsigsuboff = (uint32_t **) cli_malloc(lsigs * sizeof(uint32_t *));
- if(!data->lsigsuboff) {
+ data->lsigsuboff_last = (uint32_t **) cli_malloc(lsigs * sizeof(uint32_t *));
+ data->lsigsuboff_first = (uint32_t **) cli_malloc(lsigs * sizeof(uint32_t *));
+ if(!data->lsigsuboff_last || !data->lsigsuboff_first) {
+ free(data->lsigsuboff_last);
+ free(data->lsigsuboff_first);
free(data->lsigcnt[0]);
free(data->lsigcnt);
if(partsigs)
free(data->offmatrix);
if(reloffsigs)
free(data->offset);
- cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigsuboff\n");
+ cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigsuboff_(last|first)\n");
return CL_EMEM;
}
- data->lsigsuboff[0] = (uint32_t *) cli_calloc(lsigs * 64, sizeof(uint32_t));
- if(!data->lsigsuboff[0]) {
- free(data->lsigsuboff);
+ data->lsigsuboff_last[0] = (uint32_t *) cli_calloc(lsigs * 64, sizeof(uint32_t));
+ data->lsigsuboff_first[0] = (uint32_t *) cli_calloc(lsigs * 64, sizeof(uint32_t));
+ if(!data->lsigsuboff_last[0] || !data->lsigsuboff_first[0]) {
+ free(data->lsigsuboff_last[0]);
+ free(data->lsigsuboff_first[0]);
+ free(data->lsigsuboff_last);
+ free(data->lsigsuboff_first);
free(data->lsigcnt[0]);
free(data->lsigcnt);
if(partsigs)
free(data->offmatrix);
if(reloffsigs)
free(data->offset);
- cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigsuboff[0]\n");
+ cli_errmsg("cli_ac_init: Can't allocate memory for data->lsigsuboff_(last|first)[0]\n");
return CL_EMEM;
}
- for(j = 0; j < 64; j++)
- data->lsigsuboff[0][j] = CLI_OFF_NONE;
+ for(j = 0; j < 64; j++) {
+ data->lsigsuboff_last[0][j] = CLI_OFF_NONE;
+ data->lsigsuboff_first[0][j] = CLI_OFF_NONE;
+ }
for(i = 1; i < lsigs; i++) {
- data->lsigsuboff[i] = data->lsigsuboff[0] + 64 * i;
- for(j = 0; j < 64; j++)
- data->lsigsuboff[i][j] = CLI_OFF_NONE;
+ data->lsigsuboff_last[i] = data->lsigsuboff_last[0] + 64 * i;
+ data->lsigsuboff_first[i] = data->lsigsuboff_first[0] + 64 * i;
+ for(j = 0; j < 64; j++) {
+ data->lsigsuboff_last[i][j] = CLI_OFF_NONE;
+ data->lsigsuboff_first[i][j] = CLI_OFF_NONE;
+ }
}
}
for (i=0;i<32;i++)
data->macro_lastmatch[i] = CLI_OFF_NONE;
+ data->min_partno = 1;
+
return CL_SUCCESS;
}
@@ -1014,8 +1039,10 @@ void cli_ac_freedata(struct cli_ac_data *data)
if(data && data->lsigs) {
free(data->lsigcnt[0]);
free(data->lsigcnt);
- free(data->lsigsuboff[0]);
- free(data->lsigsuboff);
+ free(data->lsigsuboff_last[0]);
+ free(data->lsigsuboff_last);
+ free(data->lsigsuboff_first[0]);
+ free(data->lsigsuboff_first);
data->lsigs = 0;
}
@@ -1062,11 +1089,13 @@ static inline void lsig_sub_matched(const struct cli_matcher *root, struct cli_a
const struct cli_lsig_tdb *tdb = &root->ac_lsigtable[lsigid1]->tdb;
if(realoff != CLI_OFF_NONE) {
- if(mdata->lsigsuboff[lsigid1][lsigid2] != CLI_OFF_NONE && ((!partial && realoff <= mdata->lsigsuboff[lsigid1][lsigid2]) || (partial && realoff < mdata->lsigsuboff[lsigid1][lsigid2])))
+ if(mdata->lsigsuboff_first[lsigid1][lsigid2] == CLI_OFF_NONE)
+ mdata->lsigsuboff_first[lsigid1][lsigid2] = realoff;
+ if(mdata->lsigsuboff_last[lsigid1][lsigid2] != CLI_OFF_NONE && ((!partial && realoff <= mdata->lsigsuboff_last[lsigid1][lsigid2]) || (partial && realoff < mdata->lsigsuboff_last[lsigid1][lsigid2])))
return;
mdata->lsigcnt[lsigid1][lsigid2]++;
if(mdata->lsigcnt[lsigid1][lsigid2] <= 1 || !tdb->macro_ptids || !tdb->macro_ptids[lsigid2])
- mdata->lsigsuboff[lsigid1][lsigid2] = realoff;
+ mdata->lsigsuboff_last[lsigid1][lsigid2] = realoff;
}
if (mdata->lsigcnt[lsigid1][lsigid2] > 1) {
@@ -1085,7 +1114,7 @@ static inline void lsig_sub_matched(const struct cli_matcher *root, struct cli_a
/* start of last macro match */
last_macro_match = mdata->macro_lastmatch[macropt->sigid];
/* start of previous lsig subsig match */
- last_macroprev_match = mdata->lsigsuboff[lsigid1][lsigid2];
+ last_macroprev_match = mdata->lsigsuboff_last[lsigid1][lsigid2];
if (last_macro_match != CLI_OFF_NONE)
cli_dbgmsg("Checking macro match: %u + (%u - %u) == %u\n",
last_macroprev_match, smin, smax, last_macro_match);
@@ -1095,11 +1124,11 @@ static inline void lsig_sub_matched(const struct cli_matcher *root, struct cli_a
cli_dbgmsg("Canceled false lsig macro match\n");
/* Previous match was false - cancel it */
mdata->lsigcnt[lsigid1][lsigid2]--;
- mdata->lsigsuboff[lsigid1][lsigid2] = realoff;
+ mdata->lsigsuboff_last[lsigid1][lsigid2] = realoff;
} else {
/* mark the macro sig itself matched */
mdata->lsigcnt[lsigid1][lsigid2+1]++;
- mdata->lsigsuboff[lsigid1][lsigid2+1] = last_macro_match;
+ mdata->lsigsuboff_last[lsigid1][lsigid2+1] = last_macro_match;
}
}
}
@@ -1119,7 +1148,7 @@ void cli_ac_chkmacro(struct cli_matcher *root, struct cli_ac_data *data, unsigne
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)
{
struct cli_ac_node *current;
- struct cli_ac_patt *patt, *pt;
+ struct cli_ac_patt *patt, *pt, *faillist;
uint32_t i, bp, realoff, matchend;
uint16_t j;
int32_t **offmatrix, swp;
@@ -1141,10 +1170,22 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
current = current->trans[buffer[i]];
if(IS_FINAL(current)) {
+ faillist = NULL;
patt = current->list;
- if (IS_LEAF(current))
+ if(IS_LEAF(current)) {
current = current->fail;
- while(patt) {
+ faillist = current->list;
+ }
+ while(1) {
+ if(!patt) {
+ if(!(patt = faillist))
+ break;
+ faillist = NULL;
+ }
+ if(patt->partno > mdata->min_partno) {
+ patt = NULL;
+ continue;
+ }
bp = i + 1 - patt->depth;
if(patt->offdata[0] != CLI_OFF_VERSION && patt->offdata[0] != CLI_OFF_MACRO && !patt->next_same && (patt->offset_min != CLI_OFF_ANY) && (!patt->sigid || patt->partno == 1)) {
if(patt->offset_min == CLI_OFF_NONE) {
@@ -1167,6 +1208,8 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
pt = patt;
if(ac_findmatch(buffer, bp, offset + bp - patt->prefix_length, length, patt, &matchend)) {
while(pt) {
+ if(pt->partno > mdata->min_partno)
+ break;
if((pt->type && !(mode & AC_SCAN_FT)) || (!pt->type && !(mode & AC_SCAN_VIR))) {
pt = pt->next_same;
continue;
@@ -1206,6 +1249,9 @@ int cli_ac_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
continue;
}
+ if(pt->partno + 1 > mdata->min_partno)
+ mdata->min_partno = pt->partno + 1;
+
if(!mdata->offmatrix[pt->sigid - 1]) {
mdata->offmatrix[pt->sigid - 1] = cli_malloc(pt->parts * sizeof(int32_t *));
if(!mdata->offmatrix[pt->sigid - 1]) {
diff --git a/libclamav/matcher-ac.h b/libclamav/matcher-ac.h
index 8370aec..048f64a 100644
--- a/libclamav/matcher-ac.h
+++ b/libclamav/matcher-ac.h
@@ -37,11 +37,12 @@ struct cli_ac_data {
int32_t ***offmatrix;
uint32_t partsigs, lsigs, reloffsigs;
uint32_t **lsigcnt;
- uint32_t **lsigsuboff;
+ uint32_t **lsigsuboff_last, **lsigsuboff_first;
uint32_t *offset;
uint32_t macro_lastmatch[32];
/** Hashset for versioninfo matching */
const struct cli_hashset *vinfo;
+ uint32_t min_partno;
};
struct cli_ac_special {
diff --git a/libclamav/matcher-bm.c b/libclamav/matcher-bm.c
index 696e6d0..094fc7f 100644
--- a/libclamav/matcher-bm.c
+++ b/libclamav/matcher-bm.c
@@ -355,6 +355,10 @@ int cli_bm_scanbuff(const unsigned char *buffer, uint32_t length, const char **v
if(found && p->length + p->prefix_length == j) {
if(!offdata && (p->offset_min != CLI_OFF_ANY)) {
if(p->offdata[0] != CLI_OFF_ABSOLUTE) {
+ if(!info) {
+ p = p->next;
+ continue;
+ }
ret = cli_caloff(NULL, info, root->type, p->offdata, &off_min, &off_max);
if(ret != CL_SUCCESS) {
cli_errmsg("cli_bm_scanbuff: Can't calculate relative offset in signature for %s\n", p->virname);
diff --git a/libclamav/matcher-hash.c b/libclamav/matcher-hash.c
new file mode 100644
index 0000000..93a120f
--- /dev/null
+++ b/libclamav/matcher-hash.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2010 Sourcefire, Inc.
+ *
+ * Authors: aCaB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include "matcher.h"
+#include "others.h"
+#include "str.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+
+int hm_addhash(struct cli_matcher *root, const char *hash, uint32_t size, const char *virusname) {
+ const struct cli_htu32_element *item;
+ struct cli_sz_hash *szh;
+ struct cli_htu32 *ht;
+ enum CLI_HASH_TYPE type;
+ uint8_t binhash[32];
+ int hashlen, i;
+
+ if(!root || !hash) {
+ cli_errmsg("hm_addhash: NULL root or hash\n");
+ return CL_ENULLARG;
+ }
+
+ if(!size || size == (uint32_t)-1) {
+ cli_errmsg("hm_addhash: null or invalid size (%u)\n", size);
+ return CL_EARG;
+ }
+
+ hashlen = strlen(hash);
+ switch(hashlen) {
+ case 32:
+ type = CLI_HASH_MD5;
+ break;
+ case 40:
+ type = CLI_HASH_SHA1;
+ break;
+ case 64:
+ type = CLI_HASH_SHA256;
+ break;
+ default:
+ cli_errmsg("hm_addhash: invalid hash %s -- FIXME!\n", hash);
+ return CL_EARG;
+ }
+ if(cli_hex2str_to(hash, (char *)binhash, hashlen)) {
+ cli_errmsg("hm_addhash: invalid hash %s\n", hash);
+ return CL_EARG;
+ }
+
+ hashlen /= 2;
+ ht = &root->hm.sizehashes[type];
+ if(!root->hm.sizehashes[type].capacity) {
+ i = cli_htu32_init(ht, 64, root->mempool);
+ if(i) return i;
+ }
+
+ item = cli_htu32_find(ht, size);
+ if(!item) {
+ struct cli_htu32_element htitem;
+ szh = mpool_calloc(root->mempool, 1, sizeof(*szh));
+ if(!szh) {
+ cli_errmsg("hm_addhash: failed to allocate size hash\n");
+ return CL_EMEM;
+ }
+
+ htitem.key = size;
+ htitem.data.as_ptr = szh;
+ i = cli_htu32_insert(ht, &htitem, root->mempool);
+ if(i) {
+ cli_errmsg("ht_addhash: failed to add item to hashtab");
+ mpool_free(root->mempool, szh);
+ return i;
+ }
+ } else
+ szh = (struct cli_sz_hash *)item->data.as_ptr;
+
+ szh->items++;
+
+ szh->hash_array = mpool_realloc2(root->mempool, szh->hash_array, hashlen * szh->items);
+ if(!szh->hash_array) {
+ cli_errmsg("ht_add: failed to grow hash array to %u entries\n", szh->items);
+ szh->items=0;
+ mpool_free(root->mempool, szh->virusnames);
+ szh->virusnames = NULL;
+ return CL_EMEM;
+ }
+
+ szh->virusnames = mpool_realloc2(root->mempool, szh->virusnames, sizeof(*szh->virusnames) * szh->items);
+ if(!szh->virusnames) {
+ cli_errmsg("ht_add: failed to grow virusname array to %u entries\n", szh->items);
+ szh->items=0;
+ mpool_free(root->mempool, szh->hash_array);
+ szh->hash_array = NULL;
+ return CL_EMEM;
+ }
+
+ memcpy(&szh->hash_array[(szh->items-1) * hashlen], binhash, hashlen);
+ szh->virusnames[(szh->items-1)] = virusname;
+
+ return 0;
+}
+
+
+
+static const unsigned int hashlen[] = {
+ 16, /* CLI_HASH_MD5 */
+ 20, /* CLI_HASH_SHA1 */
+ 32, /* CLI_HASH_SHA256 */
+};
+
+
+static inline int hm_cmp(const uint8_t *itm, const uint8_t *ref, unsigned int keylen) {
+ uint32_t i = *(uint32_t *)itm, r = *(uint32_t *)ref;
+ if(i!=r)
+ return (i<r) * 2 -1;
+ return memcmp(&itm[4], &ref[4], keylen - 4);
+}
+
+void hm_sort(struct cli_sz_hash *szh, size_t l, size_t r, unsigned int keylen) {
+ uint8_t piv[32], tmph[32];
+ size_t l1, r1;
+
+ const char *tmpv;
+
+ if(l + 1 >= r)
+ return;
+
+ l1 = l+1, r1 = r;
+
+ memcpy(piv, &szh->hash_array[keylen * l], keylen);
+ while(l1 < r1) {
+ if(hm_cmp(&szh->hash_array[keylen * l1], piv, keylen) > 0) {
+ r1--;
+ memcpy(tmph, &szh->hash_array[keylen * l1], keylen);
+ tmpv = szh->virusnames[l1];
+ memcpy(&szh->hash_array[keylen * l1], &szh->hash_array[keylen * r1], keylen);
+ szh->virusnames[l1] = szh->virusnames[r1];
+ memcpy(&szh->hash_array[keylen * r1], tmph, keylen);
+ szh->virusnames[r1] = tmpv;
+ } else
+ l1++;
+ }
+
+ l1--;
+ if(l1!=l) {
+ memcpy(tmph, &szh->hash_array[keylen * l1], keylen);
+ tmpv = szh->virusnames[l1];
+ memcpy(&szh->hash_array[keylen * l1], &szh->hash_array[keylen * l], keylen);
+ szh->virusnames[l1] = szh->virusnames[l];
+ memcpy(&szh->hash_array[keylen * l], tmph, keylen);
+ szh->virusnames[l] = tmpv;
+ }
+
+ hm_sort(szh, l, l1, keylen);
+ hm_sort(szh, r1, r, keylen);
+}
+
+
+void hm_flush(struct cli_matcher *root) {
+ enum CLI_HASH_TYPE type;
+
+ if(!root)
+ return;
+
+ for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) {
+ struct cli_htu32 *ht = &root->hm.sizehashes[type];
+ const struct cli_htu32_element *item = NULL;
+
+ if(!root->hm.sizehashes[type].capacity)
+ continue;
+
+ while((item = cli_htu32_next(ht, item))) {
+ struct cli_sz_hash *szh = (struct cli_sz_hash *)item->data.as_ptr;
+ unsigned int keylen = hashlen[type];
+
+ if(szh->items > 1)
+ hm_sort(szh, 0, szh->items, keylen);
+ }
+ }
+}
+
+
+int cli_hm_have_size(const struct cli_matcher *root, enum CLI_HASH_TYPE type, uint32_t size) {
+ return (size && size != 0xffffffff && root && root->hm.sizehashes[type].capacity && cli_htu32_find(&root->hm.sizehashes[type], size));
+}
+
+int cli_hm_scan(const unsigned char *digest, uint32_t size, const char **virname, const struct cli_matcher *root, enum CLI_HASH_TYPE type) {
+ const struct cli_htu32_element *item;
+ unsigned int keylen;
+ struct cli_sz_hash *szh;
+ size_t l, r;
+
+ if(!digest || !size || size == 0xffffffff || !root || !root->hm.sizehashes[type].capacity)
+ return CL_CLEAN;
+
+ item = cli_htu32_find(&root->hm.sizehashes[type], size);
+ if(!item)
+ return CL_CLEAN;
+
+ szh = (struct cli_sz_hash *)item->data.as_ptr;
+ keylen = hashlen[type];
+
+ l = 0;
+ r = szh->items;
+ while(l <= r) {
+ size_t c = (l + r) / 2;
+ int res = hm_cmp(digest, &szh->hash_array[keylen * c], keylen);
+
+ if(res < 0) {
+ if(!c)
+ break;
+ r = c - 1;
+ } else if(res > 0)
+ l = c + 1;
+ else {
+ if(virname)
+ *virname = szh->virusnames[c];
+ return CL_VIRUS;
+ }
+ }
+ return CL_CLEAN;
+}
+
+void hm_free(struct cli_matcher *root) {
+ enum CLI_HASH_TYPE type;
+
+ if(!root)
+ return;
+
+ for(type = CLI_HASH_MD5; type < CLI_HASH_AVAIL_TYPES; type++) {
+ struct cli_htu32 *ht = &root->hm.sizehashes[type];
+ const struct cli_htu32_element *item = NULL;
+
+ if(!root->hm.sizehashes[type].capacity)
+ continue;
+
+ while((item = cli_htu32_next(ht, item))) {
+ struct cli_sz_hash *szh = (struct cli_sz_hash *)item->data.as_ptr;
+ unsigned int keylen = hashlen[type];
+
+ mpool_free(root->mempool, szh->hash_array);
+ while(szh->items)
+ mpool_free(root->mempool, (void *)szh->virusnames[--szh->items]);
+ mpool_free(root->mempool, szh->virusnames);
+ mpool_free(root->mempool, szh);
+ }
+ cli_htu32_free(ht, root->mempool);
+ }
+}
+
diff --git a/libclamav/matcher-hash.h b/libclamav/matcher-hash.h
new file mode 100644
index 0000000..ea581d8
--- /dev/null
+++ b/libclamav/matcher-hash.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 Sourcefire, Inc.
+ *
+ * Authors: aCaB
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MATCHER_HASH_H
+#define __MATCHER_HASH_H
+
+#if HAVE_CONFIG_H
+#include "clamav-config.h"
+#endif
+
+#include "cltypes.h"
+#include "hashtab.h"
+
+enum CLI_HASH_TYPE {
+ CLI_HASH_MD5,
+ CLI_HASH_SHA1,
+ CLI_HASH_SHA256,
+
+ /* new hash types go above this line */
+ CLI_HASH_AVAIL_TYPES
+};
+
+struct cli_sz_hash {
+ uint8_t *hash_array;
+ const char **virusnames;
+ uint32_t items;
+};
+
+
+struct cli_hash_patt {
+ struct cli_htu32 sizehashes[CLI_HASH_AVAIL_TYPES];
+};
+
+int hm_addhash(struct cli_matcher *root, const char *hash, uint32_t size, const char *virusname);
+void hm_flush(struct cli_matcher *root);
+int cli_hm_scan(const unsigned char *digest, uint32_t size, const char **virname, const struct cli_matcher *root, enum CLI_HASH_TYPE type);
+int cli_hm_have_size(const struct cli_matcher *root, enum CLI_HASH_TYPE type, uint32_t size);
+void hm_free(struct cli_matcher *root);
+
+#endif
diff --git a/libclamav/matcher-md5.c b/libclamav/matcher-md5.c
deleted file mode 100644
index 9bb2d63..0000000
--- a/libclamav/matcher-md5.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2007-2010 Sourcefire, Inc.
- *
- * Authors: Tomasz Kojm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#if HAVE_CONFIG_H
-#include "clamav-config.h"
-#endif
-
-#include <stdio.h>
-
-#include "clamav.h"
-#include "memory.h"
-#include "mpool.h"
-#include "others.h"
-#include "cltypes.h"
-#include "matcher.h"
-#include "matcher-md5.h"
-
-#define HASH(a,b,c) (211 * a + 37 * b + c)
-
-int cli_md5m_addpatt(struct cli_matcher *root, struct cli_md5m_patt *patt)
-{
- unsigned int idx;
- struct cli_md5m_patt *prev, *next = NULL;
-
- idx = HASH(patt->md5[0], patt->md5[1], patt->md5[2]);
- prev = next = root->md5tab[idx];
- while(next) {
- if(patt->md5[0] >= next->md5[0])
- break;
- prev = next;
- next = next->next;
- }
-
- if(next == root->md5tab[idx]) {
- patt->next = root->md5tab[idx];
- root->md5tab[idx] = patt;
- } else {
- patt->next = prev->next;
- prev->next = patt;
- }
-
- root->md5_patterns++;
- return CL_SUCCESS;
-}
-
-int cli_md5m_init(struct cli_matcher *root)
-{
-#ifdef USE_MPOOL
- if(!root->mempool) {
- cli_errmsg("cli_md5m_init: mempool must be initialized\n");
- return CL_EMEM;
- }
-#endif
-
- if(!(root->md5tab = (struct cli_md5m_patt **) mpool_calloc(root->mempool, HASH(255, 255, 255) + 1, sizeof(struct cli_md5m_patt *)))) {
- mpool_free(root->mempool, root->bm_shift);
- return CL_EMEM;
- }
-
- return CL_SUCCESS;
-}
-
-void cli_md5m_free(struct cli_matcher *root)
-{
- struct cli_md5m_patt *patt, *prev;
- unsigned int i, size = HASH(255, 255, 255) + 1;
-
- if(root->md5tab) {
- for(i = 0; i < size; i++) {
- patt = root->md5tab[i];
- while(patt) {
- prev = patt;
- patt = patt->next;
- if(prev->virname)
- mpool_free(root->mempool, prev->virname);
- mpool_free(root->mempool, prev);
- }
- }
- mpool_free(root->mempool, root->md5tab);
- }
-}
-
-int cli_md5m_scan(const unsigned char *md5, uint32_t filesize, const char **virname, const struct cli_matcher *root)
-{
- unsigned int pchain = 0, idx;
- struct cli_md5m_patt *p;
-
- if(!root)
- return CL_CLEAN;
-
- idx = HASH(md5[0], md5[1], md5[2]);
- p = root->md5tab[idx];
- if(!p || (!p->next && p->filesize != filesize))
- return CL_CLEAN;
-
- while(p) {
- if(p->md5[0] != md5[0]) {
- if(pchain)
- break;
- p = p->next;
- continue;
- } else pchain = 1;
-
- if(p->filesize != filesize) {
- p = p->next;
- continue;
- }
-
- if(!memcmp(p->md5, md5, 16)) {
- if(virname)
- *virname = p->virname;
- return CL_VIRUS;
- }
- p = p->next;
- }
-
- return CL_CLEAN;
-}
diff --git a/libclamav/matcher-md5.h b/libclamav/matcher-md5.h
deleted file mode 100644
index b63adf7..0000000
--- a/libclamav/matcher-md5.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2007-2010 Sourcefire, Inc.
- *
- * Authors: Tomasz Kojm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#ifndef __MATCHER_MD5_H
-#define __MATCHER_MD5_H
-
-#include "matcher.h"
-#include "cltypes.h"
-
-struct cli_md5m_patt {
- unsigned char md5[16];
- uint32_t filesize;
- char *virname;
- struct cli_md5m_patt *next;
-};
-
-int cli_md5m_addpatt(struct cli_matcher *root, struct cli_md5m_patt *patt);
-int cli_md5m_init(struct cli_matcher *root);
-int cli_md5m_scan(const unsigned char *md5, uint32_t filesize, const char **virname, const struct cli_matcher *root);
-void cli_md5m_free(struct cli_matcher *root);
-
-#endif
diff --git a/libclamav/matcher.c b/libclamav/matcher.c
index 51f09c9..2df0e0e 100644
--- a/libclamav/matcher.c
+++ b/libclamav/matcher.c
@@ -34,8 +34,9 @@
#include "others.h"
#include "matcher-ac.h"
#include "matcher-bm.h"
-#include "matcher-md5.h"
#include "md5.h"
+#include "sha1.h"
+#include "sha256.h"
#include "filetypes.h"
#include "matcher.h"
#include "pe.h"
@@ -54,11 +55,8 @@
#include "perflogging.h"
#include "bytecode_priv.h"
#include "bytecode_api_impl.h"
-
-#ifdef HAVE__INTERNAL__SHA_COLLECT
#include "sha256.h"
#include "sha1.h"
-#endif
#ifdef CLI_PERF_LOGGING
@@ -382,35 +380,65 @@ int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx)
char md5[33];
unsigned int i;
const char *virname;
+ SHA1Context sha1;
+ SHA256_CTX sha256;
+ fmap_t *map;
+ char *ptr;
+ uint8_t shash1[SHA1_HASH_SIZE*2+1];
+ uint8_t shash256[SHA256_HASH_SIZE*2+1];
+ int have_sha1, have_sha256;
- if(ctx->engine->md5_fp && cli_md5m_scan(digest, size, &virname, ctx->engine->md5_fp) == CL_VIRUS) {
- cli_dbgmsg("cli_checkfp(): Found false positive detection (fp sig: %s)\n", virname);
+ if(cli_hm_scan(digest, size, &virname, ctx->engine->hm_fp, CLI_HASH_MD5) == CL_VIRUS) {
+ cli_dbgmsg("cli_checkfp(md5): Found false positive detection (fp sig: %s)\n", virname);
return CL_CLEAN;
}
+
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");
+ map = *ctx->fmap;
+ have_sha1 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA1, size);
+ have_sha256 = cli_hm_have_size(ctx->engine->hm_fp, CLI_HASH_SHA256, size);
+ if(have_sha1 || have_sha256) {
+ if((ptr = fmap_need_off_once(map, 0, size))) {
+ if(have_sha1) {
+ SHA1Init(&sha1);
+ SHA1Update(&sha1, ptr, size);
+ SHA1Final(&sha1, &shash1[SHA1_HASH_SIZE]);
+ if(cli_hm_scan(&shash1[SHA1_HASH_SIZE], size, &virname, ctx->engine->hm_fp, CLI_HASH_SHA1) == CL_VIRUS){
+ cli_dbgmsg("cli_checkfp(sha1): Found false positive detection (fp sig: %s)\n", virname);
+ return CL_CLEAN;
+ }
+ }
+ if(have_sha256) {
+ sha256_init(&sha256);
+ sha256_update(&sha256, ptr, size);
+ sha256_final(&sha256, &shash256[SHA256_HASH_SIZE]);
+ if(cli_hm_scan(&shash256[SHA256_HASH_SIZE], size, &virname, ctx->engine->hm_fp, CLI_HASH_SHA256) == CL_VIRUS){
+ cli_dbgmsg("cli_checkfp(sha256): Found false positive detection (fp sig: %s)\n", virname);
+ return CL_CLEAN;
+ }
+ }
+ }
+ }
#ifdef HAVE__INTERNAL__SHA_COLLECT
if((ctx->options & CL_SCAN_INTERNAL_COLLECT_SHA) && ctx->sha_collect>0) {
- SHA1Context sha1;
- SHA256_CTX sha256;
- fmap_t *map = *ctx->fmap;
- char *ptr;
- uint8_t shash1[SHA1_HASH_SIZE*2+1];
- uint8_t shash256[SHA256_HASH_SIZE*2+1];
-
if((ptr = fmap_need_off_once(map, 0, size))) {
- sha256_init(&sha256);
- sha256_update(&sha256, ptr, size);
- sha256_final(&sha256, &shash256[SHA256_HASH_SIZE]);
+ if(!have_sha256) {
+ sha256_init(&sha256);
+ sha256_update(&sha256, ptr, size);
+ sha256_final(&sha256, &shash256[SHA256_HASH_SIZE]);
+ }
for(i=0; i<SHA256_HASH_SIZE; i++)
sprintf((char *)shash256+i*2, "%02x", shash256[SHA256_HASH_SIZE+i]);
- SHA1Init(&sha1);
- SHA1Update(&sha1, ptr, size);
- SHA1Final(&sha1, &shash1[SHA1_HASH_SIZE]);
+ if(!have_sha1) {
+ SHA1Init(&sha1);
+ SHA1Update(&sha1, ptr, size);
+ SHA1Final(&sha1, &shash1[SHA1_HASH_SIZE]);
+ }
for(i=0; i<SHA1_HASH_SIZE; i++)
sprintf((char *)shash1+i*2, "%02x", shash1[SHA1_HASH_SIZE+i]);
@@ -502,7 +530,7 @@ int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struc
return ret;
}
-int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info)
+int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info, const char *hash)
{
unsigned int i, evalcnt;
uint64_t evalids;
@@ -527,14 +555,17 @@ int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *ac
continue;
}
- if(root->ac_lsigtable[i]->tdb.handlertype) {
- ctx->recursion++;
- if(cli_magic_scandesc_type(map->fd, ctx, root->ac_lsigtable[i]->tdb.handlertype[0]) == CL_VIRUS) {
+ if(hash && root->ac_lsigtable[i]->tdb.handlertype) {
+ if(memcmp(ctx->handlertype_hash, hash, 16)) {
+ ctx->recursion++;
+ 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--;
+ return CL_VIRUS;
+ }
ctx->recursion--;
- return CL_VIRUS;
+ continue;
}
- ctx->recursion--;
- continue;
}
if(root->ac_lsigtable[i]->tdb.icongrp1 || root->ac_lsigtable[i]->tdb.icongrp2) {
@@ -545,7 +576,7 @@ int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *ac
if(ctx->virname)
*ctx->virname = root->ac_lsigtable[i]->virname;
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[i], map) == 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) {
return CL_VIRUS;
}
}
@@ -556,7 +587,7 @@ int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *ac
*ctx->virname = root->ac_lsigtable[i]->virname;
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[i], map) == 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;
}
}
@@ -567,16 +598,19 @@ int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *ac
int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres, unsigned char *refhash)
{
unsigned char *buff;
- int ret = CL_CLEAN, type = CL_CLEAN, bytes;
+ int ret = CL_CLEAN, type = CL_CLEAN, bytes, compute_hash[CLI_HASH_AVAIL_TYPES];
unsigned int i = 0, bm_offmode = 0;
uint32_t maxpatlen, offset = 0;
struct cli_ac_data gdata, tdata;
struct cli_bm_off toff;
cli_md5_ctx md5ctx;
- unsigned char digest[16];
+ SHA256_CTX sha256ctx;
+ SHA1Context sha1ctx;
+ unsigned char digest[CLI_HASH_AVAIL_TYPES][32];
struct cli_matcher *groot = NULL, *troot = NULL;
struct cli_target_info info;
fmap_t *map = *ctx->fmap;
+ struct cli_matcher *hdb, *fp;
if(!ctx->engine) {
cli_errmsg("cli_scandesc: engine == NULL\n");
@@ -642,8 +676,33 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
}
}
- if(!refhash && !ftonly && ctx->engine->md5_hdb)
- cli_md5_init(&md5ctx);
+ hdb = ctx->engine->hm_hdb;
+ fp = ctx->engine->hm_fp;
+
+ if(!ftonly && hdb) {
+ if(!refhash) {
+ if(cli_hm_have_size(hdb, CLI_HASH_MD5, map->len) || cli_hm_have_size(fp, CLI_HASH_MD5, map->len)) {
+ cli_md5_init(&md5ctx);
+ compute_hash[CLI_HASH_MD5] = 1;
+ } else
+ compute_hash[CLI_HASH_MD5] = 0;
+ } else {
+ compute_hash[CLI_HASH_MD5] = 0;
+ memcpy(digest[CLI_HASH_MD5], refhash, 16);
+ }
+
+ if(cli_hm_have_size(hdb, CLI_HASH_SHA1, map->len) || cli_hm_have_size(fp, CLI_HASH_SHA1, map->len)) {
+ SHA1Init(&sha1ctx);
+ compute_hash[CLI_HASH_SHA1] = 1;
+ } else
+ compute_hash[CLI_HASH_SHA1] = 0;
+
+ if(cli_hm_have_size(hdb, CLI_HASH_SHA256, map->len) || cli_hm_have_size(fp, CLI_HASH_SHA256, map->len)) {
+ sha256_init(&sha256ctx);
+ compute_hash[CLI_HASH_SHA256] = 1;
+ } else
+ compute_hash[CLI_HASH_SHA256] = 0;
+ }
while(offset < map->len) {
bytes = MIN(map->len - offset, SCANBUFF);
@@ -687,16 +746,53 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
type = ret;
}
- if(!refhash && ctx->engine->md5_hdb)
- cli_md5_update(&md5ctx, buff + maxpatlen * (offset!=0), bytes - maxpatlen * (offset!=0));
+ if(hdb) {
+ void *data = buff + maxpatlen * (offset!=0);
+ uint32_t data_len = bytes - maxpatlen * (offset!=0);
+
+ if(compute_hash[CLI_HASH_MD5])
+ cli_md5_update(&md5ctx, data, data_len);
+ if(compute_hash[CLI_HASH_SHA1])
+ SHA1Update(&sha1ctx, data, data_len);
+ if(compute_hash[CLI_HASH_SHA256])
+ sha256_update(&sha256ctx, data, data_len);
+ }
}
if(bytes < SCANBUFF) break;
offset += bytes - maxpatlen;
}
+ if(!ftonly && hdb) {
+ enum CLI_HASH_TYPE hashtype;
+
+ if(compute_hash[CLI_HASH_MD5])
+ cli_md5_final(digest[CLI_HASH_MD5], &md5ctx);
+ if(refhash)
+ compute_hash[CLI_HASH_MD5] = 1;
+ if(compute_hash[CLI_HASH_SHA1])
+ SHA1Final(&sha1ctx, digest[CLI_HASH_SHA1]);
+ if(compute_hash[CLI_HASH_SHA256])
+ sha256_final(&sha256ctx, digest[CLI_HASH_SHA256]);
+
+ 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(troot) {
- ret = cli_lsig_eval(ctx, troot, &tdata, &info);
+ if(ret != CL_VIRUS)
+ ret = cli_lsig_eval(ctx, troot, &tdata, &info, refhash);
cli_ac_freedata(&tdata);
if(bm_offmode)
cli_bm_freeoff(&toff);
@@ -704,7 +800,7 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
if(groot) {
if(ret != CL_VIRUS)
- ret = cli_lsig_eval(ctx, groot, &gdata, &info);
+ ret = cli_lsig_eval(ctx, groot, &gdata, &info, refhash);
cli_ac_freedata(&gdata);
}
@@ -715,15 +811,6 @@ int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli
if(ret == CL_VIRUS)
return CL_VIRUS;
- if(!ftonly && ctx->engine->md5_hdb) {
- if(!refhash) {
- cli_md5_final(digest, &md5ctx);
- refhash = digest;
- }
- if(cli_md5m_scan(refhash, map->len, ctx->virname, ctx->engine->md5_hdb) == CL_VIRUS && cli_md5m_scan(refhash, map->len, NULL, ctx->engine->md5_fp) != CL_VIRUS)
- return CL_VIRUS;
- }
-
return (acmode & AC_SCAN_FT) ? type : CL_CLEAN;
}
diff --git a/libclamav/matcher.h b/libclamav/matcher.h
index 6264f73..5079b7d 100644
--- a/libclamav/matcher.h
+++ b/libclamav/matcher.h
@@ -28,7 +28,6 @@
#include "others.h"
#include "execs.h"
#include "cltypes.h"
-#include "md5.h"
struct cli_target_info {
off_t fsize;
@@ -38,7 +37,7 @@ struct cli_target_info {
#include "matcher-ac.h"
#include "matcher-bm.h"
-#include "hashtab.h"
+#include "matcher-hash.h"
#include "fmap.h"
#include "mpool.h"
@@ -89,13 +88,11 @@ struct cli_matcher {
/* Extended Boyer-Moore */
uint8_t *bm_shift;
struct cli_bm_patt **bm_suffix, **bm_pattab;
- struct cli_hashset md5_sizes_hs;
uint32_t *soff, soff_len; /* for PE section sigs */
uint32_t bm_offmode, bm_patterns, bm_reloff_num, bm_absoff_num;
- /* MD5 */
- struct cli_md5m_patt **md5tab;
- uint32_t md5_patterns;
+ /* HASH */
+ struct cli_hash_patt hm;
/* Extended Aho-Corasick */
uint32_t ac_partsigs, ac_nodes, ac_patterns, ac_lsigs;
@@ -169,7 +166,7 @@ int cli_scanbuff(const unsigned char *buffer, uint32_t length, uint32_t offset,
int cli_scandesc(int desc, cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres);
int cli_fmap_scandesc(cli_ctx *ctx, cli_file_t ftype, uint8_t ftonly, struct cli_matched_type **ftoffset, unsigned int acmode, struct cli_ac_result **acres, unsigned char *refhash);
-int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info);
+int cli_lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_data *acdata, struct cli_target_info *target_info, const char *hash);
int cli_caloff(const char *offstr, const struct cli_target_info *info, unsigned int target, uint32_t *offdata, uint32_t *offset_min, uint32_t *offset_max);
int cli_checkfp(unsigned char *digest, size_t size, cli_ctx *ctx);
diff --git a/libclamav/mpool.c b/libclamav/mpool.c
index 3f3044f..839a802 100644
--- a/libclamav/mpool.c
+++ b/libclamav/mpool.c
@@ -68,81 +68,99 @@ static inline void spam(const char *fmt, ...) { fmt = fmt; } /* gcc STFU */
#if SIZEOF_VOID_P==8
static const unsigned int fragsz[] = {
-/* SIZE, MAX */
- 8, /* 783293 */
- 11, /* 4445 */
- 13, /* 10160 */
- 15, /* 8365 */
- 16, /* 24857 */
- 17, /* 24630 */
- 19, /* 136608 */
- 20, /* 90714 */
- 21, /* 176421 */
- 23, /* 52766 */
- 24, /* 161770 */
- 25, /* 38590 */
- 29, /* 18023 */
- 31, /* 15987 */
- 32, /* 104854 */
- 33, /* 9312 */
- 35, /* 371084 */
- 41, /* 5068 */
- 43, /* 142581 */
- 44, /* 99347 */
- 45, /* 74173 */
- 47, /* 31516 */
- 48, /* 320748 */
- 49, /* 45256 */
- 56, /* 1543 */
- 64, /* 963 */
- 74, /* 12397 */
- 76, /* 17846 */
- 79, /* 15721 */
- 80, /* 599771 */
- 81, /* 5618 */
- 93, /* 2101 */
- 97, /* 2425 */
- 104, /* 1495 */
- 113, /* 3107 */
- 116, /* 2403 */
- 123, /* 1415 */
- 128, /* 2368 */
- 131, /* 2697 */
- 143, /* 10539 */
- 150, /* 10982 */
- 151, /* 6869 */
- 152, /* 28254 */
- 153, /* 13670 */
- 229, /* 501 */
- 256, /* 830 */
- 304, /* 834 */
- 320, /* 377 */
- 512, /* 17 */
- 1024, /* 6 */
- 2048, /* 3 */
- 2056, /* 10116 */
- 4096, /* 3 */
- 8192, /* 2 */
- 9334, /* 3 */
- 12163, /* 4 */
- 16392, /* 257 */
- 18440, /* 2 */
- 21952, /* 1 */
- 32768, /* 1 */
- 35311, /* 1 */
- 43256, /* 2 */
- 48914, /* 1 */
- 63504, /* 8 */
- 65536, /* 0 */
- 92794, /* 1 */
- 107602, /* 1 */
- 131832, /* 7 */
- 156920, /* 1 */
- 262144, /* 1 */
- 374608, /* 1 */
- 507976, /* 10 */
- 524288, /* 0 */
-1048576,
+ 8,
+ 11,
+ 13,
+ 16,
+ 17,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ 37,
+ 40,
+ 41,
+ 48,
+ 56,
+ 72,
+ 74,
+ 75,
+ 76,
+ 78,
+ 79,
+ 80,
+ 81,
+ 101,
+ 104,
+ 109,
+ 113,
+ 116,
+ 120,
+ 128,
+ 131,
+ 143,
+ 151,
+ 152,
+ 153,
+ 196,
+ 256,
+ 360,
+ 403,
+ 404,
+ 432,
+ 486,
+ 514,
+ 548,
+ 578,
+ 604,
+ 633,
+ 697,
+ 743,
+ 784,
+ 839,
+ 1176,
+ 1536,
+ 1666,
+ 2056,
+ 2168,
+ 2392,
+ 2985,
+ 3221,
+ 3433,
+ 3753,
+ 3832,
+ 4104,
+ 4280,
+ 4696,
+ 4952,
+ 5256,
+ 5826,
+ 6264,
+ 7176,
+ 8440,
+ 9096,
+ 16392,
+ 32780,
+ 50961,
+ 63504,
+ 65558,
+ 101912,
+ 131088,
+ 262144,
+ 507976,
+ 524296,
+1048584,
2097152,
4194304,
8388608,
@@ -152,108 +170,183 @@ static const unsigned int fragsz[] = {
#else
static const unsigned int fragsz[] = {
-/* SIZE, MAX */
- 4, /* 576046 */
- 7, /* 205452 */
- 8, /* 2448 */
- 9, /* 1633 */
- 11, /* 2740 */
- 12, /* 6315 */
- 13, /* 8821 */
- 15, /* 15903 */
- 16, /* 31401 */
- 17, /* 28027 */
- 19, /* 136365 */
- 20, /* 95662 */
- 21, /* 176094 */
- 23, /* 54138 */
- 24, /* 156993 */
- 25, /* 39393 */
- 28, /* 16340 */
- 29, /* 9807 */
- 30, /* 5132 */
- 31, /* 176283 */
- 32, /* 484214 */
- 33, /* 129187 */
- 37, /* 1163 */
- 40, /* 3311 */
- 41, /* 1513 */
- 48, /* 3930 */
- 49, /* 1018 */
- 56, /* 2303 */
- 58, /* 13518 */
- 59, /* 4709 */
- 60, /* 13577 */
- 61, /* 3093 */
- 62, /* 10407 */
- 63, /* 3973 */
- 64, /* 26914 */
- 65, /* 2963 */
- 73, /* 2314 */
- 81, /* 2038 */
- 85, /* 1306 */
- 88, /* 1395 */
- 93, /* 885 */
- 96, /* 878 */
- 104, /* 3746 */
- 108, /* 685 */
- 113, /* 2940 */
- 115, /* 3625 */
- 116, /* 3827 */
- 117, /* 2517 */
- 119, /* 4260 */
- 120, /* 17485 */
- 121, /* 1945 */
- 128, /* 2653 */
- 131, /* 2304 */
- 136, /* 1090 */
- 143, /* 10787 */
- 148, /* 1292 */
- 152, /* 3494 */
- 153, /* 11788 */
- 168, /* 505 */
- 176, /* 652 */
- 200, /* 350 */
- 216, /* 312 */
- 232, /* 402 */
- 248, /* 495 */
- 256, /* 140 */
- 284, /* 439 */
- 309, /* 817 */
- 452, /* 57 */
- 512, /* 3 */
- 784, /* 14 */
- 1024, /* 2 */
- 1028, /* 3191 */
- 1032, /* 7777 */
- 2048, /* 5 */
- 4096, /* 3 */
- 5128, /* 5 */
- 8192, /* 3 */
- 11264, /* 5 */
- 11268, /* 238 */
- 11272, /* 243 */
- 16384, /* 1 */
- 17657, /* 1 */
- 21632, /* 2 */
- 23188, /* 2 */
- 24458, /* 1 */
- 32768, /* 1 */
- 46398, /* 1 */
- 53804, /* 1 */
- 63504, /* 7 */
- 65536, /* 1 */
- 131072, /* 0 */
- 131080, /* 7 */
- 131544, /* 2 */
- 156920, /* 1 */
- 187304, /* 1 */
- 253988, /* 10 */
- 262144, /* 0 */
-1048576,
-2097152,
-4194304,
-8388608,
+ 4,
+ 5,
+ 8,
+ 9,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31,
+ 32,
+ 33,
+ 35,
+ 36,
+ 37,
+ 39,
+ 40,
+ 41,
+ 44,
+ 48,
+ 49,
+ 52,
+ 53,
+ 56,
+ 58,
+ 59,
+ 60,
+ 61,
+ 62,
+ 63,
+ 64,
+ 65,
+ 68,
+ 69,
+ 72,
+ 73,
+ 77,
+ 80,
+ 81,
+ 83,
+ 85,
+ 88,
+ 89,
+ 93,
+ 96,
+ 99,
+ 101,
+ 103,
+ 104,
+ 105,
+ 108,
+ 112,
+ 113,
+ 115,
+ 116,
+ 117,
+ 119,
+ 120,
+ 121,
+ 124,
+ 128,
+ 129,
+ 131,
+ 133,
+ 136,
+ 137,
+ 141,
+ 143,
+ 145,
+ 148,
+ 151,
+ 152,
+ 153,
+ 160,
+ 168,
+ 173,
+ 176,
+ 184,
+ 194,
+ 200,
+ 208,
+ 216,
+ 224,
+ 229,
+ 232,
+ 241,
+ 244,
+ 248,
+ 256,
+ 257,
+ 264,
+ 274,
+ 280,
+ 293,
+ 296,
+ 304,
+ 307,
+ 312,
+ 326,
+ 344,
+ 354,
+ 372,
+ 396,
+ 403,
+ 418,
+ 456,
+ 485,
+ 514,
+ 546,
+ 581,
+ 608,
+ 646,
+ 693,
+ 740,
+ 776,
+ 805,
+ 828,
+ 902,
+ 964,
+ 1028,
+ 1032,
+ 1136,
+ 1238,
+ 1314,
+ 1420,
+ 1501,
+ 1668,
+ 1720,
+ 1832,
+ 1940,
+ 2048,
+ 2119,
+ 2264,
+ 2584,
+ 2724,
+ 2994,
+ 3336,
+ 3428,
+ 3828,
+ 4104,
+ 4471,
+ 4836,
+ 5044,
+ 5176,
+ 5912,
+ 6227,
+ 6792,
+ 7732,
+ 8192,
+ 11272,
+ 12500,
+ 16384,
+ 32768,
+ 63500,
+ 65536,
+ 131080,
+ 253988,
+ 262148,
+ 524292,
+ 1048576,
+ 2097152,
+ 4194304,
+ 8388608,
};
#endif
#define FRAGSBITS (sizeof(fragsz)/sizeof(fragsz[0]))
diff --git a/libclamav/msexpand.c b/libclamav/msexpand.c
index 43e15b4..bcc33bc 100644
--- a/libclamav/msexpand.c
+++ b/libclamav/msexpand.c
@@ -68,11 +68,11 @@ struct msexp_hdr {
#pragma pack
#endif
-#define BSIZE 4096
-#define RWBUFF 2048
+#define B_SIZE 4096
+#define RW_SIZE 2048
#define READBYTES \
- ret = cli_readn(fd, rbuff, RWBUFF); \
+ ret = cli_readn(fd, rbuff, RW_SIZE); \
if(ret == -1) \
return CL_EREAD; \
if(!ret) \
@@ -94,8 +94,8 @@ int cli_msexpand(int fd, int ofd, cli_ctx *ctx)
{
struct msexp_hdr hdr;
uint8_t i, mask, bits;
- unsigned char buff[BSIZE], rbuff[RWBUFF], wbuff[RWBUFF];
- unsigned int j = BSIZE - 16, k, l, r = 0, w = 0, rbytes = 0, wbytes = 0;
+ unsigned char buff[B_SIZE], rbuff[RW_SIZE], wbuff[RW_SIZE];
+ unsigned int j = B_SIZE - 16, k, l, r = 0, w = 0, rbytes = 0, wbytes = 0;
int ret;
@@ -112,7 +112,7 @@ int cli_msexpand(int fd, int ofd, cli_ctx *ctx)
if(cli_checklimits("MSEXPAND", ctx, EC32(hdr.fsize), 0, 0)!=CL_CLEAN)
return CL_SUCCESS;
- memset(buff, 0, BSIZE);
+ memset(buff, 0, B_SIZE);
while(1) {
if(!rbytes || (r == rbytes)) {
@@ -128,13 +128,13 @@ int cli_msexpand(int fd, int ofd, cli_ctx *ctx)
READBYTES;
}
- if(w == RWBUFF) {
+ if(w == RW_SIZE) {
WRITEBYTES;
}
wbuff[w] = buff[j] = rbuff[r];
r++; w++;
- j++; j %= BSIZE;
+ j++; j %= B_SIZE;
} else {
if(r == rbytes) {
READBYTES;
@@ -149,13 +149,13 @@ int cli_msexpand(int fd, int ofd, cli_ctx *ctx)
k += (l & 0xf0) << 4;
l = (l & 0x0f) + 3;
while(l--) {
- if(w == RWBUFF) {
+ if(w == RW_SIZE) {
WRITEBYTES;
}
wbuff[w] = buff[j] = buff[k];
w++;
- k++; k %= BSIZE;
- j++; j %= BSIZE;
+ k++; k %= B_SIZE;
+ j++; j %= B_SIZE;
}
}
mask *= 2;
diff --git a/libclamav/others.c b/libclamav/others.c
index 3272f53..533e382 100644
--- a/libclamav/others.c
+++ b/libclamav/others.c
@@ -60,6 +60,8 @@
#include "clamav.h"
#include "others.h"
#include "md5.h"
+#include "sha1.h"
+#include "sha256.h"
#include "cltypes.h"
#include "regex/regex.h"
#include "ltdl.h"
@@ -251,6 +253,12 @@ const char *cl_strerror(int clerror)
return "Error during bytecode execution";
case CL_EBYTECODE_TESTFAIL:
return "Failure in bytecode testmode";
+ case CL_ELOCK:
+ return "Mutex lock failed";
+ case CL_EBUSY:
+ return "Scanner still active";
+ case CL_ESTATE:
+ return "Bad state (engine not initialized, or already initialized)";
default:
return "Unknown error code";
}
@@ -562,8 +570,17 @@ struct cl_settings *cl_engine_settings_copy(const struct cl_engine *engine)
settings->maxfiles = engine->maxfiles;
settings->min_cc_count = engine->min_cc_count;
settings->min_ssn_count = engine->min_ssn_count;
+ settings->bytecode_security = engine->bytecode_security;
+ settings->bytecode_timeout = engine->bytecode_timeout;
+ settings->bytecode_mode = engine->bytecode_mode;
settings->pua_cats = engine->pua_cats ? strdup(engine->pua_cats) : NULL;
+ settings->cb_pre_scan = engine->cb_pre_scan;
+ settings->cb_post_scan = engine->cb_post_scan;
+ settings->cb_sigload = engine->cb_sigload;
+ settings->cb_sigload_ctx = engine->cb_sigload_ctx;
+ settings->cb_hash = engine->cb_hash;
+
return settings;
}
@@ -579,6 +596,9 @@ int cl_engine_settings_apply(struct cl_engine *engine, const struct cl_settings
engine->maxfiles = settings->maxfiles;
engine->min_cc_count = settings->min_cc_count;
engine->min_ssn_count = settings->min_ssn_count;
+ engine->bytecode_security = settings->bytecode_security;
+ engine->bytecode_timeout = settings->bytecode_timeout;
+ engine->bytecode_mode = settings->bytecode_mode;
if(engine->tmpdir)
mpool_free(engine->mempool, engine->tmpdir);
@@ -600,6 +620,12 @@ int cl_engine_settings_apply(struct cl_engine *engine, const struct cl_settings
engine->pua_cats = NULL;
}
+ engine->cb_pre_scan = settings->cb_pre_scan;
+ engine->cb_post_scan = settings->cb_post_scan;
+ engine->cb_sigload = settings->cb_sigload;
+ engine->cb_sigload_ctx = settings->cb_sigload_ctx;
+ engine->cb_hash = settings->cb_hash;
+
return CL_SUCCESS;
}
@@ -659,73 +685,77 @@ int cli_updatelimits(cli_ctx *ctx, unsigned long needed) {
return CL_CLEAN;
}
-unsigned char *cli_md5digest(int desc)
-{
- unsigned char *digest;
- char buff[FILEBUFF];
- cli_md5_ctx ctx;
- int bytes;
-
-
- if(!(digest = cli_malloc(16)))
- return NULL;
-
- cli_md5_init(&ctx);
-
- while((bytes = cli_readn(desc, buff, FILEBUFF)))
- cli_md5_update(&ctx, buff, bytes);
-
- cli_md5_final(digest, &ctx);
-
- return digest;
-}
-
-char *cli_md5stream(FILE *fs, unsigned char *digcpy)
+/*
+ * Type: 1 = MD5, 2 = SHA1, 3 = SHA256
+ */
+char *cli_hashstream(FILE *fs, unsigned char *digcpy, int type)
{
- unsigned char digest[16];
+ unsigned char digest[32];
char buff[FILEBUFF];
- cli_md5_ctx ctx;
- char *md5str, *pt;
- int i, bytes;
-
+ cli_md5_ctx md5;
+ SHA1Context sha1;
+ SHA256_CTX sha256;
+ char *hashstr, *pt;
+ int i, bytes, size;
- cli_md5_init(&ctx);
- while((bytes = fread(buff, 1, FILEBUFF, fs)))
- cli_md5_update(&ctx, buff, bytes);
+ if(type == 1)
+ cli_md5_init(&md5);
+ else if(type == 2)
+ SHA1Init(&sha1);
+ else
+ sha256_init(&sha256);
+
+ while((bytes = fread(buff, 1, FILEBUFF, fs))) {
+ if(type == 1)
+ cli_md5_update(&md5, buff, bytes);
+ else if(type == 2)
+ SHA1Update(&sha1, buff, bytes);
+ else
+ sha256_update(&sha256, buff, bytes);
+ }
- cli_md5_final(digest, &ctx);
+ if(type == 1) {
+ cli_md5_final(digest, &md5);
+ size = 16;
+ } else if(type == 2) {
+ SHA1Final(&sha1, digest);
+ size = 20;
+ } else {
+ sha256_final(&sha256, digest);
+ size = 32;
+ }
- if(!(md5str = (char *) cli_calloc(32 + 1, sizeof(char))))
+ if(!(hashstr = (char *) cli_calloc(size*2 + 1, sizeof(char))))
return NULL;
- pt = md5str;
- for(i = 0; i < 16; i++) {
+ pt = hashstr;
+ for(i = 0; i < size; i++) {
sprintf(pt, "%02x", digest[i]);
pt += 2;
}
if(digcpy)
- memcpy(digcpy, digest, 16);
+ memcpy(digcpy, digest, size);
- return md5str;
+ return hashstr;
}
-char *cli_md5file(const char *filename)
+char *cli_hashfile(const char *filename, int type)
{
FILE *fs;
- char *md5str;
+ char *hashstr;
if((fs = fopen(filename, "rb")) == NULL) {
- cli_errmsg("cli_md5file(): Can't read file %s\n", filename);
+ cli_errmsg("cli_hashfile(): Can't open file %s\n", filename);
return NULL;
}
- md5str = cli_md5stream(fs, NULL);
- fclose(fs);
+ hashstr = cli_hashstream(fs, NULL, type);
- return md5str;
+ fclose(fs);
+ return hashstr;
}
/* Function: unlink
diff --git a/libclamav/others.h b/libclamav/others.h
index 308b8c9..b441bd5 100644
--- a/libclamav/others.h
+++ b/libclamav/others.h
@@ -53,7 +53,7 @@
* in re-enabling affected modules.
*/
-#define CL_FLEVEL 58
+#define CL_FLEVEL 60
#define CL_FLEVEL_DCONF CL_FLEVEL
#define CL_FLEVEL_SIGTOOL CL_FLEVEL
@@ -120,6 +120,7 @@ typedef struct cli_ctx_tag {
unsigned int corrupted_input;
cli_file_t container_type; /* FIXME: to be made into a stack or array - see bb#1579 & bb#1293 */
size_t container_size;
+ unsigned char handlertype_hash[16];
struct cli_dconf *dconf;
fmap_t **fmap;
bitset_t* hook_lsig_matches;
@@ -207,14 +208,13 @@ struct cl_engine {
/* Roots table */
struct cli_matcher **root;
- /* B-M matcher for standard MD5 sigs */
- struct cli_matcher *md5_hdb;
+ /* hash matcher for standard MD5 sigs */
+ struct cli_matcher *hm_hdb;
+ /* hash matcher for MD5 sigs for PE sections */
+ struct cli_matcher *hm_mdb;
+ /* hash matcher for whitelist db */
+ struct cli_matcher *hm_fp;
- /* B-M matcher for MD5 sigs for PE sections */
- struct cli_matcher *md5_mdb;
-
- /* B-M matcher for whitelist db */
- struct cli_matcher *md5_fp;
/* Container metadata */
struct cli_cdb *cdb;
@@ -253,9 +253,7 @@ struct cl_engine {
clcb_post_scan cb_post_scan;
clcb_sigload cb_sigload;
void *cb_sigload_ctx;
- clcb_msg cb_msg;
clcb_hash cb_hash;
- enum cl_msg cb_msg_minseverity;
/* Used for bytecode */
struct cli_all_bc bcs;
@@ -283,7 +281,18 @@ struct cl_settings {
uint32_t maxfiles;
uint32_t min_cc_count;
uint32_t min_ssn_count;
+ enum bytecode_security bytecode_security;
+ uint32_t bytecode_timeout;
+ enum bytecode_mode bytecode_mode;
char *pua_cats;
+
+ /* callbacks */
+ clcb_pre_scan cb_pre_scan;
+ clcb_post_scan cb_post_scan;
+ clcb_sigload cb_sigload;
+ void *cb_sigload_ctx;
+ clcb_msg cb_msg;
+ clcb_hash cb_hash;
};
extern int (*cli_unrar_open)(int fd, const char *dirname, unrar_state_t *state);
@@ -498,9 +507,8 @@ void *cli_realloc(void *ptr, size_t size);
void *cli_realloc2(void *ptr, size_t size);
char *cli_strdup(const char *s);
int cli_rmdirs(const char *dirname);
-unsigned char *cli_md5digest(int desc);
-char *cli_md5stream(FILE *fs, unsigned char *digcpy);
-char *cli_md5file(const char *filename);
+char *cli_hashstream(FILE *fs, unsigned char *digcpy, int type);
+char *cli_hashfile(const char *filename, int type);
int cli_unlink(const char *pathname);
int cli_readn(int fd, void *buff, unsigned int count);
int cli_writen(int fd, const void *buff, unsigned int count);
diff --git a/libclamav/others_common.c b/libclamav/others_common.c
index 1cc2a93..b721d7f 100644
--- a/libclamav/others_common.c
+++ b/libclamav/others_common.c
@@ -111,6 +111,10 @@ static inline void *cli_getctx(void)
{
return current_ctx ? current_ctx->cb_ctx : NULL;
}
+
+void cli_logg_unsetup(void)
+{
+}
#endif
uint8_t cli_debug_flag = 0;
diff --git a/libclamav/pdf.c b/libclamav/pdf.c
index ae9d03c..0b5e156 100644
--- a/libclamav/pdf.c
+++ b/libclamav/pdf.c
@@ -114,7 +114,7 @@ static int find_stream_bounds(const char *start, off_t bytesleft, off_t byteslef
if ((q2 = cli_memstr(start, bytesleft, "stream", 6))) {
q2 += 6;
bytesleft -= q2 - start;
- if (bytesleft < 1)
+ if (bytesleft < 0)
return 0;
if (bytesleft >= 2 && q2[0] == '\xd' && q2[1] == '\xa')
q2 += 2;
@@ -122,7 +122,7 @@ static int find_stream_bounds(const char *start, off_t bytesleft, off_t byteslef
q2++;
*stream = q2 - start;
bytesleft2 -= q2 - start;
- if (bytesleft2 < 0)
+ if (bytesleft2 <= 0)
return 0;
q = q2;
q2 = cli_memstr(q, bytesleft2, "endstream", 9);
@@ -1761,11 +1761,12 @@ static int asciihexdecode(const char *buf, off_t len, char *output)
continue;
if (buf[i] == '>')
break;
- if (cli_hex2str_to(buf+i, output+j++, 2) == -1) {
+ if (cli_hex2str_to(buf+i, output+j, 2) == -1) {
if (len - i < 4)
continue;
return -1;
}
+ j++;
i++;
}
return j;
@@ -1831,7 +1832,7 @@ ascii85decode(const char *buf, off_t len, unsigned char *output)
if(quintet > 1)
sum += (0xFFFFFF >> ((quintet - 2) * 8));
- ret += quintet;
+ ret += quintet-1;
for(i = 0; i < quintet - 1; i++)
*output++ = (unsigned char)((sum >> (24 - 8 * i)) & 0xFF);
}
diff --git a/libclamav/pe.c b/libclamav/pe.c
index abcb2cd..76eb87a 100644
--- a/libclamav/pe.c
+++ b/libclamav/pe.c
@@ -54,7 +54,7 @@
#include "mew.h"
#include "upack.h"
#include "matcher.h"
-#include "matcher-md5.h"
+#include "matcher-hash.h"
#include "disasm.h"
#include "special.h"
#include "ishield.h"
@@ -1000,24 +1000,20 @@ int cli_scanpe(cli_ctx *ctx)
if(SCAN_ALGO && (DCONF & PE_CONF_POLIPOS) && !*sname && exe_sections[i].vsz > 40000 && exe_sections[i].vsz < 70000 && exe_sections[i].chr == 0xe0000060) polipos = i;
/* check MD5 section sigs */
- md5_sect = ctx->engine->md5_mdb;
+ md5_sect = ctx->engine->hm_mdb;
if((DCONF & PE_CONF_MD5SECT) && md5_sect) {
- found = 0;
- for(j = 0; j < md5_sect->soff_len && md5_sect->soff[j] <= exe_sections[i].rsz; j++) {
- if(md5_sect->soff[j] == exe_sections[i].rsz) {
- unsigned char md5_dig[16];
- const struct cli_md5m_patt *patt;
- if(cli_md5sect(map, &exe_sections[i], md5_dig) && cli_md5m_scan(md5_dig, exe_sections[i].rsz, ctx->virname, ctx->engine->md5_mdb) == CL_VIRUS) {
- if(cli_md5m_scan(md5_dig, fsize, NULL, ctx->engine->md5_fp) != CL_VIRUS) {
- free(section_hdr);
- free(exe_sections);
- return CL_VIRUS;
- }
- }
- break;
+ 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) {
+ 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 (exe_sections[i].urva>>31 || exe_sections[i].uvsz>>31 || (exe_sections[i].rsz && exe_sections[i].uraw>>31) || exe_sections[i].ursz>>31) {
diff --git a/libclamav/phishcheck.c b/libclamav/phishcheck.c
index 30e7865..71c0ea3 100644
--- a/libclamav/phishcheck.c
+++ b/libclamav/phishcheck.c
@@ -1205,6 +1205,7 @@ static int hash_match(const struct regex_matcher *rlist, const char *host, size_
}
h[64]='\0';
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) {
cli_dbgmsg("prefix matched\n");
@@ -1212,6 +1213,7 @@ static int hash_match(const struct regex_matcher *rlist, const char *host, size_
} else
return CL_SUCCESS;
}
+#endif
if (cli_bm_scanbuff(sha256_dig, 32, &virname, NULL, &rlist->sha256_hashes,0,NULL,NULL) == CL_VIRUS) {
cli_dbgmsg("This hash matched: %s\n", h);
switch(*virname) {
@@ -1408,6 +1410,7 @@ static int url_hash_match(const struct regex_matcher *rlist, const char *inurl,
return rc;
}
count++;
+#if 0
if (count == 2 && !prefix_matched && rlist->hostkey_prefix.bm_patterns) {
/* if hostkey is not matched, don't bother calculating
* hashes for other parts of the URL, they are not in the DB
@@ -1415,6 +1418,7 @@ static int url_hash_match(const struct regex_matcher *rlist, const char *inurl,
cli_dbgmsg("hostkey prefix not matched, short-circuiting lookups\n");
return CL_SUCCESS;
}
+#endif
}
}
return CL_SUCCESS;
diff --git a/libclamav/readdb.c b/libclamav/readdb.c
index 2dab42e..8b9ddd4 100644
--- a/libclamav/readdb.c
+++ b/libclamav/readdb.c
@@ -46,7 +46,7 @@
#endif
#include "matcher-ac.h"
#include "matcher-bm.h"
-#include "matcher-md5.h"
+#include "matcher-hash.h"
#include "matcher.h"
#include "others.h"
#include "str.h"
@@ -399,6 +399,11 @@ char *cli_dbgets(char *buff, unsigned int size, FILE *fs, struct cli_dbio *dbio)
dbio->bread += bread;
sha256_update(&dbio->sha256ctx, dbio->readpt, bread);
}
+ if(dbio->chkonly && dbio->bufpt) {
+ dbio->bufpt = NULL;
+ dbio->readsize = dbio->size < dbio->bufsize ? dbio->size : dbio->bufsize - 1;
+ continue;
+ }
nl = strchr(dbio->bufpt, '\n');
if(nl) {
if(nl - dbio->bufpt >= size) {
@@ -1860,52 +1865,16 @@ static int cli_loadign(FILE *fs, struct cl_engine *engine, unsigned int options,
#define MD5_MDB 1
#define MD5_FP 2
-static int cli_md5db_init(struct cl_engine *engine, unsigned int mode)
-{
- struct cli_matcher *bm = NULL;
- int ret;
-
-
- if(mode == MD5_HDB) {
- bm = engine->md5_hdb = (struct cli_matcher *) mpool_calloc(engine->mempool, sizeof(struct cli_matcher), 1);
- } else if(mode == MD5_MDB) {
- bm = engine->md5_mdb = (struct cli_matcher *) mpool_calloc(engine->mempool, sizeof(struct cli_matcher), 1);
- } else {
- bm = engine->md5_fp = (struct cli_matcher *) mpool_calloc(engine->mempool, sizeof(struct cli_matcher), 1);
- }
-
- if(!bm)
- return CL_EMEM;
-#ifdef USE_MPOOL
- bm->mempool = engine->mempool;
-#endif
- if((ret = cli_md5m_init(bm))) {
- cli_errmsg("cli_md5db_init: Failed to initialize MD5 matcher\n");
- return ret;
- }
-
- return CL_SUCCESS;
-}
-
-#define MD5_DB \
- if(mode == MD5_HDB) \
- db = engine->md5_hdb; \
- else if(mode == MD5_MDB) \
- db = engine->md5_mdb; \
- else \
- db = engine->md5_fp;
-
-#define MD5_TOKENS 3
-static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int mode, unsigned int options, struct cli_dbio *dbio, const char *dbname)
+#define MD5_TOKENS 5
+static int cli_loadhash(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigned int mode, unsigned int options, struct cli_dbio *dbio, const char *dbname)
{
const char *tokens[MD5_TOKENS + 1];
char buffer[FILEBUFF], *buffer_cpy = NULL;
- const char *pt;
- unsigned char *md5;
+ const char *pt, *virname;
int ret = CL_SUCCESS;
unsigned int size_field = 1, md5_field = 0, line = 0, sigs = 0, tokens_count;
- struct cli_md5m_patt *new;
struct cli_matcher *db = NULL;
+ unsigned long size;
if(mode == MD5_MDB) {
@@ -1924,12 +1893,30 @@ static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo,
strcpy(buffer_cpy, buffer);
tokens_count = cli_strtokenize(buffer, ':', MD5_TOKENS + 1, tokens);
- if(tokens_count != MD5_TOKENS) {
+ if(tokens_count < 3) {
ret = CL_EMALFDB;
break;
}
- if(!cli_isnumber(tokens[size_field])) {
- cli_errmsg("cli_loadmd5: Invalid value for the size field\n");
+ if(tokens_count > MD5_TOKENS - 2) {
+ unsigned int req_fl = atoi(tokens[MD5_TOKENS - 2]);
+
+ if(tokens_count > MD5_TOKENS) {
+ ret = CL_EMALFDB;
+ break;
+ }
+
+ if(cl_retflevel() < req_fl)
+ continue;
+ if(tokens_count == MD5_TOKENS) {
+ req_fl = atoi(tokens[MD5_TOKENS - 1]);
+ if(cl_retflevel() > req_fl)
+ continue;
+ }
+ }
+
+ size = strtol(tokens[size_field], (char **)&pt, 10);
+ if(*pt || !size || size >= 0xffffffff) {
+ cli_errmsg("cli_loadhash: Invalid value for the size field\n");
ret = CL_EMALFDB;
break;
}
@@ -1949,71 +1936,58 @@ static int cli_loadmd5(FILE *fs, struct cl_engine *engine, unsigned int *signo,
else
dot++;
if(engine->cb_sigload(dot, pt, engine->cb_sigload_ctx)) {
- cli_dbgmsg("cli_loadmd5: skipping %s due to callback\n", pt);
+ cli_dbgmsg("cli_loadhash: skipping %s (%s) due to callback\n", pt, dot);
continue;
}
}
- new = (struct cli_md5m_patt *) mpool_calloc(engine->mempool, 1, sizeof(struct cli_md5m_patt));
- if(!new) {
- ret = CL_EMEM;
- break;
- }
-
- pt = tokens[md5_field]; /* md5 */
- if(strlen(pt) != 32 || !(md5 = (unsigned char *) cli_mpool_hex2str(engine->mempool, pt))) {
- cli_errmsg("cli_loadmd5: Malformed MD5 string at line %u\n", line);
- mpool_free(engine->mempool, new);
+ virname = cli_mpool_virname(engine->mempool, pt, options & CL_DB_OFFICIAL);
+ if(!virname) {
ret = CL_EMALFDB;
break;
}
- memcpy(new->md5, md5, 16);
- mpool_free(engine->mempool, md5);
- new->filesize = atoi(tokens[size_field]);
-
- new->virname = cli_mpool_virname(engine->mempool, tokens[2], options & CL_DB_OFFICIAL);
- if(!new->virname) {
- mpool_free(engine->mempool, new);
- ret = CL_EMALFDB;
- break;
- }
+ if(mode == MD5_HDB)
+ db = engine->hm_hdb;
+ else if(mode == MD5_MDB)
+ db = engine->hm_mdb;
+ else
+ db = engine->hm_fp;
- MD5_DB;
- if(!db && (ret = cli_md5db_init(engine, mode))) {
- mpool_free(engine->mempool, new->virname);
- mpool_free(engine->mempool, new);
- break;
- } else {
- MD5_DB;
+ if(!db) {
+ if(!(db = mpool_calloc(engine->mempool, 1, sizeof(*db)))) {
+ ret = CL_EMEM;
+ break;
+ }
+#ifdef USE_MPOOL
+ db->mempool = engine->mempool;
+#endif
+ if(mode == MD5_HDB)
+ engine->hm_hdb = db;
+ else if(mode == MD5_MDB)
+ engine->hm_mdb = db;
+ else
+ engine->hm_fp = db;
}
- if((ret = cli_md5m_addpatt(db, new))) {
- cli_errmsg("cli_loadmd5: Error adding BM pattern\n");
- mpool_free(engine->mempool, new->virname);
- mpool_free(engine->mempool, new);
+ if((ret = hm_addhash(db, tokens[md5_field], size, virname))) {
+ cli_errmsg("cli_loadhash: Malformed MD5 string at line %u\n", line);
+ mpool_free(engine->mempool, (void *)virname);
break;
}
- if(mode == MD5_MDB) { /* section MD5 */
- if(!db->md5_sizes_hs.capacity) {
- cli_hashset_init_pool(&db->md5_sizes_hs, 65536, 80, engine->mempool);
- }
- cli_hashset_addkey(&db->md5_sizes_hs, new->filesize);
- }
-
sigs++;
}
if(engine->ignored)
free(buffer_cpy);
if(!line) {
- cli_errmsg("cli_loadmd5: Empty database file\n");
+ cli_errmsg("cli_loadhash: Empty database file\n");
return CL_EMALFDB;
}
if(ret) {
- cli_errmsg("cli_loadmd5: Problem parsing database at line %u\n", line);
+ cli_errmsg("cli_loadhash: Problem parsing database at line %u\n", line);
return ret;
}
@@ -2360,8 +2334,14 @@ int cli_load(const char *filename, struct cl_engine *engine, unsigned int *signo
int ret = CL_SUCCESS;
uint8_t skipped = 0;
const char *dbname;
+ char buff[FILEBUFF];
+ if(dbio && dbio->chkonly) {
+ while(cli_dbgets(buff, FILEBUFF, NULL, dbio));
+ return CL_SUCCESS;
+ }
+
if(!dbio && (fs = fopen(filename, "rb")) == NULL) {
if(options & CL_DB_DIRECTORY) { /* bb#1624 */
if(access(filename, R_OK)) {
@@ -2384,29 +2364,27 @@ int cli_load(const char *filename, struct cl_engine *engine, unsigned int *signo
ret = cli_loaddb(fs, engine, signo, options, dbio, dbname);
} else if(cli_strbcasestr(dbname, ".cvd")) {
- ret = cli_cvdload(fs, engine, signo, options, 0, filename);
+ ret = cli_cvdload(fs, engine, signo, options, 0, filename, 0);
} else if(cli_strbcasestr(dbname, ".cld")) {
- ret = cli_cvdload(fs, engine, signo, options, 1, filename);
-
- } else if(cli_strbcasestr(dbname, ".hdb")) {
- ret = cli_loadmd5(fs, engine, signo, MD5_HDB, options, dbio, dbname);
+ ret = cli_cvdload(fs, engine, signo, options, 1, filename, 0);
- } else if(cli_strbcasestr(dbname, ".hdu")) {
+ } else if(cli_strbcasestr(dbname, ".hdb") || cli_strbcasestr(dbname, ".hsb")) {
+ ret = cli_loadhash(fs, engine, signo, MD5_HDB, options, dbio, dbname);
+ } else if(cli_strbcasestr(dbname, ".hdu") || cli_strbcasestr(dbname, ".hsu")) {
if(options & CL_DB_PUA)
- ret = cli_loadmd5(fs, engine, signo, MD5_HDB, options | CL_DB_PUA_MODE, dbio, dbname);
+ ret = cli_loadhash(fs, engine, signo, MD5_HDB, options | CL_DB_PUA_MODE, dbio, dbname);
else
skipped = 1;
- } else if(cli_strbcasestr(dbname, ".fp")) {
- ret = cli_loadmd5(fs, engine, signo, MD5_FP, options, dbio, dbname);
+ } else if(cli_strbcasestr(dbname, ".fp") || cli_strbcasestr(dbname, ".sfp")) {
+ ret = cli_loadhash(fs, engine, signo, MD5_FP, options, dbio, dbname);
+ } else if(cli_strbcasestr(dbname, ".mdb") || cli_strbcasestr(dbname, ".msb")) {
+ ret = cli_loadhash(fs, engine, signo, MD5_MDB, options, dbio, dbname);
- } else if(cli_strbcasestr(dbname, ".mdb")) {
- ret = cli_loadmd5(fs, engine, signo, MD5_MDB, options, dbio, dbname);
-
- } else if(cli_strbcasestr(dbname, ".mdu")) {
+ } else if(cli_strbcasestr(dbname, ".mdu") || cli_strbcasestr(dbname, ".msu")) {
if(options & CL_DB_PUA)
- ret = cli_loadmd5(fs, engine, signo, MD5_MDB, options | CL_DB_PUA_MODE, dbio, dbname);
+ ret = cli_loadhash(fs, engine, signo, MD5_MDB, options | CL_DB_PUA_MODE, dbio, dbname);
else
skipped = 1;
@@ -2468,7 +2446,6 @@ int cli_load(const char *filename, struct cl_engine *engine, unsigned int *signo
} else if(cli_strbcasestr(dbname, ".cdb")) {
ret = cli_loadcdb(fs, engine, signo, options, dbio);
-
} else {
cli_dbgmsg("cli_load: unknown extension - assuming old database format\n");
ret = cli_loaddb(fs, engine, signo, options, dbio, dbname);
@@ -2945,22 +2922,18 @@ int cl_engine_free(struct cl_engine *engine)
mpool_free(engine->mempool, engine->root);
}
- if((root = engine->md5_hdb)) {
- cli_md5m_free(root);
+ if((root = engine->hm_hdb)) {
+ hm_free(root);
mpool_free(engine->mempool, root);
}
- if((root = engine->md5_mdb)) {
- cli_md5m_free(root);
- mpool_free(engine->mempool, root->soff);
- if(root->md5_sizes_hs.capacity) {
- cli_hashset_destroy(&root->md5_sizes_hs);
- }
+ if((root = engine->hm_mdb)) {
+ hm_free(root);
mpool_free(engine->mempool, root);
}
- if((root = engine->md5_fp)) {
- cli_md5m_free(root);
+ if((root = engine->hm_fp)) {
+ hm_free(root);
mpool_free(engine->mempool, root);
}
@@ -3045,29 +3018,6 @@ int cl_engine_free(struct cl_engine *engine)
return CL_SUCCESS;
}
-static void cli_md5db_build(struct cli_matcher* root)
-{
- if(root && root->md5_sizes_hs.capacity) {
- /* TODO: use hashset directly, instead of the array when matching*/
- cli_dbgmsg("Converting hashset to array: %u entries\n", root->md5_sizes_hs.count);
-
-#ifdef USE_MPOOL
- {
- uint32_t *mpoolht;
- unsigned int mpoolhtsz = root->md5_sizes_hs.count * sizeof(*mpoolht);
- root->soff = mpool_malloc(root->mempool, mpoolhtsz);
- root->soff_len = cli_hashset_toarray(&root->md5_sizes_hs, &mpoolht);
- memcpy(root->soff, mpoolht, mpoolhtsz);
- free(mpoolht);
- }
-#else
- root->soff_len = cli_hashset_toarray(&root->md5_sizes_hs, &root->soff);
-#endif
- cli_hashset_destroy(&root->md5_sizes_hs);
- cli_qsort(root->soff, root->soff_len, sizeof(uint32_t), NULL);
- }
-}
-
int cl_engine_compile(struct cl_engine *engine)
{
unsigned int i;
@@ -3089,11 +3039,14 @@ int cl_engine_compile(struct cl_engine *engine)
cli_dbgmsg("Matcher[%u]: %s: AC sigs: %u (reloff: %u, absoff: %u) BM sigs: %u (reloff: %u, absoff: %u) maxpatlen %u %s\n", i, cli_mtargets[i].name, root->ac_patterns, root->ac_reloff_num, root->ac_absoff_num, root->bm_patterns, root->bm_reloff_num, root->bm_absoff_num, root->maxpatlen, root->ac_only ? "(ac_only mode)" : "");
}
}
- if(engine->md5_hdb)
- cli_dbgmsg("MD5 sigs (files): %u\n", engine->md5_hdb->md5_patterns);
+ if(engine->hm_hdb)
+ hm_flush(engine->hm_hdb);
+
+ if(engine->hm_mdb)
+ hm_flush(engine->hm_mdb);
- if(engine->md5_mdb)
- cli_dbgmsg("MD5 sigs (PE sections): %u\n", engine->md5_mdb->md5_patterns);
+ if(engine->hm_fp)
+ hm_flush(engine->hm_fp);
if((ret = cli_build_regex_list(engine->whitelist_matcher))) {
return ret;
@@ -3101,7 +3054,6 @@ int cl_engine_compile(struct cl_engine *engine)
if((ret = cli_build_regex_list(engine->domainlist_matcher))) {
return ret;
}
- cli_md5db_build(engine->md5_mdb);
if(engine->ignored) {
cli_bm_free(engine->ignored);
mpool_free(engine->mempool, engine->ignored);
diff --git a/libclamav/readdb.h b/libclamav/readdb.h
index d8b48de..db9d081 100644
--- a/libclamav/readdb.h
+++ b/libclamav/readdb.h
@@ -37,6 +37,11 @@
cli_strbcasestr(ext, ".fp") || \
cli_strbcasestr(ext, ".mdb") || \
cli_strbcasestr(ext, ".mdu") || \
+ cli_strbcasestr(ext, ".hsb") || \
+ cli_strbcasestr(ext, ".hsu") || \
+ cli_strbcasestr(ext, ".sfp") || \
+ cli_strbcasestr(ext, ".msb") || \
+ cli_strbcasestr(ext, ".msu") || \
cli_strbcasestr(ext, ".ndb") || \
cli_strbcasestr(ext, ".ndu") || \
cli_strbcasestr(ext, ".ldb") || \
diff --git a/libclamav/scanners.c b/libclamav/scanners.c
index 4aa5308..85c2dbb 100644
--- a/libclamav/scanners.c
+++ b/libclamav/scanners.c
@@ -1112,9 +1112,9 @@ static int cli_scanscript(cli_ctx *ctx)
}
free(normalized);
if(ret != CL_VIRUS) {
- ret = cli_lsig_eval(ctx, troot, &tmdata, NULL);
+ ret = cli_lsig_eval(ctx, troot, &tmdata, NULL, NULL);
if(ret != CL_VIRUS)
- ret = cli_lsig_eval(ctx, groot, &gmdata, NULL);
+ ret = cli_lsig_eval(ctx, groot, &gmdata, NULL, NULL);
}
cli_ac_freedata(&tmdata);
cli_ac_freedata(&gmdata);
diff --git a/libclamav/sha1.h b/libclamav/sha1.h
index 7a6beb7..8ccb79c 100644
--- a/libclamav/sha1.h
+++ b/libclamav/sha1.h
@@ -29,13 +29,7 @@
#ifndef _SHA1_H
#define _SHA1_H
-#if HAVE_INTTYPES_H
-# include <inttypes.h>
-#else
-# if HAVE_STDINT_H
-# include <stdint.h>
-# endif
-#endif
+#include "cltypes.h"
#define SHA1_HASH_SIZE 20
diff --git a/libclamav/sis.c b/libclamav/sis.c
index 99fd705..a3d219a 100644
--- a/libclamav/sis.c
+++ b/libclamav/sis.c
@@ -506,7 +506,6 @@ static int real_scansis(FILE *f, cli_ctx *ctx, const char *tmpd) {
free(decomp);
free(ptrs);
free(alangs);
- close(fd);
return CL_EWRITE;
}
free(decomp);
diff --git a/libclamav/vba_extract.c b/libclamav/vba_extract.c
index 062ec20..8de1058 100644
--- a/libclamav/vba_extract.c
+++ b/libclamav/vba_extract.c
@@ -221,8 +221,10 @@ vba_read_project_strings(int fd, int big_endian)
free(name);
if(!read_uint16(fd, &length, big_endian)) {
- if(buf)
+ if(buf) {
free(buf);
+ buf = NULL;
+ }
break;
}
diff --git a/libltdl/Makefile.in b/libltdl/Makefile.in
index c079797..e09f467 100644
--- a/libltdl/Makefile.in
+++ b/libltdl/Makefile.in
@@ -209,6 +209,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/shared/cdiff.c b/shared/cdiff.c
index f6d29bd..927cf80 100644
--- a/shared/cdiff.c
+++ b/shared/cdiff.c
@@ -995,8 +995,16 @@ int cdiff_apply(int fd, unsigned short mode)
logg("!cdiff_apply: Can't resize line buffer to %d bytes\n", line_size);
cdiff_ctx_free(&ctx);
fclose(fh);
- free(line);
- free(lbuf);
+ if(!r1 && !r2) {
+ free(line);
+ free(lbuf);
+ } else if(!r1) {
+ free(line);
+ free(r2);
+ } else {
+ free(r1);
+ free(lbuf);
+ }
return -1;
}
line = r1;
diff --git a/shared/optparser.c b/shared/optparser.c
index a22b4c7..68a47b2 100644
--- a/shared/optparser.c
+++ b/shared/optparser.c
@@ -82,6 +82,8 @@ const struct clam_option __clam_options[] = {
{ NULL, "stream", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, 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, "", "" },
+ { NULL, "follow-file-symlinks", 0, TYPE_NUMBER, MATCH_NUMBER, 1, NULL, 0, OPT_CLAMSCAN, "", "" },
{ NULL, "bell", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN, "", "" },
{ NULL, "no-summary", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN | OPT_CLAMDSCAN, "", "" },
{ NULL, "file-list", 'f', TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMSCAN | OPT_CLAMDSCAN, "", "" },
@@ -96,6 +98,8 @@ const struct clam_option __clam_options[] = {
{ NULL, "structured-ssn-format", 0, TYPE_NUMBER, MATCH_NUMBER, 0, NULL, 0, OPT_CLAMSCAN, "", "" },
{ NULL, "hex-dump", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
{ NULL, "md5", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
+ { NULL, "sha1", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
+ { NULL, "sha256", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
{ NULL, "mdb", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_SIGTOOL, "", "" },
{ NULL, "html-normalise", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
{ NULL, "utf16-decode", 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_SIGTOOL, "", "" },
@@ -200,7 +204,7 @@ const struct clam_option __clam_options[] = {
/* FIXME: add a regex for IP addr */
{ "TCPAddr", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_CLAMD, "By default clamd binds to INADDR_ANY.\nThis option allows you to restrict the TCP address and provide\nsome degree of protection from the outside world.", "127.0.0.1" },
- { "MaxConnectionQueueLength", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 15, NULL, 0, OPT_CLAMD, "Maximum length the queue of pending connections may grow to.", "30" },
+ { "MaxConnectionQueueLength", NULL, 0, TYPE_NUMBER, MATCH_NUMBER, 200, NULL, 0, OPT_CLAMD, "Maximum length the queue of pending connections may grow to.", "30" },
{ "StreamMaxLength", NULL, 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXFILESIZE, NULL, 0, OPT_CLAMD, "Close the STREAM session when the data size limit is exceeded.\nThe value should match your MTA's limit for the maximum attachment size.", "25M" },
@@ -252,8 +256,8 @@ const struct clam_option __clam_options[] = {
{ "Bytecode", "bytecode", 0, TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "With this option enabled ClamAV will load bytecode from the database. It is highly recommended you keep this option on, otherwise you'll miss detections for many new viruses.", "yes" },
{ "BytecodeSecurity", NULL, 0, TYPE_STRING, "^(None|TrustSigned|Paranoid)$", -1, "TrustSigned", 0, OPT_CLAMD,
"Set bytecode security level.\nPossible values:\n\tNone - no security at all, meant for debugging. DO NOT USE THIS ON PRODUCTION SYSTEMS\n\tTrustSigned - trust bytecode loaded from signed .c[lv]d files,\n\t\t insert runtime safety checks for bytecode loaded from other sources\n\tParanoid - don't trust any bytecode, insert runtime checks for all\nRecommended: TrustSigned, because bytecode in .cvd files already has these checks\n","TrustSigned"},
- { "BytecodeTimeout", "bytecode-timeout", 0, TYPE_NUMBER, MATCH_NUMBER, 60000, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN,
- "Set bytecode timeout in miliseconds.\n","60000"},
+ { "BytecodeTimeout", "bytecode-timeout", 0, TYPE_NUMBER, MATCH_NUMBER, 5000, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN,
+ "Set bytecode timeout in miliseconds.\n","5000"},
{ "BytecodeMode", "bytecode-mode", 0, TYPE_STRING, "^(Auto|ForceJIT|ForceInterpreter|Test)$", -1, "Auto", FLAG_REQUIRED, OPT_CLAMD | OPT_CLAMSCAN,
"Set bytecode execution mode.\nPossible values:\n\tAuto - automatically choose JIT if possible, fallback to interpreter\nForceJIT - always choose JIT, fail if not possible\nForceIntepreter - always choose interpreter\nTest - run with both JIT and interpreter and compare results. Make all failures fatal\n","Auto"},
{ "DetectPUA", "detect-pua", 0, TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Detect Potentially Unwanted Applications.", "yes" },
@@ -445,6 +449,8 @@ const struct clam_option __clam_options[] = {
{ "LogInfected", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "This option allows to tune what is logged when a message is infected.\nPossible values are Off (the default - nothing is logged),\nBasic (minimal info logged), Full (verbose info logged)\nNote:\nFor this to work properly in sendmail, make sure the msg_id, mail_addr,\nrcpt_addr and i macroes are available in eom. In other words add a line like:\nMilter.macros.eom={msg_id}, {mail_addr}, {rcpt_addr}, i\nto your .cf file. Alternatively use the macro:\ndefine(`confMILTER_MACROS_EOM', `{msg_id}, {mail_addr}, {rcpt_addr}, i')\nPostfix should be working fine with the default settings.", "Basic" },
+ { "LogClean", NULL, 0, TYPE_STRING, NULL, -1, NULL, 0, OPT_MILTER, "This option allows to tune what is logged when no threat is found in a scanned message.\nSee LogInfected for possible values and caveats.\nUseful in debugging but drastically increases the log size.", "Basic" },
+
/* Deprecated milter options */
{ "ArchiveBlockEncrypted", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_MILTER | OPT_DEPRECATED, "", "" },
@@ -1003,7 +1009,7 @@ struct optstruct *optparse(const char *cfgfile, int argc, char **argv, int verbo
lnumarg = UINT_MAX;
}
- numarg = lnumarg;
+ numarg = lnumarg ? lnumarg : UINT_MAX;
break;
case TYPE_BOOL:
diff --git a/sigtool/Makefile.in b/sigtool/Makefile.in
index be3bc52..24b626f 100644
--- a/sigtool/Makefile.in
+++ b/sigtool/Makefile.in
@@ -134,6 +134,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/sigtool/sigtool.c b/sigtool/sigtool.c
index 7d2db91..c42ad17 100644
--- a/sigtool/sigtool.c
+++ b/sigtool/sigtool.c
@@ -88,8 +88,12 @@ static const struct dblist_s {
{ "main.db", 1 }, { "daily.db", 1 },
{ "main.hdb", 1 }, { "daily.hdb", 1 },
{ "main.hdu", 1 }, { "daily.hdu", 1 },
+ { "main.hsb", 1 }, { "daily.hsb", 1 },
+ { "main.hsu", 1 }, { "daily.hsu", 1 },
{ "main.mdb", 1 }, { "daily.mdb", 1 },
{ "main.mdu", 1 }, { "daily.mdu", 1 },
+ { "main.msb", 1 }, { "daily.msb", 1 },
+ { "main.msu", 1 }, { "daily.msu", 1 },
{ "main.ndb", 1 }, { "daily.ndb", 1 },
{ "main.ndu", 1 }, { "daily.ndu", 1 },
{ "main.ldb", 1 }, { "daily.ldb", 1 },
@@ -99,6 +103,7 @@ static const struct dblist_s {
{ "main.rmd", 1 }, { "daily.rmd", 1 },
{ "main.idb", 0 }, { "daily.idb", 0 },
{ "main.fp", 0 }, { "daily.fp", 0 },
+ { "main.sfp", 0 }, { "daily.sfp", 0 },
{ "main.pdb", 1 }, { "daily.pdb", 1 }, { "safebrowsing.gdb", 1 },
{ "main.wdb", 0 }, { "daily.wdb", 0 }, { "safebrowsing.wdb", 0 },
@@ -149,9 +154,9 @@ static int hexdump(void)
return 0;
}
-static int md5sig(const struct optstruct *opts, unsigned int mdb)
+static int hashsig(const struct optstruct *opts, unsigned int mdb, int type)
{
- char *md5;
+ char *hash;
unsigned int i;
struct stat sb;
@@ -159,19 +164,19 @@ static int md5sig(const struct optstruct *opts, unsigned int mdb)
if(opts->filename) {
for(i = 0; opts->filename[i]; i++) {
if(stat(opts->filename[i], &sb) == -1) {
- mprintf("!md5sig: Can't access file %s\n", opts->filename[i]);
- perror("md5sig");
+ mprintf("!hashsig: Can't access file %s\n", opts->filename[i]);
+ perror("hashsig");
return -1;
} else {
if((sb.st_mode & S_IFMT) == S_IFREG) {
- if((md5 = cli_md5file(opts->filename[i]))) {
+ if((hash = cli_hashfile(opts->filename[i], type))) {
if(mdb)
- mprintf("%u:%s:%s\n", (unsigned int) sb.st_size, md5, opts->filename[i]);
+ mprintf("%u:%s:%s\n", (unsigned int) sb.st_size, hash, opts->filename[i]);
else
- mprintf("%s:%u:%s\n", md5, (unsigned int) sb.st_size, opts->filename[i]);
- free(md5);
+ mprintf("%s:%u:%s\n", hash, (unsigned int) sb.st_size, opts->filename[i]);
+ free(hash);
} else {
- mprintf("!md5sig: Can't generate MD5 checksum for %s\n", opts->filename[i]);
+ mprintf("!hashsig: Can't generate hash for %s\n", opts->filename[i]);
return -1;
}
}
@@ -179,13 +184,13 @@ static int md5sig(const struct optstruct *opts, unsigned int mdb)
}
} else { /* stream */
- md5 = cli_md5stream(stdin, NULL);
- if(!md5) {
- mprintf("!md5sig: Can't generate MD5 checksum for input stream\n");
+ hash = cli_hashstream(stdin, NULL, type);
+ if(!hash) {
+ mprintf("!hashsig: Can't generate hash for input stream\n");
return -1;
}
- mprintf("%s\n", md5);
- free(md5);
+ mprintf("%s\n", hash);
+ free(hash);
}
return 0;
@@ -899,7 +904,7 @@ static int build(const struct optstruct *opts)
return -1;
}
- if(!(pt = cli_md5stream(fh, buffer))) {
+ if(!(pt = cli_hashstream(fh, buffer, 1))) {
mprintf("!build: Can't generate MD5 checksum for %s\n", tarfile);
fclose(fh);
unlink(tarfile);
@@ -1120,17 +1125,13 @@ static int cvdinfo(const struct optstruct *opts)
if(cli_strbcasestr(pt, ".cvd")) {
mprintf("MD5: %s\n", cvd->md5);
mprintf("Digital signature: %s\n", cvd->dsig);
- cl_cvdfree(cvd);
- if((ret = cl_cvdverify(pt))) {
- mprintf("!cvdinfo: Verification: %s\n", cl_strerror(ret));
- return -1;
- } else {
- mprintf("Verification OK.\n");
- return 0;
- }
}
-
cl_cvdfree(cvd);
+ if((ret = cl_cvdverify(pt))) {
+ mprintf("!cvdinfo: Verification: %s\n", cl_strerror(ret));
+ return -1;
+ }
+ mprintf("Verification OK.\n");
return 0;
}
@@ -1564,12 +1565,12 @@ static int compare(const char *oldpath, const char *newpath, FILE *diff)
{
FILE *old, *new;
char *obuff, *nbuff, *tbuff, *pt, *omd5, *nmd5;
- unsigned int oline = 0, tline, found, i;
+ unsigned int oline = 0, tline, found, i, badxchg = 0;
int l1 = 0, l2;
long opos;
- if(!access(oldpath, R_OK) && (omd5 = cli_md5file(oldpath))) {
- if(!(nmd5 = cli_md5file(newpath))) {
+ if(!access(oldpath, R_OK) && (omd5 = cli_hashfile(oldpath, 1))) {
+ if(!(nmd5 = cli_hashfile(newpath, 1))) {
mprintf("!compare: Can't get MD5 checksum of %s\n", newpath);
free(omd5);
return -1;
@@ -1675,6 +1676,10 @@ static int compare(const char *oldpath, const char *newpath, FILE *diff)
oline += tline;
} else {
+ if(!*obuff || *obuff == ' ') {
+ badxchg = 1;
+ break;
+ }
obuff[MIN(16, l1-1)] = 0;
if((pt = strchr(obuff, ' ')))
*pt = 0;
@@ -1688,23 +1693,34 @@ static int compare(const char *oldpath, const char *newpath, FILE *diff)
}
}
}
- fclose(new);
if(old) {
- while(fgets(obuff, l1, old)) {
- oline++;
- obuff[MIN(16, l1-1)] = 0;
- if((pt = strchr(obuff, ' ')))
- *pt = 0;
- fprintf(diff, "DEL %u %s\n", oline, obuff);
+ if(!badxchg) {
+ while(fgets(obuff, l1, old)) {
+ oline++;
+ obuff[MIN(16, l1-1)] = 0;
+ if((pt = strchr(obuff, ' ')))
+ *pt = 0;
+ fprintf(diff, "DEL %u %s\n", oline, obuff);
+ }
}
fclose(old);
}
-
fprintf(diff, "CLOSE\n");
free(obuff);
- free(nbuff);
free(tbuff);
+ if(badxchg) {
+ fprintf(diff, "UNLINK %s\n", newpath);
+ fprintf(diff, "OPEN %s\n", newpath);
+ rewind(new);
+ while(fgets(nbuff, l1, new)) {
+ cli_chomp(nbuff);
+ fprintf(diff, "ADD %s\n", nbuff);
+ }
+ fprintf(diff, "CLOSE\n");
+ }
+ free(nbuff);
+ fclose(new);
return 0;
}
@@ -2659,6 +2675,10 @@ static void help(void)
mprintf(" string and print it on stdout\n");
mprintf(" --md5 [FILES] generate MD5 checksum from stdin\n");
mprintf(" or MD5 sigs for FILES\n");
+ mprintf(" --sha1 [FILES] generate SHA1 checksum from stdin\n");
+ mprintf(" or SHA1 sigs for FILES\n");
+ mprintf(" --sha256 [FILES] generate SHA256 checksum from stdin\n");
+ mprintf(" or SHA256 sigs for FILES\n");
mprintf(" --mdb [FILES] generate .mdb sigs\n");
mprintf(" --html-normalise=FILE create normalised parts of HTML file\n");
mprintf(" --utf16-decode=FILE decode UTF16 encoded files\n");
@@ -2728,9 +2748,13 @@ int main(int argc, char **argv)
if(optget(opts, "hex-dump")->enabled)
ret = hexdump();
else if(optget(opts, "md5")->enabled)
- ret = md5sig(opts, 0);
+ ret = hashsig(opts, 0, 1);
+ else if(optget(opts, "sha1")->enabled)
+ ret = hashsig(opts, 0, 2);
+ else if(optget(opts, "sha256")->enabled)
+ ret = hashsig(opts, 0, 3);
else if(optget(opts, "mdb")->enabled)
- ret = md5sig(opts, 1);
+ ret = hashsig(opts, 1, 1);
else if(optget(opts, "html-normalise")->enabled)
ret = htmlnorm(opts);
else if(optget(opts, "utf16-decode")->enabled)
diff --git a/test/Makefile.in b/test/Makefile.in
index 24aaba0..14d22a1 100644
--- a/test/Makefile.in
+++ b/test/Makefile.in
@@ -82,6 +82,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/unit_tests/Makefile.in b/unit_tests/Makefile.in
index da9881a..af2ea76 100644
--- a/unit_tests/Makefile.in
+++ b/unit_tests/Makefile.in
@@ -225,6 +225,7 @@ CHECK_LIBS = @CHECK_LIBS@
CLAMAVGROUP = @CLAMAVGROUP@
CLAMAVUSER = @CLAMAVUSER@
CLAMAV_MILTER_LIBS = @CLAMAV_MILTER_LIBS@
+CLAMDSCAN_LIBS = @CLAMDSCAN_LIBS@
CLAMD_LIBS = @CLAMD_LIBS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
diff --git a/unit_tests/check_bytecode.c b/unit_tests/check_bytecode.c
index e723385..70cc0f1 100644
--- a/unit_tests/check_bytecode.c
+++ b/unit_tests/check_bytecode.c
@@ -522,7 +522,7 @@ START_TEST (test_load_bytecode_int)
}
END_TEST
-#if defined(CL_THREAD_SAFE) && defined(C_LINUX) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 3)
+#if defined(CL_THREAD_SAFE) && defined(C_LINUX) && ((__GLIBC__ << 16) + __GLIBC_MINOR__ >= (2 << 16) + 4)
#define DO_BARRIER
#endif
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list