From 436791cc905332c431ec67baa8dd71a9919d519d Mon Sep 17 00:00:00 2001 From: Micah Snyder Date: Fri, 4 Nov 2022 11:58:24 -0700 Subject: [PATCH] Reduce # of time limit checks when in logical sig evaluation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While reviewing scan time performance, the time limit checks have a notable effect on scan time. I tested reducing the number of time checks to every n'th signature evaluation. For the given sample which has a large number of very tiny embedded scans, I found that overall scan time was best when checked every 10th signature. Reducing the number of checks any further had no noticable effect. Bear in mind that these numbers include daily/main/bytecode CVD load time: | current | mod 2 | mod 10 | | ----------------- | ----------------- | ----------------- | | 63.848 s ±1.188 s | 61.773 s ±0.652 s | 59.831 s ±0.975 s | | mod 50 | mod 100 | mod 1000 | | ----------------- | ----------------- | ----------------- | | 59.279 s ±1.652 s | 59.198 s ±1.147 s | 59.440 s ±1.304 s | --- libclamav/matcher.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/libclamav/matcher.c b/libclamav/matcher.c index 1bab82cc1d..7a979f63d7 100644 --- a/libclamav/matcher.c +++ b/libclamav/matcher.c @@ -959,6 +959,12 @@ static cl_error_t lsig_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_a if (CL_SUCCESS != status) { goto done; } + + // Check time limit here, because bytecode functions may take a while. + status = cli_checktimelimit(ctx); + if (CL_SUCCESS != status) { + goto done; + } } done: @@ -1018,10 +1024,15 @@ cl_error_t cli_exp_eval(cli_ctx *ctx, struct cli_matcher *root, struct cli_ac_da break; } - if (cli_checktimelimit(ctx) != CL_SUCCESS) { - cli_dbgmsg("Exceeded scan time limit while evaluating logical and yara signatures (max: %u)\n", ctx->engine->maxscantime); - status = CL_ETIMEOUT; - break; + if (i % 10 == 0) { + // Check the time limit every n'th lsig. + // In testing with a large signature set, we found n = 10 to be just as fast as 100 or + // 1000 and has a significant performance improvement over checking with every lsig. + status = cli_checktimelimit(ctx); + if (CL_SUCCESS != status) { + cli_dbgmsg("Exceeded scan time limit while evaluating logical and yara signatures (max: %u)\n", ctx->engine->maxscantime); + break; + } } }