From 29987c0eeb7118fd2651d82ac5e77640a9cbe583 Mon Sep 17 00:00:00 2001 From: Andy Ragusa Date: Tue, 7 May 2024 09:07:56 -0700 Subject: [PATCH 1/2] Limit the max-recursion scan option to 100 There is presently no limit for the max-recursion scan option. Selecting a max-recursion limit that is too high will cause confusing errors. E.g.: /home/aragusa/install.alz/bin/clamscan -d clamav.hdb . --max-recursion=9999999999 LibClamAV Error: fmap_fd: Attempted to get fd for NULL fmap /home/aragusa/issue/clamav.hdb: Can't allocate memory ERROR LibClamAV Error: fmap_fd: Attempted to get fd for NULL fmap /home/aragusa/issue/test.sh: Can't allocate memory ERROR This commit prevents setting the max-recursion limit higher than 100. --- clamd/server-th.c | 7 +++++++ clamscan/manager.c | 8 ++++++++ docs/man/clamscan.1.in | 2 +- etc/clamd.conf.sample | 1 + libclamav/default.h | 2 ++ win32/conf_examples/clamd.conf.sample | 1 + 6 files changed, 20 insertions(+), 1 deletion(-) diff --git a/clamd/server-th.c b/clamd/server-th.c index 7dd30d5fb6..29372d68da 100644 --- a/clamd/server-th.c +++ b/clamd/server-th.c @@ -50,6 +50,7 @@ #include "clamav.h" #include "others.h" #include "readdb.h" +#include "default.h" // common #include "output.h" @@ -981,6 +982,12 @@ int recvloop(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigne #endif if ((opt = optget(opts, "MaxRecursion"))->active) { + if ((0 == opt->numarg) || (opt->numarg > CLI_MAX_MAXRECLEVEL)) { + logg(LOGG_ERROR, "MaxRecursion set to %zu, but cannot be larger than %u, and cannot be 0.\n", + (size_t) opt->numarg, CLI_MAX_MAXRECLEVEL); + cl_engine_free(engine); + return 1; + } if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECURSION, opt->numarg))) { logg(LOGG_ERROR, "cl_engine_set_num(CL_ENGINE_MAX_RECURSION) failed: %s\n", cl_strerror(ret)); cl_engine_free(engine); diff --git a/clamscan/manager.c b/clamscan/manager.c index 26b855b43b..d330c0bbd3 100644 --- a/clamscan/manager.c +++ b/clamscan/manager.c @@ -56,6 +56,7 @@ #include "matcher-pcre.h" #include "str.h" #include "readdb.h" +#include "default.h" // common #include "optparser.h" @@ -1388,6 +1389,13 @@ int scanmanager(const struct optstruct *opts) } if ((opt = optget(opts, "max-recursion"))->active) { + uint32_t opt_value = opt->numarg; + if ((0 == opt_value) || (opt_value > CLI_MAX_MAXRECLEVEL)) { + logg(LOGG_ERROR, "max-recursion set to %u, but cannot be larger than %u, and cannot be 0.\n", + opt_value, CLI_MAX_MAXRECLEVEL); + ret = 2; + goto done; + } if ((ret = cl_engine_set_num(engine, CL_ENGINE_MAX_RECURSION, opt->numarg))) { logg(LOGG_ERROR, "cli_engine_set_num(CL_ENGINE_MAX_RECURSION) failed: %s\n", cl_strerror(ret)); ret = 2; diff --git a/docs/man/clamscan.1.in b/docs/man/clamscan.1.in index d40b554a31..6eba8d0dfd 100644 --- a/docs/man/clamscan.1.in +++ b/docs/man/clamscan.1.in @@ -232,7 +232,7 @@ Extract and scan at most #n bytes from each archive. The size the archive plus t Extract at most #n files from each scanned file (when this is an archive, a document or another kind of container). This option protects your system against DoS attacks (default: 10000) .TP \fB\-\-max\-recursion=#n\fR -Set archive recursion level limit. This option protects your system against DoS attacks (default: 17). +Set archive recursion level limit. This option protects your system against DoS attacks (default: 17) (maximum: 100). .TP \fB\-\-max\-dir\-recursion=#n\fR Maximum depth directories are scanned at (default: 15). diff --git a/etc/clamd.conf.sample b/etc/clamd.conf.sample index 120cf32ab7..e7c7b9c4a6 100644 --- a/etc/clamd.conf.sample +++ b/etc/clamd.conf.sample @@ -585,6 +585,7 @@ Example # deeply the process should be continued. # Note: setting this limit too high may result in severe damage to the system. # Default: 17 +# Maximum: 100 #MaxRecursion 10 # Number of files to be scanned within an archive, a document, or any other diff --git a/libclamav/default.h b/libclamav/default.h index df50876090..caa1ad3e7b 100644 --- a/libclamav/default.h +++ b/libclamav/default.h @@ -58,6 +58,8 @@ #define CLI_DEFAULT_PCRE_RECMATCH_LIMIT 2000 #define CLI_DEFAULT_PCRE_MAX_FILESIZE (1024 * 1024 * 100) // 100 MB +/* Maximums */ +#define CLI_MAX_MAXRECLEVEL 100 // clang-format on #endif diff --git a/win32/conf_examples/clamd.conf.sample b/win32/conf_examples/clamd.conf.sample index cd293d8967..66a07a8ccd 100644 --- a/win32/conf_examples/clamd.conf.sample +++ b/win32/conf_examples/clamd.conf.sample @@ -557,6 +557,7 @@ TCPAddr localhost # deeply the process should be continued. # Note: setting this limit too high may result in severe damage to the system. # Default: 17 +# Maximum: 100 #MaxRecursion 10 # Number of files to be scanned within an archive, a document, or any other From e7cb0ff6f1526c16dd33711dfc8b462d9c2f955a Mon Sep 17 00:00:00 2001 From: Micah Snyder Date: Mon, 9 Sep 2024 12:46:33 -0400 Subject: [PATCH 2/2] Clang-format touchup --- clamd/server-th.c | 2 +- clamscan/manager.c | 2 +- libclamav/readdb.h | 12 ++++++------ libclamav/scanners.c | 4 ++-- libclamav/special.c | 2 +- libclamav/udf.h | 8 ++------ libclamav_rust/build.rs | 7 +------ 7 files changed, 14 insertions(+), 23 deletions(-) diff --git a/clamd/server-th.c b/clamd/server-th.c index 29372d68da..84c6a05641 100644 --- a/clamd/server-th.c +++ b/clamd/server-th.c @@ -984,7 +984,7 @@ int recvloop(int *socketds, unsigned nsockets, struct cl_engine *engine, unsigne if ((opt = optget(opts, "MaxRecursion"))->active) { if ((0 == opt->numarg) || (opt->numarg > CLI_MAX_MAXRECLEVEL)) { logg(LOGG_ERROR, "MaxRecursion set to %zu, but cannot be larger than %u, and cannot be 0.\n", - (size_t) opt->numarg, CLI_MAX_MAXRECLEVEL); + (size_t)opt->numarg, CLI_MAX_MAXRECLEVEL); cl_engine_free(engine); return 1; } diff --git a/clamscan/manager.c b/clamscan/manager.c index d330c0bbd3..668bfcd39b 100644 --- a/clamscan/manager.c +++ b/clamscan/manager.c @@ -1392,7 +1392,7 @@ int scanmanager(const struct optstruct *opts) uint32_t opt_value = opt->numarg; if ((0 == opt_value) || (opt_value > CLI_MAX_MAXRECLEVEL)) { logg(LOGG_ERROR, "max-recursion set to %u, but cannot be larger than %u, and cannot be 0.\n", - opt_value, CLI_MAX_MAXRECLEVEL); + opt_value, CLI_MAX_MAXRECLEVEL); ret = 2; goto done; } diff --git a/libclamav/readdb.h b/libclamav/readdb.h index a353e2a7bc..358f5d3f05 100644 --- a/libclamav/readdb.h +++ b/libclamav/readdb.h @@ -81,9 +81,9 @@ struct cli_matcher; cli_strbcasestr(ext, ".ign") || \ cli_strbcasestr(ext, ".ign2") || \ cli_strbcasestr(ext, ".imp")) -#define CLI_DBEXT_SIGNATURE(ext) \ - ( \ - cli_strbcasestr(ext, ".cvd") || \ +#define CLI_DBEXT_SIGNATURE(ext) \ + ( \ + cli_strbcasestr(ext, ".cvd") || \ cli_strbcasestr(ext, ".cld")) #else #define CLI_DBEXT(ext) \ @@ -124,9 +124,9 @@ struct cli_matcher; cli_strbcasestr(ext, ".ign") || \ cli_strbcasestr(ext, ".ign2") || \ cli_strbcasestr(ext, ".imp")) -#define CLI_DBEXT_SIGNATURE(ext) \ - ( \ - cli_strbcasestr(ext, ".cvd") || \ +#define CLI_DBEXT_SIGNATURE(ext) \ + ( \ + cli_strbcasestr(ext, ".cvd") || \ cli_strbcasestr(ext, ".cld")) #endif diff --git a/libclamav/scanners.c b/libclamav/scanners.c index 8cc19297af..3ef17bad8c 100644 --- a/libclamav/scanners.c +++ b/libclamav/scanners.c @@ -4212,9 +4212,9 @@ static inline bool result_should_goto_done(cli_ctx *ctx, cl_error_t result_in, c cl_error_t cli_magic_scan(cli_ctx *ctx, cli_file_t type) { - cl_error_t ret = CL_CLEAN; + cl_error_t ret = CL_CLEAN; cl_error_t cache_check_result = CL_VIRUS; - bool cache_enabled = true; + bool cache_enabled = true; cl_error_t verdict_at_this_level; cli_file_t dettype = 0; uint8_t typercg = 1; diff --git a/libclamav/special.c b/libclamav/special.c index 4544e59eeb..7c3d16e780 100644 --- a/libclamav/special.c +++ b/libclamav/special.c @@ -72,7 +72,7 @@ int cli_check_mydoom_log(cli_ctx *ctx) while (blocks) { /* This wasn't probably intended but that's what the current code does anyway */ const uint32_t marker_ff = 0xffffffff; - if (!memcmp(&ptr[--blocks], &marker_ff, sizeof(uint32_t))) + if (!memcmp(&ptr[--blocks], &marker_ff, sizeof(uint32_t))) return CL_CLEAN; } diff --git a/libclamav/udf.h b/libclamav/udf.h index c40027635a..f8d5a82d88 100644 --- a/libclamav/udf.h +++ b/libclamav/udf.h @@ -66,7 +66,6 @@ typedef struct __attribute__((packed)) { } lb_addr; - // Long allocation descriptor typedef struct __attribute__((packed)) { uint32_t length; // 4/14.14.1.1 @@ -211,10 +210,7 @@ static uint32_t getFileIdentifierDescriptorPaddingLength(const FileIdentifierDes static inline size_t getFileIdentifierDescriptorSize(const FileIdentifierDescriptor* fid) { - return FILE_IDENTIFIER_DESCRIPTOR_SIZE_KNOWN - + le16_to_host(fid->implementationLength) - + fid->fileIdentifierLength - + getFileIdentifierDescriptorPaddingLength(fid); + return FILE_IDENTIFIER_DESCRIPTOR_SIZE_KNOWN + le16_to_host(fid->implementationLength) + fid->fileIdentifierLength + getFileIdentifierDescriptorPaddingLength(fid); } typedef struct __attribute__((packed)) { @@ -521,7 +517,7 @@ typedef struct __attribute__((packed)) { } FileSetDescriptor; -typedef struct __attribute__((packed)) { +typedef struct __attribute__((packed)) { uint8_t structType; char standardIdentifier[5]; uint8_t structVersion; diff --git a/libclamav_rust/build.rs b/libclamav_rust/build.rs index ede1743f41..bc05a0f73e 100644 --- a/libclamav_rust/build.rs +++ b/libclamav_rust/build.rs @@ -58,12 +58,7 @@ const BINDGEN_FUNCTIONS: &[&str] = &[ ]; // Generate bindings for these types (structs, enums): -const BINDGEN_TYPES: &[&str] = &[ - "cli_matcher", - "cli_ac_data", - "cli_ac_result", - "onedump_t", -]; +const BINDGEN_TYPES: &[&str] = &["cli_matcher", "cli_ac_data", "cli_ac_result", "onedump_t"]; // Find the required functions and types in these headers: const BINDGEN_HEADERS: &[&str] = &[