| 1 | From 6a7edbf6608d10ef0c707c426511e667849518d7 Mon Sep 17 00:00:00 2001 |
| 2 | From: Jeremy Harris <jgh146exb@wizmail.org> |
| 3 | Date: Tue, 5 May 2020 21:15:34 +0100 |
| 4 | Subject: [PATCH 1/2] Fix SPA authenticator, checking client-supplied data |
| 5 | before using it. Bug 2571 |
| 6 | |
| 7 | (cherry picked from commit 57aa14b216432be381b6295c312065b2fd034f86) |
| 8 | --- |
| 9 | doc/ChangeLog | 5 +++++ |
| 10 | src/auths/spa.c | 22 ++++++++++++++++------ |
| 11 | 2 files changed, 21 insertions(+), 6 deletions(-) |
| 12 | |
| 13 | --- a/doc/ChangeLog |
| 14 | +++ b/doc/ChangeLog |
| 15 | @@ -62,6 +62,11 @@ JH/28 Fix the timeout on smtp response t |
| 16 | [from GIT master] |
| 17 | |
| 18 | |
| 19 | +JH/41 Bug 2571: Fix SPA authenticator. Running as a server, an offset supplied |
| 20 | + by the client was not checked as pointing within response data before |
| 21 | + being used. A malicious client could thus cause an out-of-bounds read and |
| 22 | + possibly gain authentication. Fix by adding the check. |
| 23 | + |
| 24 | |
| 25 | Exim version 4.92 |
| 26 | ----------------- |
| 27 | --- a/src/auths/spa.c |
| 28 | +++ b/src/auths/spa.c |
| 29 | @@ -139,7 +139,7 @@ SPAAuthChallenge challenge; |
| 30 | SPAAuthResponse response; |
| 31 | SPAAuthResponse *responseptr = &response; |
| 32 | uschar msgbuf[2048]; |
| 33 | -uschar *clearpass; |
| 34 | +uschar *clearpass, *s; |
| 35 | |
| 36 | /* send a 334, MS Exchange style, and grab the client's request, |
| 37 | unless we already have it via an initial response. */ |
| 38 | @@ -197,6 +197,13 @@ that causes failure if the size of msgbu |
| 39 | char *p = ((char*)responseptr) + IVAL(&responseptr->uUser.offset,0); |
| 40 | int len = SVAL(&responseptr->uUser.len,0)/2; |
| 41 | |
| 42 | + if (p + len*2 >= CS (responseptr+1)) |
| 43 | + { |
| 44 | + DEBUG(D_auth) |
| 45 | + debug_printf("auth_spa_server(): bad uUser spec in response\n"); |
| 46 | + return FAIL; |
| 47 | + } |
| 48 | + |
| 49 | if (len + 1 >= sizeof(msgbuf)) return FAIL; |
| 50 | for (i = 0; i < len; ++i) |
| 51 | { |
| 52 | @@ -245,14 +252,17 @@ spa_smb_nt_encrypt (clearpass, challenge |
| 53 | |
| 54 | /* compare NT hash (LM may not be available) */ |
| 55 | |
| 56 | -if (memcmp(ntRespData, |
| 57 | - ((unsigned char*)responseptr)+IVAL(&responseptr->ntResponse.offset,0), |
| 58 | - 24) == 0) |
| 59 | - /* success. we have a winner. */ |
| 60 | +s = (US responseptr) + IVAL(&responseptr->ntResponse.offset,0); |
| 61 | +if (s + 24 >= US (responseptr+1)) |
| 62 | { |
| 63 | - return auth_check_serv_cond(ablock); |
| 64 | + DEBUG(D_auth) |
| 65 | + debug_printf("auth_spa_server(): bad ntRespData spec in response\n"); |
| 66 | + return FAIL; |
| 67 | } |
| 68 | |
| 69 | +if (memcmp(ntRespData, s, 24) == 0) |
| 70 | + return auth_check_serv_cond(ablock); /* success. we have a winner. */ |
| 71 | + |
| 72 | /* Expand server_condition as an authorization check (PH) */ |
| 73 | |
| 74 | return FAIL; |