From 296e7d1791c48dff9ef65b42e56fc56a1a95de9e Mon Sep 17 00:00:00 2001 From: Micah Snyder Date: Fri, 12 Apr 2024 13:52:19 -0400 Subject: [PATCH] Freshclam: fix issue DatabaseCustomURL CVD prune issue If using DatabaseCustomURL to download a CVD that Freshclam doesn't know about, i.e. one that is not in the hardcoded standard or optional database lists in freshclam.c, Freshclam will prune the database and then re-download it. This change makes it so we look for URL's with ".cvd" at the end and then take those into consideration when checking which CVD's (or CLD's) should be pruned. Note that I didn't change the interface to fc_prune_database_directory(). That would have been cleaner, but would've changed the public API and I want to backport this fix. --- freshclam/freshclam.c | 47 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/freshclam/freshclam.c b/freshclam/freshclam.c index 50dd91465f..fd614fbee5 100644 --- a/freshclam/freshclam.c +++ b/freshclam/freshclam.c @@ -1432,6 +1432,10 @@ fc_error_t perform_database_update( uint32_t nUpdated = 0; uint32_t nTotalUpdated = 0; + uint32_t i; + char **doNotPruneDatabaseList = NULL; + uint32_t nDoNotPruneDatabases = 0; + STATBUF statbuf; if (NULL == serverList) { @@ -1452,7 +1456,38 @@ fc_error_t perform_database_update( * Prune database directory of official databases * that are no longer available or no longer desired. */ - (void)fc_prune_database_directory(databaseList, nDatabases); + + // include the URL databases in the prune process + doNotPruneDatabaseList = (char **)malloc(sizeof(char *) * (nDatabases + nUrlDatabases)); + if (NULL == doNotPruneDatabaseList) { + logg(LOGG_ERROR, "perform_database_update: Can't allocate memory for doNotPruneDatabaseList\n"); + status = FC_EMEM; + goto done; + } + + for (i = 0; i < nDatabases; i++) { + doNotPruneDatabaseList[i] = strdup(databaseList[i]); + if (doNotPruneDatabaseList[i] == NULL) { + logg(LOGG_ERROR, "perform_database_update: Can't allocate memory for database name in doNotPruneDatabaseList\n"); + status = FC_EMEM; + goto done; + } + } + nDoNotPruneDatabases = nDatabases; + + for (i = 0; i < nUrlDatabases; i++) { + // Only append the URL databases that end with '.cvd' + if (strlen(urlDatabaseList[i]) > 4 && 0 == strcasecmp(urlDatabaseList[i] + strlen(urlDatabaseList[i]) - 4, ".cvd")) { + const char *startOfFilename = strrchr(urlDatabaseList[i], '/') + 1; + if (NULL != startOfFilename) { + // Add the base database name to the do-not-prune list, excluding the '.cvd' extension. + doNotPruneDatabaseList[nDatabases + i] = CLI_STRNDUP(startOfFilename, strlen(startOfFilename) - strlen(".cvd")); + nDoNotPruneDatabases++; + } + } + } + + (void)fc_prune_database_directory(doNotPruneDatabaseList, nDoNotPruneDatabases); } /* @@ -1523,6 +1558,16 @@ fc_error_t perform_database_update( done: + // Free up the database list + if (NULL != doNotPruneDatabaseList) { + for (i = 0; i < nDoNotPruneDatabases; i++) { + free(doNotPruneDatabaseList[i]); + doNotPruneDatabaseList[i] = NULL; + } + free(doNotPruneDatabaseList); + doNotPruneDatabaseList = NULL; + } + if (LSTAT(g_freshclamTempDirectory, &statbuf) != -1) { /* Remove temp directory */ if (*g_freshclamTempDirectory) {