Browse code

bb #5405: Convert hard-coded maximum file sizes to configurable values with defaults

David Raynor authored on 2012/11/28 07:15:02
Showing 10 changed files
... ...
@@ -790,6 +790,58 @@ int recvloop_th(int *socketds, unsigned nsockets, struct cl_engine *engine, unsi
790 790
     }
791 791
 #endif
792 792
 
793
+    /* Engine max sizes */
794
+
795
+    if((opt = optget(opts, "MaxEmbeddedPE"))->active) {
796
+        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_EMBEDDEDPE, opt->numarg))) {
797
+            logg("!cli_engine_set_num(CL_ENGINE_MAX_EMBEDDEDPE) failed: %s\n", cl_strerror(ret));
798
+            cl_engine_free(engine);
799
+            return 1;
800
+        }
801
+    }
802
+    val = cl_engine_get_num(engine, CL_ENGINE_MAX_EMBEDDEDPE, NULL);
803
+    logg("Limits: MaxEmbeddedPE limit set to %llu bytes.\n", val);
804
+
805
+    if((opt = optget(opts, "MaxHTMLNormalize"))->active) {
806
+        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNORMALIZE, opt->numarg))) {
807
+            logg("!cli_engine_set_num(CL_ENGINE_MAX_HTMLNORMALIZE) failed: %s\n", cl_strerror(ret));
808
+            cl_engine_free(engine);
809
+            return 1;
810
+        }
811
+    }
812
+    val = cl_engine_get_num(engine, CL_ENGINE_MAX_HTMLNORMALIZE, NULL);
813
+    logg("Limits: MaxHTMLNormalize limit set to %llu bytes.\n", val);
814
+
815
+    if((opt = optget(opts, "MaxHTMLNoTags"))->active) {
816
+        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNOTAGS, opt->numarg))) {
817
+            logg("!cli_engine_set_num(CL_ENGINE_MAX_HTMLNOTAGS) failed: %s\n", cl_strerror(ret));
818
+            cl_engine_free(engine);
819
+            return 1;
820
+        }
821
+    }
822
+    val = cl_engine_get_num(engine, CL_ENGINE_MAX_HTMLNOTAGS, NULL);
823
+    logg("Limits: MaxHTMLNoTags limit set to %llu bytes.\n", val);
824
+
825
+    if((opt = optget(opts, "MaxScriptNormalize"))->active) {
826
+        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCRIPTNORMALIZE, opt->numarg))) {
827
+            logg("!cli_engine_set_num(CL_ENGINE_MAX_SCRIPTNORMALIZE) failed: %s\n", cl_strerror(ret));
828
+            cl_engine_free(engine);
829
+            return 1;
830
+        }
831
+    }
832
+    val = cl_engine_get_num(engine, CL_ENGINE_MAX_SCRIPTNORMALIZE, NULL);
833
+    logg("Limits: MaxScriptNormalize limit set to %llu bytes.\n", val);
834
+
835
+    if((opt = optget(opts, "MaxZipTypeRcg"))->active) {
836
+        if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_ZIPTYPERCG, opt->numarg))) {
837
+            logg("!cli_engine_set_num(CL_ENGINE_MAX_ZIPTYPERCG) failed: %s\n", cl_strerror(ret));
838
+            cl_engine_free(engine);
839
+            return 1;
840
+        }
841
+    }
842
+    val = cl_engine_get_num(engine, CL_ENGINE_MAX_ZIPTYPERCG, NULL);
843
+    logg("Limits: MaxZipTypeRcg limit set to %llu bytes.\n", val);
844
+
793 845
     if(optget(opts, "ScanArchive")->enabled) {
794 846
 	logg("Archive support enabled.\n");
795 847
 	options |= CL_SCAN_ARCHIVE;
... ...
@@ -258,7 +258,11 @@ void help(void)
258 258
     mprintf("    --max-files=#n                       The maximum number of files to scan for each container file (**)\n");
259 259
     mprintf("    --max-recursion=#n                   Maximum archive recursion level for container file (**)\n");
260 260
     mprintf("    --max-dir-recursion=#n               Maximum directory recursion level\n");
261
-
261
+    mprintf("    --max-embeddedpe=#n                  Maximum size file to check for embedded PE\n");
262
+    mprintf("    --max-htmlnormalize=#n               Maximum size of HTML file to normalize\n");
263
+    mprintf("    --max-htmlnotags=#n                  Maximum size of normalized HTML file to scan\n");
264
+    mprintf("    --max-scriptnormalize=#n             Maximum size of script file to normalize\n");
265
+    mprintf("    --max-ziptypercg=#n                  Maximum size zip to type reanalyze\n");
262 266
     mprintf("\n");
263 267
     mprintf("(*) Default scan settings\n");
264 268
     mprintf("(**) Certain files (e.g. documents, archives, etc.) may in turn contain other\n");
... ...
@@ -736,6 +736,48 @@ int scanmanager(const struct optstruct *opts)
736 736
 	}
