Fix recursion limit alert

The previous commit broke alerting when exceeding the recursion limit
because recursion tracking is so effective that by limiting the final
layer of recursion to a scan of the fmap, we prevented it from ever
hitting the recursion limit.

This commit removes that restriction where it only does an fmap scan
(aka "raw scan") of files that are at their limit so that we can
actually hit the recursion limit and alert as intended.

Also tidied up the cache_clean check so it checks the
`fmap->dont_cache_flag` at the right point (before caching) instead of
before setting the "CLEAN" verdict.
Note: The `cache_clean` variable appears to be used to record the clean
status so the `ret` variable can be re-used without losing the verdict.
This is of course only required because the verdict is stored in the
error enum. *cough*

Also fixed a couple typos.
This commit is contained in:
Micah Snyder 2021-10-25 19:41:36 -07:00 committed by Micah Snyder
parent 0354482e16
commit ffce672622
3 changed files with 8 additions and 24 deletions

View file

@ -54,7 +54,7 @@ struct cl_fmap {
uint64_t pgsz;
uint64_t paged;
uint16_t aging;
uint16_t dont_cache_flag; /** incidates that we should cache scan results for this fmap. Used if limits exceeded */
uint16_t dont_cache_flag; /** indicates if we should not cache scan results for this fmap. Used if limits exceeded */
uint16_t handle_is_fd; /** non-zero if map->handle is an fd. */
size_t offset; /** file offset representing start of original fmap, if the fmap created reading from a file starting at offset other than 0 */
size_t nested_offset; /** offset from start of original fmap (data) for nested scan. 0 for orig fmap. */

View file

@ -391,7 +391,7 @@ const char *cl_strerror(int clerror)
return "Exceeded time limit";
/* internal (needed for debug messages) */
case CL_EMAXREC:
return "Exceeded time max recursion depth";
return "Exceeded max recursion depth";
case CL_EMAXSIZE:
return "Exceeded max scan size";
case CL_EMAXFILES:

View file

@ -4299,20 +4299,10 @@ cl_error_t cli_magic_scan(cli_ctx *ctx, cli_file_t type)
old_hook_lsig_matches = ctx->hook_lsig_matches;
ctx->hook_lsig_matches = NULL;
if (!((ctx->options->general & ~CL_SCAN_GENERAL_ALLMATCHES) || (ctx->options->parse) || (ctx->options->heuristic) || (ctx->options->mail) || (ctx->options->dev)) ||
(ctx->recursion_level == ctx->recursion_stack_size - 1)) {
if (!((ctx->options->general & ~CL_SCAN_GENERAL_ALLMATCHES) || (ctx->options->parse) || (ctx->options->heuristic) || (ctx->options->mail) || (ctx->options->dev))) {
/*
* Scanning in raw mode (stdin, etc.)
* or at last level of recursion.
*/
if (ctx->recursion_level == ctx->recursion_stack_size - 1) {
emax_reached(ctx); // Disable caching for all recursion layers.
// cli_append_virus_if_heur_exceedsmax(ctx, "Heuristics.Limits.Exceeded.MaxRecursion");
cli_dbgmsg("cli_magic_scan: Hit recursion limit, only scanning raw file\n");
} else {
cli_dbgmsg("cli_magic_scan: Raw mode: No support for special files\n");
}
ret = dispatch_prescan_callback(ctx->engine->cb_pre_scan, ctx, filetype);
if (CL_CLEAN != ret) {
if (ret == CL_VIRUS) {
@ -4323,14 +4313,8 @@ cl_error_t cli_magic_scan(cli_ctx *ctx, cli_file_t type)
goto done;
}
if ((ret = cli_scan_fmap(ctx, CL_TYPE_ANY, 0, NULL, AC_SCAN_VIR, NULL, hash)) == CL_VIRUS)
if (CL_VIRUS == (ret = cli_scan_fmap(ctx, CL_TYPE_ANY, 0, NULL, AC_SCAN_VIR, NULL, hash)))
cli_dbgmsg("cli_magic_scan: %s found in descriptor %d\n", cli_get_last_virus(ctx), fmap_fd(ctx->fmap));
else if (ret == CL_CLEAN) {
if (ctx->recursion_level != ctx->engine->max_recursion_level - 1)
cache_clean = 1; /* Only cache if limits are not reached */
else
emax_reached(ctx);
}
goto done;
}
@ -4845,7 +4829,6 @@ done:
case CL_CLEAN:
cache_clean = 1;
ret = CL_CLEAN;
break;
default:
@ -4898,12 +4881,13 @@ done:
}
perf_stop(ctx, PERFT_POSTCB);
}
if (cb_retcode == CL_CLEAN && cache_clean) {
if (cb_retcode == CL_CLEAN && cache_clean && !ctx->fmap->dont_cache_flag && !SCAN_COLLECT_METADATA) {
perf_start(ctx, PERFT_CACHE);
if (!(SCAN_COLLECT_METADATA))
cache_add(hash, hashed_size, ctx);
cache_add(hash, hashed_size, ctx);
perf_stop(ctx, PERFT_CACHE);
}
if (ret == CL_VIRUS && SCAN_ALLMATCHES) {
ret = CL_CLEAN;
}