git-svn: trunk@3614
aCaB authored on 2008/02/12 02:38:21... | ... |
@@ -1,3 +1,13 @@ |
1 |
+Mon Feb 11 18:19:48 CET 2008 (acab) |
|
2 |
+----------------------------------- |
|
3 |
+ * WARNING: NEW LOGIC IN SCAN LIMITS |
|
4 |
+ The logic in the scanner limits have been reworked. This results in |
|
5 |
+ different command line options to clamscan, different config options to |
|
6 |
+ clamd and, overall, a different behaviour. |
|
7 |
+ I repeat: SOME THINGS HAVE CHANGED, BE CAREFUL! |
|
8 |
+ At the moment this is a work in progress. Final version will be available |
|
9 |
+ soon which will include a detailed ChangeLog and updated documentation. |
|
10 |
+ |
|
1 | 11 |
Mon Feb 11 18:33:22 EET 2008 (edwin) |
2 | 12 |
------------------------------------ |
3 | 13 |
* libclamav/mbox.c: replace getc() with getc_unlocked() when available. This |
... | ... |
@@ -315,33 +315,36 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne |
315 | 315 |
logg("*Listening daemon: PID: %u\n", (unsigned int) mainpid); |
316 | 316 |
max_threads = cfgopt(copt, "MaxThreads")->numarg; |
317 | 317 |
|
318 |
- if(cfgopt(copt, "ScanArchive")->enabled) { |
|
318 |
+ if(cfgopt(copt, "ScanArchive")->enabled) { /* FIXMELIMITS: unparsed if archives disabled! */ |
|
319 | 319 |
|
320 | 320 |
/* set up limits */ |
321 | 321 |
memset(&limits, 0, sizeof(struct cl_limits)); |
322 | 322 |
|
323 |
- if((limits.maxfilesize = cfgopt(copt, "ArchiveMaxFileSize")->numarg)) { |
|
324 |
- logg("Archive: Archived file size limit set to %lu bytes.\n", limits.maxfilesize); |
|
323 |
+ logg("Archive support enabled.\n"); |
|
324 |
+ options |= CL_SCAN_ARCHIVE; |
|
325 |
+ |
|
326 |
+ if((limits.maxfilesize = cfgopt(copt, "MaxScanSize")->numarg)) { |
|
327 |
+ logg("Limits: Global size limit set to %lu bytes.\n", limits.maxscansize); |
|
325 | 328 |
} else { |
326 |
- logg("^Archive: File size limit protection disabled.\n"); |
|
329 |
+ logg("^Limits: Global size limit protection disabled.\n"); |
|
327 | 330 |
} |
328 | 331 |
|
329 |
- if((limits.maxreclevel = cfgopt(copt, "ArchiveMaxRecursion")->numarg)) { |
|
330 |
- logg("Archive: Recursion level limit set to %u.\n", limits.maxreclevel); |
|
332 |
+ if((limits.maxfilesize = cfgopt(copt, "MaxFileSize")->numarg)) { |
|
333 |
+ logg("Limits: File size limit set to %lu bytes.\n", limits.maxfilesize); |
|
331 | 334 |
} else { |
332 |
- logg("^Archive: Recursion level limit protection disabled.\n"); |
|
335 |
+ logg("^Limits: File size limit protection disabled.\n"); |
|
333 | 336 |
} |
334 | 337 |
|
335 |
- if((limits.maxfiles = cfgopt(copt, "ArchiveMaxFiles")->numarg)) { |
|
336 |
- logg("Archive: Files limit set to %u.\n", limits.maxfiles); |
|
338 |
+ if((limits.maxreclevel = cfgopt(copt, "MaxRecursion")->numarg)) { |
|
339 |
+ logg("Limits: Recursion level limit set to %u.\n", limits.maxreclevel); |
|
337 | 340 |
} else { |
338 |
- logg("^Archive: Files limit protection disabled.\n"); |
|
341 |
+ logg("^Limits: Recursion level limit protection disabled.\n"); |
|
339 | 342 |
} |
340 | 343 |
|
341 |
- if((limits.maxratio = cfgopt(copt, "ArchiveMaxCompressionRatio")->numarg)) { |
|
342 |
- logg("Archive: Compression ratio limit set to %u.\n", limits.maxratio); |
|
344 |
+ if((limits.maxfiles = cfgopt(copt, "MaxFiles")->numarg)) { |
|
345 |
+ logg("Limits: Files limit set to %u.\n", limits.maxfiles); |
|
343 | 346 |
} else { |
344 |
- logg("^Archive: Compression ratio limit disabled.\n"); |
|
347 |
+ logg("^Limits: Files limit protection disabled.\n"); |
|
345 | 348 |
} |
346 | 349 |
|
347 | 350 |
if(cfgopt(copt, "ArchiveLimitMemoryUsage")->enabled) { |
... | ... |
@@ -350,22 +353,12 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne |
350 | 350 |
} else { |
351 | 351 |
limits.archivememlim = 0; |
352 | 352 |
} |
353 |
- } |
|
354 |
- |
|
355 |
- if(cfgopt(copt, "ScanArchive")->enabled) { |
|
356 |
- logg("Archive support enabled.\n"); |
|
357 |
- options |= CL_SCAN_ARCHIVE; |
|
358 | 353 |
|
359 | 354 |
if(cfgopt(copt, "ArchiveBlockEncrypted")->enabled) { |
360 | 355 |
logg("Archive: Blocking encrypted archives.\n"); |
361 | 356 |
options |= CL_SCAN_BLOCKENCRYPTED; |
362 | 357 |
} |
363 | 358 |
|
364 |
- if(cfgopt(copt, "ArchiveBlockMax")->enabled) { |
|
365 |
- logg("Archive: Blocking archives that exceed limits.\n"); |
|
366 |
- options |= CL_SCAN_BLOCKMAX; |
|
367 |
- } |
|
368 |
- |
|
369 | 359 |
} else { |
370 | 360 |
logg("Archive support disabled.\n"); |
371 | 361 |
} |
... | ... |
@@ -407,12 +400,6 @@ int acceptloop_th(int *socketds, int nsockets, struct cl_engine *engine, unsigne |
407 | 407 |
options |= CL_SCAN_MAILURL; |
408 | 408 |
} |
409 | 409 |
|
410 |
- if((limits.maxmailrec = cfgopt(copt, "MailMaxRecursion")->numarg)) { |
|
411 |
- logg("Mail: Recursion level limit set to %u.\n", limits.maxmailrec); |
|
412 |
- } else { |
|
413 |
- logg("^Mail: Recursion level limit protection disabled.\n"); |
|
414 |
- } |
|
415 |
- |
|
416 | 410 |
} else { |
417 | 411 |
logg("Mail files support disabled.\n"); |
418 | 412 |
} |
... | ... |
@@ -146,11 +146,22 @@ int main(int argc, char **argv) |
146 | 146 |
|
147 | 147 |
/* validate some numerical options */ |
148 | 148 |
|
149 |
- if(opt_check(opt, "max-space")) { |
|
150 |
- pt = opt_arg(opt, "max-space"); |
|
149 |
+ if(opt_check(opt, "max-scansize")) { |
|
150 |
+ pt = opt_arg(opt, "max-scansize"); |
|
151 | 151 |
if(!strchr(pt, 'M') && !strchr(pt, 'm')) { |
152 | 152 |
if(!cli_isnumber(pt)) { |
153 |
- logg("!--max-space requires a natural number\n"); |
|
153 |
+ logg("!--max-scansize requires a natural number\n"); |
|
154 |
+ opt_free(opt); |
|
155 |
+ return 40; |
|
156 |
+ } |
|
157 |
+ } |
|
158 |
+ } |
|
159 |
+ |
|
160 |
+ if(opt_check(opt, "max-filesize")) { |
|
161 |
+ pt = opt_arg(opt, "max-filesize"); |
|
162 |
+ if(!strchr(pt, 'M') && !strchr(pt, 'm')) { |
|
163 |
+ if(!cli_isnumber(pt)) { |
|
164 |
+ logg("!--max-filesize requires a natural number\n"); |
|
154 | 165 |
opt_free(opt); |
155 | 166 |
return 40; |
156 | 167 |
} |
... | ... |
@@ -313,14 +324,11 @@ void help(void) |
313 | 313 |
mprintf(" --block-max Block archives that exceed limits\n"); |
314 | 314 |
mprintf(" --mail-follow-urls Download and scan URLs\n"); |
315 | 315 |
mprintf("\n"); |
316 |
- mprintf(" --max-space=#n Only extract first #n kilobytes from\n"); |
|
317 |
- mprintf(" archived files\n"); |
|
318 |
- mprintf(" --max-files=#n Only extract first #n files from\n"); |
|
319 |
- mprintf(" archives\n"); |
|
320 |
- mprintf(" --max-ratio=#n Maximum compression ratio limit\n"); |
|
316 |
+ mprintf(" --max-scansize=#n FIXMELIMITS\n"); |
|
317 |
+ mprintf(" --max-filesize=#n FIXMELIMITS\n"); |
|
318 |
+ mprintf(" --max-files=#n FIXMELIMITS\n"); |
|
321 | 319 |
mprintf(" --max-recursion=#n Maximum archive recursion level\n"); |
322 | 320 |
mprintf(" --max-dir-recursion=#n Maximum directory recursion level\n"); |
323 |
- mprintf(" --max-mail-recursion=#n Maximum mail recursion level\n"); |
|
324 | 321 |
mprintf(" --unzip[=FULLPATH] Enable support for .zip files\n"); |
325 | 322 |
mprintf(" --unrar[=FULLPATH] Enable support for .rar files\n"); |
326 | 323 |
mprintf(" --arj[=FULLPATH] Enable support for .arj files\n"); |
... | ... |
@@ -54,17 +54,15 @@ static struct option clamscan_longopt[] = { |
54 | 54 |
{"include", 1, 0, 0}, |
55 | 55 |
{"include-dir", 1, 0, 0}, |
56 | 56 |
{"max-files", 1, 0, 0}, |
57 |
- {"max-space", 1, 0, 0}, |
|
58 |
- {"max-ratio", 1, 0, 0}, |
|
57 |
+ {"max-filesize", 1, 0, 0}, |
|
58 |
+ {"max-scansize", 1, 0, 0}, |
|
59 | 59 |
{"max-recursion", 1, 0, 0}, |
60 | 60 |
{"max-dir-recursion", 1, 0, 0}, |
61 |
- {"max-mail-recursion", 1, 0, 0}, |
|
62 | 61 |
{"detect-pua", 0, 0, 0}, |
63 | 62 |
{"disable-archive", 0, 0, 0}, |
64 | 63 |
{"no-archive", 0, 0, 0}, |
65 | 64 |
{"detect-broken", 0, 0, 0}, |
66 | 65 |
{"block-encrypted", 0, 0, 0}, |
67 |
- {"block-max", 0, 0, 0}, |
|
68 | 66 |
{"no-pe", 0, 0, 0}, |
69 | 67 |
{"no-elf", 0, 0, 0}, |
70 | 68 |
{"no-ole2", 0, 0, 0}, |
... | ... |
@@ -220,9 +220,22 @@ int scanmanager(const struct optstruct *opt) |
220 | 220 |
/* set limits */ |
221 | 221 |
memset(&limits, 0, sizeof(struct cl_limits)); |
222 | 222 |
|
223 |
- if(opt_check(opt, "max-space")) { |
|
223 |
+ if(opt_check(opt, "max-scansize")) { |
|
224 | 224 |
char *cpy, *ptr; |
225 |
- ptr = opt_arg(opt, "max-space"); |
|
225 |
+ ptr = opt_arg(opt, "max-scansize"); |
|
226 |
+ if(tolower(ptr[strlen(ptr) - 1]) == 'm') { |
|
227 |
+ cpy = calloc(strlen(ptr), 1); |
|
228 |
+ strncpy(cpy, ptr, strlen(ptr) - 1); |
|
229 |
+ limits.maxfilesize = atoi(cpy) * 1024 * 1024; |
|
230 |
+ free(cpy); |
|
231 |
+ } else |
|
232 |
+ limits.maxscansize = atoi(ptr) * 1024; |
|
233 |
+ } else |
|
234 |
+ limits.maxscansize = 104857600; /* FIXMELIMITS */ |
|
235 |
+ |
|
236 |
+ if(opt_check(opt, "max-filesize")) { |
|
237 |
+ char *cpy, *ptr; |
|
238 |
+ ptr = opt_arg(opt, "max-filesize"); |
|
226 | 239 |
if(tolower(ptr[strlen(ptr) - 1]) == 'm') { |
227 | 240 |
cpy = calloc(strlen(ptr), 1); |
228 | 241 |
strncpy(cpy, ptr, strlen(ptr) - 1); |
... | ... |
@@ -231,7 +244,7 @@ int scanmanager(const struct optstruct *opt) |
231 | 231 |
} else |
232 | 232 |
limits.maxfilesize = atoi(ptr) * 1024; |
233 | 233 |
} else |
234 |
- limits.maxfilesize = 10485760; |
|
234 |
+ limits.maxfilesize = 10485760; /* FIXMELIMITS */ |
|
235 | 235 |
|
236 | 236 |
if(opt_check(opt, "max-files")) |
237 | 237 |
limits.maxfiles = atoi(opt_arg(opt, "max-files")); |
... | ... |
@@ -243,16 +256,6 @@ int scanmanager(const struct optstruct *opt) |
243 | 243 |
else |
244 | 244 |
limits.maxreclevel = 8; |
245 | 245 |
|
246 |
- if(opt_check(opt, "max-mail-recursion")) |
|
247 |
- limits.maxmailrec = atoi(opt_arg(opt, "max-mail-recursion")); |
|
248 |
- else |
|
249 |
- limits.maxmailrec = 64; |
|
250 |
- |
|
251 |
- if(opt_check(opt, "max-ratio")) |
|
252 |
- limits.maxratio = atoi(opt_arg(opt, "max-ratio")); |
|
253 |
- else |
|
254 |
- limits.maxratio = 250; |
|
255 |
- |
|
256 | 246 |
/* set options */ |
257 | 247 |
|
258 | 248 |
if(opt_check(opt, "disable-archive") || opt_check(opt, "no-archive")) |
... | ... |
@@ -266,9 +269,6 @@ int scanmanager(const struct optstruct *opt) |
266 | 266 |
if(opt_check(opt, "block-encrypted")) |
267 | 267 |
options |= CL_SCAN_BLOCKENCRYPTED; |
268 | 268 |
|
269 |
- if(opt_check(opt, "block-max")) |
|
270 |
- options |= CL_SCAN_BLOCKMAX; |
|
271 |
- |
|
272 | 269 |
if(opt_check(opt, "no-pe")) |
273 | 270 |
options &= ~CL_SCAN_PE; |
274 | 271 |
else |
... | ... |
@@ -425,9 +425,10 @@ static int clamav_unpack(const char *prog, const char **args, const char *tmpdir |
425 | 425 |
else |
426 | 426 |
maxfiles = 0; |
427 | 427 |
|
428 |
- if(opt_check(opt, "max-space")) { |
|
428 |
+ /* FIXMELIMITS */ |
|
429 |
+ if(opt_check(opt, "max-filesize")) { |
|
429 | 430 |
char *cpy, *ptr; |
430 |
- ptr = opt_arg(opt, "max-space"); |
|
431 |
+ ptr = opt_arg(opt, "max-filesize"); |
|
431 | 432 |
if(tolower(ptr[strlen(ptr) - 1]) == 'm') { /* megabytes */ |
432 | 433 |
cpy = calloc(strlen(ptr), 1); |
433 | 434 |
strncpy(cpy, ptr, strlen(ptr) - 1); |
... | ... |
@@ -224,10 +224,6 @@ LocalSocket /tmp/clamd.socket |
224 | 224 |
# Default: no |
225 | 225 |
#MailFollowURLs no |
226 | 226 |
|
227 |
-# Recursion level limit for the mail scanner. |
|
228 |
-# Default: 64 |
|
229 |
-#MailMaxRecursion 128 |
|
230 |
- |
|
231 | 227 |
# With this option enabled ClamAV will try to detect phishing attempts by using |
232 | 228 |
# signatures. |
233 | 229 |
# Default: yes |
... | ... |
@@ -270,28 +266,27 @@ LocalSocket /tmp/clamd.socket |
270 | 270 |
# The options below protect your system against Denial of Service attacks |
271 | 271 |
# using archive bombs. |
272 | 272 |
|
273 |
+# FIXMELIMITS |
|
274 |
+# Value of 0 disables the limit. |
|
275 |
+# Default: FIXMELIMITS |
|
276 |
+#MaxScanSize 15M |
|
277 |
+ |
|
273 | 278 |
# Files in archives larger than this limit won't be scanned. |
274 | 279 |
# Value of 0 disables the limit. |
275 | 280 |
# Default: 10M |
276 |
-#ArchiveMaxFileSize 15M |
|
281 |
+#MaxFileSize 15M |
|
277 | 282 |
|
278 | 283 |
# Nested archives are scanned recursively, e.g. if a Zip archive contains a RAR |
279 | 284 |
# file, all files within it will also be scanned. This options specifies how |
280 | 285 |
# deeply the process should be continued. |
281 | 286 |
# Value of 0 disables the limit. |
282 | 287 |
# Default: 8 |
283 |
-#ArchiveMaxRecursion 10 |
|
288 |
+#MaxRecursion 10 |
|
284 | 289 |
|
285 | 290 |
# Number of files to be scanned within an archive. |
286 | 291 |
# Value of 0 disables the limit. |
287 | 292 |
# Default: 1000 |
288 |
-#ArchiveMaxFiles 1500 |
|
289 |
- |
|
290 |
-# If a file in an archive is compressed more than ArchiveMaxCompressionRatio |
|
291 |
-# times it will be marked as a virus (Oversized.ArchiveType, e.g. Oversized.Zip) |
|
292 |
-# Value of 0 disables the limit. |
|
293 |
-# Default: 250 |
|
294 |
-#ArchiveMaxCompressionRatio 300 |
|
293 |
+#MaxFiles 1500 |
|
295 | 294 |
|
296 | 295 |
# Use slower but memory efficient decompression algorithm. |
297 | 296 |
# only affects the bzip2 decompressor. |
... | ... |
@@ -302,12 +297,6 @@ LocalSocket /tmp/clamd.socket |
302 | 302 |
# Default: no |
303 | 303 |
#ArchiveBlockEncrypted no |
304 | 304 |
|
305 |
-# Mark archives as viruses (e.g. RAR.ExceededFileSize, Zip.ExceededFilesLimit) |
|
306 |
-# if ArchiveMaxFiles, ArchiveMaxFileSize, or ArchiveMaxRecursion limit is |
|
307 |
-# reached. |
|
308 |
-# Default: no |
|
309 |
-#ArchiveBlockMax no |
|
310 |
- |
|
311 | 305 |
|
312 | 306 |
## |
313 | 307 |
## Clamuko settings |
... | ... |
@@ -181,7 +181,7 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) { |
181 | 181 |
uint8_t b[300], comp; |
182 | 182 |
uint8_t *buf = b; |
183 | 183 |
uint32_t s, m4sum=0; |
184 |
- int i; |
|
184 |
+ int i, ret; |
|
185 | 185 |
unsigned int files=0; |
186 | 186 |
char tempfile[1024]; |
187 | 187 |
struct UNP UNP; |
... | ... |
@@ -192,7 +192,7 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) { |
192 | 192 |
for (i=0; i<16; i++) |
193 | 193 |
m4sum += buf[i]; |
194 | 194 |
|
195 |
- while(!ctx->limits || !ctx->limits->maxfiles || files < ctx->limits->maxfiles) { |
|
195 |
+ while((ret=cli_checklimits("autoit", ctx, 0, 0, 0))==CL_CLEAN) { |
|
196 | 196 |
buf = b; |
197 | 197 |
if (cli_readn(desc, buf, 8)!=8) |
198 | 198 |
return CL_CLEAN; |
... | ... |
@@ -250,8 +250,8 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) { |
250 | 250 |
cli_dbgmsg("autoit: advertised uncompressed size %x\n", cli_readint32((char *)buf+5) ^ 0x45aa); |
251 | 251 |
cli_dbgmsg("autoit: ref chksum: %x\n", cli_readint32((char *)buf+9) ^ 0xc3d2); |
252 | 252 |
|
253 |
- if(ctx->limits && ctx->limits->maxfilesize && UNP.csize > ctx->limits->maxfilesize) { |
|
254 |
- cli_dbgmsg("autoit: skipping file due to size limit (%u, max: %lu)\n", UNP.csize, ctx->limits->maxfilesize); |
|
253 |
+ |
|
254 |
+ if(cli_checklimits("autoit", ctx, UNP.csize, 0, 0)!=CL_CLEAN) { |
|
255 | 255 |
lseek(desc, UNP.csize, SEEK_CUR); |
256 | 256 |
continue; |
257 | 257 |
} |
... | ... |
@@ -275,8 +275,7 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) { |
275 | 275 |
|
276 | 276 |
if(!(UNP.usize = be32_to_host(*(uint32_t *)(buf+4)))) |
277 | 277 |
UNP.usize = UNP.csize; /* only a specifically crafted or badly corrupted sample should land here */ |
278 |
- if(ctx->limits && ctx->limits->maxfilesize && UNP.usize > ctx->limits->maxfilesize) { |
|
279 |
- cli_dbgmsg("autoit: skipping file due to size limit (%u, max: %lu)\n", UNP.csize, ctx->limits->maxfilesize); |
|
278 |
+ if(cli_checklimits("autoit", ctx, UNP.usize, 0, 0)!=CL_CLEAN) { |
|
280 | 279 |
free(buf); |
281 | 280 |
continue; |
282 | 281 |
} |
... | ... |
@@ -382,8 +381,7 @@ static int ea05(int desc, cli_ctx *ctx, char *tmpd) { |
382 | 382 |
close(i); |
383 | 383 |
if(!cli_leavetemps_flag) unlink(tempfile); |
384 | 384 |
} |
385 |
- cli_dbgmsg("autoit: files limit reached (max: %u)\n", ctx->limits->maxfiles); |
|
386 |
- return CL_EMAXFILES; |
|
385 |
+ return ret; |
|
387 | 386 |
} |
388 | 387 |
|
389 | 388 |
|
... | ... |
@@ -478,7 +476,7 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) { |
478 | 478 |
uint8_t b[600], comp, script; |
479 | 479 |
uint8_t *buf; |
480 | 480 |
uint32_t s; |
481 |
- int i; |
|
481 |
+ int i, ret; |
|
482 | 482 |
unsigned int files=0; |
483 | 483 |
char tempfile[1024]; |
484 | 484 |
const char prefixes[] = { '\0', '\0', '@', '$', '\0', '.', '"', '#' }; |
... | ... |
@@ -492,7 +490,7 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) { |
492 | 492 |
/* buf+=0x10; */ |
493 | 493 |
lseek(desc, 16, SEEK_CUR); /* for now we just skip the garbage */ |
494 | 494 |
|
495 |
- while(!ctx->limits || !ctx->limits->maxfiles || files < ctx->limits->maxfiles) { |
|
495 |
+ while((ret=cli_checklimits("cli_autoit", ctx, 0, 0, 0))==CL_CLEAN) { |
|
496 | 496 |
buf = b; |
497 | 497 |
if (cli_readn(desc, buf, 8)!=8) |
498 | 498 |
return CL_CLEAN; |
... | ... |
@@ -555,8 +553,7 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) { |
555 | 555 |
cli_dbgmsg("autoit: advertised uncompressed size %x\n", cli_readint32((char *)buf+5) ^ 0x87bc); |
556 | 556 |
cli_dbgmsg("autoit: ref chksum: %x\n", cli_readint32((char *)buf+9) ^ 0xa685); |
557 | 557 |
|
558 |
- if(ctx->limits && ctx->limits->maxfilesize && UNP.csize > ctx->limits->maxfilesize) { |
|
559 |
- cli_dbgmsg("autoit: skipping file due to size limit (%u, max: %lu)\n", UNP.csize, ctx->limits->maxfilesize); |
|
558 |
+ if(cli_checklimits("autoit", ctx, UNP.csize, 0, 0)!=CL_CLEAN) { |
|
560 | 559 |
lseek(desc, UNP.csize, SEEK_CUR); |
561 | 560 |
continue; |
562 | 561 |
} |
... | ... |
@@ -581,7 +578,7 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) { |
581 | 581 |
|
582 | 582 |
if(!(UNP.usize = be32_to_host(*(uint32_t *)(buf+4)))) |
583 | 583 |
UNP.usize = UNP.csize; /* only a specifically crafted or badly corrupted sample should land here */ |
584 |
- if(ctx->limits && ctx->limits->maxfilesize && UNP.usize > ctx->limits->maxfilesize) { |
|
584 |
+ if(cli_checklimits("autoit", ctx, UNP.usize, 0, 0)!=CL_CLEAN) { |
|
585 | 585 |
free(buf); |
586 | 586 |
continue; |
587 | 587 |
} |
... | ... |
@@ -893,8 +890,7 @@ static int ea06(int desc, cli_ctx *ctx, char *tmpd) { |
893 | 893 |
close(i); |
894 | 894 |
if(!cli_leavetemps_flag) unlink(tempfile); |
895 | 895 |
} |
896 |
- cli_dbgmsg("autoit: Files limit reached (max: %u)\n", ctx->limits->maxfiles); |
|
897 |
- return CL_EMAXFILES; |
|
896 |
+ return ret; |
|
898 | 897 |
} |
899 | 898 |
|
900 | 899 |
#endif /* FPU_WORDS_BIGENDIAN */ |
... | ... |
@@ -617,7 +617,7 @@ fileblobAddData(fileblob *fb, const unsigned char *data, size_t len) |
617 | 617 |
if(ctx) { |
618 | 618 |
int do_scan = 1; |
619 | 619 |
|
620 |
- if(ctx->limits) |
|
620 |
+ if(ctx->limits && ctx->limits->maxfilesize) /* FIXMELIMITS */ |
|
621 | 621 |
if(fb->bytes_scanned >= ctx->limits->maxfilesize) |
622 | 622 |
do_scan = 0; |
623 | 623 |
|
... | ... |
@@ -116,5 +116,8 @@ int cli_chm_open(int fd, const char *dirname, chm_metadata_t *metadata); |
116 | 116 |
int cli_chm_prepare_file(int fd, char *dirname, chm_metadata_t *metadata); |
117 | 117 |
int cli_chm_extract_file(int fd, char *dirname, chm_metadata_t *metadata); |
118 | 118 |
void cli_chm_close(chm_metadata_t *metadata); |
119 |
- |
|
119 |
+int cli_chm_open(int fd, const char *dirname, chm_metadata_t *metadata); |
|
120 |
+void cli_chm_close(chm_metadata_t *metadata); |
|
121 |
+int cli_chm_extract_file(int fd, char *dirname, chm_metadata_t *metadata); |
|
122 |
+int cli_chm_prepare_file(int fd, char *dirname, chm_metadata_t *metadata); |
|
120 | 123 |
#endif |
... | ... |
@@ -142,16 +142,17 @@ struct cl_engine { |
142 | 142 |
}; |
143 | 143 |
|
144 | 144 |
struct cl_limits { |
145 |
+ unsigned long int maxscansize; /* during the scanning of archives this size |
|
146 |
+ * will never be exceeded |
|
147 |
+ */ |
|
148 |
+ unsigned long int maxfilesize; /* compressed files will only be decompressed |
|
149 |
+ * and scanned up to this size |
|
150 |
+ */ |
|
145 | 151 |
unsigned int maxreclevel; /* maximum recursion level for archives */ |
146 | 152 |
unsigned int maxfiles; /* maximum number of files to be scanned |
147 | 153 |
* within a single archive |
148 | 154 |
*/ |
149 |
- unsigned int maxmailrec; /* maximum recursion level for mail files */ |
|
150 |
- unsigned int maxratio; /* maximum compression ratio */ |
|
151 | 155 |
unsigned short archivememlim; /* limit memory usage for some unpackers */ |
152 |
- unsigned long int maxfilesize; /* compressed files larger than this limit |
|
153 |
- * will not be scanned |
|
154 |
- */ |
|
155 | 156 |
}; |
156 | 157 |
|
157 | 158 |
struct cl_stat { |
... | ... |
@@ -1988,7 +1988,6 @@ parseEmailHeader(message *m, const char *line, const table_t *rfc821) |
1988 | 1988 |
|
1989 | 1989 |
/* |
1990 | 1990 |
* This is a recursive routine. |
1991 |
- * FIXME: We are not passed &mrec so we can't check against MAX_MAIL_RECURSION |
|
1992 | 1991 |
* |
1993 | 1992 |
* This function parses the body of mainMessage and saves its attachments in dir |
1994 | 1993 |
* |
... | ... |
@@ -2011,22 +2010,17 @@ parseEmailBody(message *messageIn, text *textIn, mbox_ctx *mctx, unsigned int re |
2011 | 2011 |
cli_dbgmsg("in parseEmailBody, %u files saved so far\n", |
2012 | 2012 |
mctx->files); |
2013 | 2013 |
|
2014 |
- if(limits) { |
|
2015 |
- if(limits->maxmailrec) { |
|
2014 |
+ if(limits) { /* FIXMELIMITS */ |
|
2015 |
+ if(limits->maxreclevel) { |
|
2016 | 2016 |
const cli_ctx *ctx = mctx->ctx; /* needed for BLOCKMAX :-( */ |
2017 | 2017 |
|
2018 | 2018 |
/* |
2019 | 2019 |
* This is approximate |
2020 | 2020 |
*/ |
2021 |
- if(recursion_level > limits->maxmailrec) { |
|
2021 |
+ if(recursion_level > limits->maxreclevel) { |
|
2022 | 2022 |
|
2023 | 2023 |
cli_warnmsg("parseEmailBody: hit maximum recursion level (%u)\n", recursion_level); |
2024 |
- if(BLOCKMAX) { |
|
2025 |
- if(ctx->virname) |
|
2026 |
- *ctx->virname = "MIME.RecursionLimit"; |
|
2027 |
- return VIRUS; |
|
2028 |
- } else |
|
2029 |
- return MAXREC; |
|
2024 |
+ return MAXREC; |
|
2030 | 2025 |
} |
2031 | 2026 |
} |
2032 | 2027 |
if(limits->maxfiles && (mctx->files >= limits->maxfiles)) { |
... | ... |
@@ -108,15 +108,8 @@ int cli_msexpand(int fd, int ofd, cli_ctx *ctx) |
108 | 108 |
|
109 | 109 |
cli_dbgmsg("MSEXPAND: File size from header: %u\n", hdr.fsize); |
110 | 110 |
|
111 |
- if(ctx->limits && ctx->limits->maxfilesize && (hdr.fsize > ctx->limits->maxfilesize)) { |
|
112 |
- cli_dbgmsg("MSEXPAND: Size exceeded (%u, max: %lu)\n", hdr.fsize, ctx->limits->maxfilesize); |
|
113 |
- if(BLOCKMAX) { |
|
114 |
- *ctx->virname = "MSEXPAND.ExceededFileSize"; |
|
115 |
- return CL_VIRUS; |
|
116 |
- } |
|
117 |
- hdr.fsize = ctx->limits->maxfilesize; |
|
118 |
- cli_dbgmsg("MSEXPAND: Only extracting first %u bytes\n", hdr.fsize); /* may extract up to 2kB more */ |
|
119 |
- } |
|
111 |
+ if(cli_checklimits("MSEXPAND", ctx, hdr.fsize, 0, 0)!=CL_CLEAN) |
|
112 |
+ return CL_SUCCESS; |
|
120 | 113 |
|
121 | 114 |
while(1) { |
122 | 115 |
|
... | ... |
@@ -163,7 +163,6 @@ static int nsis_decomp(struct nsis_st *n) { |
163 | 163 |
break; |
164 | 164 |
case Z_STREAM_END: |
165 | 165 |
ret = CL_BREAK; |
166 |
- /* FIXME: regression needed */ |
|
167 | 166 |
} |
168 | 167 |
n->nsis.avail_in = n->z.avail_in; |
169 | 168 |
n->nsis.next_in = n->z.next_in; |
... | ... |
@@ -184,10 +183,9 @@ static int nsis_unpack_next(struct nsis_st *n, cli_ctx *ctx) { |
184 | 184 |
cli_dbgmsg("NSIS: extraction complete\n"); |
185 | 185 |
return CL_BREAK; |
186 | 186 |
} |
187 |
- if (ctx->limits && ctx->limits->maxfiles && n->fno >= ctx->limits->maxfiles) { |
|
188 |
- cli_dbgmsg("NSIS: Files limit reached (max: %u)\n", ctx->limits->maxfiles); |
|
189 |
- return CL_EMAXFILES; |
|
190 |
- } |
|
187 |
+ |
|
188 |
+ if ((ret=cli_checklimits("NSIS", ctx, 0, 0, 0))!=CL_CLEAN) |
|
189 |
+ return ret; |
|
191 | 190 |
|
192 | 191 |
if (n->fno) |
193 | 192 |
snprintf(n->ofn, 1023, "%s/content.%.3u", n->dir, n->fno); |
... | ... |
@@ -225,11 +223,10 @@ static int nsis_unpack_next(struct nsis_st *n, cli_ctx *ctx) { |
225 | 225 |
|
226 | 226 |
n->asz -= size+4; |
227 | 227 |
|
228 |
- if (ctx->limits && ctx->limits->maxfilesize && size > ctx->limits->maxfilesize) { |
|
229 |
- cli_dbgmsg("NSIS: Skipping file due to size limit (%u, max: %lu)\n", size, ctx->limits->maxfilesize); |
|
228 |
+ if ((ret=cli_checklimits("NSIS", ctx, size, 0, 0))!=CL_CLEAN) { |
|
230 | 229 |
close(n->ofd); |
231 | 230 |
if (lseek(n->ifd, size, SEEK_CUR)==-1) return CL_EIO; |
232 |
- return CL_EMAXSIZE; |
|
231 |
+ return ret; |
|
233 | 232 |
} |
234 | 233 |
if (!(ibuf= (unsigned char *) cli_malloc(size))) { |
235 | 234 |
cli_dbgmsg("NSIS: out of memory"__AT__"\n"); |
... | ... |
@@ -274,12 +271,11 @@ static int nsis_unpack_next(struct nsis_st *n, cli_ctx *ctx) { |
274 | 274 |
n->nsis.next_out = obuf; |
275 | 275 |
n->nsis.avail_out = BUFSIZ; |
276 | 276 |
loops=0; |
277 |
- if (ctx->limits && ctx->limits->maxfilesize && size > ctx->limits->maxfilesize) { |
|
278 |
- cli_dbgmsg("NSIS: Skipping file due to size limit (%u, max: %lu)\n", size, ctx->limits->maxfilesize); |
|
277 |
+ if ((ret=cli_checklimits("NSIS", ctx, size, 0, 0))!=CL_CLEAN) { |
|
279 | 278 |
free(ibuf); |
280 | 279 |
close(n->ofd); |
281 | 280 |
nsis_shutdown(n); |
282 |
- return CL_EMAXSIZE; |
|
281 |
+ return ret; |
|
283 | 282 |
} |
284 | 283 |
} else if (++loops > 10) { |
285 | 284 |
cli_dbgmsg("NSIS: xs looping, breaking out"__AT__"\n"); |
... | ... |
@@ -367,10 +363,9 @@ static int nsis_unpack_next(struct nsis_st *n, cli_ctx *ctx) { |
367 | 367 |
} |
368 | 368 |
|
369 | 369 |
size=cli_readint32(obuf); |
370 |
- if (ctx->limits && ctx->limits->maxfilesize && size > ctx->limits->maxfilesize) { |
|
371 |
- cli_dbgmsg("NSIS: Breaking out due to filesize limit (%u, max: %lu) in solid archive\n", size, ctx->limits->maxfilesize); |
|
370 |
+ if ((ret=cli_checklimits("NSIS", ctx, size, 0, 0))!=CL_CLEAN) { |
|
372 | 371 |
close(n->ofd); |
373 |
- return CL_EFORMAT; |
|
372 |
+ return ret; |
|
374 | 373 |
} |
375 | 374 |
|
376 | 375 |
n->nsis.next_out = obuf; |
... | ... |
@@ -503,10 +498,6 @@ int cli_scannulsft(int desc, cli_ctx *ctx, off_t offset) { |
503 | 503 |
struct nsis_st nsist; |
504 | 504 |
|
505 | 505 |
cli_dbgmsg("in scannulsft()\n"); |
506 |
- if(ctx->limits && ctx->limits->maxreclevel && ctx->arec >= ctx->limits->maxreclevel) { |
|
507 |
- cli_dbgmsg("Archive recursion limit exceeded (arec == %u).\n", ctx->arec+1); |
|
508 |
- return CL_EMAXREC; |
|
509 |
- } |
|
510 | 506 |
|
511 | 507 |
memset(&nsist, 0, sizeof(struct nsis_st)); |
512 | 508 |
|
... | ... |
@@ -522,33 +513,25 @@ int cli_scannulsft(int desc, cli_ctx *ctx, off_t offset) { |
522 | 522 |
|
523 | 523 |
if(cli_leavetemps_flag) cli_dbgmsg("NSIS: Extracting files to %s\n", nsist.dir); |
524 | 524 |
|
525 |
- ctx->arec++; |
|
526 |
- |
|
527 | 525 |
do { |
528 | 526 |
ret = cli_nsis_unpack(&nsist, ctx); |
529 |
- if(ret != CL_SUCCESS) { |
|
530 |
- if(ret == CL_EMAXSIZE) { |
|
531 |
- if(BLOCKMAX) { |
|
532 |
- *ctx->virname = "NSIS.ExceededFileSize"; |
|
533 |
- ret=CL_VIRUS; |
|
534 |
- } else { |
|
535 |
- ret = nsist.solid ? CL_BREAK : CL_SUCCESS; |
|
536 |
- } |
|
537 |
- } |
|
538 |
- } else { |
|
539 |
- cli_dbgmsg("NSIS: Successully extracted file #%u\n", nsist.fno); |
|
540 |
- lseek(nsist.ofd, 0, SEEK_SET); |
|
541 |
- if(nsist.fno == 1) |
|
542 |
- ret=cli_scandesc(nsist.ofd, ctx, 0, 0, 0, NULL); |
|
543 |
- else |
|
544 |
- ret=cli_magic_scandesc(nsist.ofd, ctx); |
|
545 |
- close(nsist.ofd); |
|
546 |
- if(!cli_leavetemps_flag) |
|
547 |
- unlink(nsist.ofn); |
|
527 |
+ if (ret == CL_SUCCESS) { |
|
528 |
+ cli_dbgmsg("NSIS: Successully extracted file #%u\n", nsist.fno); |
|
529 |
+ lseek(nsist.ofd, 0, SEEK_SET); |
|
530 |
+ if(nsist.fno == 1) |
|
531 |
+ ret=cli_scandesc(nsist.ofd, ctx, 0, 0, 0, NULL); |
|
532 |
+ else |
|
533 |
+ ret=cli_magic_scandesc(nsist.ofd, ctx); |
|
534 |
+ close(nsist.ofd); |
|
535 |
+ if(!cli_leavetemps_flag) |
|
536 |
+ unlink(nsist.ofn); |
|
537 |
+ } else if(ret == CL_EMAXSIZE) { |
|
538 |
+ cli_errmsg("returned %d\n", ret); |
|
539 |
+ ret = nsist.solid ? CL_BREAK : CL_SUCCESS; |
|
548 | 540 |
} |
549 | 541 |
} while(ret == CL_SUCCESS); |
550 | 542 |
|
551 |
- if(ret == CL_BREAK) |
|
543 |
+ if(ret == CL_BREAK || ret == CL_EMAXFILES) |
|
552 | 544 |
ret = CL_CLEAN; |
553 | 545 |
|
554 | 546 |
cli_nsis_free(&nsist); |
... | ... |
@@ -558,7 +541,6 @@ int cli_scannulsft(int desc, cli_ctx *ctx, off_t offset) { |
558 | 558 |
|
559 | 559 |
free(nsist.dir); |
560 | 560 |
|
561 |
- ctx->arec--; |
|
562 | 561 |
return ret; |
563 | 562 |
} |
564 | 563 |
|
... | ... |
@@ -475,7 +475,9 @@ static void ole2_walk_property_tree(int fd, ole2_header_t *hdr, const char *dir, |
475 | 475 |
if ((prop_index < 0) || (prop_index > (int32_t) hdr->max_block_no) || (rec_level > 100) || (*file_count > 100000)) { |
476 | 476 |
return; |
477 | 477 |
} |
478 |
- |
|
478 |
+ /* FIXMELIMITS |
|
479 |
+ * DOES recursion on virtual object make sense ? |
|
480 |
+ * WHY no size checking ? */ |
|
479 | 481 |
if (limits && limits->maxfiles && (*file_count > limits->maxfiles)) { |
480 | 482 |
cli_dbgmsg("OLE2: File limit reached (max: %d)\n", limits->maxfiles); |
481 | 483 |
return; |
... | ... |
@@ -778,7 +780,7 @@ static int ole2_read_header(int fd, ole2_header_t *hdr) |
778 | 778 |
} |
779 | 779 |
#endif |
780 | 780 |
|
781 |
-int cli_ole2_extract(int fd, const char *dirname, const struct cl_limits *limits) |
|
781 |
+int cli_ole2_extract(int fd, const char *dirname, cli_ctx *ctx) |
|
782 | 782 |
{ |
783 | 783 |
ole2_header_t hdr; |
784 | 784 |
int hdr_size; |
... | ... |
@@ -878,7 +880,7 @@ int cli_ole2_extract(int fd, const char *dirname, const struct cl_limits *limits |
878 | 878 |
|
879 | 879 |
/* OR */ |
880 | 880 |
|
881 |
- ole2_walk_property_tree(fd, &hdr, dirname, 0, handler_writefile, 0, &file_count, limits); |
|
881 |
+ ole2_walk_property_tree(fd, &hdr, dirname, 0, handler_writefile, 0, &file_count, ctx->limits); |
|
882 | 882 |
|
883 | 883 |
abort: |
884 | 884 |
#ifdef HAVE_MMAP |
... | ... |
@@ -24,8 +24,8 @@ |
24 | 24 |
#ifndef __OLE2_EXTRACT_H |
25 | 25 |
#define __OLE2_EXTRACT_H |
26 | 26 |
|
27 |
-#include "clamav.h" |
|
27 |
+#include "others.h" |
|
28 | 28 |
|
29 |
-int cli_ole2_extract(int fd, const char *dirname, const struct cl_limits *limits); |
|
29 |
+int cli_ole2_extract(int fd, const char *dirname, cli_ctx *ctx); |
|
30 | 30 |
|
31 | 31 |
#endif |
... | ... |
@@ -204,6 +204,51 @@ const char *cl_strerror(int clerror) |
204 | 204 |
} |
205 | 205 |
} |
206 | 206 |
|
207 |
+int cli_checklimits(const char *who, cli_ctx *ctx, unsigned long need1, unsigned long need2, unsigned long need3) { |
|
208 |
+ int ret = CL_SUCCESS; |
|
209 |
+ unsigned long needed; |
|
210 |
+ |
|
211 |
+ /* if called without limits, go on, unpack, scan */ |
|
212 |
+ if(!ctx || !ctx->limits) return CL_CLEAN; |
|
213 |
+ |
|
214 |
+ needed = (need1>need2)?need1:need2; |
|
215 |
+ needed = (needed>need3)?needed:need3; |
|
216 |
+ |
|
217 |
+ /* if we have global scan limits */ |
|
218 |
+ if(needed && ctx->limits->maxscansize) { |
|
219 |
+ /* if the remaining scansize is too small... */ |
|
220 |
+ if(ctx->limits->maxscansize-ctx->scansize<needed) { |
|
221 |
+ /* ... we tell the caller to skip this file */ |
|
222 |
+ cli_dbgmsg("%s: scansize exceeded (initial: %lu, remaining: %lu, needed: %lu)\n", who, ctx->limits->maxscansize, ctx->scansize, needed); |
|
223 |
+ ret = CL_EMAXSIZE; |
|
224 |
+ } |
|
225 |
+ } |
|
226 |
+ |
|
227 |
+ /* if we have per-file size limits, and we are overlimit... */ |
|
228 |
+ if(needed && ctx->limits->maxfilesize && ctx->limits->maxfilesize<needed) { |
|
229 |
+ /* ... we tell the caller to skip this file */ |
|
230 |
+ cli_dbgmsg("%s: filesize exceeded (allowed: %lu, needed: %lu)\n", who, ctx->limits->maxfilesize, needed); |
|
231 |
+ ret = CL_EMAXSIZE; |
|
232 |
+ } |
|
233 |
+ |
|
234 |
+ if(ctx->limits->maxfiles && ctx->scannedfiles>=ctx->limits->maxfiles) { |
|
235 |
+ cli_dbgmsg("%s: files limit reached (max: %u)\n", who, ctx->limits->maxfiles); |
|
236 |
+ return CL_EMAXFILES; |
|
237 |
+ } |
|
238 |
+ return ret; |
|
239 |
+} |
|
240 |
+ |
|
241 |
+int cli_updatelimits(cli_ctx *ctx, unsigned long needed) { |
|
242 |
+ int ret=cli_checklimits("cli_updatelimits", ctx, needed, 0, 0); |
|
243 |
+ |
|
244 |
+ if (ret != CL_CLEAN) return ret; |
|
245 |
+ ctx->scannedfiles++; |
|
246 |
+ ctx->scansize+=needed; |
|
247 |
+ if(ctx->scansize > ctx->limits->maxscansize) |
|
248 |
+ ctx->scansize = ctx->limits->maxscansize; |
|
249 |
+ return CL_CLEAN; |
|
250 |
+} |
|
251 |
+ |
|
207 | 252 |
unsigned char *cli_md5digest(int desc) |
208 | 253 |
{ |
209 | 254 |
unsigned char *digest; |
... | ... |
@@ -636,11 +681,7 @@ int cli_rmdirs(const char *dirname) |
636 | 636 |
return -1; |
637 | 637 |
} |
638 | 638 |
|
639 |
-#ifdef C_WINDOWS |
|
640 |
- sprintf(path, "%s\\%s", dirname, dent->d_name); |
|
641 |
-#else |
|
642 | 639 |
sprintf(path, "%s/%s", dirname, dent->d_name); |
643 |
-#endif |
|
644 | 640 |
|
645 | 641 |
/* stat the file */ |
646 | 642 |
if(lstat(path, &statbuf) != -1) { |
... | ... |
@@ -83,9 +83,10 @@ typedef struct { |
83 | 83 |
const struct cli_matcher *root; |
84 | 84 |
const struct cl_engine *engine; |
85 | 85 |
const struct cl_limits *limits; |
86 |
+ unsigned long scansize; |
|
86 | 87 |
unsigned int options; |
87 |
- unsigned int arec; |
|
88 |
- unsigned int mrec; |
|
88 |
+ unsigned int recursion; |
|
89 |
+ unsigned int scannedfiles; |
|
89 | 90 |
unsigned int found_possibly_unwanted; |
90 | 91 |
struct cli_dconf *dconf; |
91 | 92 |
} cli_ctx; |
... | ... |
@@ -99,7 +100,7 @@ typedef struct { |
99 | 99 |
#define SCAN_ELF (ctx->options & CL_SCAN_ELF) |
100 | 100 |
#define SCAN_ALGO (ctx->options & CL_SCAN_ALGORITHMIC) |
101 | 101 |
#define DETECT_ENCRYPTED (ctx->options & CL_SCAN_BLOCKENCRYPTED) |
102 |
-#define BLOCKMAX (ctx->options & CL_SCAN_BLOCKMAX) |
|
102 |
+/* #define BLOCKMAX (ctx->options & CL_SCAN_BLOCKMAX) */ |
|
103 | 103 |
#define DETECT_BROKEN (ctx->options & CL_SCAN_BLOCKBROKEN) |
104 | 104 |
|
105 | 105 |
/* based on macros from A. Melnikoff */ |
... | ... |
@@ -234,5 +235,7 @@ void cli_bitset_free(bitset_t *bs); |
234 | 234 |
int cli_bitset_set(bitset_t *bs, unsigned long bit_offset); |
235 | 235 |
int cli_bitset_test(bitset_t *bs, unsigned long bit_offset); |
236 | 236 |
const char* cli_ctime(const time_t *timep, char *buf, const size_t bufsize); |
237 |
- |
|
237 |
+int cli_checklimits(const char *, cli_ctx *, unsigned long, unsigned long, unsigned long); |
|
238 |
+int cli_updatelimits(cli_ctx *, unsigned long); |
|
239 |
+unsigned long cli_getsizelimit(cli_ctx *, unsigned long); |
|
238 | 240 |
#endif |
... | ... |
@@ -79,10 +79,9 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
79 | 79 |
char *buf; /* start of memory mapped area */ |
80 | 80 |
const char *p, *q, *trailerstart; |
81 | 81 |
const char *xrefstart; /* cross reference table */ |
82 |
- const struct cl_limits *limits; |
|
83 | 82 |
/*size_t xreflength;*/ |
84 | 83 |
table_t *md5table; |
85 |
- int printed_predictor_message, printed_embedded_font_message, rc; |
|
84 |
+ int printed_predictor_message, printed_embedded_font_message, rc, ret; |
|
86 | 85 |
unsigned int files; |
87 | 86 |
struct stat statb; |
88 | 87 |
|
... | ... |
@@ -192,12 +191,11 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
192 | 192 |
|
193 | 193 |
rc = CL_CLEAN; |
194 | 194 |
files = 0; |
195 |
- limits = ctx->limits; |
|
196 | 195 |
|
197 | 196 |
/* |
198 | 197 |
* The body section consists of a sequence of indirect objects |
199 | 198 |
*/ |
200 |
- while((p < xrefstart) && (rc == CL_CLEAN) && |
|
199 |
+ while((p < xrefstart) && ((rc=cli_checklimits("cli_pdf", ctx, 0, 0, 0))==CL_CLEAN) && |
|
201 | 200 |
((q = pdf_nextobject(p, bytesleft)) != NULL)) { |
202 | 201 |
int is_ascii85decode, is_flatedecode, fout, len, has_cr; |
203 | 202 |
/*int object_number, generation_number;*/ |
... | ... |
@@ -494,11 +492,6 @@ cli_pdf(const char *dir, int desc, const cli_ctx *ctx) |
494 | 494 |
free(md5digest); |
495 | 495 |
cli_dbgmsg("cli_pdf: extracted file %u to %s\n", ++files, |
496 | 496 |
fullname); |
497 |
- if(limits && limits->maxfiles && (files >= limits->maxfiles)) { |
|
498 |
- /* Bug 698 */ |
|
499 |
- cli_dbgmsg("cli_pdf: number of files exceeded %u\n", limits->maxfiles); |
|
500 |
- rc = CL_EMAXFILES; |
|
501 |
- } |
|
502 | 497 |
} |
503 | 498 |
|
504 | 499 |
munmap(buf, size); |
... | ... |
@@ -541,7 +534,7 @@ try_flatedecode(unsigned char *buf, off_t real_len, off_t calculated_len, int fo |
541 | 541 |
static int |
542 | 542 |
flatedecode(unsigned char *buf, off_t len, int fout, const cli_ctx *ctx) |
543 | 543 |
{ |
544 |
- int zstat; |
|
544 |
+ int zstat, ret; |
|
545 | 545 |
off_t nbytes; |
546 | 546 |
z_stream stream; |
547 | 547 |
unsigned char output[BUFSIZ]; |
... | ... |
@@ -611,17 +604,10 @@ flatedecode(unsigned char *buf, off_t len, int fout, const cli_ctx *ctx) |
611 | 611 |
} |
612 | 612 |
nbytes += written; |
613 | 613 |
|
614 |
- if(ctx->limits && |
|
615 |
- ctx->limits->maxfilesize && |
|
616 |
- (nbytes > (off_t) ctx->limits->maxfilesize)) { |
|
617 |
- cli_dbgmsg("cli_pdf: flatedecode size exceeded (%lu > %lu)\n", |
|
618 |
- (unsigned long)nbytes, (unsigned long)ctx->limits->maxfilesize); |
|
614 |
+ if((ret=cli_checklimits("cli_pdf", ctx, nbytes, 0, 0))!=CL_CLEAN) { |
|
615 |
+ /* FIXMELIMITS */ |
|
619 | 616 |
inflateEnd(&stream); |
620 |
- if(BLOCKMAX) { |
|
621 |
- *ctx->virname = "PDF.ExceededFileSize"; |
|
622 |
- return CL_VIRUS; |
|
623 |
- } |
|
624 |
- return CL_CLEAN; |
|
617 |
+ return ret; |
|
625 | 618 |
} |
626 | 619 |
stream.next_out = output; |
627 | 620 |
stream.avail_out = sizeof(output); |
... | ... |
@@ -651,28 +637,6 @@ flatedecode(unsigned char *buf, off_t len, int fout, const cli_ctx *ctx) |
651 | 651 |
} |
652 | 652 |
} |
653 | 653 |
|
654 |
- |
|
655 |
- /* |
|
656 |
- * On BSD systems total_in and total_out are "long long", so these |
|
657 |
- * numbers could (in theory) get truncated in the debug statement |
|
658 |
- */ |
|
659 |
- cli_dbgmsg("cli_pdf: flatedecode in=%lu out=%lu ratio %lu (max %u)\n", |
|
660 |
- (unsigned long)stream.total_in, (unsigned long)stream.total_out, |
|
661 |
- (unsigned long)(stream.total_out / stream.total_in), |
|
662 |
- ctx->limits ? ctx->limits->maxratio : 0); |
|
663 |
- |
|
664 |
- if(ctx->limits && |
|
665 |
- ctx->limits->maxratio && |
|
666 |
- ((stream.total_out / stream.total_in) > ctx->limits->maxratio)) { |
|
667 |
- cli_dbgmsg("cli_pdf: flatedecode Max ratio reached\n"); |
|
668 |
- inflateEnd(&stream); |
|
669 |
- if(BLOCKMAX) { |
|
670 |
- *ctx->virname = "Oversized.PDF"; |
|
671 |
- return CL_VIRUS; |
|
672 |
- } |
|
673 |
- return CL_CLEAN; |
|
674 |
- } |
|
675 |
- |
|
676 | 654 |
#ifdef SAVE_TMP |
677 | 655 |
unlink(tmpfilename); |
678 | 656 |
#endif |
... | ... |
@@ -82,15 +82,9 @@ |
82 | 82 |
#define PESALIGN(o,a) (((a))?(((o)/(a)+((o)%(a)!=0))*(a)):(o)) |
83 | 83 |
|
84 | 84 |
#define CLI_UNPSIZELIMITS(NAME,CHK) \ |
85 |
-if(ctx->limits && ctx->limits->maxfilesize && (CHK) > ctx->limits->maxfilesize) { \ |
|
86 |
- cli_dbgmsg(NAME": Sizes exceeded (%lu > %lu)\n", (unsigned long)(CHK), (unsigned long)ctx->limits->maxfilesize); \ |
|
87 |
- free(exe_sections); \ |
|
88 |
- if(BLOCKMAX) { \ |
|
89 |
- *ctx->virname = "PE."NAME".ExceededFileSize"; \ |
|
90 |
- return CL_VIRUS; \ |
|
91 |
- } else { \ |
|
92 |
- return CL_CLEAN; \ |
|
93 |
- } \ |
|
85 |
+if(cli_checklimits(NAME, ctx, (CHK), 0, 0)!=CL_CLEAN) { \ |
|
86 |
+ free(exe_sections); \ |
|
87 |
+ return CL_CLEAN; \ |
|
94 | 88 |
} |
95 | 89 |
|
96 | 90 |
#define CLI_UNPTEMP(NAME,FREEME) \ |
... | ... |
@@ -124,12 +118,6 @@ if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRWXU)) < 0) { \ |
124 | 124 |
close(ndesc); \ |
125 | 125 |
unlink(tempfile); \ |
126 | 126 |
cli_dbgmsg("PESpin: Size exceeded\n"); \ |
127 |
- if(BLOCKMAX) { \ |
|
128 |
- free(tempfile); \ |
|
129 |
- free(exe_sections); \ |
|
130 |
- *ctx->virname = "PE.Pespin.ExceededFileSize"; \ |
|
131 |
- return CL_VIRUS; \ |
|
132 |
- } \ |
|
133 | 127 |
free(tempfile); \ |
134 | 128 |
break; \ |
135 | 129 |
|
... | ... |
@@ -102,9 +102,6 @@ |
102 | 102 |
#include <stddef.h> |
103 | 103 |
#endif |
104 | 104 |
|
105 |
-#define MAX_MAIL_RECURSION 15 |
|
106 |
- |
|
107 |
- |
|
108 | 105 |
static int cli_scanfile(const char *filename, cli_ctx *ctx); |
109 | 106 |
|
110 | 107 |
#ifdef ENABLE_UNRAR |
... | ... |
@@ -121,10 +118,10 @@ static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx |
121 | 121 |
*sfx_check = metadata->crc; |
122 | 122 |
} |
123 | 123 |
|
124 |
- cli_dbgmsg("RAR: %s, crc32: 0x%x, encrypted: %u, compressed: %u, normal: %u, method: %u, ratio: %u (max: %u)\n", |
|
124 |
+ cli_dbgmsg("RAR: %s, crc32: 0x%x, encrypted: %u, compressed: %u, normal: %u, method: %u, ratio: %u\n", |
|
125 | 125 |
metadata->filename, metadata->crc, metadata->encrypted, (unsigned int) metadata->pack_size, |
126 | 126 |
(unsigned int) metadata->unpack_size, metadata->method, |
127 |
- metadata->pack_size ? (unsigned int) (metadata->unpack_size / metadata->pack_size) : 0, ctx->limits ? ctx->limits->maxratio : 0); |
|
127 |
+ metadata->pack_size ? (unsigned int) (metadata->unpack_size / metadata->pack_size) : 0); |
|
128 | 128 |
|
129 | 129 |
/* Scan metadata */ |
130 | 130 |
mdata = ctx->engine->rar_mlist; |
... | ... |
@@ -147,7 +144,7 @@ static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx |
147 | 147 |
if(mdata->fileno && mdata->fileno != files) |
148 | 148 |
continue; |
149 | 149 |
|
150 |
- if(mdata->maxdepth && ctx->arec > mdata->maxdepth) |
|
150 |
+ if(mdata->maxdepth && ctx->recursion > mdata->maxdepth) /* FIXMELIMITS */ |
|
151 | 151 |
continue; |
152 | 152 |
|
153 | 153 |
/* TODO add support for regex */ |
... | ... |
@@ -177,42 +174,6 @@ static int cli_unrar_scanmetadata(int desc, unrar_metadata_t *metadata, cli_ctx |
177 | 177 |
return ret; |
178 | 178 |
} |
179 | 179 |
|
180 |
-static int cli_unrar_checklimits(const cli_ctx *ctx, const unrar_metadata_t *metadata, unsigned int files) |
|
181 |
-{ |
|
182 |
- if(ctx->limits) { |
|
183 |
- if(ctx->limits->maxratio && metadata->unpack_size && metadata->pack_size) { |
|
184 |
- if(metadata->unpack_size / metadata->pack_size >= ctx->limits->maxratio) { |
|
185 |
- cli_dbgmsg("RAR: Max ratio reached (%u, max: %u)\n", (unsigned int) (metadata->unpack_size / metadata->pack_size), ctx->limits->maxratio); |
|
186 |
- if(BLOCKMAX) { |
|
187 |
- *ctx->virname = "Oversized.RAR"; |
|
188 |
- return CL_VIRUS; |
|
189 |
- } |
|
190 |
- return CL_EMAXSIZE; |
|
191 |
- } |
|
192 |
- } |
|
193 |
- |
|
194 |
- if(ctx->limits->maxfilesize && (metadata->unpack_size > ctx->limits->maxfilesize)) { |
|
195 |
- cli_dbgmsg("RAR: %s: Size exceeded (%lu, max: %lu)\n", metadata->filename, (unsigned long int) metadata->unpack_size, ctx->limits->maxfilesize); |
|
196 |
- if(BLOCKMAX) { |
|
197 |
- *ctx->virname = "RAR.ExceededFileSize"; |
|
198 |
- return CL_VIRUS; |
|
199 |
- } |
|
200 |
- return CL_EMAXSIZE; |
|
201 |
- } |
|
202 |
- |
|
203 |
- if(ctx->limits->maxfiles && (files > ctx->limits->maxfiles)) { |
|
204 |
- cli_dbgmsg("RAR: Files limit reached (max: %u)\n", ctx->limits->maxfiles); |
|
205 |
- if(BLOCKMAX) { |
|
206 |
- *ctx->virname = "RAR.ExceededFilesLimit"; |
|
207 |
- return CL_VIRUS; |
|
208 |
- } |
|
209 |
- return CL_EMAXFILES; |
|
210 |
- } |
|
211 |
- } |
|
212 |
- |
|
213 |
- return CL_SUCCESS; |
|
214 |
-} |
|
215 |
- |
|
216 | 180 |
static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check) |
217 | 181 |
{ |
218 | 182 |
int ret = CL_CLEAN; |
... | ... |
@@ -258,17 +219,11 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c |
258 | 258 |
ret = CL_ERAR; |
259 | 259 |
break; |
260 | 260 |
} |
261 |
- ret = cli_unrar_checklimits(ctx, rar_state.metadata_tail, rar_state.file_count); |
|
262 |
- if(ret && ret != CL_VIRUS) { |
|
261 |
+ if((ret=cli_checklimits("RAR", ctx, rar_state.metadata_tail->unpack_size, rar_state.metadata_tail->pack_size, 0)!=CL_CLEAN)) { |
|
263 | 262 |
free(rar_state.file_header->filename); |
264 | 263 |
free(rar_state.file_header); |
265 | 264 |
ret = CL_CLEAN; |
266 | 265 |
continue; |
267 |
- } else if(ret == CL_VIRUS) { |
|
268 |
- /* needed since we didn't reach unrar_extract_next to clean this up*/ |
|
269 |
- free(rar_state.file_header->filename); |
|
270 |
- free(rar_state.file_header); |
|
271 |
- break; |
|
272 | 266 |
} |
273 | 267 |
ret = unrar_extract_next(&rar_state,dir); |
274 | 268 |
if(ret == UNRAR_OK) |
... | ... |
@@ -324,52 +279,11 @@ static int cli_scanrar(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c |
324 | 324 |
} |
325 | 325 |
#endif /* ENABLE_UNRAR */ |
326 | 326 |
|
327 |
-static int cli_unarj_checklimits(const cli_ctx *ctx, const arj_metadata_t *metadata, unsigned int files) |
|
328 |
-{ |
|
329 |
- if (ctx->limits) { |
|
330 |
- if (ctx->limits->maxfilesize && (metadata->orig_size > ctx->limits->maxfilesize)) { |
|
331 |
- cli_dbgmsg("ARJ: %s: Size exceeded (%lu, max: %lu)\n", metadata->filename ? metadata->filename : "(none)", |
|
332 |
- (unsigned long int) metadata->orig_size, ctx->limits->maxfilesize); |
|
333 |
- if (BLOCKMAX) { |
|
334 |
- *ctx->virname = "ARJ.ExceededFileSize"; |
|
335 |
- return CL_VIRUS; |
|
336 |
- } |
|
337 |
- return CL_EMAXSIZE; |
|
338 |
- } |
|
339 |
- |
|
340 |
- if (ctx->limits->maxratio && metadata->orig_size && metadata->comp_size) { |
|
341 |
- if (metadata->orig_size / metadata->comp_size >= ctx->limits->maxratio) { |
|
342 |
- cli_dbgmsg("ARJ: Max ratio reached (%u, max: %u)\n", (unsigned int) (metadata->orig_size / metadata->comp_size), ctx->limits->maxratio); |
|
343 |
- if (ctx->limits->maxfilesize && (metadata->orig_size <= ctx->limits->maxfilesize)) { |
|
344 |
- cli_dbgmsg("ARJ: Ignoring ratio limit (file size doesn't hit limits)\n"); |
|
345 |
- } else { |
|
346 |
- if(BLOCKMAX) { |
|
347 |
- *ctx->virname = "Oversized.ARJ"; |
|
348 |
- return CL_VIRUS; |
|
349 |
- } |
|
350 |
- } |
|
351 |
- } |
|
352 |
- } |
|
353 |
- |
|
354 |
- if(ctx->limits->maxfiles && (files > ctx->limits->maxfiles)) { |
|
355 |
- cli_dbgmsg("ARJ: Files limit reached (max: %u)\n", ctx->limits->maxfiles); |
|
356 |
- if (BLOCKMAX) { |
|
357 |
- *ctx->virname = "ARJ.ExceededFilesLimit"; |
|
358 |
- return CL_VIRUS; |
|
359 |
- } |
|
360 |
- return CL_EMAXFILES; |
|
361 |
- } |
|
362 |
- } |
|
363 |
- |
|
364 |
- return CL_SUCCESS; |
|
365 |
-} |
|
366 |
- |
|
367 | 327 |
static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_check) |
368 | 328 |
{ |
369 | 329 |
int ret = CL_CLEAN, rc; |
370 | 330 |
arj_metadata_t metadata; |
371 | 331 |
char *dir; |
372 |
- unsigned int file_count = 1; |
|
373 | 332 |
|
374 | 333 |
cli_dbgmsg("in cli_scanarj()\n"); |
375 | 334 |
|
... | ... |
@@ -400,9 +314,10 @@ static int cli_scanarj(int desc, cli_ctx *ctx, off_t sfx_offset, uint32_t *sfx_c |
400 | 400 |
if (ret != CL_SUCCESS) { |
401 | 401 |
break; |
402 | 402 |
} |
403 |
- ret = cli_unarj_checklimits(ctx, &metadata, file_count); |
|
404 |
- if (ret == CL_VIRUS) { |
|
405 |
- break; |
|
403 |
+ if ((ret = cli_checklimits("ARJ", ctx, metadata.orig_size, metadata.comp_size, 0))!=CL_CLEAN) { |
|
404 |
+ /* FIXMELIMITS: is this correct, shall I free something? */ |
|
405 |
+ ret = CL_SUCCESS; |
|
406 |
+ continue; |
|
406 | 407 |
} |
407 | 408 |
ret = cli_unarj_extract_file(desc, dir, &metadata); |
408 | 409 |
if (metadata.ofd >= 0) { |
... | ... |
@@ -472,15 +387,8 @@ static int cli_scangzip(int desc, cli_ctx *ctx) |
472 | 472 |
while((bytes = gzread(gd, buff, FILEBUFF)) > 0) { |
473 | 473 |
size += bytes; |
474 | 474 |
|
475 |
- if(ctx->limits) |
|
476 |
- if(ctx->limits->maxfilesize && (size + FILEBUFF > ctx->limits->maxfilesize)) { |
|
477 |
- cli_dbgmsg("GZip: Size exceeded (stopped at %ld, max: %ld)\n", size, ctx->limits->maxfilesize); |
|
478 |
- if(BLOCKMAX) { |
|
479 |
- *ctx->virname = "GZip.ExceededFileSize"; |
|
480 |
- ret = CL_VIRUS; |
|
481 |
- } |
|
482 |
- break; |
|
483 |
- } |
|
475 |
+ if(cli_checklimits("GZip", ctx, size + FILEBUFF, 0, 0)!=CL_CLEAN) |
|
476 |
+ break; |
|
484 | 477 |
|
485 | 478 |
if(cli_writen(fd, buff, bytes) != bytes) { |
486 | 479 |
cli_dbgmsg("GZip: Can't write to file.\n"); |
... | ... |
@@ -586,15 +494,8 @@ static int cli_scanbzip(int desc, cli_ctx *ctx) |
586 | 586 |
while((bytes = BZ2_bzRead(&bzerror, bfd, buff, FILEBUFF)) > 0) { |
587 | 587 |
size += bytes; |
588 | 588 |
|
589 |
- if(ctx->limits) |
|
590 |
- if(ctx->limits->maxfilesize && (size + FILEBUFF > ctx->limits->maxfilesize)) { |
|
591 |
- cli_dbgmsg("Bzip: Size exceeded (stopped at %ld, max: %ld)\n", size, ctx->limits->maxfilesize); |
|
592 |
- if(BLOCKMAX) { |
|
593 |
- *ctx->virname = "BZip.ExceededFileSize"; |
|
594 |
- ret = CL_VIRUS; |
|
595 |
- } |
|
596 |
- break; |
|
597 |
- } |
|
589 |
+ if(cli_checklimits("Bzip", ctx, size + FILEBUFF, 0, 0)!=CL_CLEAN) |
|
590 |
+ break; |
|
598 | 591 |
|
599 | 592 |
if(cli_writen(fd, buff, bytes) != bytes) { |
600 | 593 |
cli_dbgmsg("Bzip: Can't write to file.\n"); |
... | ... |
@@ -697,25 +598,8 @@ static int cli_scanmscab(int desc, cli_ctx *ctx, off_t sfx_offset) |
697 | 697 |
for(file = cab.files; file; file = file->next) { |
698 | 698 |
files++; |
699 | 699 |
|
700 |
- if(ctx->limits && ctx->limits->maxfilesize && (file->length > ctx->limits->maxfilesize)) { |
|
701 |
- cli_dbgmsg("CAB: %s: Size exceeded (%u, max: %lu)\n", file->name, file->length, ctx->limits->maxfilesize); |
|
702 |
- if(BLOCKMAX) { |
|
703 |
- *ctx->virname = "CAB.ExceededFileSize"; |
|
704 |
- cab_free(&cab); |
|
705 |
- return CL_VIRUS; |
|
706 |
- } |
|
700 |
+ if(cli_checklimits("CAB", ctx, file->length, 0, 0)!=CL_CLEAN) |
|
707 | 701 |
continue; |
708 |
- } |
|
709 |
- |
|
710 |
- if(ctx->limits && ctx->limits->maxfiles && (files > ctx->limits->maxfiles)) { |
|
711 |
- cli_dbgmsg("CAB: Files limit reached (max: %u)\n", ctx->limits->maxfiles); |
|
712 |
- cab_free(&cab); |
|
713 |
- if(BLOCKMAX) { |
|
714 |
- *ctx->virname = "CAB.ExceededFilesLimit"; |
|
715 |
- return CL_VIRUS; |
|
716 |
- } |
|
717 |
- return CL_CLEAN; |
|
718 |
- } |
|
719 | 702 |
|
720 | 703 |
tempname = cli_gentemp(NULL); |
721 | 704 |
cli_dbgmsg("CAB: Extracting file %s to %s, size %u\n", file->name, tempname, file->length); |
... | ... |
@@ -1190,6 +1074,9 @@ static int cli_scanole2(int desc, cli_ctx *ctx) |
1190 | 1190 |
|
1191 | 1191 |
cli_dbgmsg("in cli_scanole2()\n"); |
1192 | 1192 |
|
1193 |
+ if(ctx->limits && ctx->limits->maxreclevel && ctx->recursion >= ctx->limits->maxreclevel) |
|
1194 |
+ return CL_EMAXREC; |
|
1195 |
+ |
|
1193 | 1196 |
/* generate the temporary directory */ |
1194 | 1197 |
dir = cli_gentemp(NULL); |
1195 | 1198 |
if(mkdir(dir, 0700)) { |
... | ... |
@@ -1198,20 +1085,25 @@ static int cli_scanole2(int desc, cli_ctx *ctx) |
1198 | 1198 |
return CL_ETMPDIR; |
1199 | 1199 |
} |
1200 | 1200 |
|
1201 |
- if((ret = cli_ole2_extract(desc, dir, ctx->limits))) { |
|
1201 |
+ if((ret = cli_ole2_extract(desc, dir, ctx))) { |
|
1202 | 1202 |
cli_dbgmsg("OLE2: %s\n", cl_strerror(ret)); |
1203 | 1203 |
if(!cli_leavetemps_flag) |
1204 | 1204 |
cli_rmdirs(dir); |
1205 | 1205 |
free(dir); |
1206 |
+ ctx->recursion--; |
|
1206 | 1207 |
return ret; |
1207 | 1208 |
} |
1208 | 1209 |
|
1210 |
+ ctx->recursion++; |
|
1211 |
+ |
|
1209 | 1212 |
if((ret = cli_vba_scandir(dir, ctx)) != CL_VIRUS) { |
1210 | 1213 |
if(cli_scandir(dir, ctx) == CL_VIRUS) { |
1211 | 1214 |
ret = CL_VIRUS; |
1212 | 1215 |
} |
1213 | 1216 |
} |
1214 | 1217 |
|
1218 |
+ ctx->recursion--; |
|
1219 |
+ |
|
1215 | 1220 |
if(!cli_leavetemps_flag) |
1216 | 1221 |
cli_rmdirs(dir); |
1217 | 1222 |
free(dir); |
... | ... |
@@ -1234,7 +1126,7 @@ static int cli_scantar(int desc, cli_ctx *ctx, unsigned int posix) |
1234 | 1234 |
return CL_ETMPDIR; |
1235 | 1235 |
} |
1236 | 1236 |
|
1237 |
- if((ret = cli_untar(dir, desc, posix, ctx->limits))) |
|
1237 |
+ if((ret = cli_untar(dir, desc, posix, ctx))) |
|
1238 | 1238 |
cli_dbgmsg("Tar: %s\n", cl_strerror(ret)); |
1239 | 1239 |
else |
1240 | 1240 |
ret = cli_scandir(dir, ctx); |
... | ... |
@@ -1546,7 +1438,7 @@ static int cli_scanmail(int desc, cli_ctx *ctx) |
1546 | 1546 |
int ret; |
1547 | 1547 |
|
1548 | 1548 |
|
1549 |
- cli_dbgmsg("Starting cli_scanmail(), mrec == %u, arec == %u\n", ctx->mrec, ctx->arec); |
|
1549 |
+ cli_dbgmsg("Starting cli_scanmail(), recursion = %u\n", ctx->recursion); |
|
1550 | 1550 |
|
1551 | 1551 |
/* generate the temporary directory */ |
1552 | 1552 |
dir = cli_gentemp(NULL); |
... | ... |
@@ -1596,11 +1488,8 @@ static int cli_scanembpe(int desc, cli_ctx *ctx) |
1596 | 1596 |
while((bytes = read(desc, buff, sizeof(buff))) > 0) { |
1597 | 1597 |
size += bytes; |
1598 | 1598 |
|
1599 |
- if(ctx->limits && ctx->limits->maxfilesize && (size + sizeof(buff) > ctx->limits->maxfilesize)) { |
|
1600 |
- cli_dbgmsg("cli_scanembpe: Size exceeded (stopped at %lu, max: %lu)\n", size, ctx->limits->maxfilesize); |
|
1601 |
- /* BLOCKMAX should be ignored here */ |
|
1599 |
+ if(cli_checklimits("cli_scanembpe", ctx, size + sizeof(buff), 0, 0)!=CL_CLEAN) |
|
1602 | 1600 |
break; |
1603 |
- } |
|
1604 | 1601 |
|
1605 | 1602 |
if(cli_writen(fd, buff, bytes) != bytes) { |
1606 | 1603 |
cli_dbgmsg("cli_scanembpe: Can't write to temporary file\n"); |
... | ... |
@@ -1757,7 +1646,7 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type, uint8_t typercg) |
1757 | 1757 |
} |
1758 | 1758 |
} |
1759 | 1759 |
|
1760 |
- ret == CL_TYPE_MAIL ? ctx->mrec++ : ctx->arec++; |
|
1760 |
+ ctx->recursion++; |
|
1761 | 1761 |
|
1762 | 1762 |
if(nret != CL_VIRUS) switch(ret) { |
1763 | 1763 |
case CL_TYPE_HTML: |
... | ... |
@@ -1773,7 +1662,7 @@ static int cli_scanraw(int desc, cli_ctx *ctx, cli_file_t type, uint8_t typercg) |
1773 | 1773 |
default: |
1774 | 1774 |
break; |
1775 | 1775 |
} |
1776 |
- ret == CL_TYPE_MAIL ? ctx->mrec-- : ctx->arec--; |
|
1776 |
+ ctx->recursion--; |
|
1777 | 1777 |
ret = nret; |
1778 | 1778 |
} |
1779 | 1779 |
|
... | ... |
@@ -1798,7 +1687,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1798 | 1798 |
|
1799 | 1799 |
|
1800 | 1800 |
if(fstat(desc, &sb) == -1) { |
1801 |
- cli_errmsg("Can't fstat descriptor %d\n", desc); |
|
1801 |
+ cli_errmsg("magic_scandesc: Can't fstat descriptor %d\n", desc); |
|
1802 | 1802 |
return CL_EIO; |
1803 | 1803 |
} |
1804 | 1804 |
|
... | ... |
@@ -1819,22 +1708,13 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1819 | 1819 |
return ret; |
1820 | 1820 |
} |
1821 | 1821 |
|
1822 |
- if(SCAN_ARCHIVE && ctx->limits && ctx->limits->maxreclevel) |
|
1823 |
- if(ctx->arec > ctx->limits->maxreclevel) { |
|
1824 |
- cli_dbgmsg("Archive recursion limit exceeded (arec == %u).\n", ctx->arec); |
|
1825 |
- if(BLOCKMAX) { |
|
1826 |
- *ctx->virname = "Archive.ExceededRecursionLimit"; |
|
1827 |
- return CL_VIRUS; |
|
1828 |
- } |
|
1829 |
- return CL_CLEAN; |
|
1830 |
- } |
|
1822 |
+ if(cli_updatelimits(ctx, sb.st_size)!=CL_CLEAN) |
|
1823 |
+ return CL_CLEAN; |
|
1831 | 1824 |
|
1832 |
- if(SCAN_MAIL) |
|
1833 |
- if(ctx->mrec > MAX_MAIL_RECURSION) { |
|
1834 |
- cli_dbgmsg("Mail recursion level exceeded (mrec == %u).\n", ctx->mrec); |
|
1835 |
- /* return CL_EMAXREC; */ |
|
1836 |
- return CL_CLEAN; |
|
1837 |
- } |
|
1825 |
+ if((SCAN_MAIL || SCAN_ARCHIVE) && ctx->limits && ctx->limits->maxreclevel && ctx->recursion > ctx->limits->maxreclevel) { |
|
1826 |
+ cli_dbgmsg("Archive recursion limit exceeded (level = %u).\n", ctx->recursion); |
|
1827 |
+ return CL_CLEAN; |
|
1828 |
+ } |
|
1838 | 1829 |
|
1839 | 1830 |
lseek(desc, 0, SEEK_SET); |
1840 | 1831 |
type = cli_filetype2(desc, ctx->engine); |
... | ... |
@@ -1850,7 +1730,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1850 | 1850 |
lseek(desc, 0, SEEK_SET); |
1851 | 1851 |
} |
1852 | 1852 |
|
1853 |
- type == CL_TYPE_MAIL ? ctx->mrec++ : ctx->arec++; |
|
1853 |
+ ctx->recursion++; |
|
1854 | 1854 |
|
1855 | 1855 |
switch(type) { |
1856 | 1856 |
case CL_TYPE_IGNORED: |
... | ... |
@@ -1887,7 +1767,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1887 | 1887 |
break; |
1888 | 1888 |
|
1889 | 1889 |
case CL_TYPE_NULSFT: |
1890 |
- if(SCAN_ARCHIVE) |
|
1890 |
+ if(SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_NSIS)) |
|
1891 | 1891 |
ret = cli_scannulsft(desc, ctx, 0); |
1892 | 1892 |
break; |
1893 | 1893 |
|
... | ... |
@@ -1922,7 +1802,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
1922 | 1922 |
break; |
1923 | 1923 |
|
1924 | 1924 |
case CL_TYPE_RTF: |
1925 |
- if(DCONF_DOC & DOC_CONF_RTF) |
|
1925 |
+ if(SCAN_ARCHIVE && (DCONF_DOC & DOC_CONF_RTF)) |
|
1926 | 1926 |
ret = cli_scanrtf(desc, ctx); |
1927 | 1927 |
break; |
1928 | 1928 |
|
... | ... |
@@ -2009,7 +1889,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
2009 | 2009 |
break; |
2010 | 2010 |
} |
2011 | 2011 |
|
2012 |
- type == CL_TYPE_MAIL ? ctx->mrec-- : ctx->arec--; |
|
2012 |
+ ctx->recursion--; |
|
2013 | 2013 |
|
2014 | 2014 |
if(type == CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) { |
2015 | 2015 |
if(sb.st_size > 1048576) { |
... | ... |
@@ -2024,7 +1904,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
2024 | 2024 |
return CL_VIRUS; |
2025 | 2025 |
} |
2026 | 2026 |
|
2027 |
- ctx->arec++; |
|
2027 |
+ ctx->recursion++; |
|
2028 | 2028 |
lseek(desc, 0, SEEK_SET); |
2029 | 2029 |
switch(type) { |
2030 | 2030 |
/* Due to performance reasons all executables were first scanned |
... | ... |
@@ -2038,7 +1918,7 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
2038 | 2038 |
default: |
2039 | 2039 |
break; |
2040 | 2040 |
} |
2041 |
- ctx->arec--; |
|
2041 |
+ ctx->recursion--; |
|
2042 | 2042 |
|
2043 | 2043 |
if(ret == CL_EFORMAT) { |
2044 | 2044 |
cli_dbgmsg("Descriptor[%d]: %s\n", desc, cl_strerror(CL_EFORMAT)); |
... | ... |
@@ -2051,16 +1931,20 @@ int cli_magic_scandesc(int desc, cli_ctx *ctx) |
2051 | 2051 |
int cl_scandesc(int desc, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options) |
2052 | 2052 |
{ |
2053 | 2053 |
cli_ctx ctx; |
2054 |
+ struct cl_limits l_limits; |
|
2054 | 2055 |
int rc; |
2055 | 2056 |
|
2056 | 2057 |
memset(&ctx, '\0', sizeof(cli_ctx)); |
2057 | 2058 |
ctx.engine = engine; |
2058 | 2059 |
ctx.virname = virname; |
2059 |
- ctx.limits = limits; |
|
2060 | 2060 |
ctx.scanned = scanned; |
2061 | 2061 |
ctx.options = options; |
2062 | 2062 |
ctx.found_possibly_unwanted = 0; |
2063 | 2063 |
ctx.dconf = (struct cli_dconf *) engine->dconf; |
2064 |
+ if (limits) { |
|
2065 |
+ ctx.limits = &l_limits; |
|
2066 |
+ memcpy(&l_limits, limits, sizeof(struct cl_limits)); |
|
2067 |
+ } |
|
2064 | 2068 |
|
2065 | 2069 |
rc = cli_magic_scandesc(desc, &ctx); |
2066 | 2070 |
if(rc == CL_CLEAN && ctx.found_possibly_unwanted) |
... | ... |
@@ -453,10 +453,7 @@ static int real_scansis(FILE *f, cli_ctx *ctx, const char *tmpd) { |
453 | 453 |
cli_dbgmsg("\tSkipping empty file\n"); |
454 | 454 |
continue; |
455 | 455 |
} |
456 |
- if (ctx->limits && ctx->limits->maxfilesize && lens[j] > ctx->limits->maxfilesize) { |
|
457 |
- cli_dbgmsg("\tSkipping file due to size limit (%u, max: %lu)\n", lens[j], ctx->limits->maxfilesize); |
|
458 |
- continue; |
|
459 |
- } |
|
456 |
+ if (cli_checklimits("sis", ctx,lens[j], 0, 0)!=CL_CLEAN) continue; |
|
460 | 457 |
cli_dbgmsg("\tUnpacking lang#%d - ptr:%x csize:%x osize:%x\n", j, ptrs[j], lens[j], olens[j]); |
461 | 458 |
if (!(comp=cli_malloc(lens[j]))) { |
462 | 459 |
cli_dbgmsg("\tOOM\n"); |
... | ... |
@@ -471,15 +468,13 @@ static int real_scansis(FILE *f, cli_ctx *ctx, const char *tmpd) { |
471 | 471 |
continue; |
472 | 472 |
} |
473 | 473 |
if (compd) { |
474 |
- olen = (olens[j]<=lens[j]*3 || (ctx->limits && ctx->limits->maxfilesize && olens[j] > ctx->limits->maxfilesize)) ? lens[j]*3 : olens[j]; |
|
475 |
- if (ctx->limits && ctx->limits->maxfilesize && olen > ctx->limits->maxfilesize) { |
|
476 |
- if (olens[j] < ctx->limits->maxfilesize) |
|
477 |
- olen = olens[j]; |
|
478 |
- else { |
|
479 |
- cli_dbgmsg("\tSkipping file due to size limit (%u, max: %lu)\n", (unsigned int)olen, ctx->limits->maxfilesize); |
|
480 |
- free(comp); |
|
481 |
- continue; |
|
482 |
- } |
|
474 |
+ if (olens[j]<=lens[j]*3 && cli_checklimits("sis", ctx, lens[j]*3, 0, 0)==CL_CLEAN) |
|
475 |
+ olen=lens[j]*3; |
|
476 |
+ else if (cli_checklimits("sis", ctx, olens[j], 0, 0)==CL_CLEAN) |
|
477 |
+ olen=olens[j]; |
|
478 |
+ else { |
|
479 |
+ free(comp); |
|
480 |
+ continue; |
|
483 | 481 |
} |
484 | 482 |
|
485 | 483 |
if (!(decomp=cli_malloc(olen))) { |
... | ... |
@@ -524,12 +519,6 @@ static int real_scansis(FILE *f, cli_ctx *ctx, const char *tmpd) { |
524 | 524 |
} |
525 | 525 |
close(fd); |
526 | 526 |
umped++; |
527 |
- if (ctx->limits && umped > ctx->limits->maxfiles) { |
|
528 |
- cli_dbgmsg("NSIS: Files limit reached (max: %u)\n", ctx->limits->maxfiles); |
|
529 |
- free(ptrs); |
|
530 |
- free(alangs); |
|
531 |
- return CL_EMAXFILES; |
|
532 |
- } |
|
533 | 527 |
} |
534 | 528 |
fseek(f,fpos,SEEK_SET); |
535 | 529 |
} |
... | ... |
@@ -726,10 +715,7 @@ static int real_scansis9x(FILE *f, cli_ctx *ctx, const char *tmpd) { |
726 | 726 |
fseek(s->f, -(long)s->sleft, SEEK_CUR); |
727 | 727 |
s->sleft = s->smax = 0; |
728 | 728 |
|
729 |
- if (ctx->limits && ctx->limits->maxfilesize && ALIGN4(s->fsize[s->level]) > ctx->limits->maxfilesize) { |
|
730 |
- cli_dbgmsg("SIS: Skipping file due to size limit (%u, max: %lu)\n", ALIGN4(s->fsize[s->level]), ctx->limits->maxfilesize); |
|
731 |
- break; |
|
732 |
- } |
|
729 |
+ if (cli_checklimits("sis", ctx,ALIGN4(s->fsize[s->level]), 0, 0)!=CL_CLEAN) break; |
|
733 | 730 |
if (!(src=cli_malloc(ALIGN4(s->fsize[s->level])))) break; |
734 | 731 |
if (fread(src, ALIGN4(s->fsize[s->level]),1,s->f) != 1) { |
735 | 732 |
free(src); |
... | ... |
@@ -739,16 +725,15 @@ static int real_scansis9x(FILE *f, cli_ctx *ctx, const char *tmpd) { |
739 | 739 |
if(field) { /* compressed */ |
740 | 740 |
int zresult; |
741 | 741 |
|
742 |
- uusize = (usize<=s->fsize[s->level]*3 || (ctx->limits && ctx->limits->maxfilesize && uusize > ctx->limits->maxfilesize)) ? s->fsize[s->level]*3 : usize; |
|
743 |
- if (ctx->limits && ctx->limits->maxfilesize && uusize > ctx->limits->maxfilesize) { |
|
744 |
- if (usize < ctx->limits->maxfilesize) |
|
745 |
- uusize = usize; |
|
746 |
- else { |
|
747 |
- cli_dbgmsg("\tSkipping file due to size limit (%u, max: %lu)\n", (unsigned int)uusize, ctx->limits->maxfilesize); |
|
748 |
- free(src); |
|
749 |
- break; |
|
750 |
- } |
|
742 |
+ if (usize<=s->fsize[s->level]*3 && cli_checklimits("sis", ctx, s->fsize[s->level]*3, 0, 0)==CL_CLEAN) |
|
743 |
+ uusize=s->fsize[s->level]*3; |
|
744 |
+ else if (cli_checklimits("sis", ctx, usize, 0, 0)==CL_CLEAN) |
|
745 |
+ uusize=usize; |
|
746 |
+ else { |
|
747 |
+ free(src); |
|
748 |
+ break; |
|
751 | 749 |
} |
750 |
+ |
|
752 | 751 |
if (!(dst=cli_malloc(uusize))) { |
753 | 752 |
free(src); |
754 | 753 |
break; |
... | ... |
@@ -372,6 +372,7 @@ int unspin(char *src, int ssize, struct cli_exe_section *sections, int sectcnt, |
372 | 372 |
bitmap = cli_readint32(ep+0x3061); |
373 | 373 |
bitman = bitmap; |
374 | 374 |
|
375 |
+ /* FIXMELIMITS */ |
|
375 | 376 |
if(ctx->limits && ctx->limits->maxfilesize) { |
376 | 377 |
unsigned long int filesize = 0; |
377 | 378 |
|
... | ... |
@@ -142,9 +142,9 @@ uint32_t unspack(char *start_of_stuff, char *dest, cli_ctx *ctx, uint32_t rva, u |
142 | 142 |
i = allocsz; |
143 | 143 |
c = (tre+i)&0xff; |
144 | 144 |
tablesz = ((0x300<<c)+0x736)*sizeof(uint16_t); |
145 |
- if(ctx->limits && ctx->limits->maxfilesize && tablesz > ctx->limits->maxfilesize) { |
|
145 |
+ |
|
146 |
+ if(cli_checklimits("nspack", ctx, tablesz, 0, 0)!=CL_CLEAN) |
|
146 | 147 |
return 1; /* Should be ~15KB, if it's so big it's prolly just not nspacked */ |
147 |
- } |
|
148 | 148 |
|
149 | 149 |
cli_dbgmsg("unsp: table size = %d\n", tablesz); |
150 | 150 |
if (!(table = cli_malloc(tablesz))) return 1; |
... | ... |
@@ -61,9 +61,9 @@ octal(const char *str) |
61 | 61 |
} |
62 | 62 |
|
63 | 63 |
int |
64 |
-cli_untar(const char *dir, int desc, unsigned int posix, const struct cl_limits *limits) |
|
64 |
+cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx) |
|
65 | 65 |
{ |
66 |
- int size = 0; |
|
66 |
+ int size = 0, ret; |
|
67 | 67 |
int in_block = 0; |
68 | 68 |
unsigned int files = 0; |
69 | 69 |
char fullname[NAME_MAX + 1]; |
... | ... |
@@ -103,11 +103,8 @@ cli_untar(const char *dir, int desc, unsigned int posix, const struct cl_limits |
103 | 103 |
|
104 | 104 |
if(block[0] == '\0') /* We're done */ |
105 | 105 |
break; |
106 |
- |
|
107 |
- if(limits && limits->maxfiles && (files >= limits->maxfiles)) { |
|
108 |
- cli_dbgmsg("cli_untar: number of files exceeded %u\n", limits->maxfiles); |
|
109 |
- return CL_CLEAN; |
|
110 |
- } |
|
106 |
+ if((ret=cli_checklimits("cli_untar", ctx, 0, 0, 0))!=CL_CLEAN) |
|
107 |
+ return ret; |
|
111 | 108 |
|
112 | 109 |
/* Notice assumption that BLOCKSIZE > 262 */ |
113 | 110 |
if(posix) { |
... | ... |
@@ -176,8 +173,7 @@ cli_untar(const char *dir, int desc, unsigned int posix, const struct cl_limits |
176 | 176 |
return CL_EFORMAT; |
177 | 177 |
} |
178 | 178 |
cli_dbgmsg("cli_untar: size = %d\n", size); |
179 |
- if(limits && limits->maxfilesize && ((unsigned int)size > limits->maxfilesize)) { |
|
180 |
- cli_dbgmsg("cli_untar: size exceeded %d bytes\n", size); |
|
179 |
+ if((ret=cli_checklimits("cli_untar", ctx, size, 0, 0))!=CL_CLEAN) { |
|
181 | 180 |
skipEntry++; |
182 | 181 |
} |
183 | 182 |
|
... | ... |
@@ -250,7 +246,7 @@ cli_untar(const char *dir, int desc, unsigned int posix, const struct cl_limits |
250 | 250 |
} |
251 | 251 |
if (size == 0) |
252 | 252 |
in_block = 0; |
253 |
- } |
|
253 |
+ } |
|
254 | 254 |
if(outfile) |
255 | 255 |
return fclose(outfile); |
256 | 256 |
|
... | ... |
@@ -34,4 +34,12 @@ |
34 | 34 |
* First draft |
35 | 35 |
* |
36 | 36 |
*/ |
37 |
-int cli_untar(const char *dir, int desc, unsigned int posix, const struct cl_limits *limits); |
|
37 |
+ |
|
38 |
+#ifndef __UNTAR_H |
|
39 |
+#define __UNTAR_H |
|
40 |
+ |
|
41 |
+#include "others.h" |
|
42 |
+ |
|
43 |
+int cli_untar(const char *dir, int desc, unsigned int posix, cli_ctx *ctx); |
|
44 |
+ |
|
45 |
+#endif |
... | ... |
@@ -93,11 +93,6 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui |
93 | 93 |
} |
94 | 94 |
if(res==1) { |
95 | 95 |
if(ctx->limits && ctx->limits->maxfilesize && csize > ctx->limits->maxfilesize) { |
96 |
- if(BLOCKMAX) { |
|
97 |
- *ctx->virname = "Zip.ExceededFileSize"; |
|
98 |
- ret = CL_VIRUS; |
|
99 |
- break; |
|
100 |
- } |
|
101 | 96 |
cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->limits->maxfilesize); |
102 | 97 |
csize = ctx->limits->maxfilesize; |
103 | 98 |
} |
... | ... |
@@ -159,11 +154,6 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui |
159 | 159 |
if(*avail_out!=sizeof(obuf)) { |
160 | 160 |
written+=sizeof(obuf)-(*avail_out); |
161 | 161 |
if(ctx->limits && ctx->limits->maxfilesize && written > ctx->limits->maxfilesize) { |
162 |
- if(BLOCKMAX) { |
|
163 |
- *ctx->virname = "Zip.ExceededFileSize"; |
|
164 |
- ret = CL_VIRUS; |
|
165 |
- break; |
|
166 |
- } |
|
167 | 162 |
cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->limits->maxfilesize); |
168 | 163 |
res = Z_STREAM_END; |
169 | 164 |
break; |
... | ... |
@@ -201,11 +191,6 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui |
201 | 201 |
if(strm.avail_out!=sizeof(obuf)) { |
202 | 202 |
written+=sizeof(obuf)-strm.avail_out; |
203 | 203 |
if(ctx->limits && ctx->limits->maxfilesize && written > ctx->limits->maxfilesize) { |
204 |
- if(BLOCKMAX) { |
|
205 |
- *ctx->virname = "Zip.ExceededFileSize"; |
|
206 |
- ret = CL_VIRUS; |
|
207 |
- break; |
|
208 |
- } |
|
209 | 204 |
cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->limits->maxfilesize); |
210 | 205 |
res = BZ_STREAM_END; |
211 | 206 |
break; |
... | ... |
@@ -244,11 +229,6 @@ static int unz(uint8_t *src, uint32_t csize, uint32_t usize, uint16_t method, ui |
244 | 244 |
if(strm.avail_out!=sizeof(obuf)) { |
245 | 245 |
written+=sizeof(obuf)-strm.avail_out; |
246 | 246 |
if(ctx->limits && ctx->limits->maxfilesize && written > ctx->limits->maxfilesize) { |
247 |
- if(BLOCKMAX) { |
|
248 |
- *ctx->virname = "Zip.ExceededFileSize"; |
|
249 |
- ret = CL_VIRUS; |
|
250 |
- break; |
|
251 |
- } |
|
252 | 247 |
cli_dbgmsg("cli_unzip: trimming output size to maxfilesize (%lu)\n", ctx->limits->maxfilesize); |
253 | 248 |
res = 0; |
254 | 249 |
break; |
... | ... |
@@ -346,7 +326,7 @@ static unsigned int lhdr(uint8_t *zip, uint32_t zsize, unsigned int *fu, unsigne |
346 | 346 |
zip+=LH_flen; |
347 | 347 |
zsize-=LH_flen; |
348 | 348 |
|
349 |
- cli_dbgmsg("cli_unzip: lh - ZMDNAME:%d:%s:%u:%u:%u:%u:%u:%u\n", ((LH_flags & F_ENCR)==0), name, LH_usize, LH_csize, LH_crc32, LH_method, fc, ctx->arec); |
|
349 |
+ cli_dbgmsg("cli_unzip: lh - ZMDNAME:%d:%s:%u:%u:%u:%u:%u:%u\n", ((LH_flags & F_ENCR)==0), name, LH_usize, LH_csize, LH_crc32, LH_method, fc, ctx->recursion); |
|
350 | 350 |
/* ZMDfmt virname:encrypted(0-1):filename(exact|*):usize(exact|*):csize(exact|*):crc32(exact|*):method(exact|*):fileno(exact|*):maxdepth(exact|*) */ |
351 | 351 |
|
352 | 352 |
while(meta && |
... | ... |
@@ -357,7 +337,7 @@ static unsigned int lhdr(uint8_t *zip, uint32_t zsize, unsigned int *fu, unsigne |
357 | 357 |
(meta->crc32 && meta->crc32 != LH_crc32) || |
358 | 358 |
(meta->method>0 && meta->method != LH_method) || |
359 | 359 |
(meta->fileno && meta->fileno != fc ) || |
360 |
- (meta->maxdepth && ctx->arec > meta->maxdepth) || |
|
360 |
+ (meta->maxdepth && ctx->recursion > meta->maxdepth) || |
|
361 | 361 |
(meta->filename && strcmp(name, meta->filename)) /* TODO: use a regex */ |
362 | 362 |
) |
363 | 363 |
) meta = meta->next; |
... | ... |
@@ -401,10 +381,6 @@ static unsigned int lhdr(uint8_t *zip, uint32_t zsize, unsigned int *fu, unsigne |
401 | 401 |
return 0; |
402 | 402 |
} |
403 | 403 |
cli_dbgmsg("cli_unzip: lh - skipping encrypted file\n"); |
404 |
- } else if(ctx->limits && ctx->limits->maxratio > 0 && (usize / csize) >= ctx->limits->maxratio) { |
|
405 |
- *ctx->virname = "Oversized.Zip"; |
|
406 |
- *ret = CL_VIRUS; |
|
407 |
- return 0; |
|
408 | 404 |
} else *ret = unz(zip, csize, usize, LH_method, LH_flags, fu, ctx, tmpd); |
409 | 405 |
zip+=csize; |
410 | 406 |
zsize-=csize; |
... | ... |
@@ -561,11 +537,6 @@ int cli_unzip(int f, cli_ctx *ctx) { |
561 | 561 |
} |
562 | 562 |
} |
563 | 563 |
|
564 |
- if(ret == CL_EMAXFILES && BLOCKMAX) { |
|
565 |
- *ctx->virname = "Zip.ExceededFilesLimit"; |
|
566 |
- ret = CL_VIRUS; |
|
567 |
- } |
|
568 |
- |
|
569 | 564 |
munmap(map, fsize); |
570 | 565 |
if (!cli_leavetemps_flag) cli_rmdirs(tmpd); |
571 | 566 |
free(tmpd); |
... | ... |
@@ -590,7 +590,7 @@ cli_decode_ole_object(int fd, const char *dir) |
590 | 590 |
int ofd; |
591 | 591 |
uint32_t object_size; |
592 | 592 |
struct stat statbuf; |
593 |
- char fullname[NAME_MAX + 1]; |
|
593 |
+ char *fullname; |
|
594 | 594 |
|
595 | 595 |
if(dir == NULL) |
596 | 596 |
return -1; |
... | ... |
@@ -629,15 +629,19 @@ cli_decode_ole_object(int fd, const char *dir) |
629 | 629 |
if(!read_uint32(fd, &object_size, FALSE)) |
630 | 630 |
return -1; |
631 | 631 |
} |
632 |
- snprintf(fullname, sizeof(fullname) - 1, "%s/_clam_ole_object", dir); |
|
632 |
+ if(!(fullname = cli_gentemp(dir))) { |
|
633 |
+ return -1; |
|
634 |
+ } |
|
633 | 635 |
ofd = open(fullname, O_RDWR|O_CREAT|O_TRUNC|O_BINARY|O_EXCL, |
634 | 636 |
S_IWUSR|S_IRUSR); |
635 | 637 |
if (ofd < 0) { |
636 |
- cli_warnmsg("cli_decode_ole_object: can't create %s\n", |
|
637 |
- fullname); |
|
638 |
+ cli_warnmsg("cli_decode_ole_object: can't create %s\n", fullname); |
|
639 |
+ free(fullname); |
|
638 | 640 |
return -1; |
641 |
+ } else { |
|
642 |
+ cli_dbgmsg("cli_decode_ole_object: decoding to %s\n", fullname); |
|
639 | 643 |
} |
640 |
- |
|
644 |
+ free(fullname); |
|
641 | 645 |
ole_copy_file_data(fd, ofd, object_size); |
642 | 646 |
lseek(ofd, 0, SEEK_SET); |
643 | 647 |
return ofd; |
... | ... |
@@ -47,7 +47,6 @@ struct cfgoption cfg_options[] = { |
47 | 47 |
{"DetectBrokenExecutables", OPT_BOOL, 0, NULL, 0, OPT_CLAMD}, |
48 | 48 |
{"ScanMail", OPT_BOOL, 1, NULL, 0, OPT_CLAMD}, |
49 | 49 |
{"MailFollowURLs", OPT_BOOL, 0, NULL, 0, OPT_CLAMD}, |
50 |
- {"MailMaxRecursion", OPT_NUM, 64, NULL, 0, OPT_CLAMD}, |
|
51 | 50 |
{"PhishingSignatures", OPT_BOOL, 1, NULL, 0, OPT_CLAMD}, |
52 | 51 |
{"PhishingScanURLs",OPT_BOOL, 1, NULL, 0, OPT_CLAMD}, |
53 | 52 |
/* these are FP prone options, if default isn't used */ |
... | ... |
@@ -61,13 +60,12 @@ struct cfgoption cfg_options[] = { |
61 | 61 |
{"ScanOLE2", OPT_BOOL, 1, NULL, 0, OPT_CLAMD}, |
62 | 62 |
{"ScanPDF", OPT_BOOL, 0, NULL, 0, OPT_CLAMD}, |
63 | 63 |
{"ScanArchive", OPT_BOOL, 1, NULL, 0, OPT_CLAMD}, |
64 |
- {"ArchiveMaxFileSize", OPT_COMPSIZE, 10485760, NULL, 0, OPT_CLAMD}, |
|
65 |
- {"ArchiveMaxRecursion", OPT_NUM, 8, NULL, 0, OPT_CLAMD}, |
|
66 |
- {"ArchiveMaxFiles", OPT_NUM, 1000, NULL, 0, OPT_CLAMD}, |
|
67 |
- {"ArchiveMaxCompressionRatio", OPT_NUM, 250, NULL, 0, OPT_CLAMD}, |
|
64 |
+ {"MaxScanSize", OPT_COMPSIZE, 104857600, NULL, 0, OPT_CLAMD}, /* FIXMELIMITS */ |
|
65 |
+ {"MaxFileSize", OPT_COMPSIZE, 10485760, NULL, 0, OPT_CLAMD}, |
|
66 |
+ {"MaxRecursion", OPT_NUM, 8, NULL, 0, OPT_CLAMD}, |
|
67 |
+ {"MaxFiles", OPT_NUM, 1000, NULL, 0, OPT_CLAMD}, |
|
68 | 68 |
{"ArchiveLimitMemoryUsage", OPT_BOOL, 0, NULL, 0, OPT_CLAMD}, |
69 | 69 |
{"ArchiveBlockEncrypted", OPT_BOOL, 0, NULL, 0, OPT_CLAMD}, |
70 |
- {"ArchiveBlockMax", OPT_BOOL, 0, NULL, 0, OPT_CLAMD}, |
|
71 | 70 |
{"DatabaseDirectory", OPT_QUOTESTR, -1, DATADIR, 0, OPT_CLAMD | OPT_FRESHCLAM}, |
72 | 71 |
{"TCPAddr", OPT_QUOTESTR, -1, NULL, 0, OPT_CLAMD}, |
73 | 72 |
{"TCPSocket", OPT_NUM, -1, NULL, 0, OPT_CLAMD}, |