summaryrefslogtreecommitdiffstats
path: root/debian/patches/75_01-Introduce-main-config-option-allow_insecure_tainted_.patch
blob: 0295ec18fa6e2f71c29d1e599055847a89a82cd1 (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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
From ec06d64532e4952fc36429f73e0222d26997ef7c Mon Sep 17 00:00:00 2001
From: "Heiko Schlittermann (HS12-RIPE)" <hs@schlittermann.de>
Date: Thu, 1 Apr 2021 22:44:31 +0200
Subject: [PATCH 01/23] Introduce main config option
 allow_insecure_tainted_data

This option is deprecated already now.
---
 src/EDITME            |  7 +++++
 src/config.h.defaults |  2 ++
 src/functions.h       | 54 ++++++++++++++++++++++++++++++---------
 src/globals.c         | 10 ++++++++
 src/globals.h         |  4 +++
 src/macros.h          |  3 +++
 src/readconf.c        |  3 +++
 7 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/src/EDITME b/src/EDITME
index 8da36a353..cebb8e2ec 100644
--- a/src/EDITME
+++ b/src/EDITME
@@ -749,6 +749,13 @@ FIXED_NEVER_USERS=root
 
 # WHITELIST_D_MACROS=TLS:SPOOL
 
+# The next setting enables a main config option
+# "allow_insecure_tainted_data" to turn taint failures into warnings.
+# Though this option is new, it is deprecated already now, and will be
+# ignored in future releases of Exim. It is meant as mitigation for
+# upgrading old (possibly insecure) configurations to more secure ones.
+ALLOW_INSECURE_TAINTED_DATA=yes
+
 #------------------------------------------------------------------------------
 # Exim has support for the AUTH (authentication) extension of the SMTP
 # protocol, as defined by RFC 2554. If you don't know what SMTP authentication
diff --git a/src/config.h.defaults b/src/config.h.defaults
index e17f015f9..4e8b18904 100644
--- a/src/config.h.defaults
+++ b/src/config.h.defaults
@@ -17,6 +17,8 @@ Do not put spaces between # and the 'define'.
 #define ALT_CONFIG_PREFIX
 #define TRUSTED_CONFIG_LIST
 
+#define ALLOW_INSECURE_TAINTED_DATA
+
 #define APPENDFILE_MODE            0600
 #define APPENDFILE_DIRECTORY_MODE  0700
 #define APPENDFILE_LOCKFILE_MODE   0600
diff --git a/src/functions.h b/src/functions.h
index 51bb17a09..1e8083673 100644
--- a/src/functions.h
+++ b/src/functions.h
@@ -1083,36 +1083,66 @@ if (f.running_in_test_harness && f.testsuite_delays) millisleep(millisec);
 
 /******************************************************************************/
 /* Taint-checked file opens */
+static inline uschar *
+is_tainted2(const void *p, int lflags, const uschar* fmt, ...)
+{
+va_list ap;
+uschar *msg;
+rmark mark;
+
+if (!is_tainted(p))
+  return NULL;
+
+mark = store_mark();
+va_start(ap, fmt);
+msg = string_from_gstring(string_vformat(NULL, SVFMT_TAINT_NOCHK|SVFMT_EXTEND, fmt, ap));
+va_end(ap);
+
+#ifdef ALLOW_INSECURE_TAINTED_DATA
+if (allow_insecure_tainted_data)
+  {
+  if LOGGING(tainted) log_write(0, LOG_MAIN, "Warning: %s", msg);
+  store_reset(mark);
+  return NULL;
+  }
+#endif
+
+if (lflags) log_write(0, lflags, "%s", msg);
+return msg; /* no store_reset(), as the message might be used afterwards and Exim
+            is expected to exit anyway, so we do not care about the leaked
+            storage */
+}
 
 static inline int
 exim_open2(const char *pathname, int flags)
 {
-if (!is_tainted(pathname)) return open(pathname, flags);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
+  return open(pathname, flags);
 errno = EACCES;
 return -1;
 }
+
 static inline int
 exim_open(const char *pathname, int flags, mode_t mode)
 {
-if (!is_tainted(pathname)) return open(pathname, flags, mode);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
+  return open(pathname, flags, mode);
 errno = EACCES;
 return -1;
 }
 static inline int
 exim_openat(int dirfd, const char *pathname, int flags)
 {
-if (!is_tainted(pathname)) return openat(dirfd, pathname, flags);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
+  return openat(dirfd, pathname, flags);
 errno = EACCES;
 return -1;
 }
 static inline int
 exim_openat4(int dirfd, const char *pathname, int flags, mode_t mode)
 {
-if (!is_tainted(pathname)) return openat(dirfd, pathname, flags, mode);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
+  return openat(dirfd, pathname, flags, mode);
 errno = EACCES;
 return -1;
 }
@@ -1120,8 +1150,8 @@ return -1;
 static inline FILE *
 exim_fopen(const char *pathname, const char *mode)
 {
-if (!is_tainted(pathname)) return fopen(pathname, mode);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname);
+if (!is_tainted2(pathname, LOG_MAIN|LOG_PANIC, "Tainted filename '%s'", pathname))
+  return fopen(pathname, mode);
 errno = EACCES;
 return NULL;
 }
