git://git.exim.org
/
exim.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
1072af8
)
Fix $regex<n> use-after-free. Bug 2915
author
Jeremy Harris
<jgh146exb@wizmail.org>
Wed, 31 Aug 2022 14:37:40 +0000
(15:37 +0100)
committer
Jeremy Harris
<jgh146exb@wizmail.org>
Wed, 31 Aug 2022 14:57:29 +0000
(15:57 +0100)
doc/doc-txt/ChangeLog
patch
|
blob
|
history
src/src/exim.c
patch
|
blob
|
history
src/src/expand.c
patch
|
blob
|
history
src/src/functions.h
patch
|
blob
|
history
src/src/globals.c
patch
|
blob
|
history
src/src/regex.c
patch
|
blob
|
history
src/src/smtp_in.c
patch
|
blob
|
history
test/confs/4002
patch
|
blob
|
history
test/mail/4002.userx
patch
|
blob
|
history
test/scripts/4000-scanning/4002
patch
|
blob
|
history
diff --git
a/doc/doc-txt/ChangeLog
b/doc/doc-txt/ChangeLog
index 6a4e10915cc4f4c6d3dbae363de6e35293b85b14..ba5bd23d9f1a4d5c686f27f40ec615b7d707eb55 100644
(file)
--- a/
doc/doc-txt/ChangeLog
+++ b/
doc/doc-txt/ChangeLog
@@
-30,11
+30,17
@@
JH/07 OpenSSL Fix auto-reload of changed server OCSP proof. Previously, if
the file with the proof had an unchanged name, the new proof(s) were
loaded on top of the old ones (and nover used; the old ones were stapled).
the file with the proof had an unchanged name, the new proof(s) were
loaded on top of the old ones (and nover used; the old ones were stapled).
+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
-----------------
Exim version 4.96
-----------------
-JH/01 Move the wait-for-next-tick (needed for unique mess
m
age 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.
after reception to before a subsequent reception. This should
mean slightly faster delivery, and also confirmation of reception
to senders.
diff --git
a/src/src/exim.c
b/src/src/exim.c
index ea4286af34c318a767f127d59a2176f34fba782f..b9328f017decb15734c935995cda28a66dfbbe32 100644
(file)
--- a/
src/src/exim.c
+++ b/
src/src/exim.c
@@
-2000,8
+2000,6
@@
regex_whitelisted_macro =
regex_must_compile(US"^[A-Za-z0-9_/.-]*$", MCS_NOFLAGS, TRUE);
#endif
regex_must_compile(US"^[A-Za-z0-9_/.-]*$", MCS_NOFLAGS, 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 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. */
@@
-6089,7
+6087,7
@@
MORELOOP:
deliver_localpart_data = deliver_domain_data =
recipient_data = sender_data = NULL;
acl_var_m = 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);
}
store_reset(reset_point);
}
diff --git
a/src/src/expand.c
b/src/src/expand.c
index ffbdc14e514bba1eba144fbba497b5eddb10e8b4..89de56255c9b694ccac7adb77a4247ff421e81a8 100644
(file)
--- a/
src/src/expand.c
+++ b/
src/src/expand.c
@@
-1860,7
+1860,7
@@
else if (Ustrncmp(name, "r_", 2) == 0)
return node ? node->data.ptr : strict_acl_vars ? NULL : US"";
}
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)
{
if (Ustrncmp(name, "auth", 4) == 0)
{
diff --git
a/src/src/functions.h
b/src/src/functions.h
index 92a4831e381eaad21e43d8e67f08a0a5efca2531..345d7bce6749173f6a0635090bf10beb9ec81f9b 100644
(file)
--- a/
src/src/functions.h
+++ b/
src/src/functions.h
@@
-447,6
+447,7
@@
extern BOOL regex_match_and_setup(const pcre2_code *, const uschar *, int, in
extern const pcre2_code *regex_compile(const uschar *, mcs_flags, uschar **,
pcre2_compile_context *);
extern const pcre2_code *regex_must_compile(const uschar *, mcs_flags, BOOL);
extern const pcre2_code *regex_compile(const uschar *, mcs_flags, uschar **,
pcre2_compile_context *);
extern const pcre2_code *regex_must_compile(const uschar *, mcs_flags, 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 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/src/globals.c
b/src/src/globals.c
index 574ee60a4819330614fd15f87ba9035aaa0e2a35..cafb1599229de9eae20615c5ffcb7b4e122d9ec2 100644
(file)
--- a/
src/src/globals.c
+++ b/
src/src/globals.c
@@
-1324,7
+1324,7
@@
const pcre2_code *regex_EARLY_PIPE = NULL;
int regex_cachesize = 0;
const pcre2_code *regex_ismsgid = NULL;
const pcre2_code *regex_smtp_code = NULL;
int regex_cachesize = 0;
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 WHITELIST_D_MACROS
const pcre2_code *regex_whitelisted_macro = NULL;
#endif
diff --git
a/src/src/regex.c
b/src/src/regex.c
index 5de1c1704d02bc850d625b1d65b9f3d48209e9dd..25496f950db7d09debf46c15f902dda139965238 100644
(file)
--- a/
src/src/regex.c
+++ b/
src/src/regex.c
@@
-93,19
+93,27
@@
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
int
-regex(const uschar **listptr, BOOL cacheable)
+regex(const uschar **
listptr, BOOL cacheable)
{
unsigned long mbox_size;
{
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;
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 (!mime_stream) /* We are in the DATA ACL */
{
@@
-167,14
+175,13
@@
return ret;
int
mime_regex(const uschar **listptr, BOOL cacheable)
{
int
mime_regex(const uschar **listptr, BOOL cacheable)
{
-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;
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, cacheable)))
/* precompile our regexes */
if (!(re_list_head = compile(*listptr, cacheable)))
diff --git
a/src/src/smtp_in.c
b/src/src/smtp_in.c
index 11e7436b917986af08d27fd13841d42a1f1886c0..a15280bdcfdea6bbf34e1a5d988733ff2fad2cb6 100644
(file)
--- a/
src/src/smtp_in.c
+++ b/
src/src/smtp_in.c
@@
-2157,8
+2157,10
@@
prdr_requested = FALSE;
#ifdef SUPPORT_I18N
message_smtputf8 = FALSE;
#endif
#ifdef SUPPORT_I18N
message_smtputf8 = FALSE;
#endif
+regex_vars_clear();
body_linecount = body_zerocount = 0;
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. */
sender_rate = sender_rate_limit = sender_rate_period = NULL;
ratelimiters_mail = NULL; /* Updated by ratelimit ACL condition */
/* Note that ratelimiters_conn persists across resets. */
diff --git
a/test/confs/4002
b/test/confs/4002
index d9a12a36826b38fcf6d1dd0e0ddea773d70e1f1a..4578cc01909510b7eb8d000fe1d8660db7c121b9 100644
(file)
--- a/
test/confs/4002
+++ b/
test/confs/4002
@@
-10,6
+10,7
@@
rfc1413_query_timeout = 0s
acl_smtp_rcpt = check_rcpt
acl_smtp_data = check_data
acl_smtp_rcpt = check_rcpt
acl_smtp_data = check_data
+acl_smtp_mime = check_mime
acl_not_smtp = check_data
acl_not_smtp = check_data
@@
-20,6
+21,15
@@
begin acl
check_rcpt:
accept
check_rcpt:
accept
+check_mime:
+ warn condition = ${if match{$mime_content_type}{text}}
+ mime_regex = \N(?s)([\w.+=-]+@\w[\w-]*\.[\w.-]+\w)\
+ (.+?([\w.+=-]+@\w[\w-]*\.[\w.-]+\w))?\
+ (.+?([\w.+=-]+@\w[\w-]*\.[\w.-]+\w))?\
+ (.+?([\w.+=-]+@\w[\w-]*\.[\w.-]+\w))?\
+ (.+?([\w.+=-]+@\w[\w-]*\.[\w.-]+\w))?\N
+ accept
+
check_data:
warn regex = \N(THIS\s((\w+)\s)?REGEX)\N
message = X-Regex: Regex matched <$regex1> <$regex3>
check_data:
warn regex = \N(THIS\s((\w+)\s)?REGEX)\N
message = X-Regex: Regex matched <$regex1> <$regex3>
diff --git
a/test/mail/4002.userx
b/test/mail/4002.userx
index 6bc565c3f002d4e632abc8bb31eb219b0c8b4b98..8ec49da09ebd7bccf2c97c39d48dd57849a5c4c0 100644
(file)
--- a/
test/mail/4002.userx
+++ b/
test/mail/4002.userx
@@
-27,9
+27,16
@@
Subject: A real test message
Date: Tue, 2 Mar 1999 09:44:33 +0000
Message-ID: <41C2F849.3060203@projectile.test.ex>
FakeReject: test fakereject
Date: Tue, 2 Mar 1999 09:44:33 +0000
Message-ID: <41C2F849.3060203@projectile.test.ex>
FakeReject: test fakereject
+MIME-Version: 1.0
+Content-Type: text/plain
Sender: CALLER_NAME <CALLER@myhost.test.ex>
X-Regex: Regex matched <THIS gazornenplaz REGEX> <gazornenplaz>
OK, this should look like a genuine message, but
it will trip on THIS gazornenplaz REGEX.
Sender: CALLER_NAME <CALLER@myhost.test.ex>
X-Regex: Regex matched <THIS gazornenplaz REGEX> <gazornenplaz>
OK, this should look like a genuine message, but
it will trip on THIS gazornenplaz REGEX.
+This checks proper release of variable used for mime_regex
+firstname@foobar.com
+secondname@blaz.com
+thirdname@blaz.com
+
diff --git
a/test/scripts/4000-scanning/4002
b/test/scripts/4000-scanning/4002
index a660f680533738d5389167fb623b9af3e2eab6ff..fcfae698b73a1a979e96669b376d486f56a0f864 100644
(file)
--- a/
test/scripts/4000-scanning/4002
+++ b/
test/scripts/4000-scanning/4002
@@
-30,9
+30,16
@@
Subject: A real test message
Date: Fri, 17 Dec 2004 16:13:04 +0100
Message-ID: <41C2F849.3060203@projectile.test.ex>
FakeReject: test fakereject
Date: Fri, 17 Dec 2004 16:13:04 +0100
Message-ID: <41C2F849.3060203@projectile.test.ex>
FakeReject: test fakereject
+MIME-Version: 1.0
+Content-Type: text/plain
OK, this should look like a genuine message, but
it will trip on THIS gazornenplaz REGEX.
OK, this should look like a genuine message, but
it will trip on THIS gazornenplaz REGEX.
+
+This checks proper release of variable used for mime_regex
+firstname@foobar.com
+secondname@blaz.com
+thirdname@blaz.com
.
quit
****
.
quit
****