[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b
aCaB
acab at clamav.net
Sun Apr 4 00:58:57 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit 9c3c24ca6e3ef8496f1da693e34b622259c1b564
Author: aCaB <acab at clamav.net>
Date: Wed Jul 15 12:34:50 2009 +0200
use mmap for big files, fix some leaks, some portability fixes
diff --git a/ChangeLog b/ChangeLog
index 38b21fd..381f718 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+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)
diff --git a/libclamav/ishield.c b/libclamav/ishield.c
index 64aa187..5b5848a 100644
--- a/libclamav/ishield.c
+++ b/libclamav/ishield.c
@@ -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);
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list