diff options
author | Ladar Levison <ladar@lavabit.com> | 2022-04-05 17:23:21 +0300 |
---|---|---|
committer | Ladar Levison <ladar@lavabit.com> | 2022-04-06 01:27:54 +0300 |
commit | 0fe89455712db142b144256ef2178a9f7f1110b9 (patch) | |
tree | 78808758e176a2fc21b8ea894956cbf3b33d47b1 | |
parent | eddef7cf97bdcf059c464b4723dba0310b0e8d38 (diff) |
ClamAV updated to 0.103.5. Patches for 0.104.2 generated but currently unused.
-rw-r--r-- | dev/scripts/builders/build.lib.params.sh | 4 | ||||
-rwxr-xr-x | dev/scripts/builders/build.lib.sh | 11 | ||||
-rw-r--r-- | lib/archives/clamav-0.103.5.tar.gz (renamed from lib/archives/clamav-0.102.3.tar.gz) | bin | 13226108 -> 16434316 bytes | |||
-rw-r--r-- | lib/check/magma.open.symbols.c | 20 | ||||
-rw-r--r-- | lib/check/magma.open.symbols.h | 20 | ||||
-rw-r--r-- | lib/patches/clamav/freshclam_cafile_option_01035.patch | 107 | ||||
-rw-r--r-- | lib/patches/clamav/shutdown_rarload_01035.patch | 256 | ||||
-rw-r--r-- | lib/patches/clamav/shutdown_rarload_01042.patch | 52 | ||||
-rw-r--r-- | lib/patches/clamav/version_0984.patch | 1 | ||||
-rw-r--r-- | sandbox/etc/freshclam.conf | 1 | ||||
-rw-r--r-- | src/providers/symbols.c | 20 | ||||
-rw-r--r-- | src/providers/symbols.h | 20 |
12 files changed, 455 insertions, 57 deletions
diff --git a/dev/scripts/builders/build.lib.params.sh b/dev/scripts/builders/build.lib.params.sh index fb07d7f2..b48c4882 100644 --- a/dev/scripts/builders/build.lib.params.sh +++ b/dev/scripts/builders/build.lib.params.sh @@ -13,7 +13,9 @@ PCRE="pcre2-10.31" BZIP2="bzip2-1.0.8" DSPAM="dspam-3.10.2" GEOIP="GeoIP-1.4.8" -CLAMAV="clamav-0.102.3" +#CLAMAV="clamav-0.104.2" +CLAMAV="clamav-0.103.5" +#CLAMAV="clamav-0.102.3" MARIADB="mariadb-connector-c-2.3.7" CHECKER="check-0.11.0" OPENSSL="openssl-1.0.2u" diff --git a/dev/scripts/builders/build.lib.sh b/dev/scripts/builders/build.lib.sh index fccf0c82..4b92f2a9 100755 --- a/dev/scripts/builders/build.lib.sh +++ b/dev/scripts/builders/build.lib.sh @@ -1308,11 +1308,20 @@ clamav() { # Output the version number and not the git commit hash. cat "$M_PATCHES/clamav/"version_0984.patch | patch -p1 --verbose &>> "$M_LOGS/clamav.txt"; error + elif [[ $CLAMAV =~ "clamav-0.103.5" ]]; then + # Add the shutdown and clean up functions and fix the rar library dynamic loading logic. + cat "$M_PATCHES/clamav/"shutdown_rarload_01035.patch | patch -p1 --verbose &>> "$M_LOGS/clamav.txt"; error + + # Add the ability to dictate the CA bundle file location when running freshclam. + cat "$M_PATCHES/clamav/"freshclam_cafile_option_01035.patch | patch -p1 --verbose &>> "$M_LOGS/clamav.txt"; error + + # Output the version number and not the git commit hash. + cat "$M_PATCHES/clamav/"version_0984.patch | patch -p1 --verbose &>> "$M_LOGS/clamav.txt"; error # Applied to most recent version. else # Add the shutdown and clean up functions and fix the rar library dynamic loading logic. - cat "$M_PATCHES/clamav/"shutdown_rarload_01042.patch | patch -p1 --fuzz=100 --verbose &>> "$M_LOGS/clamav.txt"; error + cat "$M_PATCHES/clamav/"shutdown_rarload_01042.patch | patch -p1 --verbose &>> "$M_LOGS/clamav.txt"; error # Add the ability to dictate the CA bundle file location when running freshclam. cat "$M_PATCHES/clamav/"freshclam_cafile_option_01042.patch | patch -p1 --verbose &>> "$M_LOGS/clamav.txt"; error diff --git a/lib/archives/clamav-0.102.3.tar.gz b/lib/archives/clamav-0.103.5.tar.gz Binary files differindex 6d2ac8e6..23bb92bb 100644 --- a/lib/archives/clamav-0.102.3.tar.gz +++ b/lib/archives/clamav-0.103.5.tar.gz diff --git a/lib/check/magma.open.symbols.c b/lib/check/magma.open.symbols.c index 1af4656f..3ed3398b 100644 --- a/lib/check/magma.open.symbols.c +++ b/lib/check/magma.open.symbols.c @@ -25,19 +25,19 @@ int (*BZ2_bzBuffToBuffDecompress_d)(char *dest, unsigned int *destLen, char *sou int (*BZ2_bzBuffToBuffCompress_d)(char *dest, unsigned int *destLen, char *source, unsigned int sourceLen, int blockSize100k, int verbosity, int workFactor) = NULL; void (*cl_shutdown_d)(void) = NULL; const char * (*cl_retver_d)(void) = NULL; -int (*cl_init_d)(unsigned int initoptions) = NULL; +cl_error_t (*cl_init_d)(unsigned int initoptions) = NULL; const char * (*cl_strerror_d)(int clerror) = NULL; struct cl_engine * (*cl_engine_new_d)(void) = NULL; -int (*cl_statfree_d)(struct cl_stat *dbstat) = NULL; -int (*cl_engine_free_d)(struct cl_engine *engine) = NULL; -int (*cl_engine_compile_d)(struct cl_engine *engine) = NULL; +cl_error_t (*cl_statfree_d)(struct cl_stat *dbstat) = NULL; +cl_error_t (*cl_engine_free_d)(struct cl_engine *engine) = NULL; +cl_error_t (*cl_engine_compile_d)(struct cl_engine *engine) = NULL; int (*cl_statchkdir_d)(const struct cl_stat *dbstat) = NULL; -int (*cl_statinidir_d)(const char *dirname, struct cl_stat *dbstat) = NULL; -int (*cl_countsigs_d)(const char *path, unsigned int countoptions, unsigned int *sigs) = NULL; -int (*cl_engine_set_num_d)(struct cl_engine *engine, enum cl_engine_field field, long long num) = NULL; -int (*cl_engine_set_str_d)(struct cl_engine *engine, enum cl_engine_field field, const char *str) = NULL; -int (*cl_load_d)(const char *path, struct cl_engine *engine, unsigned int *signo, unsigned int dboptions) = NULL; -int (*cl_scandesc_d)(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions) = NULL; +cl_error_t (*cl_statinidir_d)(const char *dirname, struct cl_stat *dbstat) = NULL; +cl_error_t (*cl_countsigs_d)(const char *path, unsigned int countoptions, unsigned int *sigs) = NULL; +cl_error_t (*cl_engine_set_num_d)(struct cl_engine *engine, enum cl_engine_field field, long long num) = NULL; +cl_error_t (*cl_engine_set_str_d)(struct cl_engine *engine, enum cl_engine_field field, const char *str) = NULL; +cl_error_t (*cl_load_d)(const char *path, struct cl_engine *engine, unsigned int *signo, unsigned int dboptions) = NULL; +cl_error_t (*cl_scandesc_d)(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions) = NULL; const char * (*dspam_version_d)(void) = NULL; int (*dspam_detach_d)(DSPAM_CTX *CTX) = NULL; void (*dspam_destroy_d)(DSPAM_CTX * CTX) = NULL; diff --git a/lib/check/magma.open.symbols.h b/lib/check/magma.open.symbols.h index 8db5dcf0..e3fd51e7 100644 --- a/lib/check/magma.open.symbols.h +++ b/lib/check/magma.open.symbols.h @@ -138,19 +138,19 @@ extern int (*BZ2_bzBuffToBuffCompress_d)(char *dest, unsigned int *destLen, char //! CLAMAV extern void (*cl_shutdown_d)(void); extern const char * (*cl_retver_d)(void); -extern int (*cl_init_d)(unsigned int initoptions); +extern cl_error_t (*cl_init_d)(unsigned int initoptions); extern const char * (*cl_strerror_d)(int clerror); extern struct cl_engine * (*cl_engine_new_d)(void); -extern int (*cl_statfree_d)(struct cl_stat *dbstat); -extern int (*cl_engine_free_d)(struct cl_engine *engine); -extern int (*cl_engine_compile_d)(struct cl_engine *engine); +extern cl_error_t (*cl_statfree_d)(struct cl_stat *dbstat); +extern cl_error_t (*cl_engine_free_d)(struct cl_engine *engine); +extern cl_error_t (*cl_engine_compile_d)(struct cl_engine *engine); extern int (*cl_statchkdir_d)(const struct cl_stat *dbstat); -extern int (*cl_statinidir_d)(const char *dirname, struct cl_stat *dbstat); -extern int (*cl_countsigs_d)(const char *path, unsigned int countoptions, unsigned int *sigs); -extern int (*cl_engine_set_num_d)(struct cl_engine *engine, enum cl_engine_field field, long long num); -extern int (*cl_engine_set_str_d)(struct cl_engine *engine, enum cl_engine_field field, const char *str); -extern int (*cl_load_d)(const char *path, struct cl_engine *engine, unsigned int *signo, unsigned int dboptions); -extern int (*cl_scandesc_d)(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions); +extern cl_error_t (*cl_statinidir_d)(const char *dirname, struct cl_stat *dbstat); +extern cl_error_t (*cl_countsigs_d)(const char *path, unsigned int countoptions, unsigned int *sigs); +extern cl_error_t (*cl_engine_set_num_d)(struct cl_engine *engine, enum cl_engine_field field, long long num); +extern cl_error_t (*cl_engine_set_str_d)(struct cl_engine *engine, enum cl_engine_field field, const char *str); +extern cl_error_t (*cl_load_d)(const char *path, struct cl_engine *engine, unsigned int *signo, unsigned int dboptions); +extern cl_error_t (*cl_scandesc_d)(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions); //! DSPAM extern const char * (*dspam_version_d)(void); diff --git a/lib/patches/clamav/freshclam_cafile_option_01035.patch b/lib/patches/clamav/freshclam_cafile_option_01035.patch new file mode 100644 index 00000000..c61c1673 --- /dev/null +++ b/lib/patches/clamav/freshclam_cafile_option_01035.patch @@ -0,0 +1,107 @@ +diff --git a/freshclam/freshclam.c b/freshclam/freshclam.c +index 1f97d51..a9c33d3 100644 +--- a/freshclam/freshclam.c ++++ b/freshclam/freshclam.c +@@ -173,6 +173,7 @@ static void help(void) + printf("\n"); + printf(" --config-file=FILE Read configuration from FILE.\n"); + printf(" --log=FILE -l FILE Log into FILE\n"); ++ printf(" --ca=FILE Override the certificate bundle FILE location\n"); + printf(" --daemon -d Run in daemon mode\n"); + printf(" --pid=FILE -p FILE Save daemon's pid in FILE\n"); + #ifndef _WIN32 +@@ -875,6 +876,7 @@ static fc_error_t initialize(struct optstruct *opts) + fcConfig.localIP = (optget(opts, "LocalIPAddress"))->strarg; + + /* Select a path for the temp directory: databaseDirectory/tmp */ ++ fcConfig.caFile = optget(opts, "CAFile")->strarg; + tempDirectory = cli_gentemp_with_prefix(fcConfig.databaseDirectory, "tmp"); + fcConfig.tempDirectory = tempDirectory; + +diff --git a/libfreshclam/libfreshclam.c b/libfreshclam/libfreshclam.c +index 6258626..fde1ab7 100644 +--- a/libfreshclam/libfreshclam.c ++++ b/libfreshclam/libfreshclam.c +@@ -213,6 +213,9 @@ fc_error_t fc_initialize(fc_config *fcConfig) + if (NULL != fcConfig->proxyPassword) { + g_proxyPassword = cli_strdup(fcConfig->proxyPassword); + } ++ if (NULL != fcConfig->caFile) { ++ g_caFile = cli_strdup(fcConfig->caFile); ++ } + + #ifdef _WIN32 + if ((fcConfig->databaseDirectory[strlen(fcConfig->databaseDirectory) - 1] != '/') && +@@ -288,6 +291,10 @@ void fc_cleanup(void) + free(g_userAgent); + g_userAgent = NULL; + } ++ if (NULL != g_caFile) { ++ free(g_caFile); ++ g_caFile = NULL; ++ } + if (NULL != g_proxyServer) { + free(g_proxyServer); + g_proxyServer = NULL; +diff --git a/libfreshclam/libfreshclam.h b/libfreshclam/libfreshclam.h +index c7da23d..0780f2c 100644 +--- a/libfreshclam/libfreshclam.h ++++ b/libfreshclam/libfreshclam.h +@@ -50,6 +50,7 @@ typedef struct fc_config_ { + uint32_t connectTimeout; /**< CURLOPT_CONNECTTIMEOUT, Timeout for the. connection phase (seconds). */ + uint32_t requestTimeout; /**< CURLOPT_TIMEOUT, Timeout for libcurl transfer operation (seconds). */ + uint32_t bCompressLocalDatabase; /**< If set, will apply gz compression to CLD databases. */ ++ const char *caFile; /**< (optional) CA file to use for certificate verification, if desired. */ + const char *logFile; /**< (optional) Filepath to use for log output, if desired. */ + const char *logFacility; /**< (optional) System logging facility (I.e. "syslog"), if desired. */ + const char *localIP; /**< (optional) client IP for multihomed systems. */ +diff --git a/libfreshclam/libfreshclam_internal.c b/libfreshclam/libfreshclam_internal.c +index f6128e6..e92d266 100644 +--- a/libfreshclam/libfreshclam_internal.c ++++ b/libfreshclam/libfreshclam_internal.c +@@ -107,6 +107,7 @@ uint16_t g_proxyPort = 0; + char *g_proxyUsername = NULL; + char *g_proxyPassword = NULL; + ++char *g_caFile = NULL; + char *g_tempDirectory = NULL; + char *g_databaseDirectory = NULL; + +@@ -709,6 +710,12 @@ static fc_error_t create_curl_handle( + } + } + ++ if (g_caFile) { ++ if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_CAINFO, g_caFile)) { ++ logg("!create_curl_handle: Failed to set CURLOPT_CAINFO (%s)!\n", g_caFile); ++ } ++ } ++ + #if defined(C_DARWIN) || defined(_WIN32) + if (CURLE_OK != curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function)) { + logg("*create_curl_handle: Failed to set SSL CTX function. Your libcurl may use an SSL backend that does not support CURLOPT_SSL_CTX_FUNCTION.\n"); +diff --git a/libfreshclam/libfreshclam_internal.h b/libfreshclam/libfreshclam_internal.h +index 890d7e5..401d0d4 100644 +--- a/libfreshclam/libfreshclam_internal.h ++++ b/libfreshclam/libfreshclam_internal.h +@@ -54,6 +54,7 @@ extern uint16_t g_proxyPort; + extern char *g_proxyUsername; + extern char *g_proxyPassword; + ++extern char *g_caFile; + extern char *g_tempDirectory; + extern char *g_databaseDirectory; + +diff --git a/shared/optparser.c b/shared/optparser.c +index 3d540b9..63b8d66 100644 +--- a/shared/optparser.c ++++ b/shared/optparser.c +@@ -264,6 +264,8 @@ const struct clam_option __clam_options[] = { + + {"DatabaseDirectory", "datadir", 0, CLOPT_TYPE_STRING, NULL, -1, CONST_DATADIR, 0, OPT_CLAMD | OPT_FRESHCLAM | OPT_SIGTOOL, "This option allows you to change the default database directory.\nIf you enable it, please make sure it points to the same directory in\nboth clamd and freshclam.", "/var/lib/clamav"}, + ++ {"CAFile", "ca", 0, CLOPT_TYPE_STRING, NULL, -1, NULL, 0, OPT_FRESHCLAM, "This option allows you to override the location of the CA bundle file used by freshclam.\nIf you enable it, please make sure it points to a valid certifcate bundle file.\n", ""}, ++ + {"OfficialDatabaseOnly", "official-db-only", 0, CLOPT_TYPE_BOOL, MATCH_BOOL, 0, NULL, 0, OPT_CLAMD | OPT_CLAMSCAN, "Only load the official signatures published by the ClamAV project.", "no"}, + + {"YaraRules", "yara-rules", 0, CLOPT_TYPE_STRING, NULL, 0, NULL, 0, OPT_CLAMSCAN, "By default, yara rules will be loaded. This option allows you to exclude yara rules when scanning and also to scan only using yara rules. Valid options are yes|no|only", "yes"}, diff --git a/lib/patches/clamav/shutdown_rarload_01035.patch b/lib/patches/clamav/shutdown_rarload_01035.patch new file mode 100644 index 00000000..8f33fa10 --- /dev/null +++ b/lib/patches/clamav/shutdown_rarload_01035.patch @@ -0,0 +1,256 @@ +diff --git a/libclamav/clamav.h b/libclamav/clamav.h +index 4e34d63..c947482 100644 +--- a/libclamav/clamav.h ++++ b/libclamav/clamav.h +@@ -264,6 +264,7 @@ void cl_cleanup_crypto(void); + * @return cl_error_t CL_SUCCESS if everything initalized correctly. + */ + extern cl_error_t cl_init(unsigned int initoptions); ++extern void cl_shutdown(void); + + /** + * @brief Allocate a new scanning engine and initialize default settings. +diff --git a/libclamav/mbox.c b/libclamav/mbox.c +index 19feb67..414acf0 100644 +--- a/libclamav/mbox.c ++++ b/libclamav/mbox.c +@@ -3090,6 +3090,30 @@ initialiseTables(table_t **rfc821Table, table_t **subtypeTable) + } + + /* ++ * Cleanup the various lookup tables ++ */ ++void ++cli_mbox_shutdown(void) ++{ ++ ++#ifdef CL_THREAD_SAFE ++ pthread_mutex_lock(&tables_mutex); ++#endif ++ if(rfc821) { ++ tableDestroy(rfc821); ++ rfc821 = NULL; ++ } ++ if(subtype) { ++ tableDestroy(subtype); ++ subtype = NULL; ++ } ++#ifdef CL_THREAD_SAFE ++ pthread_mutex_unlock(&tables_mutex); ++#endif ++ ++} ++ ++/* + * If there's a HTML text version use that, otherwise + * use the first text part, otherwise just use the + * first one around. HTML text is most likely to include +diff --git a/libclamav/mbox.h b/libclamav/mbox.h +index 63ee0c4..fb767f5 100644 +--- a/libclamav/mbox.h ++++ b/libclamav/mbox.h +@@ -75,4 +75,6 @@ typedef enum { + size_t strstrip(char *s); /* remove trailing white space */ + int cli_mbox(const char *dir, cli_ctx *ctx); + ++void cli_mbox_shutdown(void); ++ + #endif /* __MBOX_H */ +diff --git a/libclamav/message.c b/libclamav/message.c +index 75c86ec..cc2fb7b 100644 +--- a/libclamav/message.c ++++ b/libclamav/message.c +@@ -137,6 +137,32 @@ static const unsigned char base64Table[256] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; + ++static table_t *mime_table = NULL; ++ ++#ifdef CL_THREAD_SAFE ++ static pthread_mutex_t mime_mutex = PTHREAD_MUTEX_INITIALIZER; ++#endif ++ ++/* ++ * Cleanup the various lookup tables ++ */ ++void ++cli_mime_shutdown(void) ++{ ++ ++#ifdef CL_THREAD_SAFE ++ pthread_mutex_lock(&mime_mutex); ++#endif ++ if(mime_table) { ++ tableDestroy(mime_table); ++ mime_table = NULL; ++ } ++#ifdef CL_THREAD_SAFE ++ pthread_mutex_unlock(&mime_mutex); ++#endif ++ ++} ++ + message * + messageCreate(void) + { +@@ -211,12 +237,8 @@ void messageReset(message *m) + */ + int messageSetMimeType(message *mess, const char *type) + { +-#ifdef CL_THREAD_SAFE +- static pthread_mutex_t mime_mutex = PTHREAD_MUTEX_INITIALIZER; +-#endif + const struct mime_map *m; + int typeval; +- static table_t *mime_table; + + if (mess == NULL) { + cli_dbgmsg("messageSetMimeType: NULL message pointer\n"); +diff --git a/libclamav/message.h b/libclamav/message.h +index 62f6b85..a0ec5cd 100644 +--- a/libclamav/message.h ++++ b/libclamav/message.h +@@ -93,4 +93,6 @@ int messageSavePartial(message *m, const char *dir, const char *id, unsigned par + json_object *messageGetJObj(message *m); + #endif + ++void cli_mime_shutdown(void); ++ + #endif /*_MESSAGE_H*/ +diff --git a/libclamav/others.c b/libclamav/others.c +index 7a0e92f..f021ffc 100644 +--- a/libclamav/others.c ++++ b/libclamav/others.c +@@ -288,7 +288,9 @@ static void *get_module_function(void *handle, const char *name) + { + void *procAddress = NULL; + procAddress = dlsym(handle, name); +- if (NULL == procAddress) { ++ ++ // Ignore missing symbols when the handle is NULL. This only means the symbol wasn't statically linked or otherwise loaded already. ++ if (NULL == procAddress && handle != NULL) { + const char *err = dlerror(); + if (NULL == err) { + cli_warnmsg("Failed to get function \"%s\": Unknown error.\n", name); +@@ -296,6 +298,10 @@ static void *get_module_function(void *handle, const char *name) + cli_warnmsg("Failed to get function \"%s\": %s\n", name, err); + } + } ++ // If the symbol wasn't found, and the handle is NULL, this will call dlerror(), which will reset the error queue. ++ else if (NULL == procAddress && handle == NULL) { ++ dlerror(); ++ } + return procAddress; + } + #endif // !_WIN32 +@@ -317,20 +323,25 @@ static void rarload(void) + + if (have_rar) return; + +- rhandle = load_module("libclamunrar_iface", "unrar"); +- if (NULL == rhandle) +- return; +- +- if ((NULL == (cli_unrar_open = (cl_unrar_error_t(*)(const char *, void **, char **, uint32_t *, uint8_t))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_open"))) || +- (NULL == (cli_unrar_peek_file_header = (cl_unrar_error_t(*)(void *, unrar_metadata_t *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_peek_file_header"))) || +- (NULL == (cli_unrar_extract_file = (cl_unrar_error_t(*)(void *, const char *, char *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_extract_file"))) || +- (NULL == (cli_unrar_skip_file = (cl_unrar_error_t(*)(void *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_skip_file"))) || +- (NULL == (cli_unrar_close = (void (*)(void *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_close")))) { +- +- cli_warnmsg("Failed to load function from UnRAR module\n"); +- cli_warnmsg("Version mismatch?\n"); +- cli_warnmsg("UnRAR support unavailable\n"); +- return; ++ if ((NULL == (cli_unrar_open = (cl_unrar_error_t(*)(const char *, void **, char **, uint32_t *, uint8_t))get_module_function(NULL, "libclamunrar_iface_LTX_unrar_open"))) || ++ (NULL == (cli_unrar_peek_file_header = (cl_unrar_error_t(*)(void *, unrar_metadata_t *))get_module_function(NULL, "libclamunrar_iface_LTX_unrar_peek_file_header"))) || ++ (NULL == (cli_unrar_extract_file = (cl_unrar_error_t(*)(void *, const char *, char *))get_module_function(NULL, "libclamunrar_iface_LTX_unrar_extract_file"))) || ++ (NULL == (cli_unrar_skip_file = (cl_unrar_error_t(*)(void *))get_module_function(NULL, "libclamunrar_iface_LTX_unrar_skip_file"))) || ++ (NULL == (cli_unrar_close = (void (*)(void *))get_module_function(NULL, "libclamunrar_iface_LTX_unrar_close")))) { ++ ++ rhandle = load_module("libclamunrar_iface", "unrar"); ++ if (NULL == rhandle) return; ++ ++ if ((NULL == (cli_unrar_open = (cl_unrar_error_t(*)(const char *, void **, char **, uint32_t *, uint8_t))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_open"))) || ++ (NULL == (cli_unrar_peek_file_header = (cl_unrar_error_t(*)(void *, unrar_metadata_t *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_peek_file_header"))) || ++ (NULL == (cli_unrar_extract_file = (cl_unrar_error_t(*)(void *, const char *, char *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_extract_file"))) || ++ (NULL == (cli_unrar_skip_file = (cl_unrar_error_t(*)(void *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_skip_file"))) || ++ (NULL == (cli_unrar_close = (void (*)(void *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_close")))) { ++ cli_warnmsg("Failed to load function from UnRAR module\n"); ++ cli_warnmsg("Version mismatch?\n"); ++ cli_warnmsg("UnRAR support unavailable\n"); ++ return; ++ } + } + have_rar = 1; + } +@@ -460,6 +471,14 @@ cl_error_t cl_init(unsigned int initoptions) + return CL_SUCCESS; + } + ++void cl_shutdown(void) { ++ cli_mbox_shutdown(); ++ cli_mime_shutdown(); ++ if (lt_dlinitialized() && lt_dlexit()) { ++ cli_errmsg("lt_dlexit: Library exit error, probably because of an invalid reference counter"); ++ } ++} ++ + struct cl_engine *cl_engine_new(void) + { + struct cl_engine *new; +diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c +index 6013f2a..6dc57ea 100644 +--- a/libltdl/ltdl.c ++++ b/libltdl/ltdl.c +@@ -91,7 +91,7 @@ static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH; + + + +- ++ + /* --- DYNAMIC MODULE LOADING --- */ + + +@@ -262,6 +262,12 @@ lt_dlinit (void) + } + + int ++lt_dlinitialized (void) ++{ ++ return initialized; ++} ++ ++int + lt_dlexit (void) + { + /* shut down libltdl */ +diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h +index f811399..ee9b03a 100644 +--- a/libltdl/ltdl.h ++++ b/libltdl/ltdl.h +@@ -43,7 +43,7 @@ LT_BEGIN_C_DECLS + /* LT_STRLEN can be used safely on NULL pointers. */ + #define LT_STRLEN(s) (((s) && (s)[0]) ? strlen (s) : 0) + +- ++ + /* --- DYNAMIC MODULE LOADING API --- */ + + +@@ -52,6 +52,7 @@ typedef struct lt__handle *lt_dlhandle; /* A loaded module. */ + /* Initialisation and finalisation functions for libltdl. */ + LT_SCOPE int lt_dlinit (void); + LT_SCOPE int lt_dlexit (void); ++LT_SCOPE int lt_dlinitialized (void); + + /* Module search path manipulation. */ + LT_SCOPE int lt_dladdsearchdir (const char *search_dir); +@@ -110,7 +111,7 @@ extern LT_DLSYM_CONST lt_dlsymlist lt__PROGRAM__LTX_preloaded_symbols[]; + + + +- ++ + /* --- MODULE INFORMATION --- */ + + diff --git a/lib/patches/clamav/shutdown_rarload_01042.patch b/lib/patches/clamav/shutdown_rarload_01042.patch index 373869ef..2ec7fdbf 100644 --- a/lib/patches/clamav/shutdown_rarload_01042.patch +++ b/lib/patches/clamav/shutdown_rarload_01042.patch @@ -1,15 +1,15 @@ diff --git a/libclamav/clamav.h b/libclamav/clamav.h -index d4be07e..c49c484 100644 +index d4be07e..70e9c72 100644 --- a/libclamav/clamav.h +++ b/libclamav/clamav.h -@@ -261,6 +261,7 @@ void cl_cleanup_crypto(void); - /** - * @brief Initialize the ClamAV library. - * -+extern void cl_shutdown(void); - * @param initoptions Unused. +@@ -265,6 +265,7 @@ void cl_cleanup_crypto(void); * @return cl_error_t CL_SUCCESS if everything initalized correctly. */ + extern cl_error_t cl_init(unsigned int initoptions); ++extern void cl_shutdown(void); + + /** + * @brief Allocate a new scanning engine and initialize default settings. diff --git a/libclamav/mbox.c b/libclamav/mbox.c index 1f1e1c3..ac97d18 100644 --- a/libclamav/mbox.c @@ -118,23 +118,45 @@ index 62f6b85..a0ec5cd 100644 + #endif /*_MESSAGE_H*/ diff --git a/libclamav/others.c b/libclamav/others.c -index 4c31381..20a0fdf 100644 +index 4c31381..f3a9c3b 100644 --- a/libclamav/others.c +++ b/libclamav/others.c -@@ -302,20 +302,26 @@ static void rarload(void) +@@ -268,7 +268,9 @@ static void *get_module_function(void *handle, const char *name) + { + void *procAddress = NULL; + procAddress = dlsym(handle, name); +- if (NULL == procAddress) { ++ ++ // Ignore missing symbols when the handle is NULL. This only means the symbol wasn't statically linked or otherwise loaded already. ++ if (NULL == procAddress && handle != NULL) { + const char *err = dlerror(); + if (NULL == err) { + cli_warnmsg("Failed to get function \"%s\": Unknown error.\n", name); +@@ -276,6 +278,10 @@ static void *get_module_function(void *handle, const char *name) + cli_warnmsg("Failed to get function \"%s\": %s\n", name, err); + } + } ++ // If the symbol wasn't found, and the handle is NULL, this will call dlerror(), which will reset the error queue. ++ else if (NULL == procAddress && handle == NULL) { ++ dlerror(); ++ } + return procAddress; + } + #endif // !_WIN32 +@@ -302,20 +308,26 @@ static void rarload(void) cli_unrar_skip_file = unrar_skip_file; cli_unrar_close = unrar_close; #else - rhandle = load_module("libclamunrar_iface", "unrar"); - if (NULL == rhandle) - return; -- + - if ((NULL == (cli_unrar_open = (cl_unrar_error_t(*)(const char *, void **, char **, uint32_t *, uint8_t))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_open"))) || - (NULL == (cli_unrar_peek_file_header = (cl_unrar_error_t(*)(void *, unrar_metadata_t *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_peek_file_header"))) || - (NULL == (cli_unrar_extract_file = (cl_unrar_error_t(*)(void *, const char *, char *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_extract_file"))) || - (NULL == (cli_unrar_skip_file = (cl_unrar_error_t(*)(void *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_skip_file"))) || - (NULL == (cli_unrar_close = (void (*)(void *))get_module_function(rhandle, "libclamunrar_iface_LTX_unrar_close")))) { - +- - cli_warnmsg("Failed to load function from UnRAR module\n"); - cli_warnmsg("Version mismatch?\n"); - cli_warnmsg("UnRAR support unavailable\n"); @@ -161,15 +183,19 @@ index 4c31381..20a0fdf 100644 } #endif -@@ -440,6 +446,14 @@ cl_error_t cl_init(unsigned int initoptions) +@@ -440,6 +452,18 @@ cl_error_t cl_init(unsigned int initoptions) return CL_SUCCESS; } +void cl_shutdown(void) { + cli_mbox_shutdown(); + cli_mime_shutdown(); ++ // Uncomment this fix once we patch libltdl to let us check the initialized counter. Until then use the ugly warning below as a reminder. ++ // if (lt_dlinitialized() && lt_dlexit()) { ++ // cli_errmsg("lt_dlexit: Library exit error, probably because of an invalid reference counter"); ++ // } + if (lt_dlexit()) { -+ cli_errmsg("lt_dlexit: Library exit error, probably because of an invalid reference counter"); ++ cli_errmsg("lt_dlexit: Library exit error, probably because of an invalid reference counter [LIBLTDL NO LONGER BUNDLED / OTHERWISE WE'D USE 0.103.5 PATCH TO CHECK INITALIZED]"); + } +} + diff --git a/lib/patches/clamav/version_0984.patch b/lib/patches/clamav/version_0984.patch index d11c11bf..d89c82fe 100644 --- a/lib/patches/clamav/version_0984.patch +++ b/lib/patches/clamav/version_0984.patch @@ -3,4 +3,3 @@ diff -r 946577531cae libclamav/version.h.static +++ b/libclamav/version.h.static Fri Oct 10 05:45:20 2014 -0500 @@ -0,0 +1,1 @@ +#define REPO_VERSION VERSION - diff --git a/sandbox/etc/freshclam.conf b/sandbox/etc/freshclam.conf index d49bfa98..7875bd41 100644 --- a/sandbox/etc/freshclam.conf +++ b/sandbox/etc/freshclam.conf @@ -3,7 +3,6 @@ # lib/sources/clamav/freshclam/.libs/freshclam --user $USER --datadir=res/virus --config-file=res/config/freshclam.conf Bytecode yes -SafeBrowsing yes CompressLocalDatabase no DatabaseMirror database.clamav.net diff --git a/src/providers/symbols.c b/src/providers/symbols.c index 46a32f7c..0e791e36 100644 --- a/src/providers/symbols.c +++ b/src/providers/symbols.c @@ -37,19 +37,19 @@ int (*BZ2_bzBuffToBuffCompress_d)(char *dest, unsigned int *destLen, char *sourc int (*lt_dlexit_d)(void) = NULL; void (*cl_shutdown_d)(void) = NULL; const char * (*cl_retver_d)(void) = NULL; -int (*cl_init_d)(unsigned int initoptions) = NULL; +cl_error_t (*cl_init_d)(unsigned int initoptions) = NULL; const char * (*cl_strerror_d)(int clerror) = NULL; struct cl_engine * (*cl_engine_new_d)(void) = NULL; -int (*cl_statfree_d)(struct cl_stat *dbstat) = NULL; -int (*cl_engine_free_d)(struct cl_engine *engine) = NULL; -int (*cl_engine_compile_d)(struct cl_engine *engine) = NULL; +cl_error_t (*cl_statfree_d)(struct cl_stat *dbstat) = NULL; +cl_error_t (*cl_engine_free_d)(struct cl_engine *engine) = NULL; +cl_error_t (*cl_engine_compile_d)(struct cl_engine *engine) = NULL; int (*cl_statchkdir_d)(const struct cl_stat *dbstat) = NULL; -int (*cl_statinidir_d)(const char *dirname, struct cl_stat *dbstat) = NULL; -int (*cl_countsigs_d)(const char *path, unsigned int countoptions, unsigned int *sigs) = NULL; -int (*cl_engine_set_num_d)(struct cl_engine *engine, enum cl_engine_field field, long long num) = NULL; -int (*cl_engine_set_str_d)(struct cl_engine *engine, enum cl_engine_field field, const char *str) = NULL; -int (*cl_load_d)(const char *path, struct cl_engine *engine, unsigned int *signo, unsigned int dboptions) = NULL; -int (*cl_scandesc_d)(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions) = NULL; +cl_error_t (*cl_statinidir_d)(const char *dirname, struct cl_stat *dbstat) = NULL; +cl_error_t (*cl_countsigs_d)(const char *path, unsigned int countoptions, unsigned int *sigs) = NULL; +cl_error_t (*cl_engine_set_num_d)(struct cl_engine *engine, enum cl_engine_field field, long long num) = NULL; +cl_error_t (*cl_engine_set_str_d)(struct cl_engine *engine, enum cl_engine_field field, const char *str) = NULL; +cl_error_t (*cl_load_d)(const char *path, struct cl_engine *engine, unsigned int *signo, unsigned int dboptions) = NULL; +cl_error_t (*cl_scandesc_d)(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions) = NULL; //! DSPAM const char * (*dspam_version_d)(void) = NULL; diff --git a/src/providers/symbols.h b/src/providers/symbols.h index e9265d43..812f782b 100644 --- a/src/providers/symbols.h +++ b/src/providers/symbols.h @@ -139,19 +139,19 @@ extern int (*BZ2_bzBuffToBuffCompress_d)(char *dest, unsigned int *destLen, char extern int (*lt_dlexit_d)(void); extern void (*cl_shutdown_d)(void); extern const char * (*cl_retver_d)(void); -extern int (*cl_init_d)(unsigned int initoptions); +extern cl_error_t (*cl_init_d)(unsigned int initoptions); extern const char * (*cl_strerror_d)(int clerror); extern struct cl_engine * (*cl_engine_new_d)(void); -extern int (*cl_statfree_d)(struct cl_stat *dbstat); -extern int (*cl_engine_free_d)(struct cl_engine *engine); -extern int (*cl_engine_compile_d)(struct cl_engine *engine); +extern cl_error_t (*cl_statfree_d)(struct cl_stat *dbstat); +extern cl_error_t (*cl_engine_free_d)(struct cl_engine *engine); +extern cl_error_t (*cl_engine_compile_d)(struct cl_engine *engine); extern int (*cl_statchkdir_d)(const struct cl_stat *dbstat); -extern int (*cl_statinidir_d)(const char *dirname, struct cl_stat *dbstat); -extern int (*cl_countsigs_d)(const char *path, unsigned int countoptions, unsigned int *sigs); -extern int (*cl_engine_set_num_d)(struct cl_engine *engine, enum cl_engine_field field, long long num); -extern int (*cl_engine_set_str_d)(struct cl_engine *engine, enum cl_engine_field field, const char *str); -extern int (*cl_load_d)(const char *path, struct cl_engine *engine, unsigned int *signo, unsigned int dboptions); -extern int (*cl_scandesc_d)(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions); +extern cl_error_t (*cl_statinidir_d)(const char *dirname, struct cl_stat *dbstat); +extern cl_error_t (*cl_countsigs_d)(const char *path, unsigned int countoptions, unsigned int *sigs); +extern cl_error_t (*cl_engine_set_num_d)(struct cl_engine *engine, enum cl_engine_field field, long long num); +extern cl_error_t (*cl_engine_set_str_d)(struct cl_engine *engine, enum cl_engine_field field, const char *str); +extern cl_error_t (*cl_load_d)(const char *path, struct cl_engine *engine, unsigned int *signo, unsigned int dboptions); +extern cl_error_t (*cl_scandesc_d)(int desc, const char *filename, const char **virname, unsigned long int *scanned, const struct cl_engine *engine, struct cl_scan_options *scanoptions); //! DSPAM extern const char * (*dspam_version_d)(void); |