Browse code

Merge remote-tracking branch 'origin/master' into features/yara

Shawn Webb authored on 2014/11/26 06:21:42
Showing 40 changed files
... ...
@@ -1,3 +1,23 @@
1
+Wed, 12 Nov 2014 14:30:39 EDT (swebb)
2
+-------------------------------------
3
+* bb11176 - Instruct OpenSSL to allow MD5 when in FIPS-compliant mode.
4
+  Patch submitted by Reinhard Max.
5
+
6
+Mon, 10 Nov 2014 11:03:29 EDT (swebb)
7
+-------------------------------------
8
+* bb11155 - Adjust the logic surrounding adjusting the PE section sizes
9
+  This fixes a crash with maliciously crafted yoda's crypter files and
10
+  also improves virus detections for PE files. 
11
+
12
+Thu, 6 Nov 2014 14:51:26 EDT (swebb)
13
+-------------------------------------
14
+* bb11088 - Merge in fixes for clamscan -a crash bug
15
+
16
+Mon, 20 Oct 2014 11:33:18 EDT (swebb)
17
+-------------------------------------
18
+* Revert "bb#10731 - Allow to specificy a group for the socket of which
19
+  the user is not a member"
20
+
1 21
 Thu, 31 Jul 2014 19:11:22 EDT (swebb)
2 22
 -------------------------------------
3 23
 * Add support for XDP PDF file format
... ...
@@ -3,20 +3,20 @@
3 3
 
4 4
 Welcome to ClamAV 0.98.5! ClamAV 0.98.5 includes important new features
5 5
 for collecting and analyzing file properties. Software developers and
6
-analysts may collect file properties using the ClamAV API and then
7
-analyze them with ClamAV bytecode programs. Using the new features will
8
-require that libjson-c is installed, but otherwise libjson-c will be
9
-optional.
6
+analysts may collect file property meta data using the ClamAV API for
7
+subsequent analysis by ClamAV bytecode programs. Using these features
8
+will require that libjson-c is installed, but otherwise libjson-c is not
9
+needed.
10 10
 
11 11
 Look for our upcoming series of blog posts to learn more about using the
12 12
 ClamAV API and bytecode facilities for collecting and analyzing file
13 13
 properties.
14 14
 
15
-ClamAV 0.98.5 also includes these new features:
15
+ClamAV 0.98.5 also includes these new features and bug fixes:
16 16
 
17 17
     - Support for the XDP file format and extracting, decoding, and
18 18
       scanning PDF files within XDP files.
19
-    - Addition of shared library support for LLVM verions 3.1 - 3.4
19
+    - Addition of shared library support for LLVM versions 3.1 - 3.5
20 20
       for the purpose of just-in-time(JIT) compilation of ClamAV
21 21
       bytecode signatures. Andreas Cadhalpun submitted the patch
22 22
       implementing this support.
... ...
@@ -24,6 +24,15 @@ ClamAV 0.98.5 also includes these new features:
24 24
       ClamAV bytecode signature authors by providing introspection
25 25
       into compiled bytecode programs.
26 26
     - Resolution of many of the warning messages from ClamAV compilation.
27
+    - Improved detection of malicious PE files.
28
+    - Security fix for ClamAV crash when using 'clamscan -a'. This issue
29
+      was identified by Kurt Siefried of Red Hat.
30
+    - Security fix for ClamAV crash when scanning maliciously crafted
31
+      yoda's crypter files. This issue, as well as several other bugs
32
+      fixed in this release, were identified by Damien Millescamp of
33
+      Oppida.
34
+    - ClamAV 0.98.5 now works with OpenSSL in FIPS compliant mode.
35
+      Thanks to Reinhard Max for supplying the patch.
27 36
     - Bug fixes and other feature enhancements. See Changelog or
28 37
       git log for details.
29 38
 
... ...
@@ -32,6 +41,9 @@ and bug reporting included in ClamAV 0.98.5:
32 32
 
33 33
 Andreas Cadhalpun
34 34
 Sebastian Andrzej Siewior
35
+Damien Millescamp
36
+Reinhard Max
37
+Kurt Seifried
35 38
 
36 39
 --
