]> git.pld-linux.org Git - packages/exim.git/blame - CVE-2023-42114+42115+42116-fixes.patch
- rel 26; official fixes for CVE-2023-42114, CVE-2023-42115, CVE-2023-42116. Still...
[packages/exim.git] / CVE-2023-42114+42115+42116-fixes.patch
CommitLineData
0a6eb0ab
AM
1;+JH/01 Bug 2999: Fix a possible OOB write in the external authenticator, which
2; could be triggered by externally-supplied input. Found by Trend Micro.
3; CVE-2023-42115
4;
5;JH/02 Bug 3000: Fix a possible OOB write in the SPA authenticator, which could
6; be triggered by externally-controlled input. Found by Trend Micro.
7; CVE-2023-42116
8;
9;JH/03 Bug 3001: Fix a possible OOB read in the SPA authenticator, which could
10; be triggered by externally-controlled input. Found by Trend Micro.
11; CVE-2023-42114
12;
13diff --git a/src/src/auths/auth-spa.c b/src/src/auths/auth-spa.c
14index 8d886b6b6..bb3d327d1 100644
15--- a/src/src/auths/auth-spa.c
16+++ b/src/src/auths/auth-spa.c
17@@ -155,6 +155,9 @@ int main (int argc, char ** argv)
18 up with a different answer to the one above)
19 */
20
21+#ifndef MACRO_PREDEF
22+
23+
24 #define DEBUG_X(a,b) ;
25
26 extern int DEBUGLEVEL;
27@@ -1211,7 +1214,9 @@ char versionString[] = "libntlm version 0.21";
28
29 #define spa_bytes_add(ptr, header, buf, count) \
30 { \
31-if (buf && (count) != 0) /* we hate -Wint-in-bool-contex */ \
32+if ( buf && (count) != 0 /* we hate -Wint-in-bool-contex */ \
33+ && ptr->bufIndex + count < sizeof(ptr->buffer) \
34+ ) \
35 { \
36 SSVAL(&ptr->header.len,0,count); \
37 SSVAL(&ptr->header.maxlen,0,count); \
38@@ -1229,35 +1234,30 @@ else \
39
40 #define spa_string_add(ptr, header, string) \
41 { \
42-char *p = string; \
43+uschar * p = string; \
44 int len = 0; \
45-if (p) len = strlen(p); \
46-spa_bytes_add(ptr, header, (US p), len); \
47+if (p) len = Ustrlen(p); \
48+spa_bytes_add(ptr, header, p, len); \
49 }
50
51 #define spa_unicode_add_string(ptr, header, string) \
52 { \
53-char *p = string; \
54-uschar *b = NULL; \
55+uschar * p = string; \
56+uschar * b = NULL; \
57 int len = 0; \
58 if (p) \
59 { \
60- len = strlen(p); \
61- b = strToUnicode(p); \
62+ len = Ustrlen(p); \
63+ b = US strToUnicode(CS p); \
64 } \
65 spa_bytes_add(ptr, header, b, len*2); \
66 }
67
68
69-#define GetUnicodeString(structPtr, header) \
70-unicodeToString(((char*)structPtr) + IVAL(&structPtr->header.offset,0) , SVAL(&structPtr->header.len,0)/2)
71-#define GetString(structPtr, header) \
72-toString(((CS structPtr) + IVAL(&structPtr->header.offset,0)), SVAL(&structPtr->header.len,0))
73-
74 #ifdef notdef
75
76 #define DumpBuffer(fp, structPtr, header) \
77-dumpRaw(fp,(US structPtr)+IVAL(&structPtr->header.offset,0),SVAL(&structPtr->header.len,0))
78+ dumpRaw(fp,(US structPtr)+IVAL(&structPtr->header.offset,0),SVAL(&structPtr->header.len,0))
79
80
81 static void
82@@ -1321,8 +1321,33 @@ buf[len] = 0;
83 return buf;
84 }
85
86+static inline uschar *
87+get_challenge_unistr(SPAAuthChallenge * challenge, SPAStrHeader * hdr)
88+{
89+int off = IVAL(&hdr->offset, 0);
90+int len = SVAL(&hdr->len, 0);
91+return off + len < sizeof(SPAAuthChallenge)
92+ ? US unicodeToString(CS challenge + off, len/2) : US"";
93+}
94+
95+static inline uschar *
96+get_challenge_str(SPAAuthChallenge * challenge, SPAStrHeader * hdr)
97+{
98+int off = IVAL(&hdr->offset, 0);
99+int len = SVAL(&hdr->len, 0);
100+return off + len < sizeof(SPAAuthChallenge)
101+ ? US toString(CS challenge + off, len) : US"";
102+}
103+
104 #ifdef notdef
105
106+#define GetUnicodeString(structPtr, header) \
107+ unicodeToString(((char*)structPtr) + IVAL(&structPtr->header.offset,0) , SVAL(&structPtr->header.len,0)/2)
108+
109+#define GetString(structPtr, header) \
110+ toString(((CS structPtr) + IVAL(&structPtr->header.offset,0)), SVAL(&structPtr->header.len,0))
111+
112+
113 void
114 dumpSmbNtlmAuthRequest (FILE * fp, SPAAuthRequest * request)
115 {
116@@ -1366,15 +1391,15 @@ fprintf (fp, " Flags = %08x\n", IVAL (&response->flags, 0));
117 #endif
118
119 void
120-spa_build_auth_request (SPAAuthRequest * request, char *user, char *domain)
121+spa_build_auth_request (SPAAuthRequest * request, uschar * user, uschar * domain)
122 {
123-char *u = strdup (user);
124-char *p = strchr (u, '@');
125+uschar * u = string_copy(user);
126+uschar * p = Ustrchr(u, '@');
127
128 if (p)
129 {
130 if (!domain)
131- domain = p + 1;
132+ domain = p + 1;
133 *p = '\0';
134 }
135
136@@ -1384,7 +1409,6 @@ SIVAL (&request->msgType, 0, 1);
137 SIVAL (&request->flags, 0, 0x0000b207); /* have to figure out what these mean */
138 spa_string_add (request, user, u);
139 spa_string_add (request, domain, domain);
140-free (u);
141 }
142
143
144@@ -1475,16 +1499,16 @@ free (u);
145
146 void
147 spa_build_auth_response (SPAAuthChallenge * challenge,
148- SPAAuthResponse * response, char *user,
149- char *password)
150+ SPAAuthResponse * response, uschar * user,
151+ uschar * password)
152 {
153 uint8x lmRespData[24];
154 uint8x ntRespData[24];
155 uint32x cf = IVAL(&challenge->flags, 0);
156-char *u = strdup (user);
157-char *p = strchr (u, '@');
158-char *d = NULL;
159-char *domain;
160+uschar * u = string_copy(user);
161+uschar * p = Ustrchr(u, '@');
162+uschar * d = NULL;
163+uschar * domain;
164
165 if (p)
166 {
167@@ -1492,33 +1516,33 @@ if (p)
168 *p = '\0';
169 }
170
171-else domain = d = strdup((cf & 0x1)?
172- CCS GetUnicodeString(challenge, uDomain) :
173- CCS GetString(challenge, uDomain));
174+else domain = d = string_copy(cf & 0x1
175+ ? CUS get_challenge_unistr(challenge, &challenge->uDomain)
176+ : CUS get_challenge_str(challenge, &challenge->uDomain));
177
178-spa_smb_encrypt (US password, challenge->challengeData, lmRespData);
179-spa_smb_nt_encrypt (US password, challenge->challengeData, ntRespData);
180+spa_smb_encrypt(password, challenge->challengeData, lmRespData);
181+spa_smb_nt_encrypt(password, challenge->challengeData, ntRespData);
182
183 response->bufIndex = 0;
184 memcpy (response->ident, "NTLMSSP\0\0\0", 8);
185 SIVAL (&response->msgType, 0, 3);
186
187-spa_bytes_add (response, lmResponse, lmRespData, (cf & 0x200) ? 24 : 0);
188-spa_bytes_add (response, ntResponse, ntRespData, (cf & 0x8000) ? 24 : 0);
189+spa_bytes_add(response, lmResponse, lmRespData, cf & 0x200 ? 24 : 0);
190+spa_bytes_add(response, ntResponse, ntRespData, cf & 0x8000 ? 24 : 0);
191
192 if (cf & 0x1) { /* Unicode Text */
193- spa_unicode_add_string (response, uDomain, domain);
194- spa_unicode_add_string (response, uUser, u);
195- spa_unicode_add_string (response, uWks, u);
196+ spa_unicode_add_string(response, uDomain, domain);
197+ spa_unicode_add_string(response, uUser, u);
198+ spa_unicode_add_string(response, uWks, u);
199 } else { /* OEM Text */
200- spa_string_add (response, uDomain, domain);
201- spa_string_add (response, uUser, u);
202- spa_string_add (response, uWks, u);
203+ spa_string_add(response, uDomain, domain);
204+ spa_string_add(response, uUser, u);
205+ spa_string_add(response, uWks, u);
206 }
207
208-spa_string_add (response, sessionKey, NULL);
209+spa_string_add(response, sessionKey, NULL);
210 response->flags = challenge->flags;
211-
212-if (d != NULL) free (d);
213-free (u);
214 }
215+
216+
217+#endif /*!MACRO_PREDEF*/
218diff --git a/src/src/auths/auth-spa.h b/src/src/auths/auth-spa.h
219index cfe1b086d..3b0b3a9e3 100644
220--- a/src/src/auths/auth-spa.h
221+++ b/src/src/auths/auth-spa.h
222@@ -79,10 +79,10 @@ typedef struct
223
224 void spa_bits_to_base64 (unsigned char *, const unsigned char *, int);
225 int spa_base64_to_bits(char *, int, const char *);
226-void spa_build_auth_response (SPAAuthChallenge *challenge,
227- SPAAuthResponse *response, char *user, char *password);
228-void spa_build_auth_request (SPAAuthRequest *request, char *user,
229- char *domain);
230+void spa_build_auth_response (SPAAuthChallenge * challenge,
231+ SPAAuthResponse * response, uschar * user, uschar * password);
232+void spa_build_auth_request (SPAAuthRequest * request, uschar * user,
233+ uschar * domain);
234 extern void spa_smb_encrypt (unsigned char * passwd, unsigned char * c8,
235 unsigned char * p24);
236 extern void spa_smb_nt_encrypt (unsigned char * passwd, unsigned char * c8,
237diff --git a/src/src/auths/external.c b/src/src/auths/external.c
238index 7e7fca841..790b98159 100644
239--- a/src/src/auths/external.c
240+++ b/src/src/auths/external.c
241@@ -103,7 +103,7 @@ if (expand_nmax == 0) /* skip if rxd data */
242 if (ob->server_param2)
243 {
244 uschar * s = expand_string(ob->server_param2);
245- auth_vars[expand_nmax] = s;
246+ auth_vars[expand_nmax = 1] = s;
247 expand_nstring[++expand_nmax] = s;
248 expand_nlength[expand_nmax] = Ustrlen(s);
249 if (ob->server_param3)
250diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c
251index ff90d33a3..bfaccefda 100644
252--- a/src/src/auths/spa.c
253+++ b/src/src/auths/spa.c
254@@ -284,14 +284,13 @@ SPAAuthRequest request;
255 SPAAuthChallenge challenge;
256 SPAAuthResponse response;
257 char msgbuf[2048];
258-char *domain = NULL;
259-char *username, *password;
260+uschar * domain = NULL, * username, * password;
261
262 /* Code added by PH to expand the options */
263
264 *buffer = 0; /* Default no message when cancelled */
265
266-if (!(username = CS expand_string(ob->spa_username)))
267+if (!(username = expand_string(ob->spa_username)))
268 {
269 if (f.expand_string_forcedfail) return CANCELLED;
270 string_format(buffer, buffsize, "expansion of \"%s\" failed in %s "
271@@ -300,7 +299,7 @@ if (!(username = CS expand_string(ob->spa_username)))
272 return ERROR;
273 }
274
275-if (!(password = CS expand_string(ob->spa_password)))
276+if (!(password = expand_string(ob->spa_password)))
277 {
278 if (f.expand_string_forcedfail) return CANCELLED;
279 string_format(buffer, buffsize, "expansion of \"%s\" failed in %s "
280@@ -310,7 +309,7 @@ if (!(password = CS expand_string(ob->spa_password)))
281 }
282
283 if (ob->spa_domain)
284- if (!(domain = CS expand_string(ob->spa_domain)))
285+ if (!(domain = expand_string(ob->spa_domain)))
286 {
287 if (f.expand_string_forcedfail) return CANCELLED;
288 string_format(buffer, buffsize, "expansion of \"%s\" failed in %s "
289@@ -330,7 +329,7 @@ if (!smtp_read_response(sx, US buffer, buffsize, '3', timeout))
290
291 DSPA("\n\n%s authenticator: using domain %s\n\n", ablock->name, domain);
292
293-spa_build_auth_request(&request, CS username, domain);
294+spa_build_auth_request(&request, username, domain);
295 spa_bits_to_base64(US msgbuf, US &request, spa_request_length(&request));
296
297 DSPA("\n\n%s authenticator: sending request (%s)\n\n", ablock->name, msgbuf);
298@@ -347,7 +346,7 @@ if (!smtp_read_response(sx, US buffer, buffsize, '3', timeout))
299 DSPA("\n\n%s authenticator: challenge (%s)\n\n", ablock->name, buffer + 4);
300 spa_base64_to_bits(CS (&challenge), sizeof(challenge), CCS (buffer + 4));
301
302-spa_build_auth_response(&challenge, &response, CS username, CS password);
303+spa_build_auth_response(&challenge, &response, username, password);
304 spa_bits_to_base64(US msgbuf, US &response, spa_request_length(&response));
305 DSPA("\n\n%s authenticator: challenge response (%s)\n\n", ablock->name, msgbuf);
306
This page took 0.101932 seconds and 4 git commands to generate.