737 737
     }
738 738
 
739
+    /* Engine max sizes */
740
+
741
+    if((opt = optget(opts, "max-embeddedpe"))->active) {
742
+	if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_EMBEDDEDPE, opt->numarg))) {
743
+	    logg("!cli_engine_set_num(CL_ENGINE_MAX_EMBEDDEDPE) failed: %s\n", cl_strerror(ret));
744
+	    cl_engine_free(engine);
745
+	    return 2;
746
+	}
747
+    }
748
+
749
+    if((opt = optget(opts, "max-htmlnormalize"))->active) {
750
+	if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNORMALIZE, opt->numarg))) {
751
+	    logg("!cli_engine_set_num(CL_ENGINE_MAX_HTMLNORMALIZE) failed: %s\n", cl_strerror(ret));
752
+	    cl_engine_free(engine);
753
+	    return 2;
754
+	}
755
+    }
756
+
757
+    if((opt = optget(opts, "max-htmlnotags"))->active) {
758
+	if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_HTMLNOTAGS, opt->numarg))) {
759
+	    logg("!cli_engine_set_num(CL_ENGINE_MAX_HTMLNOTAGS) failed: %s\n", cl_strerror(ret));
760
+	    cl_engine_free(engine);
761
+	    return 2;
762
+	}
763
+    }
764
+
765
+    if((opt = optget(opts, "max-scriptnormalize"))->active) {
766
+	if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_SCRIPTNORMALIZE, opt->numarg))) {
767
+	    logg("!cli_engine_set_num(CL_ENGINE_MAX_SCRIPTNORMALIZE) failed: %s\n", cl_strerror(ret));
768
+	    cl_engine_free(engine);
769
+	    return 2;
770
+	}
771
+    }
772
+
773
+    if((opt = optget(opts, "max-ziptypercg"))->active) {
774
+	if((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_ZIPTYPERCG, opt->numarg))) {
775
+	    logg("!cli_engine_set_num(CL_ENGINE_MAX_ZIPTYPERCG) failed: %s\n", cl_strerror(ret));
776
+	    cl_engine_free(engine);
777
+	    return 2;
778
+	}
779
+    }
780
+
739 781
     /* set scan options */
740 782
     if(optget(opts, "allmatch")->enabled)
741 783
 	options |= CL_SCAN_ALLMATCHES;
... ...
@@ -437,6 +437,41 @@ Example
437 437
 # Default: 10000
438 438
 #MaxFiles 15000
439 439
 
