From adf1c03b773d4cf2fe96323e37300af5c0a0ac32 Mon Sep 17 00:00:00 2001 From: David Raynor Date: Thu, 3 Oct 2013 10:48:52 -0400 Subject: [PATCH 01/12] bb #1570: Support ADC compression in DMG --- libclamav/Makefile.am | 2 + libclamav/Makefile.in | 20 ++- libclamav/adc.c | 291 ++++++++++++++++++++++++++++++++++++++++++ libclamav/adc.h | 55 ++++++++ libclamav/dmg.c | 87 ++++++++++++- 5 files changed, 443 insertions(+), 12 deletions(-) create mode 100644 libclamav/adc.c create mode 100644 libclamav/adc.h diff --git a/libclamav/Makefile.am b/libclamav/Makefile.am index cc1710d2d..694f0670f 100644 --- a/libclamav/Makefile.am +++ b/libclamav/Makefile.am @@ -371,6 +371,8 @@ libclamav_la_SOURCES = \ builtin_bytecodes.h\ events.c\ events.h \ + adc.c \ + adc.h \ dmg.c \ dmg.h \ xar.c \ diff --git a/libclamav/Makefile.in b/libclamav/Makefile.in index fa2351bba..b04b53dfc 100644 --- a/libclamav/Makefile.in +++ b/libclamav/Makefile.in @@ -185,7 +185,7 @@ am_libclamav_la_OBJECTS = libclamav_la-matcher-ac.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 \ - libclamav_la-dmg.lo libclamav_la-xar.lo \ + libclamav_la-adc.lo libclamav_la-dmg.lo libclamav_la-xar.lo \ libclamav_la-sf_base64decode.lo libclamav_la-hfsplus.lo \ libclamav_la-swf.lo libclamav_la-jpeg.lo libclamav_la-png.lo \ libclamav_la-iso9660.lo libclamav_la-arc4.lo \ @@ -711,11 +711,11 @@ libclamav_la_SOURCES = clamav.h matcher-ac.c matcher-ac.h matcher-bm.c \ 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 dmg.c dmg.h xar.c xar.h sf_base64decode.c \ - sf_base64decode.h hfsplus.c hfsplus.h swf.c swf.h jpeg.c \ - jpeg.h png.c png.h iso9660.c iso9660.h arc4.c arc4.h \ - rijndael.c rijndael.h crtmgr.c crtmgr.h asn1.c asn1.h bignum.h \ - bignum_fast.h tomsfastmath/addsub/fp_add.c \ + events.c events.h adc.c adc.h dmg.c dmg.h xar.c xar.h \ + sf_base64decode.c sf_base64decode.h hfsplus.c hfsplus.h swf.c \ + swf.h jpeg.c jpeg.h png.c png.h iso9660.c iso9660.h arc4.c \ + arc4.h rijndael.c rijndael.h crtmgr.c crtmgr.h asn1.c asn1.h \ + bignum.h bignum_fast.h tomsfastmath/addsub/fp_add.c \ tomsfastmath/addsub/fp_add_d.c tomsfastmath/addsub/fp_addmod.c \ tomsfastmath/addsub/fp_cmp.c tomsfastmath/addsub/fp_cmp_d.c \ tomsfastmath/addsub/fp_cmp_mag.c tomsfastmath/addsub/fp_sub.c \ @@ -916,6 +916,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-LzmaDec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Ppmd7.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-Ppmd7Dec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-adc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-arc4.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-asn1.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libclamav_la-aspack.Plo@am__quote@ @@ -1848,6 +1849,13 @@ libclamav_la-events.lo: events.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-events.lo `test -f 'events.c' || echo '$(srcdir)/'`events.c +libclamav_la-adc.lo: adc.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-adc.lo -MD -MP -MF $(DEPDIR)/libclamav_la-adc.Tpo -c -o libclamav_la-adc.lo `test -f 'adc.c' || echo '$(srcdir)/'`adc.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-adc.Tpo $(DEPDIR)/libclamav_la-adc.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='adc.c' object='libclamav_la-adc.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(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-adc.lo `test -f 'adc.c' || echo '$(srcdir)/'`adc.c + libclamav_la-dmg.lo: dmg.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-dmg.lo -MD -MP -MF $(DEPDIR)/libclamav_la-dmg.Tpo -c -o libclamav_la-dmg.lo `test -f 'dmg.c' || echo '$(srcdir)/'`dmg.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libclamav_la-dmg.Tpo $(DEPDIR)/libclamav_la-dmg.Plo diff --git a/libclamav/adc.c b/libclamav/adc.c new file mode 100644 index 000000000..915704076 --- /dev/null +++ b/libclamav/adc.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2013 Sourcefire, Inc. + * + * Authors: David Raynor + * + * 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 +#include +#if HAVE_STRING_H +#include +#endif + +#include "cltypes.h" +#include "others.h" +#include "adc.h" + +/* #define DEBUG_ADC */ + +#ifdef DEBUG_ADC +# define adc_dbgmsg(...) cli_dbgmsg( __VA_ARGS__ ) +#else +# define adc_dbgmsg(...) ; +#endif + +/* Initialize values and collect buffer + * NOTE: buffer size must be larger than largest lookback offset */ +int adc_decompressInit(adc_stream *strm) +{ + if (strm == NULL) { + return ADC_IO_ERROR; + } + if (strm->state != ADC_STATE_UNINIT) { + return ADC_DATA_ERROR; + } + + /* Have to buffer maximum backward lookup */ + strm->buffer = calloc(ADC_BUFF_SIZE, 1); + if (strm->buffer == NULL) { + return ADC_MEM_ERROR; + } + strm->buffered = 0; + strm->state = ADC_STATE_GETTYPE; + strm->length = 0; + strm->offset = 0; + strm->curr = strm->buffer; + + return ADC_OK; +} + +/* Decompress routine + * NOTE: Reaching end of input buffer does not mean end of output. + * It may fill the output buffer but have more to output. + * It will only return ADC_STREAM_END if output buffer is not full. + * It will return ADC_DATA_ERROR if it ends in the middle of a phrase + * (i.e. in the middle of a lookback code or data run) + */ +int adc_decompress(adc_stream *strm) +{ + uint8_t bData; + uint8_t didNothing = 1; + + /* first, the error returns based on strm */ + if ((strm == NULL) || (strm->next_in == NULL) || (strm->next_out == NULL)) { + return ADC_IO_ERROR; + } + if (strm->state == ADC_STATE_UNINIT) { + return ADC_DATA_ERROR; + } + + cli_dbgmsg("adc_decompress: avail_in %lu avail_out %lu state %u\n", strm->avail_in, strm->avail_out, strm->state); + + while (strm->avail_out) { + /* Exit if needs more in bytes and none available */ + int needsInput; + switch (strm->state) { + case ADC_STATE_SHORTLOOK: + case ADC_STATE_LONGLOOK: + needsInput = 0; + break; + default: + needsInput = 1; + break; + } + if (needsInput && (strm->avail_in == 0)) { + break; + } + else { + didNothing = 0; + } + + /* Find or execute statecode */ + switch (strm->state) { + case ADC_STATE_GETTYPE: { + /* Grab action code */ + bData = *(uint8_t *)(strm->next_in); + strm->next_in++; + strm->avail_in--; + if (bData & 0x80) { + strm->state = ADC_STATE_RAWDATA; + strm->offset = 0; + strm->length = (bData & 0x7F) + 1; + } + else if (bData & 0x40) { + strm->state = ADC_STATE_LONGOP2; + strm->offset = 0; + strm->length = (bData & 0x3F) + 4; + } + else { + strm->state = ADC_STATE_SHORTOP; + strm->offset = (bData & 0x3) * 0x100; + strm->length = ((bData & 0x3C) >> 2) + 3; + } + adc_dbgmsg("adc_decompress: GETTYPE bData %x state %u offset %u length %u\n", + bData, strm->state, strm->offset, strm->length); + break; + } + case ADC_STATE_LONGOP2: { + /* Grab first offset byte */ + bData = *(uint8_t *)(strm->next_in); + strm->next_in++; + strm->avail_in--; + strm->offset = bData * 0x100; + strm->state = ADC_STATE_LONGOP1; + adc_dbgmsg("adc_decompress: LONGOP2 bData %x state %u offset %u length %u\n", + bData, strm->state, strm->offset, strm->length); + break; + } + case ADC_STATE_LONGOP1: { + /* Grab second offset byte */ + bData = *(uint8_t *)(strm->next_in); + strm->next_in++; + strm->avail_in--; + strm->offset += bData + 1; + strm->state = ADC_STATE_LONGLOOK; + adc_dbgmsg("adc_decompress: LONGOP1 bData %x state %u offset %u length %u\n", + bData, strm->state, strm->offset, strm->length); + break; + } + case ADC_STATE_SHORTOP: { + /* Grab offset byte */ + bData = *(uint8_t *)(strm->next_in); + strm->next_in++; + strm->avail_in--; + strm->offset += bData + 1; + strm->state = ADC_STATE_SHORTLOOK; + adc_dbgmsg("adc_decompress: SHORTOP bData %x state %u offset %u length %u\n", + bData, strm->state, strm->offset, strm->length); + break; + } + + case ADC_STATE_RAWDATA: { + /* Grab data */ + adc_dbgmsg("adc_decompress: RAWDATA offset %u length %u\n", strm->offset, strm->length); + while ((strm->avail_in > 0) && (strm->avail_out > 0) && (strm->length > 0)) { + bData = *(uint8_t *)(strm->next_in); + strm->next_in++; + strm->avail_in--; + /* store to output */ + *(uint8_t *)(strm->next_out) = bData; + strm->next_out++; + strm->avail_out--; + /* store to buffer */ + if (strm->curr >= (strm->buffer + ADC_BUFF_SIZE)) { + strm->curr = strm->buffer; + } + *(uint8_t *)strm->curr = bData; + strm->curr++; + if (strm->buffered < ADC_BUFF_SIZE) { + strm->buffered++; + } + strm->length--; + } + if (strm->length == 0) { + /* adc_dbgmsg("adc_decompress: RAWDATADONE buffered %u avail_in %u avail_out %u \n", + strm->buffered, strm->avail_in, strm->avail_out); */ + strm->state = ADC_STATE_GETTYPE; + } + break; + } + + case ADC_STATE_SHORTLOOK: + case ADC_STATE_LONGLOOK: { + /* Copy data */ + adc_dbgmsg("adc_decompress: LOOKBACK offset %u length %u avail_in %u avail_out %u\n", + strm->offset, strm->length, strm->avail_in, strm->avail_out); + while ((strm->avail_out > 0) && (strm->length > 0)) { + /* state validation first */ + if (strm->offset > 0x10000) { + cli_dbgmsg("adc_decompress: bad LOOKBACK offset %u\n", strm->offset); + return ADC_DATA_ERROR; + } + else if ((strm->state == ADC_STATE_SHORTLOOK) && (strm->offset > 0x400)) { + cli_dbgmsg("adc_decompress: bad LOOKBACK offset %u\n", strm->offset); + return ADC_DATA_ERROR; + } + if (strm->offset > strm->buffered) { + cli_dbgmsg("adc_decompress: too large LOOKBACK offset %u\n", strm->offset); + return ADC_DATA_ERROR; + } + /* retrieve byte */ + if (strm->curr >= (strm->buffer + ADC_BUFF_SIZE)) { + strm->curr = strm->buffer; + } + if (strm->curr > (strm->buffer + strm->offset)) { + bData = *(uint8_t *)(strm->curr - strm->offset); + } + else { + bData = *(uint8_t *)(strm->curr + ADC_BUFF_SIZE - strm->offset); + } + /* store to output */ + *(uint8_t *)(strm->next_out) = bData; + strm->next_out++; + strm->avail_out--; + /* store to buffer */ + *(uint8_t *)strm->curr = bData; + strm->curr++; + if (strm->buffered < ADC_BUFF_SIZE) { + strm->buffered++; + } + strm->length--; + } + if (strm->length == 0) { + strm->state = ADC_STATE_GETTYPE; + /* adc_dbgmsg("adc_decompress: LOOKBACKDONE buffered %u avail_in %u avail_out %u \n", + strm->buffered, strm->avail_in, strm->avail_out); */ + } + break; + } + + default: { + /* bad state */ + cli_errmsg("adc_decompress: invalid state %u\n", strm->state); + return ADC_DATA_ERROR; + } + } /* end switch */ + } /* end while */ + + /* There really isn't a terminator, just end of data */ + if (didNothing && strm->avail_out) { + if (strm->state == ADC_STATE_GETTYPE) { + /* Nothing left to do */ + return ADC_STREAM_END; + } + else { + /* Ended mid phrase */ + cli_dbgmsg("adc_decompress: stream ended mid-phrase, state %u\n", strm->state); + return ADC_DATA_ERROR; + } + } + return ADC_OK; +} + +/* Cleanup routine, frees buffer */ +int adc_decompressEnd(adc_stream *strm) +{ + if (strm == NULL) { + return ADC_IO_ERROR; + } + if (strm->state == ADC_STATE_UNINIT) { + return ADC_DATA_ERROR; + } + + if (strm->buffer != NULL) { + free(strm->buffer); + } + strm->buffered = 0; + strm->state = ADC_STATE_UNINIT; + strm->length = 0; + strm->offset = 0; + + return ADC_OK; +} + diff --git a/libclamav/adc.h b/libclamav/adc.h new file mode 100644 index 000000000..2a0eda104 --- /dev/null +++ b/libclamav/adc.h @@ -0,0 +1,55 @@ + + +#ifndef CLAM_ADC_H +#define CLAM_ADC_H + +struct adc_stream { + void *next_in; + size_t avail_in; + size_t total_in; + + void *next_out; + size_t avail_out; + size_t total_out; + + /* internals */ + uint8_t *buffer; + uint8_t *curr; + + uint32_t buffered; + uint16_t state; + uint16_t length; + uint32_t offset; +}; +typedef struct adc_stream adc_stream; + +#define ADC_BUFF_SIZE 65536 + +#define ADC_MEM_ERROR -1 +#define ADC_DATA_ERROR -2 +#define ADC_IO_ERROR -3 +#define ADC_OK 0 +#define ADC_STREAM_END 1 + +enum adc_state { + ADC_STATE_UNINIT = 0, + ADC_STATE_GETTYPE = 1, + ADC_STATE_RAWDATA = 2, + ADC_STATE_SHORTOP = 3, + ADC_STATE_LONGOP2 = 4, + ADC_STATE_LONGOP1 = 5, + ADC_STATE_SHORTLOOK = 6, + ADC_STATE_LONGLOOK = 7 +}; + +/* Compression phrases + * store phrase - 1 byte header + data, first byte 0x80-0xFF, max length 0x80 (7 bits + 1), no offset + * short phrase - 2 byte header + data, first byte 0x00-0x3F, max length 0x12 (4 bits + 3), max offset 0x3FF (10 bits) + * long phrase - 3 byte header + data, first byte 0x40-0x7F, max length 0x43 (6 bits + 4), max offset 0xFFFF (16 bits) + */ + +int adc_decompressInit(adc_stream *strm); +int adc_decompress(adc_stream *strm); +int adc_decompressEnd(adc_stream *strm); + +#endif diff --git a/libclamav/dmg.c b/libclamav/dmg.c index 3defbf687..a13bafb21 100644 --- a/libclamav/dmg.c +++ b/libclamav/dmg.c @@ -54,9 +54,10 @@ #include "dmg.h" #include "scanners.h" #include "sf_base64decode.h" +#include "adc.h" -// #define DEBUG_DMG_PARSE -// #define DEBUG_DMG_BZIP +/* #define DEBUG_DMG_PARSE */ +/* #define DEBUG_DMG_BZIP */ #ifdef DEBUG_DMG_PARSE # define dmg_parsemsg(...) cli_dbgmsg( __VA_ARGS__) @@ -710,10 +711,84 @@ static int dmg_stripe_store(cli_ctx *ctx, int fd, uint32_t index, struct dmg_mis /* Stripe handling: ADC block (type 0x80000004) */ static int dmg_stripe_adc(cli_ctx *ctx, int fd, uint32_t index, struct dmg_mish_with_stripes *mish_set) { - /* Temporary stub */ - cli_dbgmsg("dmg_stripe_adc: stripe " STDu32 "\n", index); - /* Return as format error to prevent scan for now */ - return CL_EFORMAT; + int ret = CL_CLEAN, adcret; + adc_stream strm; + size_t off = mish_set->stripes[index].dataOffset; + size_t len = mish_set->stripes[index].dataLength; + uint64_t size_so_far = 0; + uint64_t expected_len = mish_set->stripes[index].sectorCount * DMG_SECTOR_SIZE; + uint8_t obuf[BUFSIZ]; + + cli_dbgmsg("dmg_stripe_adc: stripe " STDu32 " initial len " STDu64 " expected len " STDu64 "\n", + index, len, expected_len); + if (len == 0) + return CL_CLEAN; + + memset(&strm, 0, sizeof(strm)); + strm.next_in = (void*)fmap_need_off_once(*ctx->fmap, off, len); + if (!strm.next_in) { + cli_warnmsg("dmg_stripe_adc: fmap need failed on stripe " STDu32 "\n", index); + return CL_EMAP; + } + strm.avail_in = len; + strm.next_out = obuf; + strm.avail_out = sizeof(obuf); + + adcret = adc_decompressInit(&strm); + if(adcret != ADC_OK) { + cli_warnmsg("dmg_stripe_adc: adc_decompressInit failed\n"); + return CL_EMEM; + } + + while(adcret == ADC_OK) { + int written; + if (size_so_far > expected_len) { + cli_warnmsg("dmg_stripe_adc: expected size exceeded!\n"); + adc_decompressEnd(&strm); + return CL_EFORMAT; + } + adcret = adc_decompress(&strm); + switch(adcret) { + case ADC_OK: + if(strm.avail_out == 0) { + if ((written=cli_writen(fd, obuf, sizeof(obuf)))!=sizeof(obuf)) { + cli_errmsg("dmg_stripe_adc: failed write to output file\n"); + adc_decompressEnd(&strm); + return CL_EWRITE; + } + size_so_far += written; + strm.next_out = obuf; + strm.avail_out = sizeof(obuf); + } + continue; + case ADC_STREAM_END: + default: + written = sizeof(obuf) - strm.avail_out; + if (written) { + if ((cli_writen(fd, obuf, written))!=written) { + cli_errmsg("dmg_stripe_adc: failed write to output file\n"); + adc_decompressEnd(&strm); + return CL_EWRITE; + } + size_so_far += written; + strm.next_out = obuf; + strm.avail_out = sizeof(obuf); + } + if (adcret == Z_STREAM_END) + break; + cli_dbgmsg("dmg_stripe_adc: after writing " STDu64 " bytes, " + "got error %d decompressing stripe " STDu32 "\n", + size_so_far, adcret, index); + adc_decompressEnd(&strm); + return CL_EFORMAT; + } + break; + } + + adc_decompressEnd(&strm); + cli_dbgmsg("dmg_stripe_adc: stripe " STDu32 " actual len " STDu64 " expected len " STDu64 "\n", + index, size_so_far, expected_len); + return CL_CLEAN; } /* Stripe handling: deflate block (type 0x80000005) */ From 2ab4983cc2a9152fcf5ab120f581d05d665f59ca Mon Sep 17 00:00:00 2001 From: David Raynor Date: Thu, 3 Oct 2013 10:51:25 -0400 Subject: [PATCH 02/12] bb #1570: ChangeLog for ADC --- ChangeLog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ChangeLog b/ChangeLog index d782c62a8..47320ecf7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Thu Oct 3 10:49:11 2013 EDT 2013 (dar) +------------------------------------ + * bb #1570: Support ADC compression in DMG + Wed Oct 2 11:22:40 2013 EDT 2013 (dar) ------------------------------------ * bb #9053: ClamAV 0.98 can't be compiled on FreeBSD 7 From 04a1774a246dfe185c3b220067fb4a0a0137230e Mon Sep 17 00:00:00 2001 From: David Raynor Date: Thu, 3 Oct 2013 11:38:23 -0400 Subject: [PATCH 03/12] bb #9087: fix endian-ness of file mode check --- libclamav/hfsplus.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/libclamav/hfsplus.c b/libclamav/hfsplus.c index d162b766b..299803688 100644 --- a/libclamav/hfsplus.c +++ b/libclamav/hfsplus.c @@ -651,6 +651,8 @@ static int hfsplus_walk_catalog(cli_ctx *ctx, hfsPlusVolumeHeader *volHeader, hf } memcpy(&fileRec, &(nodeBuf[recordStart+keylen+2]), sizeof(hfsPlusCatalogFile)); + /* Only scan files */ + fileRec.permissions.fileMode = be16_to_host(fileRec.permissions.fileMode); if ((fileRec.permissions.fileMode & HFS_MODE_TYPEMASK) == HFS_MODE_FILE) { /* Convert forks and scan */ forkdata_to_host(&(fileRec.dataFork)); @@ -658,36 +660,41 @@ static int hfsplus_walk_catalog(cli_ctx *ctx, hfsPlusVolumeHeader *volHeader, hf if (fileRec.dataFork.logicalSize) { ret = hfsplus_scanfile(ctx, volHeader, extHeader, &(fileRec.dataFork), dirname); } + /* Check return code */ + if (ret == CL_VIRUS) { + has_alerts = 1; + if (SCAN_ALL) { + /* Continue scanning in SCAN_ALL mode */ + cli_dbgmsg("hfsplus_walk_catalog: data fork alert, continuing", ret); + ret = CL_CLEAN; + } + } if (ret != CL_CLEAN) { cli_dbgmsg("hfsplus_walk_catalog: data fork retcode %d", ret); - if (ret == CL_VIRUS) { - has_alerts = 1; - if (SCAN_ALL) { - /* Continue scanning in SCAN_ALL mode */ - ret = CL_CLEAN; - } - } break; } + /* Scan resource fork */ forkdata_to_host(&(fileRec.resourceFork)); forkdata_print("resource fork:", &(fileRec.resourceFork)); if (fileRec.resourceFork.logicalSize) { ret = hfsplus_scanfile(ctx, volHeader, extHeader, &(fileRec.resourceFork), dirname); } + /* Check return code */ + if (ret == CL_VIRUS) { + has_alerts = 1; + if (SCAN_ALL) { + /* Continue scanning in SCAN_ALL mode */ + cli_dbgmsg("hfsplus_walk_catalog: resource fork alert, continuing", ret); + ret = CL_CLEAN; + } + } if (ret != CL_CLEAN) { cli_dbgmsg("hfsplus_walk_catalog: resource fork retcode %d", ret); - if (ret == CL_VIRUS) { - has_alerts = 1; - if (SCAN_ALL) { - /* Continue scanning in SCAN_ALL mode */ - ret = CL_CLEAN; - } - } break; } } else { - cli_dbgmsg("hfsplus_walk_catalog: record mode is not File\n"); + cli_dbgmsg("hfsplus_walk_catalog: record mode %o is not File\n", fileRec.permissions.fileMode); } } /* if return code, exit loop, message already logged */ From 6b913417c0c899855e919ba6e38d1c6fcd35b976 Mon Sep 17 00:00:00 2001 From: David Raynor Date: Thu, 3 Oct 2013 13:23:18 -0400 Subject: [PATCH 04/12] bb #1570: add ADC files to win32 project --- win32/libclamav.vcxproj | 3 ++- win32/libclamav.vcxproj.filters | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/win32/libclamav.vcxproj b/win32/libclamav.vcxproj index 024cf742c..ed2445bc4 100644 --- a/win32/libclamav.vcxproj +++ b/win32/libclamav.vcxproj @@ -282,6 +282,7 @@ + @@ -470,4 +471,4 @@ - \ No newline at end of file + diff --git a/win32/libclamav.vcxproj.filters b/win32/libclamav.vcxproj.filters index 23e35fc55..c030cf66d 100644 --- a/win32/libclamav.vcxproj.filters +++ b/win32/libclamav.vcxproj.filters @@ -51,6 +51,9 @@ Source Files + + Source Files + Source Files @@ -841,4 +844,4 @@ Source Files\libxml2 - \ No newline at end of file + From 85999c7e5ff702be9e0c983bf3f5307426031d44 Mon Sep 17 00:00:00 2001 From: David Raynor Date: Thu, 3 Oct 2013 15:05:40 -0400 Subject: [PATCH 05/12] bb #1570: replacing void * type in ADC, fewer casts --- libclamav/adc.c | 20 ++++++++++---------- libclamav/adc.h | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libclamav/adc.c b/libclamav/adc.c index 915704076..06290db84 100644 --- a/libclamav/adc.c +++ b/libclamav/adc.c @@ -52,7 +52,7 @@ int adc_decompressInit(adc_stream *strm) } /* Have to buffer maximum backward lookup */ - strm->buffer = calloc(ADC_BUFF_SIZE, 1); + strm->buffer = (uint8_t *)calloc(ADC_BUFF_SIZE, 1); if (strm->buffer == NULL) { return ADC_MEM_ERROR; } @@ -110,7 +110,7 @@ int adc_decompress(adc_stream *strm) switch (strm->state) { case ADC_STATE_GETTYPE: { /* Grab action code */ - bData = *(uint8_t *)(strm->next_in); + bData = *(strm->next_in); strm->next_in++; strm->avail_in--; if (bData & 0x80) { @@ -134,7 +134,7 @@ int adc_decompress(adc_stream *strm) } case ADC_STATE_LONGOP2: { /* Grab first offset byte */ - bData = *(uint8_t *)(strm->next_in); + bData = *(strm->next_in); strm->next_in++; strm->avail_in--; strm->offset = bData * 0x100; @@ -145,7 +145,7 @@ int adc_decompress(adc_stream *strm) } case ADC_STATE_LONGOP1: { /* Grab second offset byte */ - bData = *(uint8_t *)(strm->next_in); + bData = *(strm->next_in); strm->next_in++; strm->avail_in--; strm->offset += bData + 1; @@ -156,7 +156,7 @@ int adc_decompress(adc_stream *strm) } case ADC_STATE_SHORTOP: { /* Grab offset byte */ - bData = *(uint8_t *)(strm->next_in); + bData = *(strm->next_in); strm->next_in++; strm->avail_in--; strm->offset += bData + 1; @@ -170,18 +170,18 @@ int adc_decompress(adc_stream *strm) /* Grab data */ adc_dbgmsg("adc_decompress: RAWDATA offset %u length %u\n", strm->offset, strm->length); while ((strm->avail_in > 0) && (strm->avail_out > 0) && (strm->length > 0)) { - bData = *(uint8_t *)(strm->next_in); + bData = *(strm->next_in); strm->next_in++; strm->avail_in--; /* store to output */ - *(uint8_t *)(strm->next_out) = bData; + *(strm->next_out) = bData; strm->next_out++; strm->avail_out--; /* store to buffer */ if (strm->curr >= (strm->buffer + ADC_BUFF_SIZE)) { strm->curr = strm->buffer; } - *(uint8_t *)strm->curr = bData; + *(strm->curr) = bData; strm->curr++; if (strm->buffered < ADC_BUFF_SIZE) { strm->buffered++; @@ -226,11 +226,11 @@ int adc_decompress(adc_stream *strm) bData = *(uint8_t *)(strm->curr + ADC_BUFF_SIZE - strm->offset); } /* store to output */ - *(uint8_t *)(strm->next_out) = bData; + *(strm->next_out) = bData; strm->next_out++; strm->avail_out--; /* store to buffer */ - *(uint8_t *)strm->curr = bData; + *(strm->curr) = bData; strm->curr++; if (strm->buffered < ADC_BUFF_SIZE) { strm->buffered++; diff --git a/libclamav/adc.h b/libclamav/adc.h index 2a0eda104..f63b74a8f 100644 --- a/libclamav/adc.h +++ b/libclamav/adc.h @@ -4,11 +4,11 @@ #define CLAM_ADC_H struct adc_stream { - void *next_in; + uint8_t *next_in; size_t avail_in; size_t total_in; - void *next_out; + uint8_t *next_out; size_t avail_out; size_t total_out; From 68de67e121ae0b9d3e3f1d6e2db894fc651a000b Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Mon, 7 Oct 2013 06:58:55 -0700 Subject: [PATCH 06/12] one of the bad ass people corrected the clamd.conf PUA link to the github link --- etc/clamd.conf.sample | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/clamd.conf.sample b/etc/clamd.conf.sample index 9aab51ab2..ca6d85db1 100644 --- a/etc/clamd.conf.sample +++ b/etc/clamd.conf.sample @@ -222,8 +222,8 @@ Example #DetectPUA yes # Exclude a specific PUA category. This directive can be used multiple times. -# See http://www.clamav.net/support/pua for the complete list of PUA -# categories. +# See https://github.com/vrtadmin/clamav-faq/blob/master/faq/faq-pua.md for +# the complete list of PUA categories. # Default: Load all categories (if DetectPUA is activated) #ExcludePUA NetTool #ExcludePUA PWTool From 4f749dfa2d47bc183aba8b55e3e35325e099364b Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Mon, 7 Oct 2013 08:33:51 -0700 Subject: [PATCH 07/12] bb#6075&&bb#6079 - added rough draft of requested documentation to clamdoc.tex --- docs/clamdoc.tex | 146 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 136 insertions(+), 10 deletions(-) diff --git a/docs/clamdoc.tex b/docs/clamdoc.tex index 9609c2f6a..05a7a9c41 100644 --- a/docs/clamdoc.tex +++ b/docs/clamdoc.tex @@ -316,6 +316,7 @@ \begin{verbatim} $ ./configure --enable-milter \end{verbatim} + See section /ref{sec:clamavmilter} for more details on clamav-milter. \subsection{Running unit tests}\label{unit-testing} ClamAV includes unit tests that allow you to test that the compiled binaries work correctly on your platform. @@ -393,6 +394,12 @@ $ CK_FORK=no ./libtool --mode=execute valgrind unit_tests/check-clamav \section{Configuration} + \subsubsection{clamconf} + Before proceeding with the steps below, you should + run the 'clamconf' command, which gives important information + about your ClamAV configuration. See section \ref{sec:clamconf} + for more details. + \subsection{clamd} Before you start using the daemon you have to edit the configuration file (in other case \verb+clamd+ won't run): @@ -437,14 +444,31 @@ $ CK_FORK=no ./libtool --mode=execute valgrind unit_tests/check-clamav Now configure Clamuko in \verb+clamd.conf+ and read the \ref{clamuko} section. - \subsection{clamav-milter} + \subsection{clamav-milter}\label{sec:clamavmilter} ClamAV $\ge0.95$ includes a new, redesigned clamav-milter. The most notable difference is that the internal mode has been dropped and now a working clamd companion is required. The second important difference is that now - the milter has got its own configuration and log files. To compile ClamAV - with the clamav-milter just run \verb+./configure+ \verb+--enable-milter+ - and make as usual. Please consult your MTA's manual on how to connect it - with the milter. + the milter has got its own configuration and log files. + + To compile ClamAV with the clamav-milter just run \verb+./configure+ + \verb+--enable-milter+ and make as usual. In order to use the + '--enable-milter' option with 'configure', your system MUST have the milter + library installed. If you use the '--enable-milter' option without the + library being installed, you will most likely see output like this during + 'configure': + \begin{verbatim} + checking for libiconv_open in -liconv... no + checking for iconv... yes + checking whether in_port_t is defined... yes + checking for in_addr_t definition... yes + checking for mi_stop in -lmilter... no + checking for library containing strlcpy... no + checking for mi_stop in -lmilter... no + configure: error: Cannot find libmilter + \end{verbatim} + At which point the 'configure' script will stop processing. + \\\\ + Please consult your MTA's manual on how to connect ClamAV with the milter. \subsection{Testing} Try to scan recursively the source directory: @@ -704,6 +728,108 @@ N * * * * /usr/local/bin/freshclam --quiet more better and safe idea is to use the \textbf{samba-vscan} module. NFS is not supported because Dazuko doesn't intercept NFS access calls. + \subsection{Clamdtop} + \verb+clamdtop+ is a tool to monitor one or multiple instances of clamd. It + has a (color) ncurses interface, that shows the jobs in clamd's queue, + memory usage, and information about the loaded signature database. + You can specify on the command-line to which clamd(s) it should connect + to. By default it will attempt to connect to the local clamd as defined + in clamd.conf. + \\\\ + For more detailed help, type 'man clamdtop' or 'clamdtop --help'. + + \subsection{Clamscan} + \verb+clamscan+ is ClamAV's command line virus scanner. It can be used to + scan files and/or directories for viruses. In order for clamscan + to work proper, the ClamAV virus database files must be installed on + the system you are using clamscan on. + \\\\ + The general usage of clamscan is: clamscan [options] [file/directory/-] + \\\\ + For more detailed help, type 'man clamscan' or 'clamscan --help'. + + \subsection{ClamBC} + \verb+clambc+ is Clam Anti-Virus' bytecode testing tool. It can be + used to test files which contain bytecode. For more detailed help, + type 'man clambc' or 'clambc --help'. + + \subsection{Freshclam} + \verb+freshclam+ is ClamAV's virus database update tool and reads it's + configuration from the file 'freshclam.conf' (this may be + overriden by command line options). Here is a sample usage including cdiffs: + \begin{verbatim} + $ freshclam + + ClamAV update process started at Mon Oct 7 08:15:10 2013 + main.cld is up to date (version: 55, sigs: 2424225, f-level: 60, builder: neo) + Downloading daily-17945.cdiff [100%] + Downloading daily-17946.cdiff [100%] + Downloading daily-17947.cdiff [100%] + daily.cld updated (version: 17947, sigs: 406951, f-level: 63, builder: neo) + Downloading bytecode-227.cdiff [100%] + Downloading bytecode-228.cdiff [100%] + bytecode.cld updated (version: 228, sigs: 43, f-level: 63, builder: neo) + Database updated (2831219 signatures) from database.clamav.net (IP: 64.6.100.177) + \end{verbatim} + For more detailed help, type 'man clamscan' or 'clamscan --help'. + + \subsection{Clamconf}\label{sec:clamconf} + \verb+clamconf+ is the Clam Anti-Virus configuration utility. It is used + for displaying values of configurations options in ClamAV, which + will show the contents of clamd.conf (or tell you if it is not + properly configured), the contents of freshclam.conf, and display + information about software settings, database, platform, and build + information. Here is a sample clamconf output: + \begin{verbatim} + $ clamconf + + Checking configuration files in /etc/clamav + + Config file: clamd.conf + ----------------------- + ERROR: Please edit the example config file /etc/clamav/clamd.conf + + Config file: freshclam.conf + --------------------------- + ERROR: Please edit the example config file /etc/clamav/freshclam.conf + + clamav-milter.conf not found + + Software settings + ----------------- + Version: 0.97.6 + Optional features supported: MEMPOOL IPv6 CLAMUKO AUTOIT_EA06 BZIP2 RAR JIT + + Database information + -------------------- + Database directory: /usr/local/share/clamav + WARNING: freshclam.conf and clamd.conf point to different database directories + print_dbs: Can't open directory /usr/local/share/clamav + + Platform information + -------------------- + uname: Linux 2.6.32-279.el6.x86_64 #1 SMP Fri Jun 22 12:19:21 UTC 2012 x86_64 + OS: linux-gnu, ARCH: x86_64, CPU: x86_64 + Full OS version: ``CentOS release 6.3 (Final)'' + zlib version: 1.2.3 (1.2.3), compile flags: a9 + Triple: x86_64-unknown-linux-gnu + CPU: amdfam10, Little-endian + platform id: 0x0a2143430804040607040406 + + Build information + ----------------- + GNU C: 4.4.6 20120305 (Red Hat 4.4.6-4) (4.4.6) + GNU C++: 4.4.6 20120305 (Red Hat 4.4.6-4) (4.4.6) + CPPFLAGS: + CFLAGS: -g -O2 -fno-strict-aliasing + CXXFLAGS: + LDFLAGS: + Configure: '--enable-check' '--sysconfdir=/etc/clamav' + --enable-ltdl-convenience + sizeof(void*) = 8 + \end{verbatim} + For more detailed help, type 'man clamconf' or 'clamconf --help'. + \subsection{Output format} \subsubsection{clamscan} @@ -723,7 +849,7 @@ N * * * * /usr/local/bin/freshclam --quiet \verb+FOUND+ strings. In case of archives the scanner depends on libclamav and only prints the first virus found within an archive: \begin{verbatim} - zolw@localhost:/tmp$ clamscan malware.zip + $ clamscan malware.zip malware.zip: Worm.Mydoom.U FOUND \end{verbatim} When using the --allmatch(-z) flag, clamscan may print multiple virus @@ -732,7 +858,7 @@ N * * * * /usr/local/bin/freshclam --quiet \subsubsection{clamd} The output format of \verb+clamd+ is very similar to \verb+clamscan+. \begin{verbatim} - zolw@localhost:~$ telnet localhost 3310 + $ telnet localhost 3310 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. @@ -1115,9 +1241,9 @@ const char *cl_engine_get_str(const struct cl_engine *engine, \subsubsection{clamav-config} Use \verb+clamav-config+ to check compilation information for libclamav. \begin{verbatim} - zolw@localhost:~$ clamav-config --libs + $ clamav-config --libs -L/usr/local/lib -lz -lbz2 -lgmp -lpthread - zolw@localhost:~$ clamav-config --cflags + $ clamav-config --cflags -I/usr/local/include -g -O2 \end{verbatim} @@ -1139,7 +1265,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec) \end{verbatim} \verb+sigtool --info+ displays detailed information on CVD files: \begin{verbatim} -zolw@localhost:/usr/local/share/clamav$ sigtool -i daily.cvd +$ sigtool -i daily.cvd File: daily.cvd Build time: 10 Mar 2008 10:45 +0000 Version: 6191 From 25c3b1b2f6b6d94b34d823d2c520c856c1d8295e Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Mon, 7 Oct 2013 08:44:40 -0700 Subject: [PATCH 08/12] bb#6212 - added rough draft pf requested documentation to clamdoc.tex --- docs/clamdoc.tex | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/docs/clamdoc.tex b/docs/clamdoc.tex index 05a7a9c41..259988b7f 100644 --- a/docs/clamdoc.tex +++ b/docs/clamdoc.tex @@ -392,6 +392,28 @@ $ CK_FORK=no ./libtool --mode=execute valgrind unit_tests/check-clamav \end{verbatim} \end{itemize} + \subsection{Obtain Latest ClamAV anti-virus signature databases} + Before you can run ClamAV in daemon mode (clamd), 'clamdscan', + or 'clamscan' which is ClamAV's command line virus scanner, + you must have ClamAV Virus Database (.cvd) file(s) installed + in the appropriate location on your system. The default + location for these database files are /usr/local/share/clamav + (in Linux/Unix). + \\\\ + Here is a listing of currently available ClamAV Virus Database Files: + \\\\ + bytecode.cvd (signatures to detect bytecode in files) + main.cvd (main ClamAV virus database file) + daily.cvd (daily update file for ClamAV virus databases) + safebrowsing.cvd (virus signatures for safe browsing) + \\\\ + These files can be downloaded via HTTP from the main ClamAV website + or via the 'freshclam' utility on a periodic basis. Using 'freshclam' + is the preferred method of keeping the ClamAV virus database files + up to date without manual intervention (see section \ref{conf:freshclam} for + information on how to configure 'freshclam' for automatic updating and section + \ref{sec:freshclam} for additional details on freshclam). + \section{Configuration} \subsubsection{clamconf} @@ -486,7 +508,7 @@ $ CK_FORK=no ./libtool --mode=execute valgrind unit_tests/check-clamav Please note that the scanned files must be accessible by the user running \verb+clamd+ or you will get an error. - \subsection{Setting up auto-updating} + \subsection{Setting up auto-updating}\label{conf:freshclam} \verb+freshclam+ is the automatic database update tool for Clam AntiVirus. It can work in two modes: \begin{itemize} @@ -753,7 +775,7 @@ N * * * * /usr/local/bin/freshclam --quiet used to test files which contain bytecode. For more detailed help, type 'man clambc' or 'clambc --help'. - \subsection{Freshclam} + \subsection{Freshclam}\ref{sec:freshclam} \verb+freshclam+ is ClamAV's virus database update tool and reads it's configuration from the file 'freshclam.conf' (this may be overriden by command line options). Here is a sample usage including cdiffs: @@ -949,8 +971,14 @@ N * * * * /usr/local/bin/freshclam --quiet decoding and normalization is only performed for HTML files. \subsubsection{Data Loss Prevention} - Libclamav includes a DLP module which can detect credit card and - social security numbers inside text files. + Libclamav includes a DLP module which can detect the following + credit card issuers: AMEX, VISA, MasterCard, Discover, Diner's Club, + and JCB and U.S. social security numbers inside text files. + \\\\ + Future versions of Libclamav may include additional features to + detect other credit cards and other forms of PII (Personally + Identifiable Information) which may be transmitted without the + benefit of being encrypted. \subsubsection{Others} Libclamav can handle various obfuscators, encoders, files vulnerable to From acb4a926707c9dcf531801f071106eea5e116bb3 Mon Sep 17 00:00:00 2001 From: Kevin Lin Date: Mon, 7 Oct 2013 08:58:42 -0700 Subject: [PATCH 09/12] bb#6451 - added documentation on CL_INIT_DEFAULT --- docs/html/node45.html | 3 +++ docs/html/node46.html | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/html/node45.html b/docs/html/node45.html index bb0822cf1..2ebfee34f 100644 --- a/docs/html/node45.html +++ b/docs/html/node45.html @@ -64,6 +64,9 @@ Initialization struct cl_engine *cl_engine_new(void); int cl_engine_free(struct cl_engine *engine); + At this time, cl_init() only supports the CL_INIT_DEFAULT option + which intializes libclamav with the default settings. + cl_init() and cl_engine_free() return CL_SUCCESS on success or another code on error. cl_engine_new() return a pointer or NULL if there's not enough memory to allocate a new diff --git a/docs/html/node46.html b/docs/html/node46.html index 393be2402..8a9435975 100644 --- a/docs/html/node46.html +++ b/docs/html/node46.html @@ -108,7 +108,7 @@ Load bytecode. unsigned int sigs = 0; int ret; - if((ret = cl_init()) != CL_SUCCESS) { + if((ret = cl_init(CL_INIT_DEFAULT)) != CL_SUCCESS) { printf("cl_init() error: %s\n", cl_strerror(ret)); return 1; } From 1fa9f195c2956d60ea45780ee5d681c0a4c20820 Mon Sep 17 00:00:00 2001 From: David Raynor Date: Mon, 7 Oct 2013 13:27:18 -0400 Subject: [PATCH 10/12] bb #9087: fix logging statements --- libclamav/hfsplus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libclamav/hfsplus.c b/libclamav/hfsplus.c index 299803688..7dc74362b 100644 --- a/libclamav/hfsplus.c +++ b/libclamav/hfsplus.c @@ -665,7 +665,7 @@ static int hfsplus_walk_catalog(cli_ctx *ctx, hfsPlusVolumeHeader *volHeader, hf has_alerts = 1; if (SCAN_ALL) { /* Continue scanning in SCAN_ALL mode */ - cli_dbgmsg("hfsplus_walk_catalog: data fork alert, continuing", ret); + cli_dbgmsg("hfsplus_walk_catalog: data fork alert, continuing"); ret = CL_CLEAN; } } @@ -684,7 +684,7 @@ static int hfsplus_walk_catalog(cli_ctx *ctx, hfsPlusVolumeHeader *volHeader, hf has_alerts = 1; if (SCAN_ALL) { /* Continue scanning in SCAN_ALL mode */ - cli_dbgmsg("hfsplus_walk_catalog: resource fork alert, continuing", ret); + cli_dbgmsg("hfsplus_walk_catalog: resource fork alert, continuing"); ret = CL_CLEAN; } } From f526f0b2c31aed813e18c8501d7a4a172080d807 Mon Sep 17 00:00:00 2001 From: David Raynor Date: Mon, 7 Oct 2013 13:44:19 -0400 Subject: [PATCH 11/12] mpool: move map allocation after error checks --- libclamav/mpool.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libclamav/mpool.c b/libclamav/mpool.c index 18b58b68b..b0ed837b4 100644 --- a/libclamav/mpool.c +++ b/libclamav/mpool.c @@ -452,12 +452,6 @@ struct MP *mpool_create() { sz = align_to_pagesize(&mp, MIN_FRAGSIZE); mp.u.mpm.usize = sizeof(struct MPMAP); mp.u.mpm.size = sz - sizeof(mp); -#ifndef _WIN32 - if ((mpool_p = (struct MP *)mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE|ANONYMOUS_MAP, -1, 0)) == MAP_FAILED) -#else - if(!(mpool_p = (struct MP *)VirtualAlloc(NULL, sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) -#endif - return NULL; if (FRAGSBITS > 255) { cli_errmsg("At most 255 frags possible!\n"); return NULL; @@ -466,6 +460,12 @@ struct MP *mpool_create() { cli_errmsg("fragsz[0] too small!\n"); return NULL; } +#ifndef _WIN32 + if ((mpool_p = (struct MP *)mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE|ANONYMOUS_MAP, -1, 0)) == MAP_FAILED) +#else + if(!(mpool_p = (struct MP *)VirtualAlloc(NULL, sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE))) +#endif + return NULL; #ifdef CL_DEBUG memset(mpool_p, ALLOCPOISON, sz); #endif From 6533215248b33aba2a2926e2321ada66bb144ffd Mon Sep 17 00:00:00 2001 From: Shawn Webb Date: Tue, 8 Oct 2013 13:16:14 -0400 Subject: [PATCH 12/12] bb#7861 - Improve error message for missing files --- libclamav/readdb.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 8e3764e95..a5ad07308 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -2909,7 +2909,36 @@ int cl_load(const char *path, struct cl_engine *engine, unsigned int *signo, uns } if(CLAMSTAT(path, &sb) == -1) { - cli_errmsg("cl_load(): Can't get status of %s\n", path); + switch (errno) { +#if defined(EACCES) + case EACCES: + cli_errmsg("cl_load(): Access denied for path: %s\n", path); + break; +#endif +#if defined(ENOENT) + case ENOENT: + cli_errmsg("cl_load(): No such file or directory: %s\n", path); + break; +#endif +#if defined(ELOOP) + case ELOOP: + cli_errmsg("cl_load(): Too many symbolic links encountered in path: %s\n", path); + break; +#endif +#if defined(EOVERFLOW) + case EOVERFLOW: + cli_errmsg("cl_load(): File size is too large to be recognized. Path: %s\n", path); + break; +#endif +#if defined(EIO) + case EIO: + cli_errmsg("cl_load(): An I/O error occurred while reading from path: %s\n", path); + break; +#endif + default: + cli_errmsg("cl_load: Can't get status of: %s\n", path); + break; + } return CL_ESTAT; }