From 69237cbadb827ad4efb81dc64867835ac87bb736 Mon Sep 17 00:00:00 2001 From: Vchanger Date: Wed, 22 Apr 2020 16:43:17 +0800 Subject: [PATCH] squid: fix CVE-2019-12528 CVE-2020-8517 CVE-2020-8449 CVE-2020-8450 --- CVE-2019-12528.patch | 174 ++++++++++++++++++++++++++++++ CVE-2020-8449_CVE-2020-8450.patch | 54 ++++++++++ CVE-2020-8517.patch | 30 ++++++ squid.spec | 11 +- 4 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 CVE-2019-12528.patch create mode 100644 CVE-2020-8449_CVE-2020-8450.patch create mode 100644 CVE-2020-8517.patch diff --git a/CVE-2019-12528.patch b/CVE-2019-12528.patch new file mode 100644 index 0000000..c8c42d0 --- /dev/null +++ b/CVE-2019-12528.patch @@ -0,0 +1,174 @@ +From c3972f03bed2ca25e212e52a9c216d8a3d102892 Mon Sep 17 00:00:00 2001 +From: Christos Tsantilas +Date: Fri, 20 Dec 2019 07:29:58 +0000 +Subject: [PATCH] Fix FTP buffers handling (#521) + +Fix the parsing of the received listing from FTP services. +Also relaxed size/filename grammar used for DOS listings: Tolerate +multiple spaces between the size and the filename. + +This is a Measurement Factory project +--- + src/clients/FtpGateway.cc | 81 +++++++++++++++++++++++------------------------ + 1 file changed, 39 insertions(+), 42 deletions(-) + +diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc +index 140c441..33286b5 100644 +--- a/src/clients/FtpGateway.cc ++++ b/src/clients/FtpGateway.cc +@@ -532,8 +532,10 @@ ftpListParseParts(const char *buf, struct Ftp::GatewayFlags flags) + { + ftpListParts *p = NULL; + char *t = NULL; +- const char *ct = NULL; +- char *tokens[MAX_TOKENS]; ++ struct FtpLineToken { ++ char *token = nullptr; ///< token image copied from the received line ++ size_t pos = 0; ///< token offset on the received line ++ } tokens[MAX_TOKENS]; + int i; + int n_tokens; + static char tbuf[128]; +@@ -574,7 +576,8 @@ ftpListParseParts(const char *buf, struct Ftp::GatewayFlags flags) + } + + for (t = strtok(xbuf, w_space); t && n_tokens < MAX_TOKENS; t = strtok(NULL, w_space)) { +- tokens[n_tokens] = xstrdup(t); ++ tokens[n_tokens].token = xstrdup(t); ++ tokens[n_tokens].pos = t - xbuf; + ++n_tokens; + } + +@@ -582,10 +585,10 @@ ftpListParseParts(const char *buf, struct Ftp::GatewayFlags flags) + + /* locate the Month field */ + for (i = 3; i < n_tokens - 2; ++i) { +- char *size = tokens[i - 1]; +- char *month = tokens[i]; +- char *day = tokens[i + 1]; +- char *year = tokens[i + 2]; ++ const auto size = tokens[i - 1].token; ++ char *month = tokens[i].token; ++ char *day = tokens[i + 1].token; ++ char *year = tokens[i + 2].token; + + if (!is_month(month)) + continue; +@@ -599,23 +602,27 @@ ftpListParseParts(const char *buf, struct Ftp::GatewayFlags flags) + if (regexec(&scan_ftp_time, year, 0, NULL, 0) != 0) /* Yr | hh:mm */ + continue; + +- snprintf(tbuf, 128, "%s %2s %5s", +- month, day, year); ++ const auto *copyFrom = buf + tokens[i].pos; + +- if (!strstr(buf, tbuf)) +- snprintf(tbuf, 128, "%s %2s %-5s", +- month, day, year); ++ // "MMM DD [ YYYY|hh:mm]" with at most two spaces between DD and YYYY ++ auto dateSize = snprintf(tbuf, sizeof(tbuf), "%s %2s %5s", month, day, year); ++ bool isTypeA = (dateSize == 12) && (strncmp(copyFrom, tbuf, dateSize) == 0); + +- char const *copyFrom = NULL; ++ // "MMM DD [YYYY|hh:mm]" with one space between DD and YYYY ++ dateSize = snprintf(tbuf, sizeof(tbuf), "%s %2s %-5s", month, day, year); ++ bool isTypeB = (dateSize == 12 || dateSize == 11) && (strncmp(copyFrom, tbuf, dateSize) == 0); + +- if ((copyFrom = strstr(buf, tbuf))) { +- p->type = *tokens[0]; ++ // TODO: replace isTypeA and isTypeB with a regex. ++ if (isTypeA || isTypeB) { ++ p->type = *tokens[0].token; + p->size = strtoll(size, NULL, 10); ++ const auto finalDateSize = snprintf(tbuf, sizeof(tbuf), "%s %2s %5s", month, day, year); ++ assert(finalDateSize >= 0); + p->date = xstrdup(tbuf); + ++ // point after tokens[i+2] : ++ copyFrom = buf + tokens[i + 2].pos + strlen(tokens[i + 2].token); + if (flags.skip_whitespace) { +- copyFrom += strlen(tbuf); +- + while (strchr(w_space, *copyFrom)) + ++copyFrom; + } else { +@@ -627,7 +634,6 @@ ftpListParseParts(const char *buf, struct Ftp::GatewayFlags flags) + * Assuming a single space between date and filename + * suggested by: Nathan.Bailey@cc.monash.edu.au and + * Mike Battersby */ +- copyFrom += strlen(tbuf); + if (strchr(w_space, *copyFrom)) + ++copyFrom; + } +@@ -647,45 +653,36 @@ ftpListParseParts(const char *buf, struct Ftp::GatewayFlags flags) + + /* try it as a DOS listing, 04-05-70 09:33PM ... */ + if (n_tokens > 3 && +- regexec(&scan_ftp_dosdate, tokens[0], 0, NULL, 0) == 0 && +- regexec(&scan_ftp_dostime, tokens[1], 0, NULL, 0) == 0) { +- if (!strcasecmp(tokens[2], "")) { ++ regexec(&scan_ftp_dosdate, tokens[0].token, 0, NULL, 0) == 0 && ++ regexec(&scan_ftp_dostime, tokens[1].token, 0, NULL, 0) == 0) { ++ if (!strcasecmp(tokens[2].token, "")) { + p->type = 'd'; + } else { + p->type = '-'; +- p->size = strtoll(tokens[2], NULL, 10); ++ p->size = strtoll(tokens[2].token, NULL, 10); + } + +- snprintf(tbuf, 128, "%s %s", tokens[0], tokens[1]); ++ snprintf(tbuf, sizeof(tbuf), "%s %s", tokens[0].token, tokens[1].token); + p->date = xstrdup(tbuf); + + if (p->type == 'd') { +- /* Directory.. name begins with first printable after */ +- ct = strstr(buf, tokens[2]); +- ct += strlen(tokens[2]); +- +- while (xisspace(*ct)) +- ++ct; +- +- if (!*ct) +- ct = NULL; ++ // Directory.. name begins with first printable after ++ // Because of the "n_tokens > 3", the next printable after ++ // is stored at token[3]. No need for more checks here. + } else { +- /* A file. Name begins after size, with a space in between */ +- snprintf(tbuf, 128, " %s %s", tokens[2], tokens[3]); +- ct = strstr(buf, tbuf); +- +- if (ct) { +- ct += strlen(tokens[2]) + 2; +- } ++ // A file. Name begins after size, with a space in between. ++ // Also a space should exist before size. ++ // But there is not needed to be very strict with spaces. ++ // The name is stored at token[3], take it from here. + } + +- p->name = xstrdup(ct ? ct : tokens[3]); ++ p->name = xstrdup(tokens[3].token); + goto found; + } + + /* Try EPLF format; carson@lehman.com */ + if (buf[0] == '+') { +- ct = buf + 1; ++ const char *ct = buf + 1; + p->type = 0; + + while (ct && *ct) { +@@ -756,7 +753,7 @@ blank: + found: + + for (i = 0; i < n_tokens; ++i) +- xfree(tokens[i]); ++ xfree(tokens[i].token); + + if (!p->name) + ftpListPartsFree(&p); /* cleanup */ +-- +1.8.3.1 + diff --git a/CVE-2020-8449_CVE-2020-8450.patch b/CVE-2020-8449_CVE-2020-8450.patch new file mode 100644 index 0000000..0f76598 --- /dev/null +++ b/CVE-2020-8449_CVE-2020-8450.patch @@ -0,0 +1,54 @@ +From f9fb256a80f966d7f7af7d2e04438366c74258c7 Mon Sep 17 00:00:00 2001 +From: Guido Vranken +Date: Thu, 12 Dec 2019 03:27:40 +0000 +Subject: [PATCH] Fix request URL generation in reverse proxy configurations + (#519) + +--- + src/client_side.cc | 24 ++++++++++-------------- + 1 file changed, 10 insertions(+), 14 deletions(-) + +diff --git a/src/client_side.cc b/src/client_side.cc +index 538bd5e..671f6c6 100644 +--- a/src/client_side.cc ++++ b/src/client_side.cc +@@ -1141,26 +1141,22 @@ prepareAcceleratedURL(ConnStateData * conn, const Http1::RequestParserPointer &h + if (vport < 0) + vport = conn->clientConnection->local.port(); + +- char *host = NULL; +- if (vhost && (host = hp->getHostHeaderField())) { ++ char *receivedHost = nullptr; ++ if (vhost && (receivedHost = hp->getHostHeaderField())) { ++ SBuf host(receivedHost); + debugs(33, 5, "ACCEL VHOST REWRITE: vhost=" << host << " + vport=" << vport); +- char thost[256]; + if (vport > 0) { +- thost[0] = '\0'; +- char *t = NULL; +- if (host[strlen(host) - 1] != ']' && (t = strrchr(host,':')) != nullptr) { +- strncpy(thost, host, (t-host)); +- snprintf(thost+(t-host), sizeof(thost)-(t-host), ":%d", vport); +- host = thost; +- } else if (!t) { +- snprintf(thost, sizeof(thost), "%s:%d",host, vport); +- host = thost; ++ // remove existing :port (if any), cope with IPv6+ without port ++ const auto lastColonPos = host.rfind(':'); ++ if (lastColonPos != SBuf::npos && *host.rbegin() != ']') { ++ host.chop(0, lastColonPos); // truncate until the last colon + } ++ host.appendf(":%d", vport); + } // else nothing to alter port-wise. + const SBuf &scheme = AnyP::UriScheme(conn->transferProtocol.protocol).image(); +- const int url_sz = scheme.length() + strlen(host) + url.length() + 32; ++ const auto url_sz = scheme.length() + host.length() + url.length() + 32; + char *uri = static_cast(xcalloc(url_sz, 1)); +- snprintf(uri, url_sz, SQUIDSBUFPH "://%s" SQUIDSBUFPH, SQUIDSBUFPRINT(scheme), host, SQUIDSBUFPRINT(url)); ++ snprintf(uri, url_sz, SQUIDSBUFPH "://" SQUIDSBUFPH SQUIDSBUFPH, SQUIDSBUFPRINT(scheme), SQUIDSBUFPRINT(host), SQUIDSBUFPRINT(url)); + debugs(33, 5, "ACCEL VHOST REWRITE: " << uri); + return uri; + } else if (conn->port->defaultsite /* && !vhost */) { +-- +1.8.3.1 + diff --git a/CVE-2020-8517.patch b/CVE-2020-8517.patch new file mode 100644 index 0000000..16811d7 --- /dev/null +++ b/CVE-2020-8517.patch @@ -0,0 +1,30 @@ +From 71d6f8af3458d3462371d544c5d144abe4c9ee55 Mon Sep 17 00:00:00 2001 +From: aaron-costello <56684862+aaron-costello@users.noreply.github.com> +Date: Fri, 22 Nov 2019 02:44:29 +0000 +Subject: [PATCH] ext_lm_group_acl: Improved username handling (#512) + +--- + src/acl/external/LM_group/ext_lm_group_acl.cc | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/acl/external/LM_group/ext_lm_group_acl.cc b/src/acl/external/LM_group/ext_lm_group_acl.cc +index dee369c..a0fb6ad 100644 +--- a/src/acl/external/LM_group/ext_lm_group_acl.cc ++++ b/src/acl/external/LM_group/ext_lm_group_acl.cc +@@ -343,10 +343,10 @@ Valid_Global_Groups(char *UserName, const char **Groups) + break; + } + if (domain_qualify == NULL) { +- strcpy(User, NTDomain); +- strcpy(NTDomain, DefaultDomain); ++ xstrncpy(User, NTDomain, sizeof(User)); ++ xstrncpy(NTDomain, DefaultDomain, sizeof(NTDomain)); + } else { +- strcpy(User, domain_qualify + 1); ++ xstrncpy(User, domain_qualify + 1, sizeof(User)); + domain_qualify[0] = '\0'; + strlwr(NTDomain); + } +-- +1.8.3.1 + diff --git a/squid.spec b/squid.spec index 926120b..c26cd0a 100644 --- a/squid.spec +++ b/squid.spec @@ -2,7 +2,7 @@ Name: squid Version: 4.9 -Release: 1 +Release: 2 Summary: The Squid proxy caching server Epoch: 7 License: GPLv2+ and (LGPLv2+ and MIT and BSD and Public Domain) @@ -22,6 +22,9 @@ Patch1: squid-3.1.0.9-location.patch Patch2: squid-3.0.STABLE1-perlpath.patch Patch3: squid-3.5.9-include-guards.patch Patch4: squid-4.0.21-large-acl.patch +Patch5: CVE-2019-12528.patch +Patch6: CVE-2020-8517.patch +Patch7: CVE-2020-8449_CVE-2020-8450.patch Buildroot: %{_tmppath}/squid-4.9-1-root-%(%{__id_u} -n) Requires: bash >= 2.0 @@ -200,6 +203,12 @@ fi chgrp squid /var/cache/samba/winbindd_privileged >/dev/null 2>&1 || : %changelog +* Wed Apr 22 2020 openEuler Buildteam - 4.9-2 +- Type:cves +- ID:CVE-2019-12528 CVE-2020-8517 CVE-2020-8449 CVE-2020-8450 +- SUG:restart +- DESC:fix CVE-2019-12528 CVE-2020-8517 CVE-2020-8449 CVE-2020-8450 + * Tue Jan 14 2020 openEuler Buildteam - 4.9-1 - Type:NA - ID:NA -- Gitee