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