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/