CVE-2020-28022: Heap out-of-bounds read and write in extract_option()
authorHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Mon, 29 Mar 2021 21:12:02 +0000 (23:12 +0200)
committerHeiko Schlittermann (HS12-RIPE) <hs@schlittermann.de>
Tue, 27 Apr 2021 22:40:43 +0000 (00:40 +0200)
Based on Phil Pennock's commit c5017adf.

(cherry picked from commit 9e941e1807b624b255c9ec0f41a0b3a89e144de3)

src/src/smtp_in.c

index 190064eed13cbed184575678393325000ae1a22b..a8b92d0bed001fadfa0d8acd30987a9bdd35effd 100644 (file)
@@ -2031,30 +2031,35 @@ static BOOL
 extract_option(uschar **name, uschar **value)
 {
 uschar *n;
-uschar *v = smtp_cmd_data + Ustrlen(smtp_cmd_data) - 1;
-while (isspace(*v)) v--;
-v[1] = '\0';
+uschar *v;
+if (Ustrlen(smtp_cmd_data) <= 0) return FALSE;
+v = smtp_cmd_data + Ustrlen(smtp_cmd_data) - 1;
+while (v > smtp_cmd_data && isspace(*v)) v--;
+v[1] = 0;
+
 while (v > smtp_cmd_data && *v != '=' && !isspace(*v))
   {
   /* Take care to not stop at a space embedded in a quoted local-part */
-
-  if ((*v == '"') && (v > smtp_cmd_data + 1))
-    do v--; while (*v != '"' && v > smtp_cmd_data+1);
+  if (*v == '"')
+    {
+    do v--; while (v > smtp_cmd_data && *v != '"');
+    if (v <= smtp_cmd_data) return FALSE;
+    }
   v--;
   }
+if (v <= smtp_cmd_data) return FALSE;
 
 n = v;
 if (*v == '=')
   {
-  while(isalpha(n[-1])) n--;
+  while (n > smtp_cmd_data && isalpha(n[-1])) n--;
   /* RFC says SP, but TAB seen in wild and other major MTAs accept it */
-  if (!isspace(n[-1])) return FALSE;
+  if (n <= smtp_cmd_data || !isspace(n[-1])) return FALSE;
   n[-1] = 0;
   }
 else
   {
   n++;
-  if (v == smtp_cmd_data) return FALSE;
   }
 *v++ = 0;
 *name = n;