[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 01:01:39 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit 774898a764e3f3a6cf64d44eac83babe2c94dfa0
Author: aCaB <acab at clamav.net>
Date: Mon Aug 24 17:02:27 2009 +0200
use fmap in unzip
diff --git a/libclamav/fmap.c b/libclamav/fmap.c
index 462e141..9df907c 100644
--- a/libclamav/fmap.c
+++ b/libclamav/fmap.c
@@ -305,6 +305,8 @@ void *fmap_need_str(struct F_MAP *m, void *ptr, size_t len) {
return NULL;
}
+ fmap_aging(m);
+
cli_errmsg("FMAPDBG: need_str map %p at %p len %u\n", m, ptr, len);
first_page = fmap_which_page(m, at);
last_page = fmap_which_page(m, at + len - 1);
diff --git a/libclamav/unzip.c b/libclamav/unzip.c
index 8dd0bc0..c5608a2 100644
--- a/libclamav/unzip.c
+++ b/libclamav/unzip.c
@@ -35,12 +35,6 @@
#endif
#include <stdlib.h>
-#if HAVE_MMAP
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#endif
-#endif /* HAVE_MMAP */
-
#include <stdio.h>
#include <zlib.h>
@@ -54,6 +48,7 @@
#include "clamav.h"
#include "scanners.h"
#include "matcher.h"
+#include "fmap.h"
#define UNZIP_PRIVATE
#include "unzip.h"
@@ -67,15 +62,6 @@ static int wrap_inflateinit2(void *a, int b) {
return inflateInit2(a, b);
}
-static inline void destroy_map(void *map, size_t fsize) {
-#if HAVE_MMAP
- munmap(map, fsize);
-#else
- free(map);
-#endif
-}
-
-
static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, uint16_t flags, unsigned int *fu, cli_ctx *ctx, char *tmpd) {
char name[1024], obuf[BUFSIZ];
char *tempfile = name;
@@ -317,33 +303,39 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui
return ret;
}
-static unsigned int lhdr(uint8_t *zip, uint32_t zsize, unsigned int *fu, unsigned int fc, uint8_t *ch, int *ret, cli_ctx *ctx, char *tmpd, int fd) {
- uint8_t *lh = zip;
+static unsigned int lhdr(struct F_MAP *map, uint32_t loff,uint32_t zsize, unsigned int *fu, unsigned int fc, uint8_t *ch, int *ret, cli_ctx *ctx, char *tmpd, int fd) {
+ uint8_t *lh, *zip;
char name[256];
uint32_t csize, usize;
struct cli_meta_node *meta = ctx->engine->zip_mlist;
- if(zsize<=SIZEOF_LH) {
- cli_dbgmsg("cli_unzip: lh - out of file\n");
- return 0;
+ if(!(lh = fmap_need_off(map, loff, SIZEOF_LH))) {
+ cli_dbgmsg("cli_unzip: lh - out of file\n");
+ return 0;
}
if(LH_magic != 0x04034b50) {
if (!ch) cli_dbgmsg("cli_unzip: lh - wrkcomplete\n");
else cli_dbgmsg("cli_unzip: lh - bad magic\n");
+ fmap_unneed_off(map, loff, SIZEOF_LH);
return 0;
}
- zip+=SIZEOF_LH;
+ zip = lh + SIZEOF_LH;
zsize-=SIZEOF_LH;
if(zsize<=LH_flen) {
cli_dbgmsg("cli_unzip: lh - fname out of file\n");
+ fmap_need_off(map, loff, SIZEOF_LH);
return 0;
}
if(meta || cli_debug_flag) {
- uint32_t nsize = (LH_flen>=sizeof(name))?sizeof(name)-1:LH_flen;
- memcpy(name, zip, nsize);
- name[nsize]='\0';
+ uint32_t nsize = (LH_flen>=sizeof(name))?sizeof(name)-1:LH_flen;
+ char *src;
+ if(nsize && (src = fmap_need_ptr_once(map, zip, nsize))) {
+ memcpy(name, zip, nsize);
+ name[nsize]='\0';
+ } else
+ name[0] = '\0';
}
zip+=LH_flen;
zsize-=LH_flen;
@@ -370,12 +362,14 @@ static unsigned int lhdr(uint8_t *zip, uint32_t zsize, unsigned int *fu, unsigne
} else
*ret = CL_CLEAN;
+ fmap_need_off(map, loff, SIZEOF_LH);
return 0;
}
if(LH_flags & F_MSKED) {
cli_dbgmsg("cli_unzip: lh - header has got unusable masked data\n");
/* FIXME: need to find/craft a sample */
+ fmap_need_off(map, loff, SIZEOF_LH);
return 0;
}
@@ -383,63 +377,76 @@ static unsigned int lhdr(uint8_t *zip, uint32_t zsize, unsigned int *fu, unsigne
cli_dbgmsg("cli_unzip: Encrypted files found in archive.\n");
*ctx->virname = "Encrypted.Zip";
*ret = CL_VIRUS;
+ fmap_need_off(map, loff, SIZEOF_LH);
return 0;
}
if(LH_flags & F_USEDD) {
cli_dbgmsg("cli_unzip: lh - has data desc\n");
- if(!ch) return 0;
+ if(!ch) {
+ fmap_need_off(map, loff, SIZEOF_LH);
+ return 0;
+ }
else { usize = CH_usize; csize = CH_csize; }
} else { usize = LH_usize; csize = LH_csize; }
if(zsize<=LH_elen) {
cli_dbgmsg("cli_unzip: lh - extra out of file\n");
+ fmap_need_off(map, loff, SIZEOF_LH);
return 0;
}
zip+=LH_elen;
zsize-=LH_elen;
if (!csize) { /* FIXME: what's used for method0 files? csize or usize? Nothing in the specs, needs testing */
- cli_dbgmsg("cli_unzip: lh - skipping empty file\n");
+ cli_dbgmsg("cli_unzip: lh - skipping empty file\n");
} else {
- if(zsize<csize) {
- cli_dbgmsg("cli_unzip: lh - stream out of file\n");
- return 0;
- }
- if(LH_flags & F_ENCR) {
- cli_dbgmsg("cli_unzip: lh - skipping encrypted file\n");
- } else *ret = unz(zip, csize, usize, LH_method, LH_flags, fu, ctx, tmpd);
- zip+=csize;
- zsize-=csize;
+ if(zsize<csize) {
+ cli_dbgmsg("cli_unzip: lh - stream out of file\n");
+ fmap_need_off(map, loff, SIZEOF_LH);
+ return 0;
+ }
+ if(LH_flags & F_ENCR) {
+ cli_dbgmsg("cli_unzip: lh - skipping encrypted file\n");
+ } else {
+ if(fmap_need_ptr_once(map, zip, csize))
+ *ret = unz(zip, csize, usize, LH_method, LH_flags, fu, ctx, tmpd);
+ }
+ zip+=csize;
+ zsize-=csize;
}
+ fmap_need_off(map, loff, SIZEOF_LH); /* unneed now. block is guaranteed to exists till the next need */
if(LH_flags & F_USEDD) {
- if(zsize<12) {
- cli_dbgmsg("cli_unzip: lh - data desc out of file\n");
- return 0;
- }
- zsize-=12;
- if(cli_readint32(zip)==0x08074b50) {
- if(zsize<4) {
- cli_dbgmsg("cli_unzip: lh - data desc out of file\n");
- return 0;
+ if(zsize<12) {
+ cli_dbgmsg("cli_unzip: lh - data desc out of file\n");
+ return 0;
}
- zip+=4;
- }
- zip+=12;
+ zsize-=12;
+ if(fmap_need_ptr_once(map, zip, 4)) {
+ if(cli_readint32(zip)==0x08074b50) {
+ if(zsize<4) {
+ cli_dbgmsg("cli_unzip: lh - data desc out of file\n");
+ return 0;
+ }
+ zip+=4;
+ }
+ }
+ zip+=12;
}
return zip-lh;
}
-static unsigned int chdr(uint8_t *zip, uint32_t coff, uint32_t zsize, unsigned int *fu, unsigned int fc, int *ret, cli_ctx *ctx, char *tmpd, int fd) {
- uint8_t *ch = &zip[coff];
+static unsigned int chdr(struct F_MAP *map, uint32_t coff, uint32_t zsize, unsigned int *fu, unsigned int fc, int *ret, cli_ctx *ctx, char *tmpd, int fd) {
char name[256];
int last = 0;
+ int8_t *ch;
- if(zsize-coff<=SIZEOF_CH || CH_magic != 0x02014b50) {
- cli_dbgmsg("cli_unzip: ch - wrkcomplete\n");
- return 0;
+ if(!(ch = fmap_need_off(map, coff, SIZEOF_CH)) || CH_magic != 0x02014b50) {
+ if(ch) fmap_unneed_ptr(map, ch, SIZEOF_CH);
+ cli_dbgmsg("cli_unzip: ch - wrkcomplete\n");
+ return 0;
}
coff+=SIZEOF_CH;
@@ -450,10 +457,13 @@ static unsigned int chdr(uint8_t *zip, uint32_t coff, uint32_t zsize, unsigned i
last=1;
}
if(cli_debug_flag && !last) {
- unsigned int size = (CH_flen>=sizeof(name))?sizeof(name)-1:CH_flen;
- memcpy(name, &zip[coff], size);
- name[size]='\0';
- cli_dbgmsg("cli_unzip: ch - fname: %s\n", name);
+ unsigned int size = (CH_flen>=sizeof(name))?sizeof(name)-1:CH_flen;
+ char *src = fmap_need_off_once(map, coff, size);
+ if(src) {
+ memcpy(name, src, size);
+ name[size]='\0';
+ cli_dbgmsg("cli_unzip: ch - fname: %s\n", name);
+ }
}
coff+=CH_flen;
@@ -470,8 +480,9 @@ static unsigned int chdr(uint8_t *zip, uint32_t coff, uint32_t zsize, unsigned i
coff+=CH_clen;
if(CH_off<zsize-SIZEOF_LH) {
- lhdr(&zip[CH_off], zsize-CH_off, fu, fc, ch, ret, ctx, tmpd, fd);
+ lhdr(map, CH_off, zsize-CH_off, fu, fc, ch, ret, ctx, tmpd, fd);
} else cli_dbgmsg("cli_unzip: ch - local hdr out of file\n");
+ fmap_unneed_ptr(map, ch, SIZEOF_CH);
return last?0:coff;
}
@@ -481,8 +492,8 @@ int cli_unzip(int f, cli_ctx *ctx) {
int ret=CL_CLEAN;
uint32_t fsize, lhoff = 0, coff = 0;
struct stat st;
- uint8_t *map;
- char *tmpd;
+ struct F_MAP *map;
+ char *tmpd, *ptr;
cli_dbgmsg("in cli_unzip\n");
if (fstat(f, &st)==-1) {
@@ -499,58 +510,46 @@ int cli_unzip(int f, cli_ctx *ctx) {
return CL_CLEAN;
}
-#if HAVE_MMAP
- if ((map = mmap(NULL, fsize, PROT_READ, MAP_PRIVATE, f, 0))==MAP_FAILED) {
- cli_dbgmsg("cli_unzip: mmap failed\n");
- return CL_EMAP;
- }
-#else
- if(fsize > CLI_MAX_ALLOCATION) {
- cli_warnmsg("cli_unzip: mmap not available and file is too big\n");
- return CL_CLEAN;
+ if (!(map = fmap(f, 0, fsize))) {
+ cli_dbgmsg("cli_unzip: mmap failed\n");
+ return CL_EMAP;
}
- lseek(f, 0, SEEK_SET);
- if(!(map = cli_malloc(fsize)))
- return CL_EMEM;
- if(cli_readn(f, map, fsize)!=fsize) {
- free(map);
- return CL_EREAD;
- }
-#endif
if (!(tmpd = cli_gentemp(ctx->engine->tmpdir))) {
- destroy_map(map, fsize);
+ fmunmap(map);
return CL_ETMPDIR;
}
if (mkdir(tmpd, 0700)) {
cli_dbgmsg("cli_unzip: Can't create temporary directory %s\n", tmpd);
- destroy_map(map, fsize);
+ fmunmap(map);
free(tmpd);
return CL_ETMPDIR;
}
for(coff=fsize-22 ; coff>0 ; coff--) { /* sizeof(EOC)==22 */
- if(cli_readint32(&map[coff])==0x06054b50) {
- uint32_t chptr = cli_readint32(&map[coff+16]);
- if(!CLI_ISCONTAINED(map, fsize, map+chptr, SIZEOF_CH)) continue;
- coff=chptr;
- break;
- }
+ if(!(ptr = fmap_need_off_once(map, coff, 20)))
+ continue;
+ if(cli_readint32(ptr)==0x06054b50) {
+ uint32_t chptr = cli_readint32(&ptr[16]);
+ if(!CLI_ISCONTAINED(0, fsize, chptr, SIZEOF_CH)) continue;
+ coff=chptr;
+ break;
+ }
}
if(coff) {
- cli_dbgmsg("cli_unzip: central @%x\n", coff);
- while(ret==CL_CLEAN && (coff=chdr(map, coff, fsize, &fu, fc+1, &ret, ctx, tmpd, f))) {
- fc++;
- if (ctx->engine->maxfiles && fu>=ctx->engine->maxfiles) {
- cli_dbgmsg("cli_unzip: Files limit reached (max: %u)\n", ctx->engine->maxfiles);
- ret=CL_EMAXFILES;
+ cli_dbgmsg("cli_unzip: central @%x\n", coff);
+ while(ret==CL_CLEAN && (coff=chdr(map, coff, fsize, &fu, fc+1, &ret, ctx, tmpd, f))) {
+ fc++;
+ if (ctx->engine->maxfiles && fu>=ctx->engine->maxfiles) {
+ cli_dbgmsg("cli_unzip: Files limit reached (max: %u)\n", ctx->engine->maxfiles);
+ ret=CL_EMAXFILES;
+ }
}
- }
} else cli_dbgmsg("cli_unzip: central not found, using localhdrs\n");
if(fu<=(fc/4)) { /* FIXME: make up a sane ratio or remove the whole logic */
fc = 0;
- while (ret==CL_CLEAN && lhoff<fsize && (coff=lhdr(&map[lhoff], fsize-lhoff, &fu, fc+1, NULL, &ret, ctx, tmpd, f))) {
+ while (ret==CL_CLEAN && lhoff<fsize && (coff=lhdr(map, lhoff, fsize-lhoff, &fu, fc+1, NULL, &ret, ctx, tmpd, f))) {
fc++;
lhoff+=coff;
if (ctx->engine->maxfiles && fu>=ctx->engine->maxfiles) {
@@ -560,7 +559,7 @@ int cli_unzip(int f, cli_ctx *ctx) {
}
}
- destroy_map(map, fsize);
+ fmunmap(map);
if (!ctx->engine->keeptmp) cli_rmdirs(tmpd);
free(tmpd);
@@ -572,7 +571,7 @@ int cli_unzip_single(int f, cli_ctx *ctx, off_t lhoffl) {
unsigned int fu=0;
struct stat st;
uint32_t fsize;
- uint8_t *map;
+ struct F_MAP *map;
cli_dbgmsg("in cli_unzip_single\n");
if (fstat(f, &st)==-1) {
@@ -589,26 +588,13 @@ int cli_unzip_single(int f, cli_ctx *ctx, off_t lhoffl) {
return CL_CLEAN;
}
-#if HAVE_MMAP
- if ((map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, f, 0))==MAP_FAILED) {
- cli_dbgmsg("cli_unzip: mmap() failed\n");
- return CL_EMAP;
+ if (!(map = fmap(f, 0, fsize))) {
+ cli_dbgmsg("cli_unzip: mmap failed\n");
+ return CL_EMAP;
}
-#else
- if(st.st_size > CLI_MAX_ALLOCATION) {
- cli_warnmsg("cli_unzip: mmap not available and file is too big\n");
- return CL_CLEAN;
- }
- lseek(f, 0, SEEK_SET);
- if(!(map = cli_malloc(st.st_size)))
- return CL_EMEM;
- if(cli_readn(f, map, st.st_size)!=st.st_size) {
- free(map);
- return CL_EREAD;
- }
-#endif
- lhdr(&map[lhoffl], fsize, &fu, 0, NULL, &ret, ctx, NULL, f);
- destroy_map(map, st.st_size);
+ lhdr(map, lhoffl, fsize, &fu, 0, NULL, &ret, ctx, NULL, f);
+
+ fmunmap(map);
return ret;
}
--
Debian repository for ClamAV
More information about the Pkg-clamav-commits
mailing list