440
+# Maximum size of a file to check for embedded PE. Files larger than this value
441
+# will skip the additional analysis step.
442
+# Note: disabling this limit or setting it too high may result in severe damage
443
+# to the system.
444
+# Default: 10M
445
+#MaxEmbeddedPE 10M
446
+
447
+# Maximum size of a HTML file to normalize. HTML files larger than this value
448
+# will not be normalized or scanned.
449
+# Note: disabling this limit or setting it too high may result in severe damage
450
+# to the system.
451
+# Default: 10M
452
+#MaxHTMLNormalize 10M
453
+
454
+# Maximum size of a normalized HTML file to scan. HTML files larger than this
455
+# value after normalization will not be scanned.
456
+# Note: disabling this limit or setting it too high may result in severe damage
457
+# to the system.
458
+# Default: 2M
459
+#MaxHTMLNoTags 2M
460
+
461
+# Maximum size of a script file to normalize. Script content larger than this
462
+# value will not be normalized or scanned.
463
+# Note: disabling this limit or setting it too high may result in severe damage
464
+# to the system.
465
+# Default: 5M
466
+#MaxScriptNormalize 5M
467
+
468
+# Maximum size of a ZIP file to reanalyze type recognition. ZIP files larger
469
+# than this value will skip the step to potentially reanalyze as PE.
470
+# Note: disabling this limit or setting it too high may result in severe damage
471
+# to the system.
472
+# Default: 1M
473
+#MaxZipTypeRcg 1M
474
+
440 475
 
441 476
 ##
442 477
 ## Clamuko settings
... ...
@@ -185,7 +185,12 @@ enum cl_engine_field {
185 185
     CL_ENGINE_KEEPTMP,		    /* uint32_t */
186 186
     CL_ENGINE_BYTECODE_SECURITY,    /* uint32_t */
187 187
     CL_ENGINE_BYTECODE_TIMEOUT,     /* uint32_t */
188
-    CL_ENGINE_BYTECODE_MODE         /* uint32_t */
188
+    CL_ENGINE_BYTECODE_MODE,        /* uint32_t */
189
+    CL_ENGINE_MAX_EMBEDDEDPE,       /* uint64_t */
190
+    CL_ENGINE_MAX_HTMLNORMALIZE,    /* uint64_t */
191
+    CL_ENGINE_MAX_HTMLNOTAGS,       /* uint64_t */
192
+    CL_ENGINE_MAX_SCRIPTNORMALIZE,  /* uint64_t */
193
+    CL_ENGINE_MAX_ZIPTYPERCG        /* uint64_t */
189 194
 };
190 195
 