37 40
 The ClamAV team (http://www.clamav.net/about.html#credits)
... ...
@@ -7,20 +7,20 @@ here may not be available in binary packages.
7 7
 
8 8
 Welcome to ClamAV 0.98.5! ClamAV 0.98.5 includes important new features
9 9
 for collecting and analyzing file properties. Software developers and
10
-analysts may collect file properties using the ClamAV API and then
11
-analyze them with ClamAV bytecode programs. Using the new features will
12
-require that libjson-c is installed, but otherwise libjson-c will be
13
-optional.
10
+analysts may collect file property meta data using the ClamAV API for
11
+subsequent analysis by ClamAV bytecode programs. Using these features
12
+will require that libjson-c is installed, but otherwise libjson-c is not
13
+needed.
14 14
 
15 15
 Look for our upcoming series of blog posts to learn more about using the
16 16
 ClamAV API and bytecode facilities for collecting and analyzing file
17 17
 properties.
18 18
 
19
-ClamAV 0.98.5 also includes these new features:
19
+ClamAV 0.98.5 also includes these new features and bug fixes:
20 20
 
21 21
     - Support for the XDP file format and extracting, decoding, and
22 22
       scanning PDF files within XDP files.
23
-    - Addition of shared library support for LLVM verions 3.1 - 3.4
23
+    - Addition of shared library support for LLVM versions 3.1 - 3.5
24 24
       for the purpose of just-in-time(JIT) compilation of ClamAV
25 25
       bytecode signatures. Andreas Cadhalpun submitted the patch
26 26
       implementing this support.
... ...
@@ -28,6 +28,15 @@ ClamAV 0.98.5 also includes these new features:
28 28
       ClamAV bytecode signature authors by providing introspection
29 29
       into compiled bytecode programs.
30 30
     - Resolution of many of the warning messages from ClamAV compilation.
31
+    - Improved detection of malicious PE files.
32
+    - Security fix for ClamAV crash when using 'clamscan -a'. This issue
33
+      was identified by Kurt Siefried of Red Hat.
34
+    - Security fix for ClamAV crash when scanning maliciously crafted
35
+      yoda's crypter files. This issue, as well as several other bugs
36
+      fixed in this release, were identified by Damien Millescamp of
37
+      Oppida.
38
+    - ClamAV 0.98.5 now works with OpenSSL in FIPS compliant mode.
39
+      Thanks to Reinhard Max for supplying the patch.
31 40
     - Bug fixes and other feature enhancements. See Changelog or
32 41
       git log for details.
33 42
 
... ...
@@ -36,6 +45,9 @@ and bug reporting included in ClamAV 0.98.5:
36 36
 
37 37
 Andreas Cadhalpun
38 38
 Sebastian Andrzej Siewior
39
+Damien Millescamp
40
+Reinhard Max
41
+Kurt Seifried
39 42
 
40 43
 0.98.4
41 44
 ------
... ...
@@ -47,5 +47,5 @@ endif
47 47
 
48 48
 DEFS = @DEFS@ -DCL_NOLIBCLAMAV
49 49
 LIBS = $(top_builddir)/libclamav/libclamav_internal_utils.la @CLAMAV_MILTER_LIBS@ @THREAD_LIBS@
50
-AM_CPPFLAGS = @SSL_CPPFLAGS@ -I$(top_srcdir)/clamd -I$(top_srcdir)/libclamav -I$(top_srcdir)/shared -I$(top_srcdir) @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
50
+AM_CPPFLAGS = -I$(top_srcdir)/clamd -I$(top_srcdir)/libclamav -I$(top_srcdir)/shared -I$(top_srcdir) @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
51 51
 CLEANFILES=*.gcda *.gcno
... ...
@@ -512,7 +512,7 @@ top_srcdir = @top_srcdir@
512 512
 
513 513
 @BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@man_MANS = $(top_builddir)/docs/man/clamav-milter.8
514 514
 @BUILD_CLAMD_TRUE@@HAVE_MILTER_TRUE@AM_CFLAGS = @WERR_CFLAGS_MILTER@
515
-AM_CPPFLAGS = @SSL_CPPFLAGS@ -I$(top_srcdir)/clamd -I$(top_srcdir)/libclamav -I$(top_srcdir)/shared -I$(top_srcdir) @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
515
+AM_CPPFLAGS = -I$(top_srcdir)/clamd -I$(top_srcdir)/libclamav -I$(top_srcdir)/shared -I$(top_srcdir) @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
516 516
 CLEANFILES = *.gcda *.gcno
517 517
 all: all-am
518 518
 
... ...
@@ -381,7 +381,7 @@ int main(int argc, char **argv) {
381 381
 	if((fd = fopen(opt->strarg, "w")) == NULL) {
382 382
 	    logg("!Can't save PID in file %s\n", opt->strarg);
383 383
 	} else {
384
-	    if (fprintf(fd, "%u", (unsigned int)getpid())<0) {
384
+	    if (fprintf(fd, "%u\n", (unsigned int)getpid())<0) {
385 385
 	    	logg("!Can't save PID in file %s\n", opt->strarg);
386 386
 	    }
387 387
 	    fclose(fd);
... ...
@@ -53,7 +53,7 @@ AM_CFLAGS=@WERR_CFLAGS@
53 53
 endif
54 54
 
55 55
 LIBS = $(top_builddir)/libclamav/libclamav.la @CLAMD_LIBS@ @THREAD_LIBS@
56
-AM_CPPFLAGS = @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav
56
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
57 57
 
58 58
 # it does support --help and --version but with the default config file
59 59
 # it outputs an error message which tells us to edit the config files
... ...
@@ -487,7 +487,7 @@ top_srcdir = @top_srcdir@
487 487
 @BUILD_CLAMD_TRUE@    fan.h
488 488
 
489 489
 @BUILD_CLAMD_TRUE@AM_CFLAGS = @WERR_CFLAGS@
490
-AM_CPPFLAGS = @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav
490
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
491 491
 
492 492
 # it does support --help and --version but with the default config file
493 493
 # it outputs an error message which tells us to edit the config files
... ...
@@ -1064,7 +1064,7 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
1064 1064
 	if((fd = fopen(opt->strarg, "w")) == NULL) {
1065 1065
 	    logg("!Can't save PID in file %s\n", opt->strarg);
1066 1066
 	} else {
1067
-	    if (fprintf(fd, "%u", (unsigned int) mainpid)<0) {
1067
+	    if (fprintf(fd, "%u\n", (unsigned int) mainpid)<0) {
1068 1068
 	    	logg("!Can't save PID in file %s\n", opt->strarg);
1069 1069
 	    }
1070 1070
 	    fclose(fd);
... ...
@@ -44,7 +44,7 @@ endif
44 44
 
45 45
 
46 46
 DEFS = @DEFS@ -DCL_NOTHREADS -DCL_NOLIBCLAMAV
47
-AM_CPPFLAGS = @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/clamscan -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @CLAMDSCAN_CPPFLAGS@
47
+AM_CPPFLAGS = @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/clamscan -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @CLAMDSCAN_CPPFLAGS@
48 48
 LIBS = $(top_builddir)/libclamav/libclamav_internal_utils_nothreads.la  @CLAMDSCAN_LIBS@
49 49
 
50 50
 AM_INSTALLCHECK_STD_OPTIONS_EXEMPT=clamdscan$(EXEEXT)
... ...
@@ -476,7 +476,7 @@ top_srcdir = @top_srcdir@
476 476
 @BUILD_CLAMD_TRUE@    client.h
477 477
 
478 478
 @BUILD_CLAMD_TRUE@AM_CFLAGS = @WERR_CFLAGS@
479
-AM_CPPFLAGS = @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/clamscan -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @CLAMDSCAN_CPPFLAGS@
479
+AM_CPPFLAGS = @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/clamscan -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @CLAMDSCAN_CPPFLAGS@
480 480
 AM_INSTALLCHECK_STD_OPTIONS_EXEMPT = clamdscan$(EXEEXT)
481 481
 CLEANFILES = *.gcda *.gcno
482 482
 all: all-am
... ...
@@ -11,8 +11,8 @@ clamdtop_SOURCES = \
11 11
     clamdtop.c
12 12
 
13 13
 AM_CFLAGS=@WERR_CFLAGS@
14
-AM_CPPFLAGS = -I$(top_srcdir) @CURSES_CPPFLAGS@ @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
15
-clamdtop_LDADD = @CURSES_LIBS@ @SSL_LDFLAGS@ @SSL_LIBS@ $(top_builddir)/libclamav/libclamav_internal_utils_nothreads.la
14
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @CURSES_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
15
+clamdtop_LDADD = @SSL_LDFLAGS@ @SSL_LIBS@ @CURSES_LIBS@ $(top_builddir)/libclamav/libclamav_internal_utils_nothreads.la
16 16
 endif
17 17
 DEFS = @DEFS@ -DCL_NOTHREADS -DCL_NOLIBCLAMAV
18 18
 EXTRA_DIST = clamdtop.c
... ...
@@ -473,8 +473,8 @@ top_srcdir = @top_srcdir@
473 473
 @HAVE_CURSES_TRUE@    clamdtop.c
474 474
 
475 475
 @HAVE_CURSES_TRUE@AM_CFLAGS = @WERR_CFLAGS@
476
-@HAVE_CURSES_TRUE@AM_CPPFLAGS = -I$(top_srcdir) @CURSES_CPPFLAGS@ @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
477
-@HAVE_CURSES_TRUE@clamdtop_LDADD = @CURSES_LIBS@ @SSL_LDFLAGS@ @SSL_LIBS@ $(top_builddir)/libclamav/libclamav_internal_utils_nothreads.la
476
+@HAVE_CURSES_TRUE@AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @CURSES_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
477
+@HAVE_CURSES_TRUE@clamdtop_LDADD = @SSL_LDFLAGS@ @SSL_LIBS@ @CURSES_LIBS@ $(top_builddir)/libclamav/libclamav_internal_utils_nothreads.la
478 478
 EXTRA_DIST = clamdtop.c
479 479
 all: all-am
480 480
 
... ...
@@ -38,6 +38,6 @@ clamscan_SOURCES = \
38 38
 AM_CFLAGS=@WERR_CFLAGS@
39 39
 DEFS = @DEFS@ -DCL_NOTHREADS
40 40
 LIBS = $(top_builddir)/libclamav/libclamav.la @THREAD_LIBS@ @CLAMSCAN_LIBS@
41
-AM_CPPFLAGS = @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @CLAMSCAN_CPPFLAGS@
41
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ @CLAMSCAN_CPPFLAGS@
42 42
 
43 43
 CLEANFILES=*.gcda *.gcno
... ...
@@ -464,7 +464,7 @@ clamscan_SOURCES = \
464 464
     manager.h
465 465
 
466 466
 AM_CFLAGS = @WERR_CFLAGS@
467
-AM_CPPFLAGS = @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @CLAMSCAN_CPPFLAGS@
467
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ @CLAMSCAN_CPPFLAGS@
468 468
 CLEANFILES = *.gcda *.gcno
469 469
 all: all-am
470 470
 
... ...
@@ -31,7 +31,7 @@ clamsubmit_SOURCES = \
31 31
 
32 32
 AM_CFLAGS=@WERR_CFLAGS@ @CLAMSUBMIT_CFLAGS@
33 33
 DEFS = @DEFS@ -DCL_NOTHREADS
34
-AM_CPPFLAGS = @JSON_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav
34
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @JSON_CPPFLAGS@
35 35
 LIBS = $(top_builddir)/libclamav/libclamav.la @CLAMSUBMIT_LIBS@ @THREAD_LIBS@
36 36
 
37 37
 AM_INSTALLCHECK_STD_OPTIONS_EXEMPT=clamsubmit$(EXEEXT)
... ...
@@ -457,7 +457,7 @@ clamsubmit_SOURCES = \
457 457
 	clamsubmit.c
458 458
 
459 459
 AM_CFLAGS = @WERR_CFLAGS@ @CLAMSUBMIT_CFLAGS@
460
-AM_CPPFLAGS = @JSON_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav
460
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @JSON_CPPFLAGS@
461 461
 AM_INSTALLCHECK_STD_OPTIONS_EXEMPT = clamsubmit$(EXEEXT)
462 462
 CLEANFILES = *.gcda *.gcno
463 463
 all: all-am
... ...
@@ -5108,7 +5108,7 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
5108 5108
 VERSION="devel-`date +%Y%m%d`"
5109 5109
 
5110 5110
 LC_CURRENT=7
5111
-LC_REVISION=22
5111
+LC_REVISION=24
5112 5112
 LC_AGE=1
5113 5113
 LIBCLAMAV_VERSION="$LC_CURRENT":"$LC_REVISION":"$LC_AGE"
5114 5114
 
5115 5115
Binary files a/docs/ClamAV_Document_Properties.xlsx and b/docs/ClamAV_Document_Properties.xlsx differ
... ...
@@ -51,7 +51,7 @@ freshclam_SOURCES = \
51 51
 
52 52
 AM_CFLAGS=@WERR_CFLAGS@
53 53
 DEFS = @DEFS@ -DCL_NOTHREADS
54
-AM_CPPFLAGS = @SSL_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @FRESHCLAM_CPPFLAGS@  @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
54
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @FRESHCLAM_CPPFLAGS@  @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
55 55
 LIBS = @SSL_LDFLAGS@ @SSL_LIBS@ $(top_builddir)/libclamav/libclamav.la @FRESHCLAM_LIBS@ @THREAD_LIBS@
56 56
 
57 57
 AM_INSTALLCHECK_STD_OPTIONS_EXEMPT=freshclam$(EXEEXT)
... ...
@@ -480,7 +480,7 @@ freshclam_SOURCES = \
480 480
     mirman.h
481 481
 
482 482
 AM_CFLAGS = @WERR_CFLAGS@
483
-AM_CPPFLAGS = @SSL_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @FRESHCLAM_CPPFLAGS@  @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
483
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @FRESHCLAM_CPPFLAGS@  @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@
484 484
 AM_INSTALLCHECK_STD_OPTIONS_EXEMPT = freshclam$(EXEEXT)
485 485
 CLEANFILES = *.gcda *.gcno
486 486
 all: all-am
... ...
@@ -135,7 +135,7 @@ writepid (const char *pidfile)
135 135
     }
136 136
     else
137 137
     {
138
-        fprintf (fd, "%d", (int) getpid ());
138
+        fprintf (fd, "%d\n", (int) getpid ());
139 139
         fclose (fd);
140 140
     }
141 141
     umask (old_umask);
... ...
@@ -244,7 +244,7 @@ download (const struct optstruct *opts, const char *cfgfile)
244 244
                     opt = (struct optstruct *) opt->nextarg;
245 245
                     if (!opt)
246 246
                     {
247
-                        logg ("Update failed. Your network may be down or none of the mirrors listed in %s is working. Check http://www.clamav.net/documentation.html for possible reasons.\n", cfgfile);
247
+                        logg ("Update failed. Your network may be down or none of the mirrors listed in %s is working. Check http://www.clamav.net/doc/mirrors-faq.html for possible reasons.\n", cfgfile);
248 248
                     }
249 249
                 }
250 250
 
... ...
@@ -2060,7 +2060,7 @@ updatedb (const char *dbname, const char *hostname, char *ip, int *signo,
2060 2060
             logg ("^Current functionality level = %d, recommended = %d\n",
2061 2061
                   flevel, current->fl);
2062 2062
             logg ("Please check if ClamAV tools are linked against the proper version of libclamav\n");
2063
-            logg ("DON'T PANIC! Read http://www.clamav.net/documentation.html\n");
2063
+            logg ("DON'T PANIC! Read http://www.clamav.net/doc/install.html\n");
2064 2064
         }
2065 2065
 
2066 2066
         *signo += current->sigs;
... ...
@@ -100,7 +100,9 @@ enum FunctionalityLevels {
100 100
     FUNC_LEVEL_098_1     = 76, /**< LibClamAV release 0.98.2 */ /*last syncing to clamav*/
101 101
     FUNC_LEVEL_098_2     = 77, /**< LibClamAV release 0.98.2 */
102 102
     FUNC_LEVEL_098_3     = 77, /**< LibClamAV release 0.98.3 */
103
-    FUNC_LEVEL_098_4     = 78, /**< LibClamAV release 0.98.4: JSON reading API requires this minimum level */
103
+    FUNC_LEVEL_098_4     = 77, /**< LibClamAV release 0.98.4 */
104
+    FUNC_LEVEL_098_5     = 79, /**< LibClamAV release 0.98.5: JSON reading API requires this minimum level */
105
+    FUNC_LEVEL_098_6     = 79, /**< LibClamAV release 0.98.6 */
104 106
     FUNC_LEVEL_100       = 100 /*future release candidate*/
105 107
 };
106 108
 
... ...
@@ -60,11 +60,22 @@
60 60
 #include "others.h"
61 61
 #include "libclamav/conv.h"
62 62
 #include "libclamav/str.h"
63
+#include "iowrap.h"
63 64
 
64 65
 #if defined(_WIN32)
65 66
 char * strptime(const char *buf, const char *fmt, struct tm *tm);
66 67
 #endif
67 68
 
69
+#if defined(_WIN32)
70
+#define EXCEPTION_PREAMBLE __try {
71
+#define EXCEPTION_POSTAMBLE } __except (filter_memcpy(GetExceptionCode(), GetExceptionInformation())) { \
72
+    winres=1; \
73
+}
74
+#else
75
+#define EXCEPTION_PREAMBLE
76
+#define EXCEPTION_POSTAMBLE
77
+#endif
78
+
68 79
 #if !defined(MIN)
69 80
     #define MIN(x,y) ((x)<(y)?(x):(y))
70 81
 #endif
... ...
@@ -132,6 +143,7 @@ unsigned char *cl_hash_data(char *alg, const void *buf, size_t len, unsigned cha
132 132
     const EVP_MD *md;
133 133
     unsigned int i;
134 134
     size_t cur;
135
+    int winres=0;
135 136
 
136 137
     md = EVP_get_digestbyname(alg);
137 138
     if (!(md))
... ...
@@ -151,6 +163,11 @@ unsigned char *cl_hash_data(char *alg, const void *buf, size_t len, unsigned cha
151 151
         return NULL;
152 152
     }
153 153
 
154
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
155
+    /* we will be using MD5, which is not allowed under FIPS */
156
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
157
+#endif
158
+
154 159
     if (!EVP_DigestInit_ex(ctx, md, NULL)) {
155 160
         if (!(obuf))
156 161
             free(ret);
... ...
@@ -165,6 +182,8 @@ unsigned char *cl_hash_data(char *alg, const void *buf, size_t len, unsigned cha
165 165
     cur=0;
166 166
     while (cur < len) {
167 167
         size_t todo = MIN((unsigned long)EVP_MD_block_size(md), (unsigned long)(len-cur));
168
+
169
+        EXCEPTION_PREAMBLE
168 170
         if (!EVP_DigestUpdate(ctx, (void *)(((unsigned char *)buf)+cur), todo)) {
169 171
             if (!(obuf))
170 172
                 free(ret);
... ...
@@ -175,6 +194,18 @@ unsigned char *cl_hash_data(char *alg, const void *buf, size_t len, unsigned cha
175 175
             EVP_MD_CTX_destroy(ctx);
176 176
             return NULL;
177 177
         }
178
+        EXCEPTION_POSTAMBLE
179
+
180
+        if (winres) {
181
+            if (!(obuf))
182
+                free(ret);
183
+
184
+            if ((olen))
185
+                *olen = 0;
186
+
187
+            EVP_MD_CTX_destroy(ctx);
188
+            return NULL;
189
+        }
178 190
 
179 191
         cur += todo;
180 192
     }
... ...
@@ -212,6 +243,11 @@ unsigned char *cl_hash_file_fd(int fd, char *alg, unsigned int *olen)
212 212
     if (!(ctx))
213 213
         return NULL;
214 214
 
215
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
216
+    /* we will be using MD5, which is not allowed under FIPS */
217
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
218
+#endif
219
+
215 220
     if (!EVP_DigestInit_ex(ctx, md, NULL)) {
216 221
         EVP_MD_CTX_destroy(ctx);
217 222
         return NULL;
... ...
@@ -230,6 +266,7 @@ unsigned char *cl_hash_file_fd_ctx(EVP_MD_CTX *ctx, int fd, unsigned int *olen)
230 230
     int mdsz;
231 231
     unsigned int hashlen;
232 232
     STATBUF sb;
233
+    int winres=0;
233 234
 
234 235
 	unsigned int blocksize;
235 236
 
... ...
@@ -267,12 +304,21 @@ unsigned char *cl_hash_file_fd_ctx(EVP_MD_CTX *ctx, int fd, unsigned int *olen)
267 267
 #else
268 268
     while ((nread = read(fd, buf, blocksize)) > 0) {
269 269
 #endif
270
+        EXCEPTION_PREAMBLE
270 271
         if (!EVP_DigestUpdate(ctx, buf, nread)) {
271 272
             free(buf);
272 273
             free(hash);
273 274
 
274 275
             return NULL;
275 276
         }
277
+        EXCEPTION_POSTAMBLE
278
+
279
+        if (winres) {
280
+            free(buf);
281
+            free(hash);
282
+
283
+            return NULL;
284
+        }
276 285
     }
277 286
 
278 287
     if (!EVP_DigestFinal_ex(ctx, hash, &hashlen)) {
... ...
@@ -321,6 +367,11 @@ int cl_verify_signature_hash(EVP_PKEY *pkey, char *alg, unsigned char *sig, unsi
321 321
 
322 322
     mdsz = EVP_MD_size(md);
323 323
 
324
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
325
+    /* we will be using MD5, which is not allowed under FIPS */
326
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
327
+#endif
328
+
324 329
     if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
325 330
         EVP_MD_CTX_destroy(ctx);
326 331
         return -1;
... ...
@@ -365,6 +416,11 @@ int cl_verify_signature_fd(EVP_PKEY *pkey, char *alg, unsigned char *sig, unsign
365 365
         return -1;
366 366
     }
367 367
 
368
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
369
+    /* we will be using MD5, which is not allowed under FIPS */
370
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
371
+#endif
372
+
368 373
     if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
369 374
         free(digest);
370 375
         EVP_MD_CTX_destroy(ctx);
... ...
@@ -435,6 +491,11 @@ int cl_verify_signature(EVP_PKEY *pkey, char *alg, unsigned char *sig, unsigned
435 435
         return -1;
436 436
     }
437 437
 
438
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
439
+    /* we will be using MD5, which is not allowed under FIPS */
440
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
441
+#endif
442
+
438 443
     if (!EVP_VerifyInit_ex(ctx, md, NULL)) {
439 444
         free(digest);
440 445
         if (decode)
... ...
@@ -643,6 +704,11 @@ unsigned char *cl_sign_data(EVP_PKEY *pkey, char *alg, unsigned char *hash, unsi
643 643
         return NULL;
644 644
     }
645 645
 
646
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
647
+    /* we will be using MD5, which is not allowed under FIPS */
648
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
649
+#endif
650
+
646 651
     if (!EVP_SignInit_ex(ctx, md, NULL)) {
647 652
         free(sig);
648 653
         EVP_MD_CTX_destroy(ctx);
... ...
@@ -1078,6 +1144,11 @@ void *cl_hash_init(const char *alg)
1078 1078
         return NULL;
1079 1079
     }
1080 1080
 
1081
+#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW
1082
+    /* we will be using MD5, which is not allowed under FIPS */
1083
+    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
1084
+#endif
1085
+
1081 1086
     if (!EVP_DigestInit_ex(ctx, md, NULL)) {
1082 1087
         EVP_MD_CTX_destroy(ctx);
1083 1088
         return NULL;
... ...
@@ -1088,11 +1159,18 @@ void *cl_hash_init(const char *alg)
1088 1088
 
1089 1089
 int cl_update_hash(void *ctx, void *data, size_t sz)
1090 1090
 {
1091
+    int winres=0;
1092
+
1091 1093
     if (!(ctx) || !(data))
1092 1094
         return -1;
1093 1095
 
1096
+    EXCEPTION_PREAMBLE
1094 1097
     if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx, data, sz))
1095 1098
         return -1;
1099
+    EXCEPTION_POSTAMBLE
1100
+
1101
+    if (winres)
1102
+        return -1;
1096 1103
 
1097 1104
     return 0;
1098 1105
 }
... ...
@@ -660,7 +660,7 @@ int cli_cvdload(FILE *fs, struct cl_engine *engine, unsigned int *signo, unsigne
660 660
     if(cvd.fl > cl_retflevel()) {
661 661
 	cli_warnmsg("***********************************************************\n");
662 662
 	cli_warnmsg("***  This version of the ClamAV engine is outdated.     ***\n");
663
-	cli_warnmsg("***   Read http://www.clamav.net/documentation.html     ***\n");
663
+	cli_warnmsg("***   Read http://www.clamav.net/doc/install.html       ***\n");
664 664
 	cli_warnmsg("***********************************************************\n");
665 665
     }
666 666
 
... ...
@@ -41,6 +41,7 @@
41 41
 #include "iowrap.h"
42 42
 #include "mbr.h"
43 43
 #include "gpt.h"
44
+#include "ooxml.h"
44 45
 
45 46
 #include "htmlnorm.h"
46 47
 #include "entconv.h"
... ...
@@ -33,7 +33,7 @@
33 33
 #endif
34 34
 
35 35
 #ifdef _WIN32
36
-static int filter_memcpy(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
36
+int filter_memcpy(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
37 37
     if ((code == EXCEPTION_IN_PAGE_ERROR) || (code == STATUS_DEVICE_DATA_ERROR)) {
38 38
         return EXCEPTION_EXECUTE_HANDLER;
39 39
     }
... ...
@@ -42,4 +42,8 @@
42 42
  */
43 43
 int cli_memcpy(void *target, const void *source, unsigned long size);
44 44
 
45
+#ifdef _WIN32
46
+int filter_memcpy(unsigned int code, struct _EXCEPTION_POINTERS *ep);
47
+#endif
48
+
45 49
 #endif
... ...
@@ -3315,7 +3315,7 @@ getline_from_mbox(char *buffer, size_t buffer_len, fmap_t *map, size_t *at)
3315 3315
 	return NULL;
3316 3316
     }
3317 3317
     if((buffer_len == 0) || (buffer == NULL)) {
3318
-	cli_errmsg("Invalid call to getline_from_mbox(). Refer to http://www.clamav.net/documentation.html\n");
3318
+	cli_errmsg("Invalid call to getline_from_mbox(). Refer to http://www.clamav.net/doc/install.html\n");
3319 3319
 	return NULL;
3320 3320
     }
3321 3321
 
... ...
@@ -623,7 +623,11 @@ void *mpool_malloc(struct MP *mp, size_t size) {
623 623
     struct FRAG *fold = f;
624 624
     mp->avail[sbits] = f->u.next.ptr;
625 625
     /* we always have enough space for this, align_increase ensured that */
626
+#ifdef _WIN64
627
+    f = (struct FRAG*)(alignto((unsigned long long)f + FRAG_OVERHEAD, align)-FRAG_OVERHEAD);
628
+#else
626 629
     f = (struct FRAG*)(alignto((unsigned long)f + FRAG_OVERHEAD, align)-FRAG_OVERHEAD);
630
+#endif
627 631
     f->u.a.sbits = sbits;
628 632
     f->u.a.padding = (char*)f - (char*)fold;
629 633
 #ifdef CL_DEBUG
... ...
@@ -62,7 +62,35 @@ ole2_convert_utf(summary_ctx_t *sctx, char *begin, size_t sz, const char *encodi
62 62
 #endif
63 63
     /* applies in the both case */
64 64
     if (sctx->codepage == 20127 || sctx->codepage == 65001) {
65
-        outbuf = cli_strdup(begin);
65
+        char *track;
66
+        int bcnt, scnt;
67
+
68
+        outbuf = cli_calloc(1, sz+1);
69
+        if (!(outbuf))
70
+            return NULL;
71
+        memcpy(outbuf, begin, sz);
72
+
73
+        track = outbuf+sz-1;
74
+        if ((sctx->codepage == 65001) && (*track & 0x80)) { /* UTF-8 with a most significant bit */
75
+            /* locate the start of the last character */
76
+            for (bcnt = 1; (track != outbuf); track--, bcnt++) {
77
+                if (((uint8_t)*track & 0xC0) != 0x80)
78
+                    break;
79
+            }
80
+
81
+            /* count number of set (1) significant bits */
82
+            for (scnt = 0; scnt < sizeof(uint8_t)*8; scnt++) {
83
+                if (((uint8_t)*track & (0x80 >> scnt)) == 0)
84
+                    break;
85
+            }
86
+
87
+            if (bcnt != scnt) {
88
+                cli_dbgmsg("ole2_convert_utf: cleaning out %d bytes from incomplete "
89
+                           "utf-8 character length %d\n", bcnt, scnt);
90
+                for (; bcnt > 0; bcnt--, track++)
91
+                    *track = '\0';
92
+            }
93
+        }
66 94
         return outbuf;
67 95
     }
68 96
 
... ...
@@ -78,11 +78,29 @@ static int ooxml_is_int(const char *value, size_t len, int32_t *val)
78 78
     return 1;
79 79
 }
80 80
 
81
+static int ooxml_add_parse_error(json_object *wrkptr, const xmlChar *errstr)
82
+{
83
+    json_object *perr;
84
+
85
+    if (!wrkptr)
86
+        return CL_ENULLARG;
87
+
88
+    perr = cli_jsonarray(wrkptr, "ParseErrors");
89
+    if (perr == NULL) {
90
+        return CL_EMEM;
91
+    }
92
+
93
+    return cli_jsonstr(perr, NULL, errstr);
94
+}
95
+
81 96
 static int ooxml_parse_value(json_object *wrkptr, const char *arrname, const xmlChar *node_value)
82 97
 {
83 98
     json_object *newobj, *arrobj;
84 99
     int val;
85 100
 
101
+    if (!wrkptr)
102
+        return CL_ENULLARG;
103
+
86 104
     arrobj = cli_jsonarray(wrkptr, arrname);
87 105
     if (arrobj == NULL) {
88 106
         return CL_EMEM;
... ...
@@ -247,7 +265,7 @@ static int ooxml_parse_element(cli_ctx *ctx, xmlTextReaderPtr reader, json_objec
247 247
 
248 248
     if (node_type != XML_READER_TYPE_ELEMENT) {
249 249
         cli_dbgmsg("ooxml_parse_element: first node typed %d, not %d\n", node_type, XML_READER_TYPE_ELEMENT);
250
-        return CL_EPARSE; /* first type is not an element */
250
+        return CL_EFORMAT; /* first type is not an element */
251 251
     }
252 252
 
253 253
     node_name = xmlTextReaderConstLocalName(reader);
... ...
@@ -267,7 +285,7 @@ static int ooxml_parse_element(cli_ctx *ctx, xmlTextReaderPtr reader, json_objec
267 267
     /* generate json object */
268 268
     thisjobj = cli_jsonobj(wrkptr, element_tag);
269 269
     if (!thisjobj) {
270
-        return CL_EPARSE;
270
+        return CL_EMEM;
271 271
     }
272 272
     cli_dbgmsg("ooxml_parse_element: generated json object [%s]\n", element_tag);
273 273
 
... ...
@@ -386,6 +404,17 @@ static int ooxml_parse_element(cli_ctx *ctx, xmlTextReaderPtr reader, json_objec
386 386
     return CL_SUCCESS;
387 387
 }
388 388
 
389
+static int ooxml_updatelimits(int fd, cli_ctx *ctx)
390
+{
391
+    STATBUF sb;
392
+    if (FSTAT(fd, &sb) == -1) {
393
+        cli_errmsg("ooxml_updatelimits: Can't fstat descriptor %d\n", fd);
394
+        return CL_ESTAT;
395
+    }
396
+
397
+    return cli_updatelimits(ctx, sb.st_size);
398
+}
399
+
389 400
 static int ooxml_parse_document(int fd, cli_ctx *ctx)
390 401
 {
391 402
     int ret = CL_SUCCESS;
... ...
@@ -393,6 +422,11 @@ static int ooxml_parse_document(int fd, cli_ctx *ctx)
393 393
 
394 394
     cli_dbgmsg("in ooxml_parse_document\n");
395 395
 
396
+    /* perform engine limit checks in temporary tracking session */
397
+    ret = ooxml_updatelimits(fd, ctx);
398
+    if (ret != CL_CLEAN)
399
+        return ret;
400
+
396 401
     reader = xmlReaderForFd(fd, "properties.xml", NULL, CLAMAV_MIN_XMLREADER_FLAGS);
397 402
     if (reader == NULL) {
398 403
         cli_dbgmsg("ooxml_parse_document: xmlReaderForFd error\n");
... ...
@@ -406,10 +440,8 @@ static int ooxml_parse_document(int fd, cli_ctx *ctx)
406 406
 
407 407
     ret = ooxml_parse_element(ctx, reader, ctx->wrkproperty, 0, NULL);
408 408
 
409
-    if (ret != CL_SUCCESS && ret != CL_ETIMEOUT && ret != CL_BREAK) {
409
+    if (ret != CL_SUCCESS && ret != CL_ETIMEOUT && ret != CL_BREAK)
410 410
         cli_warnmsg("ooxml_parse_document: encountered issue in parsing properties document\n");
411
-        cli_jsonbool(ctx->wrkproperty, "ParseError", 1);
412
-    }
413 411
 
414 412
     xmlTextReaderClose(reader);
415 413
     xmlFreeTextReader(reader);
... ...
@@ -418,37 +450,64 @@ static int ooxml_parse_document(int fd, cli_ctx *ctx)
418 418
 
419 419
 static int ooxml_core_cb(int fd, cli_ctx *ctx)
420 420
 {
421
+    int ret;
422
+
421 423
     cli_dbgmsg("in ooxml_core_cb\n");
422
-    return ooxml_parse_document(fd, ctx);
423
-    //return ooxml_basic_json(fd, ctx, "CoreProperties");
424
+    ret = ooxml_parse_document(fd, ctx);
425
+    if (ret == CL_EPARSE)
426
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_CORE_XMLPARSER");
427
+    else if (ret == CL_EFORMAT)
428
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_CORE_MALFORMED");
429
+
430
+    return ret;
424 431
 }
425 432
 
426 433
 static int ooxml_extn_cb(int fd, cli_ctx *ctx)
427 434
 {
435
+    int ret;
436
+
428 437
     cli_dbgmsg("in ooxml_extn_cb\n");
429
-    return ooxml_parse_document(fd, ctx);
430
-    //return ooxml_basic_json(fd, ctx, "ExtendedProperties");
438
+    ret = ooxml_parse_document(fd, ctx);
439
+    if (ret == CL_EPARSE)
440
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_EXTN_XMLPARSER");
441
+    else if (ret == CL_EFORMAT)
442
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_EXTN_MALFORMED");
443
+
444
+    return ret;
431 445
 }
432 446
 
433 447
 static int ooxml_content_cb(int fd, cli_ctx *ctx)
434 448
 {
435
-    int ret = CL_SUCCESS, tmp, toval = 0;
449
+    int ret = CL_SUCCESS, tmp, toval = 0, state;
436 450
     int core=0, extn=0, cust=0, dsig=0;
437 451
     int mcore=0, mextn=0, mcust=0;
438 452
     const xmlChar *name, *value, *CT, *PN;
439 453
     xmlTextReaderPtr reader = NULL;
440 454
     uint32_t loff;
441 455
 
456
+    unsigned long sav_scansize = ctx->scansize;
457
+    unsigned int sav_scannedfiles = ctx->scannedfiles;
458
+
442 459
     cli_dbgmsg("in ooxml_content_cb\n");
443 460
 
461
+    /* perform engine limit checks in temporary tracking session */
462
+    ret = ooxml_updatelimits(fd, ctx);
463
+    if (ret != CL_CLEAN)
464
+        return ret;
465
+
466
+    /* apply a reader to the document */
444 467
     reader = xmlReaderForFd(fd, "[Content_Types].xml", NULL, CLAMAV_MIN_XMLREADER_FLAGS);
445 468
     if (reader == NULL) {
446 469
         cli_dbgmsg("ooxml_content_cb: xmlReaderForFd error for ""[Content_Types].xml""\n");
470
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_XML_READER_FD");
471
+
472
+        ctx->scansize = sav_scansize;
473
+        ctx->scannedfiles = sav_scannedfiles;
447 474
         return CL_SUCCESS; // libxml2 failed!
448 475
     }
449 476
 
450
-    /* locate core-properties, extended-properties, and custom-properties (optional)  */
451
-    while (xmlTextReaderRead(reader) == 1) {
477
+    /* locate core-properties, extended-properties, and custom-properties (optional) */
478
+    while ((state = xmlTextReaderRead(reader)) == 1) {
452 479
         if (cli_json_timeout_cycle_check(ctx, &toval) != CL_SUCCESS) {
453 480
             ret = CL_ETIMEOUT;
454 481
             goto ooxml_content_exit;
... ...
@@ -480,93 +539,116 @@ static int ooxml_content_cb(int fd, cli_ctx *ctx)
480 480
         if (!CT && !PN) continue;
481 481
 
482 482
         if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-package.core-properties+xml")) {
483
-            if (!core) {
484
-                /* default: /docProps/core.xml*/
485
-                tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
486
-                if (tmp == CL_ETIMEOUT) {
487
-                    ret = tmp;
488
-                }
489
-                else if (tmp != CL_VIRUS) {
490
-                    cli_dbgmsg("cli_process_ooxml: failed to find core properties file \"%s\"!\n", PN);
491
-                    mcore++;
492
-                }
493
-                else {
494
-                    cli_dbgmsg("ooxml_content_cb: found core properties file \"%s\" @ %x\n", PN, loff);
495
-                    ret = unzip_single_internal(ctx, loff, ooxml_core_cb);
496
-                    core++;
483
+            /* default: /docProps/core.xml*/
484
+            tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
485
+            if (tmp == CL_ETIMEOUT) {
486
+                ret = tmp;
487
+            }
488
+            else if (tmp != CL_VIRUS) {
489
+                cli_dbgmsg("cli_process_ooxml: failed to find core properties file \"%s\"!\n", PN);
490
+                mcore++;
491
+            }
492
+            else {
493
+                cli_dbgmsg("ooxml_content_cb: found core properties file \"%s\" @ %x\n", PN, loff);
494
+                if (!core) {
495
+                    tmp = unzip_single_internal(ctx, loff, ooxml_core_cb);
496
+                    if (tmp == CL_ETIMEOUT || tmp == CL_EMEM) {
497
+                        ret = tmp;
498
+                    }
497 499
                 }
500
+                core++;
498 501
             }
499 502
         }
500 503
         else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-officedocument.extended-properties+xml")) {
501
-            if (!extn) {
502
-                /* default: /docProps/app.xml */
503
-                tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
504
-                if (tmp == CL_ETIMEOUT) {
505
-                    ret = tmp;
506
-                }
507
-                else if (tmp != CL_VIRUS) {
508
-                    cli_dbgmsg("cli_process_ooxml: failed to find extended properties file \"%s\"!\n", PN);
509
-                    mextn++;
510
-                }
511
-                else {
512
-                    cli_dbgmsg("ooxml_content_cb: found extended properties file \"%s\" @ %x\n", PN, loff);
513
-                    ret = unzip_single_internal(ctx, loff, ooxml_extn_cb);
514
-                    extn++;
504
+            /* default: /docProps/app.xml */
505
+            tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
506
+            if (tmp == CL_ETIMEOUT) {
507
+                ret = tmp;
508
+            }
509
+            else if (tmp != CL_VIRUS) {
510
+                cli_dbgmsg("cli_process_ooxml: failed to find extended properties file \"%s\"!\n", PN);
511
+                mextn++;
512
+            }
513
+            else {
514
+                cli_dbgmsg("ooxml_content_cb: found extended properties file \"%s\" @ %x\n", PN, loff);
515
+                if (!extn) {
516
+                    tmp = unzip_single_internal(ctx, loff, ooxml_extn_cb);
517
+                    if (tmp == CL_ETIMEOUT || tmp == CL_EMEM) {
518
+                        ret = tmp;
519
+                    }
515 520
                 }
521
+                extn++;
516 522
             }
517 523
         }
518 524
         else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-officedocument.custom-properties+xml")) {
519
-            if (!cust) {
520
-                /* default: /docProps/custom.xml */
521
-                tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
522
-                if (tmp == CL_ETIMEOUT) {
523
-                    ret = tmp;
524
-                }
525
-                else if (tmp != CL_VIRUS) {
526
-                    cli_dbgmsg("cli_process_ooxml: failed to find custom properties file \"%s\"!\n", PN);
527
-                    mcust++;
528
-                }
529
-                else {
530
-                    cli_dbgmsg("ooxml_content_cb: found custom properties file \"%s\" @ %x\n", PN, loff);
531
-                    cust++;
532
-                    //ret = unzip_single_internal(ctx, loff, ooxml_cust_cb);
533
-                }
525
+            /* default: /docProps/custom.xml */
526
+            tmp = unzip_search_single(ctx, (const char *)(PN+1), xmlStrlen(PN)-1, &loff);
527
+            if (tmp == CL_ETIMEOUT) {
528
+                ret = tmp;
529
+            }
530
+            else if (tmp != CL_VIRUS) {
531
+                cli_dbgmsg("cli_process_ooxml: failed to find custom properties file \"%s\"!\n", PN);
532
+                mcust++;
533
+            }
534
+            else {
535
+                cli_dbgmsg("ooxml_content_cb: found custom properties file \"%s\" @ %x\n", PN, loff);
536
+                /* custom properties are not parsed */
537
+                cust++;
534 538
             }
535 539
         }
536 540
         else if (!xmlStrcmp(CT, (const xmlChar *)"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml")) {
537 541
             dsig++;
538 542
         }
539 543
 
540
-        if (ret != CL_BREAK && ret != CL_SUCCESS)
544
+        if (ret != CL_SUCCESS)
541 545
             goto ooxml_content_exit;
542 546
     }
543 547
 
544 548
  ooxml_content_exit:
545
-    if (core)
549
+    if (core) {
546 550
         cli_jsonint(ctx->wrkproperty, "CorePropertiesFileCount", core);
551
+        if (core > 1)
552
+            ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MULTIPLE_CORE_PROPFILES");
553
+    }
547 554
     else if (!mcore)
548 555
         cli_dbgmsg("cli_process_ooxml: file does not contain core properties file\n");
549
-    if (mcore)
550
-        cli_jsonint(ctx->wrkproperty, "CorePropertiesMissingFileCount", core);
556
+    if (mcore) {
557
+        cli_jsonint(ctx->wrkproperty, "CorePropertiesMissingFileCount", mcore);
558
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MISSING_CORE_PROPFILES");
559
+    }
551 560
 
552
-    if (extn)
561
+    if (extn) {
553 562
         cli_jsonint(ctx->wrkproperty, "ExtendedPropertiesFileCount", extn);
563
+        if (extn > 1)
564
+            ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MULTIPLE_EXTN_PROPFILES");
565
+    }
554 566
     else if (!mextn)
555 567
         cli_dbgmsg("cli_process_ooxml: file does not contain extended properties file\n");
556
-    if (mextn)
557
-        cli_jsonint(ctx->wrkproperty, "ExtendedPropertiesMissingFileCount", extn);
568
+    if (mextn) {
569
+        cli_jsonint(ctx->wrkproperty, "ExtendedPropertiesMissingFileCount", mextn);
570
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MISSING_EXTN_PROPFILES");
571
+    }
558 572
 
559
-    if (cust)
573
+    if (cust) {
560 574
         cli_jsonint(ctx->wrkproperty, "CustomPropertiesFileCount", cust);
575
+        if (cust > 1)
576
+            ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MULTIPLE_CUSTOM_PROPFILES");
577
+    }
561 578
     else if (!mcust)
562 579
         cli_dbgmsg("cli_process_ooxml: file does not contain custom properties file\n");
563
-    if (mcust)
564
-        cli_jsonint(ctx->wrkproperty, "CustomPropertiesMissingFileCount", cust);
580
+    if (mcust) {
581
+        cli_jsonint(ctx->wrkproperty, "CustomPropertiesMissingFileCount", mcust);
582
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_MISSING_CUST_PROPFILES");
583
+    }
565 584
 
566 585
     if (dsig) {
567 586
         cli_jsonint(ctx->wrkproperty, "DigitalSignaturesCount", dsig);
568 587
     }
569 588
 
589
+    /* restore the engine tracking limits; resets session limit tracking */
590
+    ctx->scansize = sav_scansize;
591
+    ctx->scannedfiles = sav_scannedfiles;
592
+
570 593
     xmlTextReaderClose(reader);
571 594
     xmlFreeTextReader(reader);
572 595
     return ret;
... ...
@@ -620,15 +702,27 @@ int cli_process_ooxml(cli_ctx *ctx)
620 620
     /* find "[Content Types].xml" */
621 621
     tmp = unzip_search_single(ctx, "[Content_Types].xml", 18, &loff);
622 622
     if (tmp == CL_ETIMEOUT) {
623
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_TIMEOUT");
623 624
         return CL_ETIMEOUT;
624 625
     }
625 626
     else if (tmp != CL_VIRUS) {
626 627
         cli_dbgmsg("cli_process_ooxml: failed to find ""[Content_Types].xml""!\n");
628
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_NO_CONTENT_TYPES");
627 629
         return CL_EFORMAT;
628 630
     }
629 631
     cli_dbgmsg("cli_process_ooxml: found ""[Content_Types].xml"" @ %x\n", loff);
630 632
 
631
-    return unzip_single_internal(ctx, loff, ooxml_content_cb);
633
+    tmp = unzip_single_internal(ctx, loff, ooxml_content_cb);
634
+    if (tmp == CL_ETIMEOUT)
635
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_TIMEOUT");
636
+    else if (tmp == CL_EMEM)
637
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_OUTOFMEM");
638
+    else if (tmp == CL_EMAXSIZE)
639
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_EMAXSIZE");
640
+    else if (tmp == CL_EMAXFILES)
641
+        ooxml_add_parse_error(ctx->wrkproperty, "OOXML_ERROR_EMAXFILES");
642
+
643
+    return tmp;
632 644
 #else
633 645
     UNUSEDPARAM(ctx);
634 646
     cli_dbgmsg("in cli_processooxml\n");
... ...
@@ -2779,11 +2779,13 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
2779 2779
 #if HAVE_JSON
2780 2780
             if ((ctx->options & CL_SCAN_FILE_PROPERTIES) && (ctx->wrkproperty != NULL)) {
2781 2781
                 ret = cli_process_ooxml(ctx);
2782
-                if (ret == CL_ETIMEOUT) {
2783
-                    return magic_scandesc_cleanup(ctx, type, hash, hashed_size, cache_clean, ret, parent_property);
2782
+                if (ret == CL_EMEM || ret == CL_ENULLARG) {
2783
+                    /* critical error */
2784
+                    break;
2784 2785
                 }
2785 2786
                 else if (ret != CL_SUCCESS) {
2786
-                    /* JSONOOXML - what to do if something else fails? placeholder */
2787
+                    /* allow for the CL_TYPE_ZIP scan to occur; cli_process_ooxml other possible returns: */
2788
+                    /* CL_ETIMEOUT, CL_EMAXSIZE, CL_EMAXFILES, CL_EPARSE, CL_EFORMAT, CL_BREAK, CL_ESTAT  */
2787 2789
                     ret = CL_SUCCESS;
2788 2790
                 }
2789 2791
             }
... ...
@@ -166,7 +166,7 @@ cli_tnef(const char *dir, cli_ctx *ctx)
166 166
 					if(fout >= 0) {
167 167
 						int count;
168 168
 
169
-						cli_warnmsg("Saving dump to %s:  refer to http://www.clamav.net/documentation.html\n", filename);
169
+						cli_warnmsg("Saving dump to %s:  refer to http://www.clamav.net/doc/install.html\n", filename);
170 170
 
171 171
 						pos = 0;
172 172
 						while ((count = fmap_readn(*ctx->fmap, buffer, pos, sizeof(buffer))) > 0) {
... ...
@@ -541,7 +541,7 @@ int cli_unzip(cli_ctx *ctx) {
541 541
 	  }
542 542
 #if HAVE_JSON
543 543
           if (cli_json_timeout_cycle_check(ctx, &toval) != CL_SUCCESS) {
544
-              return CL_ETIMEOUT;
544
+              ret=CL_ETIMEOUT;
545 545
           }
546 546
 #endif
547 547
 
... ...
@@ -562,7 +562,7 @@ int cli_unzip(cli_ctx *ctx) {
562 562
       }
563 563
 #if HAVE_JSON
564 564
       if (cli_json_timeout_cycle_check(ctx, &toval) != CL_SUCCESS) {
565
-          return CL_ETIMEOUT;
565
+          ret=CL_ETIMEOUT;
566 566
       }
567 567
 #endif
568 568
 
... ...
@@ -668,7 +668,7 @@ int unzip_search(cli_ctx *ctx, fmap_t *map, struct zip_requests *requests)
668 668
         cli_dbgmsg("unzip_search: central @%x\n", coff);
669 669
         while(ret==CL_CLEAN && (coff=chdr(zmap, coff, fsize, NULL, fc+1, &ret, ctx, NULL, requests))) {
670 670
             if (requests->match) {
671
-                return CL_VIRUS;
671
+                ret=CL_VIRUS;
672 672
             }
673 673
 
674 674
             fc++;
... ...
@@ -678,7 +678,7 @@ int unzip_search(cli_ctx *ctx, fmap_t *map, struct zip_requests *requests)
678 678
             }
679 679
 #if HAVE_JSON
680 680
             if (ctx && cli_json_timeout_cycle_check(ctx, (int *)(&toval)) != CL_SUCCESS) {
681
-                return CL_ETIMEOUT;
681
+                ret=CL_ETIMEOUT;
682 682
             }
683 683
 #endif
684 684
         }
... ...
@@ -3,7 +3,7 @@ VERSION="devel-`date +%Y%m%d`"
3 3
 dnl VERSION="1.0rc1"
4 4
 
5 5
 LC_CURRENT=7
6
-LC_REVISION=22
6
+LC_REVISION=24
7 7
 LC_AGE=1
8 8
 LIBCLAMAV_VERSION="$LC_CURRENT":"$LC_REVISION":"$LC_AGE"
9 9
 AC_SUBST([LIBCLAMAV_VERSION])
... ...
@@ -301,7 +301,7 @@ const struct clam_option __clam_options[] = {
301 301
 
302 302
    { "DetectPUA", "detect-pua", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Detect Potentially Unwanted Applications.", "yes" },
303 303
 
304
-    { "ExcludePUA", "exclude-pua", 0, CLOPT_TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD | OPT_CLAMSCAN, "Exclude a specific PUA category. This directive can be used multiple times.\nSee http://www.clamav.net/documentation.html#pua for the complete list of PUA\ncategories.", "NetTool\nPWTool" },
304
+    { "ExcludePUA", "exclude-pua", 0, CLOPT_TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD | OPT_CLAMSCAN, "Exclude a specific PUA category. This directive can be used multiple times.\nSee http://www.clamav.net/doc/pua.html for the complete list of PUA\ncategories.", "NetTool\nPWTool" },
305 305
 
306 306
     { "IncludePUA", "include-pua", 0, CLOPT_TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD | OPT_CLAMSCAN, "Only include a specific PUA category. This directive can be used multiple\ntimes.", "Spy\nScanner\nRAT" },
307 307
 
... ...
@@ -464,9 +464,9 @@ const struct clam_option __clam_options[] = {
464 464
 
465 465
     { "DetectionStatsCountry", NULL, 0, CLOPT_TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM, "Country of origin of malware/detection statistics (for statistical\npurposes only). The statistics collector at ClamAV.net will look up\nyour IP address to determine the geographical origin of the malware\nreported by your installation. If this installation is mainly used to\nscan data which comes from a different location, please enable this\noption and enter a two-letter code (see http://www.iana.org/domains/root/db/)\nof the country of origin.", "country-code" },
466 466
 
467
-    { "DetectionStatsHostID", NULL, 0, CLOPT_TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM, "This option enables support for our \"Personal Statistics\" service.\nWhen this option is enabled, the information on malware detected by\nyour clamd installation is made available to you through our website.\nTo get your HostID, log on http://www.stats.clamav.net and add a new\nhost to your host list. Once you have the HostID, uncomment this option\nand paste the HostID here. As soon as your freshclam starts submitting\ninformation to our stats collecting service, you will be able to view\nthe statistics of this clamd installation by logging into\nhttp://www.stats.clamav.net with the same credentials you used to\ngenerate the HostID. For more information refer to:\nhttp://www.clamav.net/documentation.html#cctts\nThis feature requires SubmitDetectionStats to be enabled.", "unique-id" },
467
+    { "DetectionStatsHostID", NULL, 0, CLOPT_TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM, "This option enables support for our \"Personal Statistics\" service.\nWhen this option is enabled, the information on malware detected by\nyour clamd installation is made available to you through our website.\nTo get your HostID, log on http://www.stats.clamav.net and add a new\nhost to your host list. Once you have the HostID, uncomment this option\nand paste the HostID here. As soon as your freshclam starts submitting\ninformation to our stats collecting service, you will be able to view\nthe statistics of this clamd installation by logging into\nhttp://www.stats.clamav.net with the same credentials you used to\ngenerate the HostID. For more information refer to:\nhttp://www.clamav.net/doc/cctts.html\nThis feature requires SubmitDetectionStats to be enabled.", "unique-id" },
468 468
 
469
-    { "SafeBrowsing", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM, "This option enables support for Google Safe Browsing. When activated for\nthe first time, freshclam will download a new database file (safebrowsing.cvd)\nwhich will be automatically loaded by clamd and clamscan during the next\nreload, provided that the heuristic phishing detection is turned on. This\ndatabase includes information about websites that may be phishing sites or\npossible sources of malware. When using this option, it's mandatory to run\nfreshclam at least every 30 minutes.\nFreshclam uses the ClamAV's mirror infrastructure to distribute the\ndatabase and its updates but all the contents are provided under Google's\nterms of use. See http://www.google.com/transparencyreport/safebrowsing\nand http://www.clamav.net/documentation.html for more information.", "yes" },
469
+    { "SafeBrowsing", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_FRESHCLAM, "This option enables support for Google Safe Browsing. When activated for\nthe first time, freshclam will download a new database file (safebrowsing.cvd)\nwhich will be automatically loaded by clamd and clamscan during the next\nreload, provided that the heuristic phishing detection is turned on. This\ndatabase includes information about websites that may be phishing sites or\npossible sources of malware. When using this option, it's mandatory to run\nfreshclam at least every 30 minutes.\nFreshclam uses the ClamAV's mirror infrastructure to distribute the\ndatabase and its updates but all the contents are provided under Google's\nterms of use. See http://www.google.com/transparencyreport/safebrowsing\nand http://www.clamav.net/doc/safebrowsing.html for more information.", "yes" },
470 470
 
471 471
     { "Bytecode", NULL, 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 1, NULL, 0, OPT_FRESHCLAM, "This option enables downloading of bytecode.cvd, which includes additional\ndetection mechanisms and improvements to the ClamAV engine.", "yes" },
472 472
 
... ...
@@ -37,6 +37,6 @@ sigtool_SOURCES = \
37 37
 
38 38
 AM_CFLAGS=@WERR_CFLAGS@
39 39
 DEFS = @DEFS@ -DCL_NOTHREADS
40
-AM_CPPFLAGS = @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SIGTOOL_CPPFLAGS@
40
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ @SIGTOOL_CPPFLAGS@
41 41
 LIBS = @SSL_LDFLAGS@ @SSL_LIBS@ $(top_builddir)/libclamav/libclamav.la @FRESHCLAM_LIBS@ @THREAD_LIBS@
42 42
 CLEANFILES=*.gcda *.gcno
... ...
@@ -464,7 +464,7 @@ sigtool_SOURCES = \
464 464
     sigtool.c
465 465
 
466 466
 AM_CFLAGS = @WERR_CFLAGS@
467
-AM_CPPFLAGS = @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SIGTOOL_CPPFLAGS@
467
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav @SSL_CPPFLAGS@ @JSON_CPPFLAGS@ @PCRE_CPPFLAGS@ @SIGTOOL_CPPFLAGS@
468 468
 CLEANFILES = *.gcda *.gcno
469 469
 all: all-am
470 470