Browse code

bb11522 - enable clamscan option --blockmax to flag files as virus Heuristic.Limits.Exceeded when --max-filesize, --max-scansize, or --max-recursion is exceeded.

Steven Morgan authored on 2016/08/25 06:39:20
Showing 5 changed files
... ...
@@ -400,9 +400,6 @@ static void scanfile(const char *filename, struct cl_engine *engine, const struc
400 400
                 logg("~%s!(%llu): %s FOUND\n", filename, (long long unsigned)(chain.lastvir-1), virname);
401 401
             }
402 402
         }
403
-        if (!(options & CL_SCAN_ALLMATCHES))
404
-            logg("~%s: %s FOUND\n", filename, virname);
405
-
406 403
         info.files++;
407 404
         info.ifiles++;
408 405
 
... ...
@@ -596,9 +593,6 @@ static int scanstdin(const struct cl_engine *engine, const struct optstruct *opt
596 596
     data.filename = "stdin";
597 597
     data.chain = NULL;
598 598
     if((ret = cl_scanfile_callback(file, &virname, &info.blocks, engine, options, &data)) == CL_VIRUS) {
599
-        if (!(options & CL_SCAN_ALLMATCHES))
600
-            logg("stdin: %s FOUND\n", virname);
601
-
602 599
         info.ifiles++;
603 600
 
604 601
         if(bell)
... ...
@@ -676,6 +670,8 @@ int scanmanager(const struct optstruct *opts)
676 676
         return 2;
677 677
     }
678 678
 
679
+    cl_engine_set_clcb_virus_found(engine, clamscan_virus_found_cb);
680
+    
679 681
     if (optget(opts, "disable-cache")->enabled)
680 682
         cl_engine_set_num(engine, CL_ENGINE_DISABLE_CACHE, 1);
681 683
 
... ...
@@ -1038,7 +1034,6 @@ int scanmanager(const struct optstruct *opts)
1038 1038
     /* set scan options */
1039 1039
     if(optget(opts, "allmatch")->enabled) {
1040 1040
         options |= CL_SCAN_ALLMATCHES;
1041
-        cl_engine_set_clcb_virus_found(engine, clamscan_virus_found_cb);
1042 1041
     }
1043 1042
 
1044 1043
     if(optget(opts,"phishing-ssl")->enabled)
... ...
@@ -1095,6 +1090,10 @@ int scanmanager(const struct optstruct *opts)
1095 1095
     if(optget(opts, "algorithmic-detection")->enabled)
1096 1096
         options |= CL_SCAN_ALGORITHMIC;
1097 1097
 
1098
+    if(optget(opts, "block-max")->enabled) {
1099
+        options |= CL_SCAN_BLOCKMAX;
1100
+    }
1101
+
1098 1102
 #ifdef HAVE__INTERNAL__SHA_COLLECT
1099 1103
     if(optget(opts, "dev-collect-hashes")->enabled)
1100 1104
         options |= CL_SCAN_INTERNAL_COLLECT_SHA;
... ...
@@ -934,6 +934,16 @@ int cl_engine_settings_free(struct cl_settings *settings)
934 934
     return CL_SUCCESS;
935 935
 }
936 936
 
