84 lines
2.4 KiB
Diff
84 lines
2.4 KiB
Diff
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) */
|