From 8bb1858b231ee90a76e21c9af2529044ac9c42e5 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Thu, 11 Jul 2024 14:00:53 +0800 Subject: [PATCH] Fix $regex use-after-free. Bug 2915 --- src/exim.c | 3 +-- src/expand.c | 2 +- src/functions.h | 2 ++ src/globals.c | 2 +- src/regex.c | 16 ++++++++++++---- src/smtp_in.c | 3 +++ 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/exim.c b/src/exim.c index fd01d13..ac6682f 100644 --- a/src/exim.c +++ b/src/exim.c @@ -2001,7 +2001,6 @@ 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 @@ -6084,7 +6083,7 @@ MORELOOP: 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); } diff --git a/src/expand.c b/src/expand.c index 36c9f42..466733f 100644 --- a/src/expand.c +++ b/src/expand.c @@ -1873,7 +1873,7 @@ else if (Ustrncmp(name, "r_", 2) == 0) return node ? node->data.ptr : strict_acl_vars ? NULL : US""; } -/* Handle $auth variables. */ +/* Handle $auth, $regex variables. */ if (Ustrncmp(name, "auth", 4) == 0) { diff --git a/src/functions.h b/src/functions.h index 224666c..b82edcd 100644 --- a/src/functions.h +++ b/src/functions.h @@ -438,6 +438,8 @@ extern int regex(const uschar **); 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 **); diff --git a/src/globals.c b/src/globals.c index b9dfbbb..f3d9c76 100644 --- a/src/globals.c +++ b/src/globals.c @@ -1319,7 +1319,7 @@ 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 diff --git a/src/regex.c b/src/regex.c index 5c0f7c4..922e365 100644 --- a/src/regex.c +++ b/src/regex.c @@ -96,6 +96,15 @@ 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) { @@ -103,11 +112,11 @@ unsigned long mbox_size; 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 */ { @@ -175,8 +184,7 @@ 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))) diff --git a/src/smtp_in.c b/src/smtp_in.c index edb0adf..34e6865 100644 --- a/src/smtp_in.c +++ b/src/smtp_in.c @@ -2157,7 +2157,10 @@ prdr_requested = FALSE; #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 */ -- 2.27.0