937
+void cli_check_blockmax(cli_ctx *ctx, int rc)
938
+{
939
+    if (BLOCKMAX && !ctx->limit_exceeded) {
940
+        cli_append_virus (ctx, "Heuristic.Limits.Exceeded");
941
+        ctx->limit_exceeded = 1;
942
+        cli_dbgmsg ("Limit %s Exceeded: scanning may be incomplete and additional analysis needed for this file.\n",
943
+            cl_strerror(rc));
944
+    }
945
+}
946
+
937 947
 int cli_checklimits(const char *who, cli_ctx *ctx, unsigned long need1, unsigned long need2, unsigned long need3) {
938 948
     int ret = CL_SUCCESS;
939 949
     unsigned long needed;
... ...
@@ -963,8 +973,12 @@ int cli_checklimits(const char *who, cli_ctx *ctx, unsigned long need1, unsigned
963 963
 
964 964
     if(ctx->engine->maxfiles && ctx->scannedfiles>=ctx->engine->maxfiles) {
965 965
         cli_dbgmsg("%s: files limit reached (max: %u)\n", who, ctx->engine->maxfiles);
966
-	return CL_EMAXFILES;
966
+	ret = CL_EMAXFILES;
967 967
     }
968
+
969
+    if (ret != CL_SUCCESS)
970
+        cli_check_blockmax(ctx, ret);
971
+
968 972
     return ret;
969 973
 }
970 974
 
... ...
@@ -157,6 +157,7 @@ typedef struct cli_ctx_tag {
157 157
     struct json_object *wrkproperty;
158 158
 #endif
159 159
     struct timeval time_limit;
160
+    int limit_exceeded;
160 161
 } cli_ctx;
161 162
 
162 163
 #define STATS_ANON_UUID "5b585e8f-3be5-11e3-bf0b-18037319526c"
... ...
@@ -473,7 +474,7 @@ extern int have_rar;
473 473
 #define SCAN_ELF	    (ctx->options & CL_SCAN_ELF)
474 474
 #define SCAN_ALGO 	    (ctx->options & CL_SCAN_ALGORITHMIC)
475 475
 #define DETECT_ENCRYPTED    (ctx->options & CL_SCAN_BLOCKENCRYPTED)
476
-/* #define BLOCKMAX	    (ctx->options & CL_SCAN_BLOCKMAX) */
476
+#define BLOCKMAX	    (ctx->options & CL_SCAN_BLOCKMAX)
477 477
 #define DETECT_BROKEN	    (ctx->options & CL_SCAN_BLOCKBROKEN)
478 478
 #define BLOCK_MACROS	    (ctx->options & CL_SCAN_BLOCKMACROS)
479 479
 #define SCAN_STRUCTURED	    (ctx->options & CL_SCAN_STRUCTURED)
... ...
@@ -712,6 +713,7 @@ void cli_bitset_free(bitset_t *bs);
712 712
 int cli_bitset_set(bitset_t *bs, unsigned long bit_offset);
713 713
 int cli_bitset_test(bitset_t *bs, unsigned long bit_offset);
714 714
 const char* cli_ctime(const time_t *timep, char *buf, const size_t bufsize);
715
+void cli_check_blockmax(cli_ctx *, int);
715 716
 int cli_checklimits(const char *, cli_ctx *, unsigned long, unsigned long, unsigned long);
716 717
 int cli_updatelimits(cli_ctx *, unsigned long);
717 718
 unsigned long cli_getsizelimit(cli_ctx *, unsigned long);
... ...
@@ -2276,8 +2276,10 @@ static int cli_scanraw(cli_ctx *ctx, cli_file_t type, uint8_t typercg, cli_file_
2276 2276
 	size_t current_container_size = ctx->container_size;
2277 2277
 
2278 2278
 
2279
-    if(ctx->engine->maxreclevel && ctx->recursion >= ctx->engine->maxreclevel)
2279
+    if(ctx->engine->maxreclevel && ctx->recursion >= ctx->engine->maxreclevel) {
2280
+        cli_check_blockmax(ctx, CL_EMAXREC);
2280 2281
         return CL_EMAXREC;
2282
+    }
2281 2283
 
2282 2284
     perf_start(ctx, PERFT_RAW);
2283 2285
     if(typercg)
... ...
@@ -2697,6 +2699,7 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
2697 2697
     if(ctx->engine->maxreclevel && ctx->recursion > ctx->engine->maxreclevel) {
2698 2698
         cli_dbgmsg("cli_magic_scandesc: Archive recursion limit exceeded (%u, max: %u)\n", ctx->recursion, ctx->engine->maxreclevel);
2699 2699
 	emax_reached(ctx);
2700
+        cli_check_blockmax(ctx, CL_EMAXREC);
2700 2701
 	early_ret_from_magicscan(CL_CLEAN);
2701 2702
     }
2702 2703
 
... ...
@@ -2835,8 +2838,10 @@ static int magic_scandesc(cli_ctx *ctx, cli_file_t type)
2835 2835
     ctx->hook_lsig_matches = NULL;
2836 2836
 
2837 2837
     if(!(ctx->options&~CL_SCAN_ALLMATCHES) || (ctx->recursion == ctx->engine->maxreclevel)) { /* raw mode (stdin, etc.) or last level of recursion */
2838
-	if(ctx->recursion == ctx->engine->maxreclevel)
2838
+	if(ctx->recursion == ctx->engine->maxreclevel) {
2839
+            cli_check_blockmax(ctx, CL_EMAXREC);
2839 2840
 	    cli_dbgmsg("cli_magic_scandesc: Hit recursion limit, only scanning raw file\n");
2841
+        }
2840 2842
 	else
2841 2843
 	    cli_dbgmsg("Raw mode: No support for special files\n");
2842 2844
 
... ...
@@ -3736,7 +3741,7 @@ static int scan_common(int desc, cl_fmap_t *map, const char **virname, unsigned
3736 3736
     cli_bitset_free(ctx.hook_lsig_matches);
3737 3737
     free(ctx.fmap);
3738 3738
     if (rc == CL_CLEAN) {
3739
-        if ((ctx.num_viruses != 0 && ctx.options & CL_SCAN_ALLMATCHES) ||
3739
+        if ((ctx.num_viruses != 0 && (ctx.options & (CL_SCAN_ALLMATCHES | CL_SCAN_BLOCKMAX))) ||
3740 3740
             ctx.found_possibly_unwanted)
3741 3741
                 rc = CL_VIRUS;
3742 3742
     }
... ...
@@ -175,7 +175,7 @@ const struct clam_option __clam_options[] = {
175 175
     { NULL, "no-phishing-restrictedscan", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN | OPT_DEPRECATED, "", "" },
176 176
     { NULL, "max-ratio", 0, CLOPT_TYPE_NUMBER, MATCH_NUMBER, 0, NULL, 0, OPT_CLAMSCAN | OPT_DEPRECATED, "", "" },
177 177
     { NULL, "max-space", 0, CLOPT_TYPE_SIZE, MATCH_SIZE, 0, NULL, 0, OPT_CLAMSCAN | OPT_DEPRECATED, "", "" },
178
-    { NULL, "block-max", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN | OPT_DEPRECATED, "", "" },
178
+    { NULL, "block-max", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMSCAN, "", "" },
179 179
     { NULL, "unzip", 0, CLOPT_TYPE_STRING, NULL, -1, "foo", 0, OPT_CLAMSCAN | OPT_DEPRECATED, "", "" },
180 180
     { NULL, "unrar", 0, CLOPT_TYPE_STRING, NULL, -1, "foo", 0, OPT_CLAMSCAN | OPT_DEPRECATED, "", "" },
181 181
     { NULL, "arj", 0, CLOPT_TYPE_STRING, NULL, -1, "foo", 0, OPT_CLAMSCAN | OPT_DEPRECATED, "", "" },