diff --git a/SOURCES/squid-4.4.0-CVE-2019-12527.patch b/SOURCES/squid-4.4.0-CVE-2019-12527.patch new file mode 100644 index 0000000..ea950f5 --- /dev/null +++ b/SOURCES/squid-4.4.0-CVE-2019-12527.patch @@ -0,0 +1,139 @@ +commit 7f73e9c5d17664b882ed32590e6af310c247f320 +Author: Amos Jeffries +Date: 2019-06-19 05:58:36 +0000 + + Update HttpHeader::getAuth to SBuf (#416) + + Replace the fixed-size buffer for decoding base64 tokens with an + SBuf to avoid decoder issues on large inputs. + + Update callers to SBuf API operations for more efficient memory + management. + +diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc +index 1e2b650..284a057 100644 +--- a/src/HttpHeader.cc ++++ b/src/HttpHeader.cc +@@ -1268,43 +1268,46 @@ HttpHeader::getContRange() const + return cr; + } + +-const char * +-HttpHeader::getAuth(Http::HdrType id, const char *auth_scheme) const ++SBuf ++HttpHeader::getAuthToken(Http::HdrType id, const char *auth_scheme) const + { + const char *field; + int l; + assert(auth_scheme); + field = getStr(id); + ++ static const SBuf nil; + if (!field) /* no authorization field */ +- return NULL; ++ return nil; + + l = strlen(auth_scheme); + + if (!l || strncasecmp(field, auth_scheme, l)) /* wrong scheme */ +- return NULL; ++ return nil; + + field += l; + + if (!xisspace(*field)) /* wrong scheme */ +- return NULL; ++ return nil; + + /* skip white space */ + for (; field && xisspace(*field); ++field); + + if (!*field) /* no authorization cookie */ +- return NULL; ++ return nil; + +- static char decodedAuthToken[8192]; ++ const auto fieldLen = strlen(field); ++ SBuf result; ++ char *decodedAuthToken = result.rawAppendStart(BASE64_DECODE_LENGTH(fieldLen)); + struct base64_decode_ctx ctx; + base64_decode_init(&ctx); + size_t decodedLen = 0; +- if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast(decodedAuthToken), strlen(field), field) || ++ if (!base64_decode_update(&ctx, &decodedLen, reinterpret_cast(decodedAuthToken), fieldLen, field) || + !base64_decode_final(&ctx)) { +- return NULL; ++ return nil; + } +- decodedAuthToken[decodedLen] = '\0'; +- return decodedAuthToken; ++ result.rawAppendFinish(decodedAuthToken, decodedLen); ++ return result; + } + + ETag +diff --git a/src/HttpHeader.h b/src/HttpHeader.h +index a26b127..3b262be 100644 +--- a/src/HttpHeader.h ++++ b/src/HttpHeader.h +@@ -134,7 +134,7 @@ public: + HttpHdrRange *getRange() const; + HttpHdrSc *getSc() const; + HttpHdrContRange *getContRange() const; +- const char *getAuth(Http::HdrType id, const char *auth_scheme) const; ++ SBuf getAuthToken(Http::HdrType id, const char *auth_scheme) const; + ETag getETag(Http::HdrType id) const; + TimeOrTag getTimeOrTag(Http::HdrType id) const; + int hasListMember(Http::HdrType id, const char *member, const char separator) const; +diff --git a/src/cache_manager.cc b/src/cache_manager.cc +index da22f7a..2fae767 100644 +--- a/src/cache_manager.cc ++++ b/src/cache_manager.cc +@@ -27,6 +27,7 @@ + #include "mgr/FunAction.h" + #include "mgr/QueryParams.h" + #include "protos.h" ++#include "sbuf/StringConvert.h" + #include "SquidConfig.h" + #include "SquidTime.h" + #include "Store.h" +@@ -243,20 +244,20 @@ CacheManager::ParseHeaders(const HttpRequest * request, Mgr::ActionParams ¶m + // TODO: use the authentication system decode to retrieve these details properly. + + /* base 64 _decoded_ user:passwd pair */ +- const char *basic_cookie = request->header.getAuth(Http::HdrType::AUTHORIZATION, "Basic"); ++ const auto basic_cookie(request->header.getAuthToken(Http::HdrType::AUTHORIZATION, "Basic")); + +- if (!basic_cookie) ++ if (basic_cookie.isEmpty()) + return; + +- const char *passwd_del; +- if (!(passwd_del = strchr(basic_cookie, ':'))) { ++ const auto colonPos = basic_cookie.find(':'); ++ if (colonPos == SBuf::npos) { + debugs(16, DBG_IMPORTANT, "CacheManager::ParseHeaders: unknown basic_cookie format '" << basic_cookie << "'"); + return; + } + + /* found user:password pair, reset old values */ +- params.userName.limitInit(basic_cookie, passwd_del - basic_cookie); +- params.password = passwd_del + 1; ++ params.userName = SBufToString(basic_cookie.substr(0, colonPos)); ++ params.password = SBufToString(basic_cookie.substr(colonPos+1)); + + /* warning: this prints decoded password which maybe not be what you want to do @?@ @?@ */ + debugs(16, 9, "CacheManager::ParseHeaders: got user: '" << +diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc +index b958b14..7ca5d24 100644 +--- a/src/clients/FtpGateway.cc ++++ b/src/clients/FtpGateway.cc +@@ -1050,7 +1050,7 @@ Ftp::Gateway::checkAuth(const HttpHeader * req_hdr) + + #if HAVE_AUTH_MODULE_BASIC + /* Check HTTP Authorization: headers (better than defaults, but less than URL) */ +- const SBuf auth(req_hdr->getAuth(Http::HdrType::AUTHORIZATION, "Basic")); ++ const auto auth(req_hdr->getAuthToken(Http::HdrType::AUTHORIZATION, "Basic")); + if (!auth.isEmpty()) { + flags.authenticated = 1; + loginParser(auth, false); diff --git a/SOURCES/squid-4.4.0-CVE-2019-13345.patch b/SOURCES/squid-4.4.0-CVE-2019-13345.patch new file mode 100644 index 0000000..9a5754e --- /dev/null +++ b/SOURCES/squid-4.4.0-CVE-2019-13345.patch @@ -0,0 +1,64 @@ +diff --git a/tools/cachemgr.cc b/tools/cachemgr.cc +index 0c745c2..8a67eba 100644 +--- a/tools/cachemgr.cc ++++ b/tools/cachemgr.cc +@@ -355,7 +355,7 @@ auth_html(const char *host, int port, const char *user_name) + + printf("Manager name:\n", user_name); ++ printf("size=\"30\" VALUE=\"%s\">\n", rfc1738_escape(user_name)); + + printf("Password:hostname, + req->port, +- safe_str(req->user_name), ++ rfc1738_escape(safe_str(req->user_name)), + action, + safe_str(req->pub_auth)); + return url; +@@ -1074,8 +1074,8 @@ make_pub_auth(cachemgr_request * req) + const int bufLen = snprintf(buf, sizeof(buf), "%s|%d|%s|%s", + req->hostname, + (int) now, +- req->user_name ? req->user_name : "", +- req->passwd); ++ rfc1738_escape(safe_str(req->user_name)), ++ rfc1738_escape(req->passwd)); + debug("cmgr: pre-encoded for pub: %s\n", buf); + + const int encodedLen = base64_encode_len(bufLen); +@@ -1094,8 +1094,6 @@ decode_pub_auth(cachemgr_request * req) + char *buf; + const char *host_name; + const char *time_str; +- const char *user_name; +- const char *passwd; + + debug("cmgr: decoding pub: '%s'\n", safe_str(req->pub_auth)); + safe_free(req->passwd); +@@ -1131,17 +1129,21 @@ decode_pub_auth(cachemgr_request * req) + + debug("cmgr: decoded time: '%s' (now: %d)\n", time_str, (int) now); + ++ char *user_name; + if ((user_name = strtok(NULL, "|")) == NULL) { + xfree(buf); + return; + } ++ rfc1738_unescape(user_name); + + debug("cmgr: decoded uname: '%s'\n", user_name); + ++ char *passwd; + if ((passwd = strtok(NULL, "|")) == NULL) { + xfree(buf); + return; + } ++ rfc1738_unescape(passwd); + + debug("cmgr: decoded passwd: '%s'\n", passwd); + diff --git a/SOURCES/squid-4.4.0-lower-cachepeer.patch b/SOURCES/squid-4.4.0-lower-cachepeer.patch new file mode 100644 index 0000000..42bc2aa --- /dev/null +++ b/SOURCES/squid-4.4.0-lower-cachepeer.patch @@ -0,0 +1,12 @@ +diff --git a/src/cache_cf.cc b/src/cache_cf.cc +index 9165ef99c..32a3df322 100644 +--- a/src/cache_cf.cc ++++ b/src/cache_cf.cc +@@ -2081,6 +2081,7 @@ parse_peer(CachePeer ** head) + + CachePeer *p = new CachePeer; + p->host = xstrdup(host_str); ++ Tolower(p->host); + p->name = xstrdup(host_str); + p->type = parseNeighborType(token); + diff --git a/SOURCES/squid.service b/SOURCES/squid.service index da1c0ea..f49d7db 100644 --- a/SOURCES/squid.service +++ b/SOURCES/squid.service @@ -1,6 +1,7 @@ [Unit] Description=Squid caching proxy -After=network.target nss-lookup.target +Documentation=man:squid(8) +After=network.target network-online.target nss-lookup.target [Service] Type=forking diff --git a/SPECS/squid.spec b/SPECS/squid.spec index 1696777..81f9470 100644 --- a/SPECS/squid.spec +++ b/SPECS/squid.spec @@ -2,7 +2,7 @@ Name: squid Version: 4.4 -Release: 4%{?dist} +Release: 8%{?dist} Summary: The Squid proxy caching server Epoch: 7 # See CREDITS for breakdown of non GPLv2+ code @@ -35,6 +35,14 @@ Patch205: squid-4.0.21-large-acl.patch Patch206: squid-4.4.0-active-ftp.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1612524 Patch207: squid-4.4.0-man-pages.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1691741 +Patch208: squid-4.4.0-lower-cachepeer.patch + +# Security fixes +# https://bugzilla.redhat.com/show_bug.cgi?id=1729436 +Patch500: squid-4.4.0-CVE-2019-13345.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1738485 +Patch501: squid-4.4.0-CVE-2019-12527.patch Requires: bash >= 2.0 Requires(pre): shadow-utils @@ -92,22 +100,23 @@ lookup program (dnsserver), a program for retrieving FTP data %patch205 -p1 -b .large_acl %patch206 -p1 -b .active-ftp %patch207 -p1 -b .man-pages +%patch208 -p1 -b .lower-cachepeer + +%patch500 -p1 -b .CVE-2019-13345 +%patch501 -p1 -b .CVE-2019-12527 + +# https://bugzilla.redhat.com/show_bug.cgi?id=1679526 +# Patch in the vendor documentation and used different location for documentation +sed -i 's|@SYSCONFDIR@/squid.conf.documented|%{_pkgdocdir}/squid.conf.documented|' src/squid.8.in %build # cppunit-config patch changes configure.ac autoconf -# libtool fails somewhat on -fpie. PIC also works for -pie -CXXFLAGS="$RPM_OPT_FLAGS -fPIC" -CFLAGS="$RPM_OPT_FLAGS -fPIC" -LDFLAGS="$RPM_LD_FLAGS -pie -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel" - # NIS helper has been removed because of the following bug # https://bugzilla.redhat.com/show_bug.cgi?id=1531540 %configure \ - --exec_prefix=%{_prefix} \ --libexecdir=%{_libdir}/squid \ - --localstatedir=%{_localstatedir} \ --datadir=%{_datadir}/squid \ --sysconfdir=%{_sysconfdir}/squid \ --with-logdir='%{_localstatedir}/log/squid' \ @@ -147,20 +156,17 @@ LDFLAGS="$RPM_LD_FLAGS -pie -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel" --with-openssl \ --with-pthreads \ --disable-arch-native \ - --with-pic \ - --disable-security-cert-validators + --disable-security-cert-validators \ + --with-swapdir=%{_localstatedir}/spool/squid -make \ - DEFAULT_SWAP_DIR=%{_localstatedir}/spool/squid \ - %{?_smp_mflags} +%make_build %check make check %install -make \ - DESTDIR=$RPM_BUILD_ROOT \ - install +%make_install + echo " # # This is %{_sysconfdir}/httpd/conf.d/squid.conf @@ -277,6 +283,25 @@ done exit 0 +%pretrans -p +-- Due to a bug #447156 +paths = {"/usr/share/squid/errors/zh-cn", "/usr/share/squid/errors/zh-tw"} +for key,path in ipairs(paths) +do + st = posix.stat(path) + if st and st.type == "directory" then + status = os.rename(path, path .. ".rpmmoved") + if not status then + suffix = 0 + while not status do + suffix = suffix + 1 + status = os.rename(path .. ".rpmmoved", path .. ".rpmmoved." .. suffix) + end + os.rename(path, path .. ".rpmmoved") + end + end +end + %post %systemd_post squid.service @@ -295,6 +320,23 @@ fi %changelog +* Fri Aug 23 2019 Lubos Uhliarik - 7:4.4-8 +- Resolves: # 1738485 - CVE-2019-12527 squid:4/squid: heap-based buffer overflow + in HttpHeader::getAuth + +* Wed Jul 31 2019 Lubos Uhliarik - 7:4.4-7 +- Resolves: #1729436 - CVE-2019-13345 squid: XSS via user_name or auth parameter + in cachemgr.cgi + +* Fri Jun 21 2019 Lubos Uhliarik - 7:4.4-6 +- Resolves: #1679526 - Missing detailed configuration file +- Resolves: #1703117 - RHEL 7 to 8 fails with squid installed because dirs + changed to symlinks +- Resolves: #1691741 - Squid cache_peer DNS lookup failed when not all lower + case +- Resolves: #1683527 - "Reloading" message on a fresh reboot after enabling + squid + * Tue Dec 11 2018 Lubos Uhliarik - 7:4.4-4 - Resolves: #1612524 - Man page scan results for squid