diff options
Diffstat (limited to 'debian/patches/75_08-Fix-regex-n-use-after-free.-Bug-2915.patch')
-rw-r--r-- | debian/patches/75_08-Fix-regex-n-use-after-free.-Bug-2915.patch | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/debian/patches/75_08-Fix-regex-n-use-after-free.-Bug-2915.patch b/debian/patches/75_08-Fix-regex-n-use-after-free.-Bug-2915.patch new file mode 100644 index 0000000..be6ccae --- /dev/null +++ b/debian/patches/75_08-Fix-regex-n-use-after-free.-Bug-2915.patch @@ -0,0 +1,196 @@ +From 4e9ed49f8f12eb331b29bd5b6dc3693c520fddc2 Mon Sep 17 00:00:00 2001 +From: Jeremy Harris <jgh146exb@wizmail.org> +Date: Wed, 31 Aug 2022 15:37:40 +0100 +Subject: [PATCH] Fix $regex<n> use-after-free. Bug 2915 + +--- + doc/ChangeLog | 8 +++++++- + src/exim.c | 4 +--- + src/expand.c | 2 +- + src/functions.h | 1 + + src/globals.c | 2 +- + src/regex.c | 29 ++++++++++++++++++----------- + src/smtp_in.c | 2 ++ + test/confs/4002 | 10 ++++++++++ + test/mail/4002.userx | 7 +++++++ + test/scripts/4000-scanning/4002 | 7 +++++++ + 10 files changed, 55 insertions(+), 17 deletions(-) + +--- a/doc/ChangeLog ++++ b/doc/ChangeLog +@@ -4,15 +4,21 @@ + + JH/04 Bug 2903: avoid exit on an attempt to rewrite a malformed address. + Make the rewrite never match and keep the logging. Trust the + admin to be using verify=header-syntax (to actually reject the message). + ++JH/08 Bug 2915: Fix use-after-free for $regex<n> variables. Previously when ++ more than one message arrived in a single connection a reference from ++ the earlier message could be re-used. Often a sigsegv resulted. ++ These variables were introduced in Exim 4.87. ++ Debug help from Graeme Fowler. ++ + + Exim version 4.96 + ----------------- + +-JH/01 Move the wait-for-next-tick (needed for unique messmage IDs) from ++JH/01 Move the wait-for-next-tick (needed for unique message IDs) from + after reception to before a subsequent reception. This should + mean slightly faster delivery, and also confirmation of reception + to senders. + + JH/02 Move from using the pcre library to pcre2. The former is no longer +--- a/src/exim.c ++++ b/src/exim.c +@@ -1999,12 +1999,10 @@ + + regex_whitelisted_macro = + regex_must_compile(US"^[A-Za-z0-9_/.-]*$", FALSE, TRUE); + #endif + +-for (i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; +- + /* If the program is called as "mailq" treat it as equivalent to "exim -bp"; + this seems to be a generally accepted convention, since one finds symbolic + links called "mailq" in standard OS configurations. */ + + if ((namelen == 5 && Ustrcmp(argv[0], "mailq") == 0) || +@@ -6082,11 +6080,11 @@ + callout_address = NULL; + sending_ip_address = NULL; + deliver_localpart_data = deliver_domain_data = + recipient_data = sender_data = NULL; + acl_var_m = NULL; +- for(int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; ++ regex_vars_clear(); + + store_reset(reset_point); + } + + exim_exit(EXIT_SUCCESS); /* Never returns */ +--- a/src/expand.c ++++ b/src/expand.c +@@ -1871,11 +1871,11 @@ + { + tree_node * node = tree_search(router_var, name + 2); + return node ? node->data.ptr : strict_acl_vars ? NULL : US""; + } + +-/* Handle $auth<n> variables. */ ++/* Handle $auth<n>, $regex<n> variables. */ + + if (Ustrncmp(name, "auth", 4) == 0) + { + uschar *endptr; + int n = Ustrtoul(name + 4, &endptr, 10); +--- a/src/functions.h ++++ b/src/functions.h +@@ -436,10 +436,11 @@ + extern int regex(const uschar **); + #endif + extern BOOL regex_match(const pcre2_code *, const uschar *, int, uschar **); + extern BOOL regex_match_and_setup(const pcre2_code *, const uschar *, int, int); + extern const pcre2_code *regex_must_compile(const uschar *, BOOL, BOOL); ++extern void regex_vars_clear(void); + extern void retry_add_item(address_item *, uschar *, int); + extern BOOL retry_check_address(const uschar *, host_item *, uschar *, BOOL, + uschar **, uschar **); + extern retry_config *retry_find_config(const uschar *, const uschar *, int, int); + extern BOOL retry_ultimate_address_timeout(uschar *, const uschar *, +--- a/src/globals.c ++++ b/src/globals.c +@@ -1313,11 +1313,11 @@ + #ifndef DISABLE_PIPE_CONNECT + const pcre2_code *regex_EARLY_PIPE = NULL; + #endif + const pcre2_code *regex_ismsgid = NULL; + const pcre2_code *regex_smtp_code = NULL; +-const uschar *regex_vars[REGEX_VARS]; ++const uschar *regex_vars[REGEX_VARS] = { 0 };; + #ifdef WHITELIST_D_MACROS + const pcre2_code *regex_whitelisted_macro = NULL; + #endif + #ifdef WITH_CONTENT_SCAN + uschar *regex_match_string = NULL; +--- a/src/regex.c ++++ b/src/regex.c +@@ -94,22 +94,32 @@ + } + pcre2_match_data_free(md); + return FAIL; + } + ++ ++/* reset expansion variables */ ++void ++regex_vars_clear(void) ++{ ++regex_match_string = NULL; ++for (int i = 0; i < REGEX_VARS; i++) regex_vars[i] = NULL; ++} ++ ++ ++ + int +-regex(const uschar **listptr) ++regex(const uschar ** listptr) + { + unsigned long mbox_size; +-FILE *mbox_file; +-pcre_list *re_list_head; +-uschar *linebuffer; ++FILE * mbox_file; ++pcre_list * re_list_head; ++uschar * linebuffer; + long f_pos = 0; + int ret = FAIL; + +-/* reset expansion variable */ +-regex_match_string = NULL; ++regex_vars_clear(); + + if (!mime_stream) /* We are in the DATA ACL */ + { + if (!(mbox_file = spool_mbox(&mbox_size, NULL, NULL))) + { /* error while spooling */ +@@ -167,18 +177,17 @@ + + + int + mime_regex(const uschar **listptr) + { +-pcre_list *re_list_head = NULL; +-FILE *f; +-uschar *mime_subject = NULL; ++pcre_list * re_list_head = NULL; ++FILE * f; ++uschar * mime_subject = NULL; + int mime_subject_len = 0; + int ret; + +-/* reset expansion variable */ +-regex_match_string = NULL; ++regex_vars_clear(); + + /* precompile our regexes */ + if (!(re_list_head = compile(*listptr))) + return FAIL; /* no regexes -> nothing to do */ + +--- a/src/smtp_in.c ++++ b/src/smtp_in.c +@@ -2155,12 +2155,14 @@ + prdr_requested = FALSE; + #endif + #ifdef SUPPORT_I18N + message_smtputf8 = FALSE; + #endif ++regex_vars_clear(); + body_linecount = body_zerocount = 0; + ++lookup_value = NULL; /* Can be set by ACL */ + sender_rate = sender_rate_limit = sender_rate_period = NULL; + ratelimiters_mail = NULL; /* Updated by ratelimit ACL condition */ + /* Note that ratelimiters_conn persists across resets. */ + + /* Reset message ACL variables */ |