4bccc70e07
Fixes CVE-2022-3559: A vulnerability was found in Exim and classified as problematic. This issue affects some unknown processing of the component Regex Handler. The manipulation leads to use after free. The name of the patch is 4e9ed49f8f12eb331b29bd5b6dc3693c520fddc2. It is recommended to apply a patch to fix this issue. The identifier VDB-211073 was assigned to this vulnerability. The upstream patch does not apply to 4.96, so use the backported patches from Debian. Amazingly, the patch needs 3 additional patches to unbreak builds without "WITH_CONTENT_SCAN" (default in Buildroot), so add those as well. Signed-off-by: Peter Korsgaard <peter@korsgaard.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
174 lines
5.0 KiB
Diff
174 lines
5.0 KiB
Diff
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
|
|
|
|
[Upstream: https://sources.debian.org/data/main/e/exim4/4.96-9/debian/patches/75_08-Fix-regex-n-use-after-free.-Bug-2915.patch]
|
|
[Peter: drop Changelog hunk]
|
|
Signed-off-by: Peter Korsgaard <peter@korsgard.com>
|
|
---
|
|
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 +++++++
|
|
9 files changed, 53 insertions(+), 17 deletions(-)
|
|
|
|
--- 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 */
|