more limits and ole2 collision fixup

git-svn-id: file:///var/lib/svn/clamav-devel/branches/newlimits@3608 77e5149b-7576-45b1-b177-96237e5ba77b
remotes/push_mirror/metadata
aCaB 18 years ago
parent ec32d1d8cb
commit bbd6ca3fbb
  1. 25
      libclamav/nsis/nulsft.c
  2. 8
      libclamav/ole2_extract.c
  3. 4
      libclamav/ole2_extract.h
  4. 15
      libclamav/scanners.c
  5. 14
      libclamav/vba_extract.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);

@ -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

@ -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

@ -102,9 +102,6 @@
#include <stddef.h>
#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;

@ -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;

Loading…
Cancel
Save