git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@567 77e5149b-7576-45b1-b177-96237e5ba77b
Trog authored on 2004/05/19 17:09:50... | ... |
@@ -34,6 +34,14 @@ |
34 | 34 |
#include <stdlib.h> |
35 | 35 |
#include <clamav.h> |
36 | 36 |
|
37 |
+#if HAVE_MMAP |
|
38 |
+#if HAVE_SYS_MMAN_H |
|
39 |
+#include <sys/mman.h> |
|
40 |
+#else /* HAVE_SYS_MMAN_H */ |
|
41 |
+#undef HAVE_MMAP |
|
42 |
+#endif |
|
43 |
+#endif |
|
44 |
+ |
|
37 | 45 |
#include "cltypes.h" |
38 | 46 |
#include "others.h" |
39 | 47 |
|
... | ... |
@@ -101,6 +109,8 @@ typedef struct ole2_header_tag |
101 | 101 |
/* must take account of the size of variables below here when |
102 | 102 |
reading the header */ |
103 | 103 |
int32_t sbat_root_start __attribute__ ((packed)); |
104 |
+ unsigned char *m_area; |
|
105 |
+ off_t m_length; |
|
104 | 106 |
} ole2_header_t; |
105 | 107 |
|
106 | 108 |
typedef struct property_tag |
... | ... |
@@ -256,11 +266,19 @@ static int ole2_read_block(int fd, ole2_header_t *hdr, void *buff, int32_t block |
256 | 256 |
|
257 | 257 |
/* other methods: (blockno+1) * 512 or (blockno * block_size) + 512; */ |
258 | 258 |
offset = (blockno << hdr->log2_big_block_size) + 512; /* 512 is header size */ |
259 |
- if (lseek(fd, offset, SEEK_SET) != offset) { |
|
260 |
- return FALSE; |
|
261 |
- } |
|
262 |
- if (cli_readn(fd, buff, (1 << hdr->log2_big_block_size)) != (1 << hdr->log2_big_block_size)) { |
|
263 |
- return FALSE; |
|
259 |
+ |
|
260 |
+ if (hdr->m_area == NULL) { |
|
261 |
+ if (lseek(fd, offset, SEEK_SET) != offset) { |
|
262 |
+ return FALSE; |
|
263 |
+ } |
|
264 |
+ if (cli_readn(fd, buff, (1 << hdr->log2_big_block_size)) != (1 << hdr->log2_big_block_size)) { |
|
265 |
+ return FALSE; |
|
266 |
+ } |
|
267 |
+ } else { |
|
268 |
+ if ((offset + (1 << hdr->log2_big_block_size)) > hdr->m_length) { |
|
269 |
+ return FALSE; |
|
270 |
+ } |
|
271 |
+ memcpy(buff, hdr->m_area+offset, (1 << hdr->log2_big_block_size)); |
|
264 | 272 |
} |
265 | 273 |
return TRUE; |
266 | 274 |
} |
... | ... |
@@ -673,22 +691,40 @@ int cli_ole2_extract(int fd, const char *dirname) |
673 | 673 |
{ |
674 | 674 |
ole2_header_t hdr; |
675 | 675 |
int hdr_size; |
676 |
+ struct stat statbuf; |
|
676 | 677 |
|
677 | 678 |
cli_dbgmsg("in cli_ole2_extract()\n"); |
678 | 679 |
|
679 | 680 |
/* size of header - size of other values in struct */ |
680 |
- hdr_size = sizeof(struct ole2_header_tag) - sizeof(int32_t); |
|
681 |
+ hdr_size = sizeof(struct ole2_header_tag) - sizeof(int32_t) - |
|
682 |
+ sizeof(unsigned char *) - sizeof(off_t); |
|
681 | 683 |
|
682 |
-#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK) |
|
683 |
- if (cli_readn(fd, &hdr, hdr_size) != hdr_size) { |
|
684 |
- return 0; |
|
685 |
- } |
|
686 |
-#else |
|
687 |
- if (!ole2_read_header(fd, &hdr)) { |
|
688 |
- return 0; |
|
684 |
+ hdr.m_area = NULL; |
|
685 |
+ |
|
686 |
+#ifdef HAVE_MMAP |
|
687 |
+ if (fstat(fd, &statbuf) == 0) { |
|
688 |
+ hdr.m_length = statbuf.st_size; |
|
689 |
+ hdr.m_area = (unsigned char *) mmap(NULL, hdr.m_length, PROT_READ, MAP_PRIVATE, fd, 0); |
|
690 |
+ if (hdr.m_area == MAP_FAILED) { |
|
691 |
+ hdr.m_area = NULL; |
|
692 |
+ } |
|
693 |
+ cli_dbgmsg("mmap'ed file\n"); |
|
694 |
+ memcpy(&hdr, hdr.m_area, hdr_size); |
|
689 | 695 |
} |
690 | 696 |
#endif |
691 | 697 |
|
698 |
+ if (hdr.m_area == NULL) { |
|
699 |
+#if defined(HAVE_ATTRIB_PACKED) || defined(HAVE_PRAGMA_PACK) |
|
700 |
+ if (cli_readn(fd, &hdr, hdr_size) != hdr_size) { |
|
701 |
+ return 0; |
|
702 |
+ } |
|
703 |
+#else |
|
704 |
+ if (!ole2_read_header(fd, &hdr)) { |
|
705 |
+ return 0; |
|
706 |
+ } |
|
707 |
+#endif |
|
708 |
+ } |
|
709 |
+ |
|
692 | 710 |
hdr.minor_version = ole2_endian_convert_16(hdr.minor_version); |
693 | 711 |
hdr.dll_version = ole2_endian_convert_16(hdr.dll_version); |
694 | 712 |
hdr.byte_order = ole2_endian_convert_16(hdr.byte_order); |
... | ... |
@@ -703,7 +739,7 @@ int cli_ole2_extract(int fd, const char *dirname) |
703 | 703 |
hdr.xbat_count = ole2_endian_convert_32(hdr.xbat_count); |
704 | 704 |
|
705 | 705 |
hdr.sbat_root_start = -1; |
706 |
- |
|
706 |
+ |
|
707 | 707 |
if (strncmp(hdr.magic, magic_id, 8) != 0) { |
708 | 708 |
cli_dbgmsg("OLE2 magic failed!\n"); |
709 | 709 |
return CL_EOLE2; |
... | ... |
@@ -718,7 +754,7 @@ int cli_ole2_extract(int fd, const char *dirname) |
718 | 718 |
if (hdr.sbat_cutoff != 4096) { |
719 | 719 |
cli_dbgmsg("WARNING: untested sbat cutoff - please report\n\n"); |
720 | 720 |
} |
721 |
- |
|
721 |
+ |
|
722 | 722 |
print_ole2_header(&hdr); |
723 | 723 |
|
724 | 724 |
/* NOTE: Select only ONE of the following two methods */ |
... | ... |
@@ -728,6 +764,11 @@ int cli_ole2_extract(int fd, const char *dirname) |
728 | 728 |
/* OR */ |
729 | 729 |
|
730 | 730 |
ole2_walk_property_tree(fd, &hdr, dirname, 0, handler_writefile, 0, 0); |
731 |
- |
|
731 |
+ |
|
732 |
+#ifdef HAVE_MMAP |
|
733 |
+ if (hdr.m_area != NULL) { |
|
734 |
+ munmap(hdr.m_area, hdr.m_length); |
|
735 |
+ } |
|
736 |
+#endif |
|
732 | 737 |
return 0; |
733 | 738 |
} |