Merge branch 'master' of ssh://tkojm@git.clam.sourcefire.com/var/lib/git/clamav-devel

Conflicts:
	ChangeLog
0.96
Tomasz Kojm 16 years ago
commit 8adcd36671
  1. 5
      ChangeLog
  2. 70
      libclamav/ishield.c

@ -2,6 +2,11 @@ Wed Jul 15 12:20:04 CEST 2009 (tk)
----------------------------------
* clamd, clamav-milter: make pid files globally readable (bb#1642)
Wed Jul 15 12:33:22 CEST 2009 (acab)
------------------------------------
* libclamav/ishield.c: use mmap for big files, fix some leaks,
some portability fixes
Wed Jul 15 11:20:56 CEST 2009 (tk)
----------------------------------
* libclamav/filetypes.c: fix off-by-one error (bb#1639)

@ -32,7 +32,15 @@
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_MMAP
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#endif /* HAVE_MMAP */
#if HAVE_STRING_H
#include <string.h>
#endif
#include <limits.h>
#include <strings.h>
#include <zlib.h>
@ -45,6 +53,10 @@
#define O_BINARY 0
#endif
#ifndef LONG_MAX
#define LONG_MAX ((-1UL)>>1)
#endif
#ifndef HAVE_ATTRIB_PACKED
#define __attribute__(x)
#endif
@ -463,12 +475,20 @@ struct IS_HDR {
};
#define IS_FREE_HDR if(map) munmap(map, mp_hdrsz); else free(hdr);
#if HAVE_MMAP
#define IS_MAX_NOMAP_SZ 0x100000
#else
#define IS_MAX_NOMAP_SZ CLI_MAX_ALLOCATION
#endif
/* Process data1.hdr and extracts all the available files from dataX.cab */
static int is_parse_hdr(int desc, cli_ctx *ctx, struct IS_CABSTUFF *c) {
uint32_t h1_data_off, objs_files_cnt, objs_dirs_off;
unsigned int off, i, scanned = 0;
int ret = CL_BREAK;
char hash[33], *hdr;
char hash[33], *hdr, *map = NULL;
size_t mp_hdrsz;
struct IS_HDR *h1;
struct IS_OBJECTS *objs;
@ -479,26 +499,41 @@ static int is_parse_hdr(int desc, cli_ctx *ctx, struct IS_CABSTUFF *c) {
return CL_CLEAN;
}
if(!(hdr = (char *)cli_malloc(c->hdrsz))) /* FIXMEISHIELD: mmap if large */
return CL_EMEM;
if(pread(desc, hdr, c->hdrsz, c->hdr) < (ssize_t)c->hdrsz) {
cli_errmsg("is_parse_hdr: short read for header\n");
free(hdr);
return CL_EREAD; /* hdr must be within bounds, it's k to hard fail here */
if(c->hdrsz < IS_MAX_NOMAP_SZ) {
if(!(hdr = (char *)cli_malloc(c->hdrsz)))
return CL_EMEM;
if(pread(desc, hdr, c->hdrsz, c->hdr) < (ssize_t)c->hdrsz) {
cli_errmsg("is_parse_hdr: short read for header\n");
free(hdr);
return CL_EREAD; /* hdr must be within bounds, it's k to hard fail here */
}
} else {
#if HAVE_MMAP
int psz = getpagesize();
off_t mp_hdr = (c->hdr / psz) * psz;
mp_hdrsz = c->hdrsz + c->hdr - mp_hdr;
if((map = mmap(NULL, mp_hdrsz, PROT_READ, MAP_PRIVATE, desc, mp_hdr))==MAP_FAILED) {
cli_errmsg("is_parse_hdr: mmap failed\n");
return CL_EMEM;
}
hdr = map + c->hdr - mp_hdr;
#else
cli_warnmsg("is_parse_hdr: hdr too big and mmap unavailable\n");
return CL_CLEAN
#endif
}
h1 = (struct IS_HDR *)hdr;
if(!CLI_ISCONTAINED(hdr, c->hdrsz, ((char *)h1), sizeof(*h1))) {
cli_dbgmsg("is_parse_hdr: not enough room for H1\n");
free(hdr);
IS_FREE_HDR;
return CL_CLEAN;
}
h1_data_off = le32_to_host(h1->data_off);
objs = (struct IS_OBJECTS *)(hdr + h1_data_off);
if(!CLI_ISCONTAINED(hdr, c->hdrsz, ((char *)objs), sizeof(*objs))) {
cli_dbgmsg("is_parse_hdr: not enough room for OBJECTS\n");
free(hdr);
IS_FREE_HDR;
return CL_CLEAN;
}
@ -506,6 +541,7 @@ static int is_parse_hdr(int desc, cli_ctx *ctx, struct IS_CABSTUFF *c) {
h1->magic, h1->unk1, h1->unk2, h1_data_off, h1->data_sz);
if(le32_to_host(h1->magic) != 0x28635349) {
cli_dbgmsg("is_parse_hdr: bad magic. wrong version?\n");
IS_FREE_HDR;
return CL_CLEAN;
}
@ -602,6 +638,7 @@ static int is_parse_hdr(int desc, cli_ctx *ctx, struct IS_CABSTUFF *c) {
scanned++;
if (ctx->engine->maxfiles && scanned >= ctx->engine->maxfiles) {
cli_dbgmsg("is_parse_hdr: File limit reached (max: %u)\n", ctx->engine->maxfiles);
IS_FREE_HDR;
return CL_EMAXFILES;
}
cabret = is_extract_cab(desc, ctx, file_stream_off + c->cabs[j].off, file_size, file_csize);
@ -635,7 +672,7 @@ static int is_parse_hdr(int desc, cli_ctx *ctx, struct IS_CABSTUFF *c) {
}
off += sizeof(*file);
}
free(hdr);
IS_FREE_HDR;
return ret;
}
@ -687,10 +724,17 @@ static int is_extract_cab(int desc, cli_ctx *ctx, uint64_t off, uint64_t size, u
fclose(in);
return CL_EMEM;
}
if(!(tempfile = cli_gentemp(ctx->engine->tmpdir))) return CL_EMEM;
if(!(tempfile = cli_gentemp(ctx->engine->tmpdir))) {
free(inbuf);
free(outbuf);
fclose(in);
return CL_EMEM;
}
if((ofd = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR)) < 0) {
cli_errmsg("is_extract_cab: failed to create file %s\n", tempfile);
free(tempfile);
free(inbuf);
free(outbuf);
fclose(in);
return CL_ECREAT;
}
@ -754,6 +798,8 @@ static int is_extract_cab(int desc, cli_ctx *ctx, uint64_t off, uint64_t size, u
if(!success) break;
}
fclose(in);
free(inbuf);
free(outbuf);
if(success) {
if (outsz != size)
cli_dbgmsg("is_extract_cab: extracted %llu bytes to %s, expected %llu, scanning anyway.\n", outsz, tempfile, size);

Loading…
Cancel
Save