... | ... |
@@ -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, "", "" }, |