From 8c85278d28ff4da32106714a1420371fe37ef349 Mon Sep 17 00:00:00 2001 From: Brian Stafford Date: Mon, 24 Aug 2020 16:11:13 +0100 Subject: [PATCH] CVE-2019-19977 avoid stach overrwrite #6 --- ntlm/ntlm.h | 2 +- ntlm/ntlmdes.c | 9 ++++-- ntlm/ntlmstruct.c | 76 ++++++++++++++--------------------------------- 3 files changed, 30 insertions(+), 57 deletions(-) Index: libesmtp-1.0.6/ntlm/ntlm.h =================================================================== --- libesmtp-1.0.6.orig/ntlm/ntlm.h +++ libesmtp-1.0.6/ntlm/ntlm.h @@ -24,7 +24,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -char *lm_uccpy (char *dst, size_t dstlen, const char *src); +int lm_uccpy (char *dst, size_t dstlen, const char *src); unsigned char *nt_unicode (const char *string, size_t len); void lm_hash_password (unsigned char *hash, const char *pass); Index: libesmtp-1.0.6/ntlm/ntlmdes.c =================================================================== --- libesmtp-1.0.6.orig/ntlm/ntlmdes.c +++ libesmtp-1.0.6/ntlm/ntlmdes.c @@ -66,19 +66,19 @@ lm_deshash (void *result, const_des_cblo /* Copy and convert to upper case. If supplied string is shorter than the destination, zero pad the remainder. */ -char * +int lm_uccpy (char *dst, size_t dstlen, const char *src) { char *p; size_t len; - if ((len = strlen (src)) > dstlen) + if ((len = src != NULL ? strlen (src) : 0) > dstlen) len = dstlen; for (p = dst; len > 0; p++, src++, len--) *p = toupper (*src); if (p < dst + dstlen) memset (p, 0, dst + dstlen - p); - return dst; + return len; } /* create LanManager hashed password */ @@ -101,6 +101,9 @@ nt_unicode (const char *string, size_t l { unsigned char *uni, *pp; + if (len == 0) + return NULL; + uni = malloc (len * 2); if ((pp = uni) != NULL) while (len-- > 0) Index: libesmtp-1.0.6/ntlm/ntlmstruct.c =================================================================== --- libesmtp-1.0.6.orig/ntlm/ntlmstruct.c +++ libesmtp-1.0.6/ntlm/ntlmstruct.c @@ -187,7 +187,6 @@ ntlm_build_type_1 (char *buf, size_t buf { size_t offset = T1SIZE; size_t len; - unsigned char *up; char string[256]; if (buflen < offset) @@ -195,25 +194,13 @@ ntlm_build_type_1 (char *buf, size_t buf memcpy (buf, NTLMSSP, 8); write_uint32 (buf, MSGTYPE, 1); write_uint32 (buf, T1FLAGS, flags); - up = NULL; - len = 0; - if (domain != NULL) - { - len = strlen (domain); - if (offset + len > buflen) - return 0; - lm_uccpy (string, len, domain); - } + len = lm_uccpy (string, sizeof string, domain); + if (offset + len > buflen) + return 0; write_string (buf, T1DOMAIN, &offset, string, len); - up = NULL; - len = 0; - if (workstation != NULL) - { - len = strlen (workstation); - if (offset + len > buflen) - return 0; - lm_uccpy (string, len, workstation); - } + len = lm_uccpy (string, sizeof string, workstation); + if (offset + len > buflen) + return 0; write_string (buf, T1WKSTN, &offset, string, len); return offset; } @@ -232,16 +219,11 @@ ntlm_build_type_2 (char *buf, size_t buf return 0; memcpy (buf, NTLMSSP, 8); write_uint32 (buf, MSGTYPE, 2); - up = NULL; - len = 0; - if (domain != NULL) - { - len = strlen (domain); - if (offset + 2 * len > buflen) - return 0; - up = nt_unicode (lm_uccpy (string, len, domain), 2 * len); - } - write_string (buf, T2AUTHTARGET, &offset, up, len); + len = lm_uccpy (string, sizeof string, domain); + if (offset + 2 * len > buflen) + return 0; + up = nt_unicode (string, len); + write_string (buf, T2AUTHTARGET, &offset, up, 2 * len); if (up != NULL) free (up); write_uint32 (buf, T2FLAGS, flags); @@ -267,39 +249,24 @@ ntlm_build_type_3 (char *buf, size_t buf write_uint32 (buf, MSGTYPE, 3); write_string (buf, T3LMRESPONSE, &offset, lm_resp, 24); write_string (buf, T3NTRESPONSE, &offset, nt_resp, 24); - up = NULL; - len = 0; - if (domain != NULL) - { - len = strlen (domain); - if (offset + 2 * len > buflen) - return 0; - up = nt_unicode (lm_uccpy (string, len, domain), 2 * len); - } + len = lm_uccpy (string, sizeof string, domain); + if (offset + 2 * len > buflen) + return 0; + up = nt_unicode (string, len); write_string (buf, T3DOMAIN, &offset, up, 2 * len); if (up != NULL) free (up); - up = NULL; - len = 0; - if (user != NULL) - { - len = strlen (user); - if (offset + 2 * len > buflen) - return 0; - up = nt_unicode (lm_uccpy (string, len, user), 2 * len); - } + len = lm_uccpy (string, sizeof string, user); + if (offset + 2 * len > buflen) + return 0; + up = nt_unicode (string, len); write_string (buf, T3USER, &offset, up, 2 * len); if (up != NULL) free (up); - up = NULL; - len = 0; - if (workstation != NULL) - { - len = strlen (workstation); - if (offset + 2 * len > buflen) - return 0; - up = nt_unicode (lm_uccpy (string, len, workstation), 2 * len); - } + len = lm_uccpy (string, sizeof string, workstation); + if (offset + 2 * len > buflen) + return 0; + up = nt_unicode (string, len); write_string (buf, T3WKSTN, &offset, up, 2 * len); if (up != NULL) free (up);