@@ -1129,8 +1159,8 @@ return NULL;
 static inline DIR *
 exim_opendir(const uschar * name)
 {
-if (!is_tainted(name)) return opendir(CCS name);
-log_write(0, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name);
+if (!is_tainted2(name, LOG_MAIN|LOG_PANIC, "Tainted dirname '%s'", name))
+  return opendir(CCS name);
 errno = EACCES;
 return NULL;
 }
diff --git a/src/globals.c b/src/globals.c
index c34ac9ddd..ff660c352 100644
--- a/src/globals.c
+++ b/src/globals.c
@@ -98,6 +98,10 @@ int     sqlite_lock_timeout    = 5;
 BOOL    move_frozen_messages   = FALSE;
 #endif
 
+#ifdef ALLOW_INSECURE_TAINTED_DATA
+BOOL    allow_insecure_tainted_data = FALSE;
+#endif
+
 /* These variables are outside the #ifdef because it keeps the code less
 cluttered in several places (e.g. during logging) if we can always refer to
 them. Also, the tls_ variables are now always visible.  Note that these are
@@ -1033,6 +1037,9 @@ int     log_default[]          = { /* for initializing log_selector */
   Li_size_reject,
   Li_skip_delivery,
   Li_smtp_confirmation,
+#ifdef ALLOW_INSECURE_TAINTED_DATA
+  Li_tainted,
+#endif
   Li_tls_certificate_verified,
   Li_tls_cipher,
   -1
@@ -1100,6 +1107,9 @@ bit_table log_options[]        = { /* must be in alphabetical order,
   BIT_TABLE(L, smtp_protocol_error),
   BIT_TABLE(L, smtp_syntax_error),
   BIT_TABLE(L, subject),
+#ifdef ALLOW_INSECURE_TAINTED_DATA
+  BIT_TABLE(L, tainted),
+#endif
   BIT_TABLE(L, tls_certificate_verified),
   BIT_TABLE(L, tls_cipher),
   BIT_TABLE(L, tls_peerdn),
diff --git a/src/globals.h b/src/globals.h
index a4c1143b7..8d72577e0 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -77,6 +77,10 @@ extern int     sqlite_lock_timeout;    /* Internal lock waiting timeout */
 extern BOOL    move_frozen_messages;   /* Get them out of the normal directory */
 #endif
 
+#ifdef ALLOW_INSECURE_TAINTED_DATA
+extern BOOL    allow_insecure_tainted_data;
+#endif
+
 /* These variables are outside the #ifdef because it keeps the code less
 cluttered in several places (e.g. during logging) if we can always refer to
 them. Also, the tls_ variables are now always visible. */
diff --git a/src/macros.h b/src/macros.h
index f78ae2e3d..322ddbf56 100644
--- a/src/macros.h
+++ b/src/macros.h
@@ -498,6 +498,9 @@ enum logbit {
   Li_smtp_mailauth,
   Li_smtp_no_mail,
   Li_subject,
+#ifdef ALLOW_INSECURE_TAINTED_DATA
+  Li_tainted,
+#endif
   Li_tls_certificate_verified,
   Li_tls_cipher,
   Li_tls_peerdn,
diff --git a/src/readconf.c b/src/readconf.c
index 948fa2403..133135f8f 100644
--- a/src/readconf.c
+++ b/src/readconf.c
@@ -68,6 +68,9 @@ static optionlist optionlist_config[] = {
   { "add_environment",          opt_stringptr,   {&add_environment} },
   { "admin_groups",             opt_gidlist,     {&admin_groups} },
   { "allow_domain_literals",    opt_bool,        {&allow_domain_literals} },
+#ifdef ALLOW_INSECURE_TAINTED_DATA
+  { "allow_insecure_tainted_data", opt_bool,     {&allow_insecure_tainted_data} },
+#endif
   { "allow_mx_to_ip",           opt_bool,        {&allow_mx_to_ip} },
   { "allow_utf8_domains",       opt_bool,        {&allow_utf8_domains} },
   { "auth_advertise_hosts",     opt_stringptr,   {&auth_advertise_hosts} },
-- 
2.30.2