git-svn: trunk@1786
Tomasz Kojm authored on 2005/12/16 04:53:52... | ... |
@@ -29,6 +29,14 @@ |
29 | 29 |
#include <unistd.h> |
30 | 30 |
#include <time.h> |
31 | 31 |
|
32 |
+#if HAVE_MMAP |
|
33 |
+#if HAVE_SYS_MMAN_H |
|
34 |
+#include <sys/mman.h> |
|
35 |
+#else /* HAVE_SYS_MMAN_H */ |
|
36 |
+#undef HAVE_MMAP |
|
37 |
+#endif |
|
38 |
+#endif |
|
39 |
+ |
|
32 | 40 |
#include "cltypes.h" |
33 | 41 |
#include "clamav.h" |
34 | 42 |
#include "others.h" |
... | ... |
@@ -69,17 +77,46 @@ int cli_scansis(int desc, const char **virname, long int *scanned, const struct |
69 | 69 |
struct sis_file_hdr6 file_hdr6; |
70 | 70 |
uint8_t release = 0; |
71 | 71 |
uint16_t opts, nlangs, *langrecs; |
72 |
- char *langs; |
|
72 |
+ char *mfile = NULL, *langs; |
|
73 |
+ struct stat sb; |
|
73 | 74 |
int i; |
74 | 75 |
|
75 | 76 |
|
76 |
- if(read(desc, &file_hdr, sizeof(struct sis_file_hdr)) != sizeof(struct sis_file_hdr)) { |
|
77 |
- cli_dbgmsg("SIS: Can't read file header\n"); /* Not a SIS file? */ |
|
77 |
+ if(fstat(desc, &sb) == -1) { |
|
78 |
+ cli_errmsg("SIS: fstat() failed\n"); |
|
79 |
+ return CL_EIO; |
|
80 |
+ } |
|
81 |
+ |
|
82 |
+ if(sb.st_size < sizeof(struct sis_file_hdr)) { |
|
83 |
+ cli_dbgmsg("SIS: Broken or not a SIS file (too small)\n"); |
|
78 | 84 |
return CL_CLEAN; |
79 | 85 |
} |
80 | 86 |
|
87 |
+#if HAVE_MMAP |
|
88 |
+ if(sb.st_size < 33554432) { |
|
89 |
+ mfile = (char *) mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, desc, 0); |
|
90 |
+ if(mfile == MAP_FAILED) { |
|
91 |
+ mfile = NULL; |
|
92 |
+ } else { |
|
93 |
+ cli_dbgmsg("SIS: mmap'ed file\n"); |
|
94 |
+ memcpy(&file_hdr, mfile, sizeof(struct sis_file_hdr)); |
|
95 |
+ } |
|
96 |
+ } |
|
97 |
+#endif |
|
98 |
+ |
|
99 |
+ if(!mfile) { |
|
100 |
+ if(read(desc, &file_hdr, sizeof(struct sis_file_hdr)) != sizeof(struct sis_file_hdr)) { |
|
101 |
+ cli_dbgmsg("SIS: Can't read file header\n"); /* Not a SIS file? */ |
|
102 |
+ return CL_CLEAN; |
|
103 |
+ } |
|
104 |
+ } |
|
105 |
+ |
|
81 | 106 |
if(EC32(file_hdr.uid3) != 0x10000419) { |
82 | 107 |
cli_dbgmsg("SIS: Not a SIS file\n"); |
108 |
+#if HAVE_MMAP |
|
109 |
+ if(mfile) |
|
110 |
+ munmap(mfile, sb.st_size); |
|
111 |
+#endif |
|
83 | 112 |
return CL_CLEAN; |
84 | 113 |
} |
85 | 114 |
|
... | ... |
@@ -104,17 +141,32 @@ int cli_scansis(int desc, const char **virname, long int *scanned, const struct |
104 | 104 |
cli_dbgmsg("SIS: Offset of languages records: %d\n", EC32(file_hdr.plangs)); |
105 | 105 |
|
106 | 106 |
if(nlangs && nlangs < 100) { |
107 |
- if(lseek(desc, EC32(file_hdr.plangs), SEEK_SET) < 0) { |
|
108 |
- cli_errmsg("SIS: No language records\n"); |
|
107 |
+ |
|
108 |
+ if(EC32(file_hdr.plangs) + nlangs * 2 >= sb.st_size) { |
|
109 |
+ cli_errmsg("SIS: Broken file structure (language records)\n"); |
|
110 |
+#if HAVE_MMAP |
|
111 |
+ if(mfile) |
|
112 |
+ munmap(mfile, sb.st_size); |
|
113 |
+#endif |
|
109 | 114 |
return CL_EFORMAT; |
110 | 115 |
} |
111 | 116 |
|
112 | 117 |
langrecs = (uint16_t *) cli_malloc(nlangs * 2); |
113 | 118 |
|
114 |
- if(read(desc, langrecs, nlangs * 2) != nlangs * 2) { |
|
115 |
- cli_errmsg("SIS: Can't read language records\n"); |
|
116 |
- free(langrecs); |
|
117 |
- return CL_EFORMAT; |
|
119 |
+ if(!mfile) { |
|
120 |
+ if(lseek(desc, EC32(file_hdr.plangs), SEEK_SET) < 0) { |
|
121 |
+ cli_errmsg("SIS: No language records\n"); |
|
122 |
+ free(langrecs); |
|
123 |
+ return CL_EFORMAT; |
|
124 |
+ } |
|
125 |
+ |
|
126 |
+ if(read(desc, langrecs, nlangs * 2) != nlangs * 2) { |
|
127 |
+ cli_errmsg("SIS: Can't read language records\n"); |
|
128 |
+ free(langrecs); |
|
129 |
+ return CL_EFORMAT; |
|
130 |
+ } |
|
131 |
+ } else { |
|
132 |
+ memcpy(langrecs, mfile + EC32(file_hdr.plangs), nlangs * 2); |
|
118 | 133 |
} |
119 | 134 |
|
120 | 135 |
langs = (char *) cli_calloc(nlangs * 3 + 1, sizeof(char)); |
... | ... |
@@ -184,16 +236,33 @@ int cli_scansis(int desc, const char **virname, long int *scanned, const struct |
184 | 184 |
|
185 | 185 |
if(release == 6) { |
186 | 186 |
|
187 |
- lseek(desc, sizeof(struct sis_file_hdr), SEEK_SET); |
|
188 |
- |
|
189 |
- if(read(desc, &file_hdr6, sizeof(struct sis_file_hdr6)) != sizeof(struct sis_file_hdr6)) { |
|
190 |
- cli_dbgmsg("SIS: Can't read additional data of EPOC 6 file header\n"); /* Not a SIS file? */ |
|
187 |
+ if(sizeof(struct sis_file_hdr) + sizeof(struct sis_file_hdr6) >= sb.st_size) { |
|
188 |
+ cli_errmsg("SIS: Broken file structure (language records)\n"); |
|
189 |
+#if HAVE_MMAP |
|
190 |
+ if(mfile) |
|
191 |
+ munmap(mfile, sb.st_size); |
|
192 |
+#endif |
|
191 | 193 |
return CL_EFORMAT; |
192 | 194 |
} |
193 | 195 |
|
196 |
+ |
|
197 |
+ if(!mfile) { |
|
198 |
+ lseek(desc, sizeof(struct sis_file_hdr), SEEK_SET); |
|
199 |
+ |
|
200 |
+ if(read(desc, &file_hdr6, sizeof(struct sis_file_hdr6)) != sizeof(struct sis_file_hdr6)) { |
|
201 |
+ cli_dbgmsg("SIS: Can't read additional data of EPOC 6 file header\n"); /* Not a SIS file? */ |
|
202 |
+ return CL_EFORMAT; |
|
203 |
+ } |
|
204 |
+ } else { |
|
205 |
+ memcpy(&file_hdr6, mfile + sizeof(struct sis_file_hdr), sizeof(struct sis_file_hdr6)); |
|
206 |
+ } |
|
194 | 207 |
cli_dbgmsg("SIS: Maximum space required: %d\n", EC32(file_hdr6.maxispace)); |
195 | 208 |
} |
196 | 209 |
|
210 |
+#if HAVE_MMAP |
|
211 |
+ if(mfile) |
|
212 |
+ munmap(mfile, sb.st_size); |
|
213 |
+#endif |
|
197 | 214 |
|
198 | 215 |
return CL_CLEAN; |
199 | 216 |
} |