summaryrefslogtreecommitdiffstats
path: root/debian/patches/75_66-Fix-crash-in-expansions.patch
blob: d776c8edf393ddb1015b351555953536d5aee286 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
From 70069b65a39a7ba73a36fbd95371ff03cde1eb23 Mon Sep 17 00:00:00 2001
From: Jeremy Harris <jgh146exb@wizmail.org>
Date: Thu, 2 Feb 2023 20:00:35 +0000
Subject: [PATCH] Fix crash in expansions

Broken-by: 1058096b8c53
---
 doc/ChangeLog | 4 ++++
 src/expand.c      | 9 +++++----
 test/stderr/0630      | 1 +
 3 files changed, 10 insertions(+), 4 deletions(-)

--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -50,10 +50,14 @@ JH/20 Bug 2954: (OpenSSL) Fix setting of
 
 JH/20 Fix TLSA lookups.  Previously dns_again_means_nonexist would affect
       SERVFAIL results, which breaks the downgrade resistance of DANE.  Change
       to not checking that list for these looks.
 
+JH/23 Fix crash in string expansions. Previously, if an empty variable was
+      immediately followed by an expansion operator, a null-indirection read
+      was done, killing the process.
+
 
 Exim version 4.96
 -----------------
 
 JH/01 Move the wait-for-next-tick (needed for unique message IDs) from
--- a/src/expand.c
+++ b/src/expand.c
@@ -4652,11 +4652,11 @@ while (*s)
       yield = string_catn(yield, value, len);
 
     continue;
     }
 
-  if (isdigit(*s))
+  if (isdigit(*s))		/* A $<n> variable */
     {
     int n;
     s = read_cnumber(&n, s);
     if (n >= 0 && n <= expand_nmax)
       yield = string_catn(yield, expand_nstring[n], expand_nlength[n]);
@@ -7060,10 +7060,11 @@ NOT_ITEM: ;
       if (arg) *arg++ = '_';		/* Put back for error messages */
       }
 
     /* Deal specially with operators that might take a certificate variable
     as we do not want to do the usual expansion. For most, expand the string.*/
+
     switch(c)
       {
 #ifndef DISABLE_TLS
       case EOP_MD5:
       case EOP_SHA1:
@@ -7107,11 +7108,11 @@ NOT_ITEM: ;
 
     /* Otherwise, switch on the operator type.  After handling go back
     to the main loop top. */
 
      {
-     int start = yield->ptr;
+     unsigned expansion_start = gstring_length(yield);
      switch(c)
       {
       case EOP_BASE32:
 	{
 	uschar *t;
@@ -8168,12 +8169,12 @@ NOT_ITEM: ;
 	  goto EXPAND_FAILED;
 	}	/* EOP_* switch */
 
        DEBUG(D_expand)
 	{
-	const uschar * s = yield->s + start;
-	int i = yield->ptr - start;
+	const uschar * s = yield->s + expansion_start;
+	int i = gstring_length(yield) - expansion_start;
 	BOOL tainted = is_tainted(s);
 
 	DEBUG(D_noutf8)
 	  {
 	  debug_printf_indent("|-----op-res: %.*s\n", i, s);