diff options
author | Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de> | 2021-03-29 23:12:02 +0200 |
---|---|---|
committer | Heiko Schlittermann (HS12-RIPE) <hs@schlittermann.de> | 2021-05-27 21:30:50 +0200 |
commit | d17c916db7c661aacf65684a5568f8e105e50b3b (patch) | |
tree | d9c8b6cd3cad38bf7e0aa2351825ee9f0c28f469 /src | |
parent | feef71897f2e24910009744b3aeb735cf07da31b (diff) |
CVE-2020-28022: Heap out-of-bounds read and write in extract_option()
Based on Phil Pennock's commit c5017adf.
(cherry picked from commit 9e941e1807b624b255c9ec0f41a0b3a89e144de3)
(cherry picked from commit 33d4c87653ddbbea9fd8cb8eb2ff78c149850006)
Diffstat (limited to 'src')
-rw-r--r-- | src/src/smtp_in.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 6d2339770..9efe7baa9 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -2003,30 +2003,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; |