From bbd6ca3fbb1336e303e5b622ccc1e0908901cf8c Mon Sep 17 00:00:00 2001 From: aCaB Date: Mon, 11 Feb 2008 13:18:41 +0000 Subject: [PATCH] more limits and ole2 collision fixup git-svn-id: file:///var/lib/svn/clamav-devel/branches/newlimits@3608 77e5149b-7576-45b1-b177-96237e5ba77b --- libclamav/nsis/nulsft.c | 25 ++++++++++--------------- libclamav/ole2_extract.c | 8 +++++--- libclamav/ole2_extract.h | 4 ++-- libclamav/scanners.c | 15 ++++++++++----- libclamav/vba_extract.c | 14 +++++++++----- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/libclamav/nsis/nulsft.c b/libclamav/nsis/nulsft.c index d4a2af57b..0a02fb17b 100644 --- a/libclamav/nsis/nulsft.c +++ b/libclamav/nsis/nulsft.c @@ -163,7 +163,6 @@ static int nsis_decomp(struct nsis_st *n) { break; case Z_STREAM_END: ret = CL_BREAK; - /* FIXME: regression needed */ } n->nsis.avail_in = n->z.avail_in; n->nsis.next_in = n->z.next_in; @@ -184,10 +183,9 @@ static int nsis_unpack_next(struct nsis_st *n, cli_ctx *ctx) { cli_dbgmsg("NSIS: extraction complete\n"); return CL_BREAK; } - if (ctx->limits && ctx->limits->maxfiles && n->fno >= ctx->limits->maxfiles) { - cli_dbgmsg("NSIS: Files limit reached (max: %u)\n", ctx->limits->maxfiles); - return CL_EMAXFILES; - } + + if ((ret=cli_checklimits("NSIS", ctx 0, 0, 0))!=CL_CLEAN) + return ret; if (n->fno) snprintf(n->ofn, 1023, "%s/content.%.3u", n->dir, n->fno); @@ -225,11 +223,10 @@ static int nsis_unpack_next(struct nsis_st *n, cli_ctx *ctx) { n->asz -= size+4; - if (ctx->limits && ctx->limits->maxfilesize && size > ctx->limits->maxfilesize) { - cli_dbgmsg("NSIS: Skipping file due to size limit (%u, max: %lu)\n", size, ctx->limits->maxfilesize); + if ((ret=cli_checklimits("NSIS", ctx, size, 0, 0)!=CL_CLEAN) { close(n->ofd); if (lseek(n->ifd, size, SEEK_CUR)==-1) return CL_EIO; - return CL_EMAXSIZE; + return ret; } if (!(ibuf= (unsigned char *) cli_malloc(size))) { cli_dbgmsg("NSIS: out of memory"__AT__"\n"); @@ -274,12 +271,11 @@ static int nsis_unpack_next(struct nsis_st *n, cli_ctx *ctx) { n->nsis.next_out = obuf; n->nsis.avail_out = BUFSIZ; loops=0; - if (ctx->limits && ctx->limits->maxfilesize && size > ctx->limits->maxfilesize) { - cli_dbgmsg("NSIS: Skipping file due to size limit (%u, max: %lu)\n", size, ctx->limits->maxfilesize); + if ((ret=cli_checklimits("NSIS", ctx, size, 0, 0))!=CL_CLEAN) { free(ibuf); close(n->ofd); nsis_shutdown(n); - return CL_EMAXSIZE; + return ret; } } else if (++loops > 10) { cli_dbgmsg("NSIS: xs looping, breaking out"__AT__"\n"); @@ -367,10 +363,9 @@ static int nsis_unpack_next(struct nsis_st *n, cli_ctx *ctx) { } size=cli_readint32(obuf); - if (ctx->limits && ctx->limits->maxfilesize && size > ctx->limits->maxfilesize) { - cli_dbgmsg("NSIS: Breaking out due to filesize limit (%u, max: %lu) in solid archive\n", size, ctx->limits->maxfilesize); + if ((ret=cli_checklimits("NSIS", ctx, size, 0, 0))!=CL_CLEAN) { close(n->ofd); - return CL_EFORMAT; + return ret; } n->nsis.next_out = obuf; @@ -536,7 +531,7 @@ int cli_scannulsft(int desc, cli_ctx *ctx, off_t offset) { } } while(ret == CL_SUCCESS); - if(ret == CL_BREAK) + if(ret == CL_BREAK || ret == CL_EMAXFILES) ret = CL_CLEAN; cli_nsis_free(&nsist); diff --git a/libclamav/ole2_extract.c b/libclamav/ole2_extract.c index e3969661c..02c2b5ef7 100644 --- a/libclamav/ole2_extract.c +++ b/libclamav/ole2_extract.c @@ -475,7 +475,9 @@ static void ole2_walk_property_tree(int fd, ole2_header_t *hdr, const char *dir, if ((prop_index < 0) || (prop_index > (int32_t) hdr->max_block_no) || (rec_level > 100) || (*file_count > 100000)) { return; } - /* FIXMELIMITS */ + /* FIXMELIMITS + * DOES recursion on virtual object make sense ? + * WHY no size checking ? */ if (limits && limits->maxfiles && (*file_count > limits->maxfiles)) { cli_dbgmsg("OLE2: File limit reached (max: %d)\n", limits->maxfiles); return; @@ -778,7 +780,7 @@ static int ole2_read_header(int fd, ole2_header_t *hdr) } #endif -int cli_ole2_extract(int fd, const char *dirname, const struct cl_limits *limits) +int cli_ole2_extract(int fd, const char *dirname, cli_ctx *ctx) { ole2_header_t hdr; int hdr_size; @@ -878,7 +880,7 @@ int cli_ole2_extract(int fd, const char *dirname, const struct cl_limits *limits /* OR */ - ole2_walk_property_tree(fd, &hdr, dirname, 0, handler_writefile, 0, &file_count, limits); + ole2_walk_property_tree(fd, &hdr, dirname, 0, handler_writefile, 0, &file_count, ctx->limits); abort: #ifdef HAVE_MMAP diff --git a/libclamav/ole2_extract.h b/libclamav/ole2_extract.h index 9542a4619..8dfbce961 100644 --- a/libclamav/ole2_extract.h +++ b/libclamav/ole2_extract.h @@ -24,8 +24,8 @@ #ifndef __OLE2_EXTRACT_H #define __OLE2_EXTRACT_H -#include "clamav.h" +#include "others.h" -int cli_ole2_extract(int fd, const char *dirname, const struct cl_limits *limits); +int cli_ole2_extract(int fd, const char *dirname, cli_ctx *ctx); #endif diff --git a/libclamav/scanners.c b/libclamav/scanners.c index 86509d5dc..3871d61a6 100644 --- a/libclamav/scanners.c +++ b/libclamav/scanners.c @@ -102,9 +102,6 @@ #include #endif -#define MAX_MAIL_RECURSION 15 - - static int cli_scanfile(const char *filename, cli_ctx *ctx); #ifdef ENABLE_UNRAR @@ -1077,6 +1074,9 @@ static int cli_scanole2(int desc, cli_ctx *ctx) cli_dbgmsg("in cli_scanole2()\n"); + if(ctx->limits && ctx->limits->maxreclevel && ctx->recursion >= ctx->limits->maxreclevel) + return CL_EMAXREC; + /* generate the temporary directory */ dir = cli_gentemp(NULL); if(mkdir(dir, 0700)) { @@ -1085,20 +1085,25 @@ static int cli_scanole2(int desc, cli_ctx *ctx) return CL_ETMPDIR; } - if((ret = cli_ole2_extract(desc, dir, ctx->limits))) { + if((ret = cli_ole2_extract(desc, dir, ctx))) { cli_dbgmsg("OLE2: %s\n", cl_strerror(ret)); if(!cli_leavetemps_flag) cli_rmdirs(dir); free(dir); + ctx->recursion--; return ret; } + ctx->recursion++; + if((ret = cli_vba_scandir(dir, ctx)) != CL_VIRUS) { if(cli_scandir(dir, ctx) == CL_VIRUS) { ret = CL_VIRUS; } } + ctx->recursion--; + if(!cli_leavetemps_flag) cli_rmdirs(dir); free(dir); @@ -1758,7 +1763,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) break; case CL_TYPE_NULSFT: - if(SCAN_ARCHIVE) + if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_NSIS)) ret = cli_scannulsft(desc, ctx, 0); break; diff --git a/libclamav/vba_extract.c b/libclamav/vba_extract.c index 27c647c5e..0c1188dc6 100644 --- a/libclamav/vba_extract.c +++ b/libclamav/vba_extract.c @@ -590,7 +590,7 @@ cli_decode_ole_object(int fd, const char *dir) int ofd; uint32_t object_size; struct stat statbuf; - char fullname[NAME_MAX + 1]; + char *fullname; if(dir == NULL) return -1; @@ -629,15 +629,19 @@ cli_decode_ole_object(int fd, const char *dir) if(!read_uint32(fd, &object_size, FALSE)) return -1; } - snprintf(fullname, sizeof(fullname) - 1, "%s/_clam_ole_object", dir); + if(!(fullname = cli_gentemp(dir))) { + return -1; + } ofd = open(fullname, O_RDWR|O_CREAT|O_TRUNC|O_BINARY|O_EXCL, S_IWUSR|S_IRUSR); if (ofd < 0) { - cli_warnmsg("cli_decode_ole_object: can't create %s\n", - fullname); + cli_warnmsg("cli_decode_ole_object: can't create %s\n", fullname); + free(fullname); return -1; + } else { + cli_dbgmsg("cli_decode_ole_object: decoding to %s\n", fullname); } - + free(fullname); ole_copy_file_data(fd, ofd, object_size); lseek(ofd, 0, SEEK_SET); return ofd;