191 196
 enum bytecode_security {
... ...
@@ -37,4 +37,10 @@
37 37
 #define CLI_DEFAULT_MIN_CC_COUNT    3
38 38
 #define CLI_DEFAULT_MIN_SSN_COUNT   3
39 39
 
40
+#define CLI_DEFAULT_MAXEMBEDDEDPE       10485760
41
+#define CLI_DEFAULT_MAXHTMLNORMALIZE    10485760
42
+#define CLI_DEFAULT_MAXHTMLNOTAGS       2097152
43
+#define CLI_DEFAULT_MAXSCRIPTNORMALIZE  5242880
44
+#define CLI_DEFAULT_MAXZIPTYPERCG       1048576
45
+
40 46
 #endif
... ...
@@ -312,6 +312,12 @@ struct cl_engine *cl_engine_new(void)
312 312
     new->maxfiles = CLI_DEFAULT_MAXFILES;
313 313
     new->min_cc_count = CLI_DEFAULT_MIN_CC_COUNT;
314 314
     new->min_ssn_count = CLI_DEFAULT_MIN_SSN_COUNT;
315
+    /* Engine Max sizes */
316
+    new->maxembeddedpe = CLI_DEFAULT_MAXEMBEDDEDPE;
317
+    new->maxhtmlnormalize = CLI_DEFAULT_MAXHTMLNORMALIZE;
318
+    new->maxhtmlnotags = CLI_DEFAULT_MAXHTMLNOTAGS;
319
+    new->maxscriptnormalize = CLI_DEFAULT_MAXSCRIPTNORMALIZE;
320
+    new->maxziptypercg = CLI_DEFAULT_MAXZIPTYPERCG;
315 321
 
316 322
     new->bytecode_security = CL_BYTECODE_TRUST_SIGNED;
317 323
     /* 5 seconds timeout */
... ...
@@ -392,6 +398,41 @@ int cl_engine_set_num(struct cl_engine *engine, enum cl_engine_field field, long
392 392
 	case CL_ENGINE_MAX_FILES:
393 393
 	    engine->maxfiles = num;
394 394
 	    break;
395
+	case CL_ENGINE_MAX_EMBEDDEDPE:
396
+	    if(num < 0) {
397
+		cli_warnmsg("MaxEmbeddedPE: negative values are not allowed, using default: %u\n", CLI_DEFAULT_MAXEMBEDDEDPE);
398
+		engine->maxembeddedpe = CLI_DEFAULT_MAXEMBEDDEDPE;
399
+	    } else
400
+		engine->maxembeddedpe = num;
401
+	    break;
402
+	case CL_ENGINE_MAX_HTMLNORMALIZE:
403
+	    if(num < 0) {
404
+		cli_warnmsg("MaxHTMLNormalize: negative values are not allowed, using default: %u\n", CLI_DEFAULT_MAXHTMLNORMALIZE);
405
+		engine->maxhtmlnormalize = CLI_DEFAULT_MAXHTMLNORMALIZE;
406
+	    } else
407
+		engine->maxhtmlnormalize = num;
408
+	    break;
409
+	case CL_ENGINE_MAX_HTMLNOTAGS:
410
+	    if(num < 0) {
411
+		cli_warnmsg("MaxHTMLNoTags: negative values are not allowed, using default: %u\n", CLI_DEFAULT_MAXHTMLNOTAGS);
412
+		engine->maxhtmlnotags = CLI_DEFAULT_MAXHTMLNOTAGS;
413
+	    } else
414
+		engine->maxhtmlnotags = num;
415
+	    break;
416
+	case CL_ENGINE_MAX_SCRIPTNORMALIZE:
417
+	    if(num < 0) {
418
+		cli_warnmsg("MaxScriptNormalize: negative values are not allowed, using default: %u\n", CLI_DEFAULT_MAXSCRIPTNORMALIZE);
419
+		engine->maxscriptnormalize = CLI_DEFAULT_MAXSCRIPTNORMALIZE;
420
+	    } else
421
+		engine->maxscriptnormalize = num;
422
+	    break;
423
+	case CL_ENGINE_MAX_ZIPTYPERCG:
424
+	    if(num < 0) {
425
+		cli_warnmsg("MaxZipTypeRcg: negative values are not allowed, using default: %u\n", CLI_DEFAULT_MAXZIPTYPERCG);
426
+		engine->maxziptypercg = CLI_DEFAULT_MAXZIPTYPERCG;
427
+	    } else
428
+		engine->maxziptypercg = num;
429
+	    break;
395 430
 	case CL_ENGINE_MIN_CC_COUNT:
396 431
 	    engine->min_cc_count = num;
397 432
 	    break;
... ...
@@ -469,6 +510,16 @@ long long cl_engine_get_num(const struct cl_engine *engine, enum cl_engine_field
469 469
 	    return engine->maxreclevel;
470 470
 	case CL_ENGINE_MAX_FILES:
471 471
 	    return engine->maxfiles;
472
+	case CL_ENGINE_MAX_EMBEDDEDPE:
473
+	    return engine->maxembeddedpe;
474
+	case CL_ENGINE_MAX_HTMLNORMALIZE:
475
+	    return engine->maxhtmlnormalize;
476
+	case CL_ENGINE_MAX_HTMLNOTAGS:
477
+	    return engine->maxhtmlnotags;
478
+	case CL_ENGINE_MAX_SCRIPTNORMALIZE:
479
+	    return engine->maxscriptnormalize;
480
+	case CL_ENGINE_MAX_ZIPTYPERCG:
481
+	    return engine->maxziptypercg;
472 482
 	case CL_ENGINE_MIN_CC_COUNT:
473 483
 	    return engine->min_cc_count;
474 484
 	case CL_ENGINE_MIN_SSN_COUNT:
... ...
@@ -565,6 +616,11 @@ struct cl_settings *cl_engine_settings_copy(const struct cl_engine *engine)
565 565
     settings->maxfilesize = engine->maxfilesize;
566 566
     settings->maxreclevel = engine->maxreclevel;
567 567
     settings->maxfiles = engine->maxfiles;
568
+    settings->maxembeddedpe = engine->maxembeddedpe;
569
+    settings->maxhtmlnormalize = engine->maxhtmlnormalize;
570
+    settings->maxhtmlnotags = engine->maxhtmlnotags;
571
+    settings->maxscriptnormalize = engine->maxscriptnormalize;
572
+    settings->maxziptypercg = engine->maxziptypercg;
568 573
     settings->min_cc_count = engine->min_cc_count;
569 574
     settings->min_ssn_count = engine->min_ssn_count;
570 575
     settings->bytecode_security = engine->bytecode_security;
... ...
@@ -592,6 +648,11 @@ int cl_engine_settings_apply(struct cl_engine *engine, const struct cl_settings
592 592
     engine->maxfilesize = settings->maxfilesize;
593 593
     engine->maxreclevel = settings->maxreclevel;
594 594
     engine->maxfiles = settings->maxfiles;
595
+    engine->maxembeddedpe = settings->maxembeddedpe;
596
+    engine->maxhtmlnormalize = settings->maxhtmlnormalize;
597
+    engine->maxhtmlnotags = settings->maxhtmlnotags;
598
+    engine->maxscriptnormalize = settings->maxscriptnormalize;
599
+    engine->maxziptypercg = settings->maxziptypercg;
595 600
     engine->min_cc_count = settings->min_cc_count;
596 601
     engine->min_ssn_count = settings->min_ssn_count;
597 602
     engine->bytecode_security = settings->bytecode_security;
... ...
@@ -274,6 +274,13 @@ struct cl_engine {
274 274
     enum bytecode_security bytecode_security;
275 275
     uint32_t bytecode_timeout;
276 276
     enum bytecode_mode bytecode_mode;
277
+
278
+    /* Engine max settings */
279
+    uint64_t maxembeddedpe;  /* max size to scan MSEXE for PE */
280
+    uint64_t maxhtmlnormalize; /* max size to normalize HTML */
281
+    uint64_t maxhtmlnotags; /* max size for scanning normalized HTML */
282
+    uint64_t maxscriptnormalize; /* max size to normalize scripts */
283
+    uint64_t maxziptypercg; /* max size to re-do zip filetype */
277 284
 };
278 285
 
279 286
 struct cl_settings {
... ...
@@ -305,6 +312,13 @@ struct cl_settings {
305 305
     void *cb_sigload_ctx;
306 306
     clcb_msg cb_msg;
307 307
     clcb_hash cb_hash;
308
+
309
+    /* Engine max settings */
310
+    uint64_t maxembeddedpe;  /* max size to scan MSEXE for PE */
311
+    uint64_t maxhtmlnormalize; /* max size to normalize HTML */
312
+    uint64_t maxhtmlnotags; /* max size for scanning normalized HTML */
313
+    uint64_t maxscriptnormalize; /* max size to normalize scripts */
314
+    uint64_t maxziptypercg; /* max size to re-do zip filetype */
308 315
 };
309 316
 
310 317
 extern int (*cli_unrar_open)(int fd, const char *dirname, unrar_state_t *state);
... ...
@@ -1042,19 +1042,17 @@ static int cli_vba_scandir(const char *dirname, cli_ctx *ctx, struct uniq *U)
1042 1042
 
1043 1043
 static int cli_scanhtml(cli_ctx *ctx)
1044 1044
 {
1045
-	char *tempname, fullname[1024];
1046
-	int ret=CL_CLEAN, fd;
1047
-	fmap_t *map = *ctx->fmap;
1048
-	unsigned int viruses_found = 0;
1045
+    char *tempname, fullname[1024];
1046
+    int ret=CL_CLEAN, fd;
1047
+    fmap_t *map = *ctx->fmap;
1048
+    unsigned int viruses_found = 0;
1049
+    uint64_t curr_len = map->len;
1049 1050
 
1050 1051
     cli_dbgmsg("in cli_scanhtml()\n");
1051 1052
 
1052
-    /* Because HTML detection is FP-prone and html_normalise_fd() needs to
1053
-     * mmap the file don't normalise files larger than 10 MB.
1054
-     */
1055
-
1056
-    if(map->len > 10485760) {
1057
-	cli_dbgmsg("cli_scanhtml: exiting (file larger than 10 MB)\n");
1053
+    /* CL_ENGINE_MAX_HTMLNORMALIZE */
1054
+    if(curr_len > ctx->engine->maxhtmlnormalize) {
1055
+	cli_dbgmsg("cli_scanhtml: exiting (file larger than MaxHTMLNormalize)\n");
1058 1056
 	return CL_CLEAN;
1059 1057
     }
1060 1058
 
... ...
@@ -1078,16 +1076,23 @@ static int cli_scanhtml(cli_ctx *ctx)
1078 1078
 	close(fd);
1079 1079
     }
1080 1080
 
1081
-    if((ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) && map->len < 2097152) {
1082
-	    /* limit to 2 MB, we're not interesting in scanning large files in notags form */
1083
-	    /* TODO: don't even create notags if file is over 2 MB */
1084
-	    snprintf(fullname, 1024, "%s"PATHSEP"notags.html", tempname);
1085
-	    fd = open(fullname, O_RDONLY|O_BINARY);
1086
-	    if(fd >= 0) {
1087
-		if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS) 
1088
-		    viruses_found++;
1089
-		close(fd);
1090
-	    }
1081
+    if(ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) {
1082
+        /* CL_ENGINE_MAX_HTMLNOTAGS */
1083
+        curr_len = map->len;
1084
+        if (curr_len > ctx->engine->maxhtmlnotags) {
1085
+	    /* we're not interested in scanning large files in notags form */
1086
+            /* TODO: don't even create notags if file is over limit */
1087
+            cli_dbgmsg("cli_scanhtml: skipping notags (normalized size over MaxHTMLNoTags)\n");
1088
+	}
1089
+        else {
1090
+            snprintf(fullname, 1024, "%s"PATHSEP"notags.html", tempname);
1091
+            fd = open(fullname, O_RDONLY|O_BINARY);
1092
+            if(fd >= 0) {
1093
+                if ((ret = cli_scandesc(fd, ctx, CL_TYPE_HTML, 0, NULL, AC_SCAN_VIR, NULL)) == CL_VIRUS) 
1094
+                    viruses_found++;
1095
+                close(fd);
1096
+            }
1097
+        }
1091 1098
     }
1092 1099
 
1093 1100
     if(ret == CL_CLEAN || (ret == CL_VIRUS && SCAN_ALL)) {
... ...
@@ -1120,19 +1125,20 @@ static int cli_scanhtml(cli_ctx *ctx)
1120 1120
 
1121 1121
 static int cli_scanscript(cli_ctx *ctx)
1122 1122
 {
1123
-	const unsigned char *buff;
1124
-	unsigned char* normalized;
1125
-	struct text_norm_state state;
1126
-	char *tmpname = NULL;
1127
-	int ofd = -1, ret;
1128
-	struct cli_matcher *troot;
1129
-	uint32_t maxpatlen, offset = 0;
1130
-	struct cli_matcher *groot;
1131
-	struct cli_ac_data gmdata, tmdata;
1132
-	struct cli_ac_data *mdata[2];
1133
-	fmap_t *map = *ctx->fmap;
1134
-	size_t at = 0;
1135
-	unsigned int viruses_found = 0;
1123
+    const unsigned char *buff;
1124
+    unsigned char* normalized;
1125
+    struct text_norm_state state;
1126
+    char *tmpname = NULL;
1127
+    int ofd = -1, ret;
1128
+    struct cli_matcher *troot;
1129
+    uint32_t maxpatlen, offset = 0;
1130
+    struct cli_matcher *groot;
1131
+    struct cli_ac_data gmdata, tmdata;
1132
+    struct cli_ac_data *mdata[2];
1133
+    fmap_t *map = *ctx->fmap;
1134
+    size_t at = 0;
1135
+    unsigned int viruses_found = 0;
1136
+    uint64_t curr_len = map->len;
1136 1137
 
1137 1138
     if (!ctx || !ctx->engine->root)
1138 1139
         return CL_ENULLARG;
... ...
@@ -1141,12 +1147,13 @@ static int cli_scanscript(cli_ctx *ctx)
1141 1141
     troot = ctx->engine->root[7];
1142 1142
     maxpatlen = troot ? troot->maxpatlen : 0;
1143 1143
 
1144
-	cli_dbgmsg("in cli_scanscript()\n");
1144
+    cli_dbgmsg("in cli_scanscript()\n");
1145 1145
 
1146
-	if(map->len > 5242880) {
1147
-		cli_dbgmsg("cli_scanscript: exiting (file larger than 5 MB)\n");
1148
-		return CL_CLEAN;
1149
-	}
1146
+    /* CL_ENGINE_MAX_SCRIPTNORMALIZE */
1147
+    if(curr_len > ctx->engine->maxscriptnormalize) {
1148
+        cli_dbgmsg("cli_scanscript: exiting (file larger than MaxScriptSize)\n");
1149
+        return CL_CLEAN;
1150
+    }
1150 1151
 
1151 1152
 	/* dump to disk only if explicitly asked to,
1152 1153
 	 * otherwise we can process just in-memory */
... ...
@@ -2100,8 +2107,12 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_
2100 2100
 
2101 2101
 		    case CL_TYPE_MSEXE:
2102 2102
  			if(SCAN_PE && (type == CL_TYPE_MSEXE || type == CL_TYPE_ZIP || type == CL_TYPE_MSOLE2) && ctx->dconf->pe) {
2103
-			    if(map->len > 10485760)
2103
+			    uint64_t curr_len = map->len;
2104
+			    /* CL_ENGINE_MAX_EMBEDDED_PE */
2105
+			    if(curr_len > ctx->engine->maxembeddedpe) {
2106
+				cli_dbgmsg("cli_scanraw: MaxEmbeddedPE exceeded\n");
2104 2107
 				break;
2108
+			    }
2105 2109
 			    ctx->container_type = CL_TYPE_MSEXE; /* PE is a container for another executable here */
2106 2110
 			    ctx->container_size = map->len - fpt->offset; /* not precise */
2107 2111
 			    memset(&peinfo, 0, sizeof(struct cli_exe_info));
... ...
@@ -2266,13 +2277,6 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
2266 2266
 	int cache_clean = 0, res;
2267 2267
 	unsigned int viruses_found = 0;
2268 2268
 
2269
-    cli_dbgmsg("in magic_scandesc\n");
2270
-    if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) {
2271
-        cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel);
2272
-	emax_reached(ctx);
2273
-	early_ret_from_magicscan(CL_CLEAN);
2274
-    }
2275
-
2276 2269
     if(!ctx->engine) {
2277 2270
 	cli_errmsg("CRITICAL: engine == NULL\n");
2278 2271
 	early_ret_from_magicscan(CL_ENULLARG);
... ...
@@ -2283,6 +2287,12 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
2283 2283
 	early_ret_from_magicscan(CL_EMALFDB);
2284 2284
     }
2285 2285
 
2286
+    if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) {
2287
+        cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel);
2288
+	emax_reached(ctx);
2289
+	early_ret_from_magicscan(CL_CLEAN);
2290
+    }
2291
+
2286 2292
     if(cli_updatelimits(ctx, (*ctx->fmap)->len)!=CL_CLEAN) {
2287 2293
 	emax_reached(ctx);
2288 2294
         early_ret_from_magicscan(CL_CLEAN);
... ...
@@ -2636,8 +2646,10 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
2636 2636
     }
2637 2637
 
2638 2638
     if(type == CL_TYPE_ZIP && SCAN_ARCHIVE && (DCONF_ARCH & ARCH_CONF_ZIP)) {
2639
-	if((*ctx->fmap)->len > 1048576) {
2640
-	    cli_dbgmsg("cli_magic_scandesc: Not checking for embedded PEs (zip file > 1 MB)\n");
2639
+	/* CL_ENGINE_MAX_ZIPTYPERCG */
2640
+	uint64_t curr_len = (*ctx->fmap)->len;
2641
+	if(curr_len > ctx->engine->maxziptypercg) {
2642
+	    cli_dbgmsg("cli_magic_scandesc: Not checking for embedded PEs (zip file > MaxZipTypeRcg)\n");
2641 2643
 	    typercg = 0;
2642 2644
 	}
2643 2645
     }
... ...
@@ -334,6 +334,18 @@ const struct clam_option __clam_options[] = {
334 334
 
335 335
     { "MaxFiles", "max-files", 0, TYPE_NUMBER, MATCH_NUMBER, CLI_DEFAULT_MAXFILES, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Number of files to be scanned within an archive, a document, or any other\ncontainer file.\nThe value of 0 disables the limit.\nWARNING: disabling this limit or setting it too high may result in severe\ndamage to the system.", "10000" },
336 336
 
337
+    /* Engine maximums */
338
+    { "MaxEmbeddedPE", "max-embeddedpe", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXEMBEDDEDPE, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum size of a file to check for embedded PE.\nFiles larger than this value will skip the additional analysis step.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "10M" },
339
+
340
+    { "MaxHTMLNormalize", "max-htmlnormalize", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXHTMLNORMALIZE, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum size of a HTML file to normalize.\nHTML files larger than this value will not be normalized or scanned.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "10M" },
341
+
342
+    { "MaxHTMLNoTags", "max-htmlnotags", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXHTMLNOTAGS, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum size of a normalized HTML file to scan.\nHTML files larger than this value after normalization will not be scanned.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "2M" },
343
+
344
+    { "MaxScriptNormalize", "max-scriptnormalize", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXSCRIPTNORMALIZE, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum size of a script file to normalize.\nScript content larger than this value will not be normalized or scanned.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "5M" },
345
+
346
+    { "MaxZipTypeRcg", "max-ziptypercg", 0, TYPE_SIZE, MATCH_SIZE, CLI_DEFAULT_MAXZIPTYPERCG, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "This option sets the maximum size of a ZIP file to reanalyze type recognition.\nZIP files larger than this value will skip the step to potentially reanalyze as PE.\nNegative values are not allowed.\nWARNING: setting this limit too high may result in severe damage or impact performance.", "1M" },
347
+
348
+    /* OnAccess settings */
337 349
     { "ScanOnAccess", NULL, 0, TYPE_BOOL, MATCH_BOOL, -1, NULL, 0, OPT_CLAMD, "This option enables on-access scanning (Linux only)", "no" },
338 350
 
339 351
     { "OnAccessIncludePath", NULL, 0, TYPE_STRING, NULL, -1, NULL, FLAG_MULTIPLE, OPT_CLAMD, "This option specifies a directory (including all files and directories\ninside it), which should be scanned on access. This option can\nbe used multiple times.", "/home\n/students" },