]> git.pld-linux.org Git - packages/exim.git/blob - CVE-2023-42114+42115+42116-fixes.patch
15d70479129a0e130d69d818630aa4dce344b0e6
[packages/exim.git] / CVE-2023-42114+42115+42116-fixes.patch
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 ;
13 diff --git a/src/src/auths/auth-spa.c b/src/src/auths/auth-spa.c
14 index 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*/
218 diff --git a/src/src/auths/auth-spa.h b/src/src/auths/auth-spa.h
219 index 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,
237 diff --git a/src/src/auths/external.c b/src/src/auths/external.c
238 index 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)
250 diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c
251 index 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.07575 seconds and 3 git commands to generate.