[exim-cvs] Appendfile: release regex-match store every thous…

Góra strony
Delete this message
Reply to this message
Autor: Exim Git Commits Mailing List
Data:  
Dla: exim-cvs
Temat: [exim-cvs] Appendfile: release regex-match store every thousand files. Bug 3047
Gitweb: https://git.exim.org/exim.git/commitdiff/b4e7527561f1c68b821d5cf25efe29ae63d1d434
Commit:     b4e7527561f1c68b821d5cf25efe29ae63d1d434
Parent:     fe105877d57ac7e05a4333e0d072f232d212b9fe
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Thu Jan 25 17:48:43 2024 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Fri Jan 26 21:13:52 2024 +0000


    Appendfile: release regex-match store every thousand files.  Bug 3047
---
 doc/doc-txt/ChangeLog           |  7 +++++++
 src/src/exim.c                  |  5 +++++
 src/src/transports/appendfile.c | 17 ++++++++++++++---
 3 files changed, 26 insertions(+), 3 deletions(-)


diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 14cd45d85..e258966d8 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -93,6 +93,13 @@ JH/19 Fix TLS startup. When the last expansion done before the initiation of a
       parts.  It could also potentially affect tls_privatekeys.  The underlyding
       coding errors go back to 4.90 but were only exposed in 4.97.


+JH/20 Bug 3047: A recent (somewhere between 10.34 and 10.42) version of the
+      pcre2 library starting allocating 20kB rather than 112 bytes per match
+      call, which broke the 2GB total limitation on Exim's memory management
+      when a user had over 104207 messages stored and the appendfile
+      maildir_quota_directory_regex option is in use.  Release the allocated
+      memory every thosand files to avoid this.
+


Exim version 4.97
-----------------
diff --git a/src/src/exim.c b/src/src/exim.c
index c53b98186..e5b72f11a 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -49,6 +49,8 @@ optimize out the tail recursion and so not make them too expensive. */
static void *
function_store_malloc(PCRE2_SIZE size, void * tag)
{
+if (size > INT_MAX)
+ log_write(0, LOG_MAIN|LOG_PANIC_DIE, "excessive memory alloc request");
return store_malloc((int)size);
}

@@ -63,12 +65,15 @@ if (block) store_free(block);
 static void *
 function_store_get(PCRE2_SIZE size, void * tag)
 {
+if (size > INT_MAX)
+  log_write(0, LOG_MAIN|LOG_PANIC_DIE, "excessive memory alloc request");
 return store_get((int)size, GET_UNTAINTED);    /* loses track of taint */
 }


static void
function_store_nullfree(void * block, void * tag)
{
+/* We cannot free memory allocated using store_get() */
}


diff --git a/src/src/transports/appendfile.c b/src/src/transports/appendfile.c
index ec41ca035..91b353079 100644
--- a/src/src/transports/appendfile.c
+++ b/src/src/transports/appendfile.c
@@ -153,6 +153,10 @@ static const char *mailbox_formats[] = {
(!ob->quota_warn_threshold_is_percent || ob->quota_value > 0))


+/* Free memory allocated by PCRE2 every so often, because a recent version
+is now using 20kB for every match call */
+
+#define RESET_STORE_FILECNT    1000


 /*************************************************
 *              Setup entry point                 *
@@ -661,13 +665,14 @@ Returns:        the sum of the sizes of the stattable files
 off_t
 check_dir_size(const uschar * dirname, int * countptr, const pcre2_code * re)
 {
-DIR *dir;
+DIR * dir;
 off_t sum = 0;
-int count = *countptr;
+int count = *countptr, lcount = RESET_STORE_FILECNT;
+rmark reset_point = store_mark();


if (!(dir = exim_opendir(dirname))) return 0;

-for (struct dirent *ent; ent = readdir(dir); )
+for (struct dirent * ent; ent = readdir(dir); )
{
uschar * path, * name = US ent->d_name;
struct stat statbuf;
@@ -675,6 +680,11 @@ for (struct dirent *ent; ent = readdir(dir); )
if (Ustrcmp(name, ".") == 0 || Ustrcmp(name, "..") == 0) continue;

   count++;
+  if (--lcount == 0)
+    {
+    store_reset(reset_point); reset_point = store_mark();
+    lcount = RESET_STORE_FILECNT;
+    }


/* If there's a regex, try to find the size using it */

@@ -726,6 +736,7 @@ DEBUG(D_transport)
   debug_printf("check_dir_size: dir=%s sum=" OFF_T_FMT " count=%d\n", dirname,
     sum, count);


+store_reset(reset_point);
*countptr = count;
return sum;
}

--
## subscription configuration (requires account):
## https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/