newlimits started

git-svn-id: file:///var/lib/svn/clamav-devel/branches/newlimits@3556 77e5149b-7576-45b1-b177-96237e5ba77b
remotes/push_mirror/metadata
aCaB 18 years ago
parent 36582be0a5
commit b80ae27752
  1. 30
      libclamav/autoit.c
  2. 10
      libclamav/msexpand.c
  3. 102
      libclamav/others.c
  4. 2
      libclamav/others.h
  5. 46
      libclamav/pdf.c

@ -181,7 +181,7 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) {
uint8_t b[300], comp;
uint8_t *buf = b;
uint32_t s, m4sum=0;
int i;
int i, ret;
unsigned int files=0;
char tempfile[1024];
struct UNP UNP;
@ -192,7 +192,7 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) {
for (i=0; i<16; i++)
m4sum += buf[i];
while(!ctx->limits || !ctx->limits->maxfiles || files < ctx->limits->maxfiles) {
while((ret=cli_checklimits("autoit", ctx, 0, 0, 0))==CL_CONTINUE) {
buf = b;
if (cli_readn(desc, buf, 8)!=8)
return CL_CLEAN;
@ -250,8 +250,9 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) {
cli_dbgmsg("autoit: advertised uncompressed size %x\n", cli_readint32((char *)buf+5) ^ 0x45aa);
cli_dbgmsg("autoit: ref chksum: %x\n", cli_readint32((char *)buf+9) ^ 0xc3d2);
if(ctx->limits && ctx->limits->maxfilesize && UNP.csize > ctx->limits->maxfilesize) {
cli_dbgmsg("autoit: skipping file due to size limit (%u, max: %lu)\n", UNP.csize, ctx->limits->maxfilesize);
if((ret=cli_checklimits("autoit", ctx, UNP.csize, 0, 0))!=CL_CONTINUE) {
if(ret==CL_VIRUS) return ret;
lseek(desc, UNP.csize, SEEK_CUR);
continue;
}
@ -275,9 +276,9 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) {
if(!(UNP.usize = be32_to_host(*(uint32_t *)(buf+4))))
UNP.usize = UNP.csize; /* only a specifically crafted or badly corrupted sample should land here */
if(ctx->limits && ctx->limits->maxfilesize && UNP.usize > ctx->limits->maxfilesize) {
cli_dbgmsg("autoit: skipping file due to size limit (%u, max: %lu)\n", UNP.csize, ctx->limits->maxfilesize);
if((ret=cli_checklimits("autoit", ctx, UNP.usize, 0, 0))!=CL_CONTINUE) {
free(buf);
if(ret==CL_VIRUS) return ret;
continue;
}
@ -382,8 +383,7 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) {
close(i);
if(!cli_leavetemps_flag) unlink(tempfile);
}
cli_dbgmsg("autoit: files limit reached (max: %u)\n", ctx->limits->maxfiles);
return CL_EMAXFILES;
return ret;
}
@ -478,7 +478,7 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) {
uint8_t b[600], comp, script;
uint8_t *buf;
uint32_t s;
int i;
int i, ret;
unsigned int files=0;
char tempfile[1024];
const char prefixes[] = { '\0', '\0', '@', '$', '\0', '.', '"', '#' };
@ -492,7 +492,7 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) {
/* buf+=0x10; */
lseek(desc, 16, SEEK_CUR); /* for now we just skip the garbage */
while(!ctx->limits || !ctx->limits->maxfiles || files < ctx->limits->maxfiles) {
while((ret=cli_checklimits("cli_autoit", ctx, 0, 0, 0))==CL_CONTINUE) {
buf = b;
if (cli_readn(desc, buf, 8)!=8)
return CL_CLEAN;
@ -555,8 +555,8 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) {
cli_dbgmsg("autoit: advertised uncompressed size %x\n", cli_readint32((char *)buf+5) ^ 0x87bc);
cli_dbgmsg("autoit: ref chksum: %x\n", cli_readint32((char *)buf+9) ^ 0xa685);
if(ctx->limits && ctx->limits->maxfilesize && UNP.csize > ctx->limits->maxfilesize) {
cli_dbgmsg("autoit: skipping file due to size limit (%u, max: %lu)\n", UNP.csize, ctx->limits->maxfilesize);
if((ret=cli_checklimits("autoit", ctx, UNP.csize, 0, 0))!=CL_CONTINUE) {
if(ret==CL_VIRUS) return ret;
lseek(desc, UNP.csize, SEEK_CUR);
continue;
}
@ -581,8 +581,9 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) {
if(!(UNP.usize = be32_to_host(*(uint32_t *)(buf+4))))
UNP.usize = UNP.csize; /* only a specifically crafted or badly corrupted sample should land here */
if(ctx->limits && ctx->limits->maxfilesize && UNP.usize > ctx->limits->maxfilesize) {
if((ret=cli_checklimits("autoit", ctx, UNP.usize, 0, 0))!=CL_CONTINUE) {
free(buf);
if(ret==CL_VIRUS) return ret;
continue;
}
if (!(UNP.outputbuf = cli_malloc(UNP.usize))) {
@ -893,8 +894,7 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) {
close(i);
if(!cli_leavetemps_flag) unlink(tempfile);
}
cli_dbgmsg("autoit: Files limit reached (max: %u)\n", ctx->limits->maxfiles);
return CL_EMAXFILES;
return ret;
}
#endif /* FPU_WORDS_BIGENDIAN */

@ -108,13 +108,9 @@ int cli_msexpand(int fd, int ofd, cli_ctx *ctx)
cli_dbgmsg("MSEXPAND: File size from header: %u\n", hdr.fsize);
if(ctx->limits && ctx->limits->maxfilesize && (hdr.fsize > ctx->limits->maxfilesize)) {
cli_dbgmsg("MSEXPAND: Size exceeded (%u, max: %lu)\n", hdr.fsize, ctx->limits->maxfilesize);
if(BLOCKMAX) {
*ctx->virname = "MSEXPAND.ExceededFileSize";
return CL_VIRUS;
}
hdr.fsize = ctx->limits->maxfilesize;
if((ret=cli_checklimits("MSEXPAND", ctx, hdr.fsize, 0, 0))!=CL_CONTINUE) {
if(ret==CL_VIRUS) return ret;
hdr.fsize = (ctx->limits->maxfilesize > ctx->limits->maxscansize-ctx->scansize) ? ctx->limits->maxscansize-ctx->scansize : ctx->limits->maxfilesize;
cli_dbgmsg("MSEXPAND: Only extracting first %u bytes\n", hdr.fsize); /* may extract up to 2kB more */
}

@ -196,63 +196,65 @@ const char *cl_strerror(int clerror)
}
}
int cli_sizelimits(cli_ctx *ctx, unsigned long need1, unsigned long need2, unsigned long need3) {
int ret = CL_SUCCESS;
unsigned long needed;
/* if called without limits, go on, unpack, scan */
if(!ctx || !ctx->limits) return CL_SUCCESS;
needed = (need1>need2)?need1:need2;
needed = (needed>need3)?needed:need3;
/* if we have global scan limits */
if(ctx->limits->maxscansize) {
/* if the remaining scansize is too small... */
if(ctx->limits->maxscansize-ctx->scansize<needed) {
cli_dbgmsg("cli_limits: scansize exceeded (initial: %u, remaining: %u, needed: %u)\n", ctx->limits->maxscansize, ctx->scansize, needed);
/* ... we return INFECTED only upon request */
if(BLOCKMAX) {
*ctx->virname = "Archive.ExceededScanSize";
return CL_VIRUS;
}
/* ... otherwise we tell the caller to skip this file */
ret = CL_BREAK;
} else {
/* if the remaining scanzise is big enough, we update it */
ctx->scansize+=needed;
int cli_checklimits(const char *who, cli_ctx *ctx, unsigned long need1, unsigned long need2, unsigned long need3) {
int ret = CL_SUCCESS;
unsigned long needed;
/* if called without limits, go on, unpack, scan */
if(!ctx || !ctx->limits) return CL_SUCCESS;
/* check if we have limits on the number of files */
/* FIMMELIMITS: this only makes sense in updatelimits */
if(ctx->limits->maxfiles && ctx->scanned>=ctx->limits->maxfiles) {
cli_dbgmsg("%s: files limit reached (max: %u)\n", who, ctx->maxfiles);
return CL_EMAXFILES;
}
}
/* if we have per-file size limits, and we are overlimit... */
if(ctx->limits->maxfilesize && ctx->limits->maxfilesize<needed) {
/* ... we return INFECTED only upon request */
if(BLOCKMAX) {
*ctx->virname = "Archive.ExceededFileSize";
return CL_VIRUS;
needed = (need1>need2)?need1:need2;
needed = (needed>need3)?needed:need3;
/* if we have global scan limits */
if(ctx->limits->maxscansize) {
/* if the remaining scansize is too small... */
if(ctx->limits->maxscansize-ctx->scansize<needed) {
cli_dbgmsg("%s: scansize exceeded (initial: %u, remaining: %u, needed: %u)\n", who, ctx->limits->maxscansize, ctx->scansize, needed);
/* ... we return INFECTED only upon request */
if(BLOCKMAX) {
*ctx->virname = "Archive.ExceededScanSize";
return CL_VIRUS;
}
/* ... otherwise we tell the caller to skip this file */
ret = CL_EMAXSIZE;
}
}
/* ... otherwise we tell the caller to skip this file */
ret = CL_BREAK;
}
return ret;
/* if we have per-file size limits, and we are overlimit... */
if(ctx->limits->maxfilesize && ctx->limits->maxfilesize<needed) {
cli_dbgmsg("%s: filesize exceeded (allowed: %u, needed: %u)\n", who, ctx->limits->maxfilesize, needed);
/* ... we return INFECTED only upon request */
if(BLOCKMAX) {
*ctx->virname = "Archive.ExceededFileSize";
return CL_VIRUS;
}
/* ... otherwise we tell the caller to skip this file */
ret = CL_EMAXSIZE;
}
return ret;
}
int cli_filelimits(cli_ctx *ctx) {
/* FIXME: inline in magic_scandesc? */
int cli_updatelimits(cli_ctx *ctx, unsigned long need) {
int ret;
/* if called without limits, go on, unpack, scan */
if(!ctx || !ctx->limits || !ctx->limits->maxfiles) return CL_SUCCESS;
if((ret=cli_checklimits(ctx, need, 0, 0))==CL_SUCCESS) {
/* update counter */
ctx->scanned++;
/* update the remaining scanzise */
ctx->scansize+=needed;
if(ctx->scansize > ctx->limits->maxscansize)
ctx->scansize = ctx->limits->maxscansize;
}
/* if we are within the limit */
if(ctx->limits->maxfiles > ctx->scanned) {
/* update counters and ack */
ctx->scanned++;
return CL_SUCCESS;
} else {
/* else tell the caller to quit */
return CL_BREAK;
}
return ret;
}
unsigned char *cli_md5digest(int desc)

@ -231,5 +231,7 @@ bitset_t *cli_bitset_init(void);
void cli_bitset_free(bitset_t *bs);
int cli_bitset_set(bitset_t *bs, unsigned long bit_offset);
int cli_bitset_test(bitset_t *bs, unsigned long bit_offset);
int cli_checklimits(const char *, cli_ctx *, unsigned long, unsigned long, unsigned long);
int cli_updatelimits(cli_ctx *, unsigned long);
#endif

@ -79,10 +79,9 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx)
char *buf; /* start of memory mapped area */
const char *p, *q, *trailerstart;
const char *xrefstart; /* cross reference table */
const struct cl_limits *limits;
/*size_t xreflength;*/
table_t *md5table;
int printed_predictor_message, printed_embedded_font_message, rc;
int printed_predictor_message, printed_embedded_font_message, rc, ret;
unsigned int files;
struct stat statb;
@ -192,7 +191,6 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx)
rc = CL_CLEAN;
files = 0;
limits = ctx->limits;
/*
* The body section consists of a sequence of indirect objects
@ -494,10 +492,10 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx)
free(md5digest);
cli_dbgmsg("cli_pdf: extracted file %u to %s\n", ++files,
fullname);
if(limits && limits->maxfiles && (files >= limits->maxfiles)) {
if((ret=cli_checklimits("cli_pdf", ctx, 0, 0, 0))!=CL_CONTINUE) {
/* Bug 698 */
cli_dbgmsg("cli_pdf: number of files exceeded %u\n", limits->maxfiles);
rc = CL_EMAXFILES;
rc = ret;
}
}
@ -541,7 +539,7 @@ try_flatedecode(unsigned char *buf, off_t real_len, off_t calculated_len, int fo
static int
flatedecode(unsigned char *buf, off_t len, int fout, const cli_ctx *ctx)
{
int zstat;
int zstat, ret;
off_t nbytes;
z_stream stream;
unsigned char output[BUFSIZ];
@ -611,17 +609,9 @@ flatedecode(unsigned char *buf, off_t len, int fout, const cli_ctx *ctx)
}
nbytes += written;
if(ctx->limits &&
ctx->limits->maxfilesize &&
(nbytes > (off_t) ctx->limits->maxfilesize)) {
cli_dbgmsg("cli_pdf: flatedecode size exceeded (%lu > %lu)\n",
(unsigned long)nbytes, (unsigned long)ctx->limits->maxfilesize);
if((ret=cli_checklimits("cli_pdf", ctx, nbytes, 0, 0))!=CL_CONTINUE) {
inflateEnd(&stream);
if(BLOCKMAX) {
*ctx->virname = "PDF.ExceededFileSize";
return CL_VIRUS;
}
return CL_CLEAN;
return ret;
}
stream.next_out = output;
stream.avail_out = sizeof(output);
@ -651,28 +641,6 @@ flatedecode(unsigned char *buf, off_t len, int fout, const cli_ctx *ctx)
}
}
/*
* On BSD systems total_in and total_out are "long long", so these
* numbers could (in theory) get truncated in the debug statement
*/
cli_dbgmsg("cli_pdf: flatedecode in=%lu out=%lu ratio %lu (max %u)\n",
(unsigned long)stream.total_in, (unsigned long)stream.total_out,
(unsigned long)(stream.total_out / stream.total_in),
ctx->limits ? ctx->limits->maxratio : 0);
if(ctx->limits &&
ctx->limits->maxratio &&
((stream.total_out / stream.total_in) > ctx->limits->maxratio)) {
cli_dbgmsg("cli_pdf: flatedecode Max ratio reached\n");
inflateEnd(&stream);
if(BLOCKMAX) {
*ctx->virname = "Oversized.PDF";
return CL_VIRUS;
}
return CL_CLEAN;
}
#ifdef SAVE_TMP
unlink(tmpfilename);
#endif

Loading…
Cancel
Save