summaryrefslogtreecommitdiff
path: root/mail-mta/exim/files/exim-4.93-CVE-2020-12783.patch
blob: c957d5541e4728d818c119cd7d1f5b7551622dfb (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
auths/spa: fix for CVE-2020-12783

This is a combined patch of git commits:

57aa14b216432be381b6295c312065b2fd034f86
a04174dc2a84ae1008c23b6a7109e7fa3fb7b8b0

leaving out whitespace noise for a smaller patch
and made it apply to the 4.93 release

modified paths because Exim dists differ in layout from the git repo

Fix SPA authenticator, checking client-supplied data before using it.  Bug 2571
Rework SPA fix to avoid overflows.  Bug 2571


--- a/src/auths/auth-spa.c
+++ b/src/auths/auth-spa.c
@@ -405,7 +405,7 @@ int
 /* base 64 to raw bytes in quasi-big-endian order, returning count of bytes */
 {
   int len = 0;
-  register uschar digit1, digit2, digit3, digit4;
+  uschar digit1, digit2, digit3, digit4;
 
   if (in[0] == '+' && in[1] == ' ')
     in += 2;
--- a/src/auths/spa.c
+++ b/src/auths/spa.c
@@ -139,7 +139,8 @@ SPAAuthChallenge challenge;
 SPAAuthResponse  response;
 SPAAuthResponse  *responseptr = &response;
 uschar msgbuf[2048];
-uschar *clearpass;
+uschar *clearpass, *s;
+unsigned off;
 
 /* send a 334, MS Exchange style, and grab the client's request,
 unless we already have it via an initial response. */
@@ -194,9 +195,19 @@ that causes failure if the size of msgbuf is exceeded. ****/
 
   {
   int i;
-  char *p = ((char*)responseptr) + IVAL(&responseptr->uUser.offset,0);
+  char * p;
   int len = SVAL(&responseptr->uUser.len,0)/2;
 
+  if (  (off = IVAL(&responseptr->uUser.offset,0)) >= sizeof(SPAAuthResponse)
+     || len >= sizeof(responseptr->buffer)/2
+     || (p = (CS responseptr) + off) + len*2 >= CS (responseptr+1)
+     )
+    {
+    DEBUG(D_auth)
+      debug_printf("auth_spa_server(): bad uUser spec in response\n");
+    return FAIL;
+    }
+
   if (len + 1 >= sizeof(msgbuf)) return FAIL;
   for (i = 0; i < len; ++i)
     {
@@ -245,12 +256,16 @@ spa_smb_nt_encrypt(clearpass, challenge.challengeData, ntRespData);
 
 /* compare NT hash (LM may not be available) */
 
-if (memcmp(ntRespData,
-      ((unsigned char*)responseptr)+IVAL(&responseptr->ntResponse.offset,0),
-      24) == 0)
-  /* success. we have a winner. */
-  {
+off = IVAL(&responseptr->ntResponse.offset,0);
+if (off >= sizeof(SPAAuthResponse) - 24)
+  {
+  DEBUG(D_auth)
+    debug_printf("auth_spa_server(): bad ntRespData spec in response\n");
+  return FAIL;
+  }
+s = (US responseptr) + off;
+
+if (memcmp(ntRespData, s, 24) == 0)
   return auth_check_serv_cond(ablock);
-  }
 
   /* Expand server_condition as an authorization check (PH) */