From eb089cb774b9c1b999eb6d3435d7749286b464ae Mon Sep 17 00:00:00 2001 From: Micah Snyder Date: Fri, 22 Sep 2023 16:33:35 -0700 Subject: [PATCH] Fix alert-exceeds-max feature for files > 2GB and < max-filesize The --alert-exceeds-max feature should alert for all files larger than 2GB because 2GB is the internal limit for individual files. This isn't working correctly because the `goto done;` exit condition after recording the exceeds-max heuristic skips over the logic that reports the alert. This fix moves the ">2GB" check up to the location where the max-filesize engine option is set by clamd or clamscan. If max-filesize > 2GB - 1 is requested, then max-filesize is set to 2GB - 1. Additionally, a warning is printed if max-filesize > 2GB is requested (with an exception for when it's maxed out by setting --max-filesize=0). Resolves: https://github.com/Cisco-Talos/clamav/issues/1030 --- libclamav/others.c | 15 ++++++++++++++- libclamav/scanners.c | 15 --------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/libclamav/others.c b/libclamav/others.c index dd7adba60b..319326203c 100644 --- a/libclamav/others.c +++ b/libclamav/others.c @@ -623,7 +623,20 @@ cl_error_t cl_engine_set_num(struct cl_engine *engine, enum cl_engine_field fiel engine->maxscansize = num; break; case CL_ENGINE_MAX_FILESIZE: - engine->maxfilesize = num; + /* We have a limit of around 2GB (INT_MAX - 2). Enforce it here. + * + * TODO: Large file support is large-ly untested. Remove this restriction and test with a large set of large files of various types. + * libclamav's integer type safety has come a long way since 2014, so it's possible we could lift this restriction, but at least one + * of the parsers is bound to behave badly with large files. */ + if ((uint64_t)num > INT_MAX - 2) { + if ((uint64_t)num > (uint64_t)2 * 1024 * 1024 * 1024 && num != LLONG_MAX) { + // If greater than 2GB, warn. If exactly at 2GB, don't hassle the user. + cli_warnmsg("Max file-size was set to %lld bytes. Unfortunately, scanning files greater than 2147483647 bytes (2 GiB - 1) is not supported.\n", num); + } + engine->maxfilesize = INT_MAX - 2; + } else { + engine->maxfilesize = num; + } break; case CL_ENGINE_MAX_RECURSION: if (!num) { diff --git a/libclamav/scanners.c b/libclamav/scanners.c index 5313f8e2ac..c75b2eef61 100644 --- a/libclamav/scanners.c +++ b/libclamav/scanners.c @@ -5497,21 +5497,6 @@ static cl_error_t scan_common(cl_fmap_t *map, const char *filepath, const char * cli_logg_setup(&ctx); logg_initalized = true; - /* We have a limit of around 2GB (INT_MAX - 2). Enforce it here. */ - /* TODO: Large file support is large-ly untested. Remove this restriction - * and test with a large set of large files of various types. libclamav's - * integer type safety has come a long way since 2014, so it's possible - * we could lift this restriction, but at least one of the parsers is - * bound to behave badly with large files. */ - if (map->len > INT_MAX - 2) { - if (scanoptions->heuristic & CL_SCAN_HEURISTIC_EXCEEDS_MAX) { - status = cli_append_potentially_unwanted(&ctx, "Heuristics.Limits.Exceeded.MaxFileSize"); - } else { - status = CL_CLEAN; - } - goto done; - } - status = cli_magic_scan(&ctx, CL_TYPE_ANY); #if HAVE_JSON