[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