From 4071b4c87b464069e3605798d3133a8545f4e5d4 Mon Sep 17 00:00:00 2001 From: pkgagent Date: Wed, 6 May 2026 13:47:21 +0800 Subject: [PATCH 1/5] fix CVE-2026-33515 --- squid-6.5-CVE-2026-33515.patch | 201 +++++++++++++++++++++++++++++++++ squid.spec | 1 + 2 files changed, 202 insertions(+) create mode 100644 squid-6.5-CVE-2026-33515.patch diff --git a/squid-6.5-CVE-2026-33515.patch b/squid-6.5-CVE-2026-33515.patch new file mode 100644 index 0000000..1fc733d --- /dev/null +++ b/squid-6.5-CVE-2026-33515.patch @@ -0,0 +1,201 @@ +From 8138e909d2058d4401e0ad49b583afaec912b165 Mon Sep 17 00:00:00 2001 +From: Joshua Rogers +Date: Thu, 12 Feb 2026 20:28:43 +0000 +Subject: [PATCH] ICP: Fix validation of packet sizes and URLs (#2220) + +Fix handling of malformed ICP queries and replies instead of passing +invalid URL pointer to consumers, leading to out-of-bounds memory reads +and other problems. These fixes affect both ICP v2 and ICP v3 traffic. + +* Reject packets with URLs that are not NUL-terminated. +* Reject packets with URLs containing embedded NULs or trailing garbage. + +The above two restrictions may backfire if popular ICP agents do send +such malformed URLs, and we will need to do more to handle them +correctly, but it is _safe_ to reject them for now. + +Also protect icpHandleUdp() from dereferencing a nil icpOutgoingConn +pointer. It is not clear whether icpHandleUdp() can be exposed to nil +icpOutgoingConn in current code. More work is needed to polish this. + +Adapted-by: PkgAgent (modified to adapt to opencloudos-stream) + +--- + src/ICP.h | 8 +++++-- + src/icp_v2.cc | 58 ++++++++++++++++++++++++++++++++++++++++++------- + src/icp_v3.cc | 10 ++++++-- + src/tests/stub_icp.cc | 5 +++- + 4 files changed, 66 insertions(+), 15 deletions(-) + +diff --git a/src/ICP.h b/src/ICP.h +index e74082d..2ee8df3 100644 +--- a/src/ICP.h ++++ b/src/ICP.h +@@ -89,8 +89,12 @@ extern Comm::ConnectionPointer icpIncomingConn; + extern Comm::ConnectionPointer icpOutgoingConn; + extern Ip::Address theIcpPublicHostID; + ++/// A URI extracted from the given raw packet buffer. ++/// On errors, details the problem and returns nil. ++const char *icpGetUrl(const Ip::Address &from, const char *, const icp_common_t &); ++ + /// \ingroup ServerProtocolICPAPI +-HttpRequest* icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from); ++HttpRequest *icpGetRequest(const char *url, int reqnum, int fd, const Ip::Address &from); + + /// \ingroup ServerProtocolICPAPI + bool icpAccessAllowed(Ip::Address &from, HttpRequest * icp_request); +@@ -102,7 +106,7 @@ void icpCreateAndSend(icp_opcode, int flags, char const *url, int reqnum, int pa + icp_opcode icpGetCommonOpcode(); + + /// \ingroup ServerProtocolICPAPI +-void icpDenyAccess(Ip::Address &from, char *url, int reqnum, int fd); ++void icpDenyAccess(const Ip::Address &from, const char *url, int reqnum, int fd); + + /// \ingroup ServerProtocolICPAPI + PF icpHandleUdp; +diff --git a/src/icp_v2.cc b/src/icp_v2.cc +index 6f7e7c8..8b9f9b7 100644 +--- a/src/icp_v2.cc ++++ b/src/icp_v2.cc +@@ -425,7 +425,7 @@ icpCreateAndSend(icp_opcode opcode, int flags, char const *url, int reqnum, int + } + + void +-icpDenyAccess(Ip::Address &from, char *url, int reqnum, int fd) ++icpDenyAccess(const Ip::Address &from, const char * const url, const int reqnum, const int fd) + { + debugs(12, 2, "icpDenyAccess: Access Denied for " << from << " by " << AclMatchedName << "."); + +@@ -453,11 +453,43 @@ icpAccessAllowed(Ip::Address &from, HttpRequest * icp_request) + return checklist.fastCheck().allowed(); + } + ++const char * ++icpGetUrl(const Ip::Address &from, const char * const buf, const icp_common_t &header) ++{ ++ const auto receivedPacketSize = static_cast(header.length); ++ const auto payloadOffset = sizeof(header); ++ ++ // Query payload contains a "Requester Host Address" followed by a URL. ++ // Payload of other ICP packets (with opcode that we recognize) is a URL. ++ const auto urlOffset = payloadOffset + ((header.opcode == ICP_QUERY) ? sizeof(uint32_t) : 0); ++ ++ // A URL field cannot be empty because it includes a terminating NUL char. ++ // Ensure that the packet has at least one URL field byte. ++ if (urlOffset >= receivedPacketSize) { ++ debugs(12, 3, "too small packet from " << from << ": " << urlOffset << " >= " << receivedPacketSize); ++ return nullptr; ++ } ++ ++ // All ICP packets (with opcode that we recognize) _end_ with a URL field. ++ // RFC 2186 requires all URLs to be "Null-Terminated". ++ if (buf[receivedPacketSize - 1] != '\0') { ++ debugs(12, 3, "unterminated URL or trailing garbage from " << from); ++ return nullptr; ++ } ++ ++ const auto url = buf + urlOffset; // a possibly empty c-string ++ if (urlOffset + strlen(url) + 1 != receivedPacketSize) { ++ debugs(12, 3, "URL with an embedded NUL or trailing garbage from " << from); ++ return nullptr; ++ } ++ ++ return url; ++} ++ + HttpRequest * +-icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from) ++icpGetRequest(const char * const url, const int reqnum, const int fd, const Ip::Address &from) + { + if (strpbrk(url, w_space)) { +- url = rfc1738_escape(url); + icpCreateAndSend(ICP_ERR, 0, rfc1738_escape(url), reqnum, 0, fd, from, nullptr); + return nullptr; + } +@@ -472,13 +504,18 @@ icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from) + } + + static void +-doV2Query(int fd, Ip::Address &from, char *buf, icp_common_t header) ++doV2Query(const int fd, Ip::Address &from, const char * const buf, icp_common_t header) + { + int rtt = 0; + int src_rtt = 0; + uint32_t flags = 0; +- /* We have a valid packet */ +- char *url = buf + sizeof(icp_common_t) + sizeof(uint32_t); ++ ++ const auto url = icpGetUrl(from, buf, header); ++ if (!url) { ++ icpCreateAndSend(ICP_ERR, 0, "", header.reqnum, 0, fd, from, nullptr); ++ return; ++ } ++ + HttpRequest *icp_request = icpGetRequest(url, header.reqnum, fd, from); + + if (!icp_request) +@@ -545,7 +582,9 @@ icp_common_t::handleReply(char *buf, Ip::Address &from) + neighbors_do_private_keys = 0; + } + +- char *url = buf + sizeof(icp_common_t); ++ const auto url = icpGetUrl(from, buf, *this); ++ if (!url) ++ return; + debugs(12, 3, "icpHandleIcpV2: " << icp_opcode_str[opcode] << " from " << from << " for '" << url << "'"); + + const cache_key *key = icpGetCacheKey(url, (int) reqnum); +@@ -680,7 +719,10 @@ icpHandleUdp(int sock, void *) + + icp_version = (int) buf[1]; /* cheat! */ + +- if (icpOutgoingConn->local == from) ++ // XXX: The IP equality comparison below ignores port differences but ++ // should not. It also fails to detect loops when `local` is a wildcard ++ // address (e.g., [::]:3130) because `from` address is never a wildcard. ++ if (icpOutgoingConn && icpOutgoingConn->local == from) + // ignore ICP packets which loop back (multicast usually) + debugs(12, 4, "icpHandleUdp: Ignoring UDP packet sent by myself"); + else if (icp_version == ICP_VERSION_2) +diff --git a/src/icp_v3.cc b/src/icp_v3.cc +index 290fdae..dc06457 100644 +--- a/src/icp_v3.cc ++++ b/src/icp_v3.cc +@@ -32,10 +32,14 @@ public: + + /// \ingroup ServerProtocolICPInternal3 + static void +-doV3Query(int fd, Ip::Address &from, char *buf, icp_common_t header) ++doV3Query(int fd, Ip::Address &from, const char * const buf, icp_common_t header) + { +- /* We have a valid packet */ +- char *url = buf + sizeof(icp_common_t) + sizeof(uint32_t); ++ const auto url = icpGetUrl(from, buf, header); ++ if (!url) { ++ icpCreateAndSend(ICP_ERR, 0, "", header.reqnum, 0, fd, from, nullptr); ++ return; ++ } ++ + HttpRequest *icp_request = icpGetRequest(url, header.reqnum, fd, from); + + if (!icp_request) +diff --git a/src/tests/stub_icp.cc b/src/tests/stub_icp.cc +index 95c523b..5ef0720 100644 +--- a/src/tests/stub_icp.cc ++++ b/src/tests/stub_icp.cc +@@ -29,11 +29,12 @@ Comm::ConnectionPointer icpIncomingConn; + Comm::ConnectionPointer icpOutgoingConn; + Ip::Address theIcpPublicHostID; + +-HttpRequest* icpGetRequest(char *, int, int, Ip::Address &) STUB_RETVAL(nullptr) ++const char *icpGetUrl(const Ip::Address &, const char *, const icp_common_t &) STUB_RETVAL(nullptr) ++HttpRequest* icpGetRequest(const char *, int, int, const Ip::Address &) STUB_RETVAL(nullptr) + bool icpAccessAllowed(Ip::Address &, HttpRequest *) STUB_RETVAL(false) + void icpCreateAndSend(icp_opcode, int, char const *, int, int, int, const Ip::Address &, AccessLogEntryPointer) STUB + icp_opcode icpGetCommonOpcode() STUB_RETVAL(ICP_INVALID) +-void icpDenyAccess(Ip::Address &, char *, int, int) STUB ++void icpDenyAccess(const Ip::Address &, const char *, int, int) STUB + void icpHandleIcpV3(int, Ip::Address &, char *, int) STUB + void icpConnectionShutdown(void) STUB + int icpSetCacheKey(const cache_key *) STUB_RETVAL(0) diff --git a/squid.spec b/squid.spec index 4e434e9..8f16784 100644 --- a/squid.spec +++ b/squid.spec @@ -25,6 +25,7 @@ Patch0003: SQUID-2024_1.patch Patch0004: fix-CVE-2024-37894.patch Patch0005: fix-CVE-2025-59362.patch Patch0006: fix-CVE-2025-62168.patch +Patch0007: squid-6.5-CVE-2026-33515.patch Patch3001: squid-4.0.11-config.patch Patch3002: squid-3.1.0.9-location.patch Patch3003: squid-6.1-perlpath.patch -- Gitee From 268fb1d4c1e1c5b5facdb82cacf340035098a342 Mon Sep 17 00:00:00 2001 From: pkgagent Date: Wed, 6 May 2026 14:02:29 +0800 Subject: [PATCH 2/5] fix CVE-2026-33526 --- squid-6.5-CVE-2026-33526.patch | 0 squid.spec | 1 + 2 files changed, 1 insertion(+) create mode 100644 squid-6.5-CVE-2026-33526.patch diff --git a/squid-6.5-CVE-2026-33526.patch b/squid-6.5-CVE-2026-33526.patch new file mode 100644 index 0000000..e69de29 diff --git a/squid.spec b/squid.spec index 8f16784..34457e8 100644 --- a/squid.spec +++ b/squid.spec @@ -26,6 +26,7 @@ Patch0004: fix-CVE-2024-37894.patch Patch0005: fix-CVE-2025-59362.patch Patch0006: fix-CVE-2025-62168.patch Patch0007: squid-6.5-CVE-2026-33515.patch +Patch0008: squid-6.5-CVE-2026-33526.patch Patch3001: squid-4.0.11-config.patch Patch3002: squid-3.1.0.9-location.patch Patch3003: squid-6.1-perlpath.patch -- Gitee From 03e091145452aa0148365ef6229f7b6e91039045 Mon Sep 17 00:00:00 2001 From: pkgagent Date: Wed, 6 May 2026 14:16:11 +0800 Subject: [PATCH 3/5] fix CVE-2026-32748 --- squid-6.5-CVE-2026-32748.patch | 181 +++++++++++++++++++++++++++++++++ squid.spec | 1 + 2 files changed, 182 insertions(+) create mode 100644 squid-6.5-CVE-2026-32748.patch diff --git a/squid-6.5-CVE-2026-32748.patch b/squid-6.5-CVE-2026-32748.patch new file mode 100644 index 0000000..4119d85 --- /dev/null +++ b/squid-6.5-CVE-2026-32748.patch @@ -0,0 +1,181 @@ +From 703e07d25ca6fa11f52d20bf0bb879e22ab7481b Mon Sep 17 00:00:00 2001 +From: Alex Rousskov +Date: Wed, 18 Feb 2026 21:13:26 +0000 +Subject: [PATCH] ICP: Fix HttpRequest lifetime for ICP v3 queries (#2377) + +ACLFilledChecklist correctly locks and unlocks HttpRequest. Thus, when +given an unlocked request object, an on-stack checklist destroys it. +Upon icpAccessAllowed() return, Squid uses the destroyed request object. + +This bug was probably introduced in 2003 commit 8000a965 that started +automatically unlocking requests in ACLChecklist destructor. However, +the bug did not affect allowed ICP v3 queries until 2007 commit f72fb56b +started _using_ the request object for them. 2005 commit 319bf5a7 fixed +an equivalent ICP v2 bug for denied queries but missed the ICP v3 case. + +The scope, age, and effect of this bug imply that Squid v3+ deployments +receive no ICP v3 queries since 2007 (or earlier). Squid itself does not +send ICP v3 messages, responding with ICP v2 replies to ICP v3 queries. +TODO: Consider dropping ICP v3 support. + +Also moved icpAccessAllowed() inside icpGetRequest() to deduplicate code +and reduce the risk of allowing a request without consulting icp_access. + +Adapted-by: PkgAgent (modified to adapt to opencloudos-stream) + +--- + src/ICP.h | 5 +---- + src/icp_v2.cc | 33 +++++++++++++++------------------ + src/icp_v3.cc | 10 ++-------- + src/tests/stub_icp.cc | 4 ++-- + 4 files changed, 20 insertions(+), 32 deletions(-) + +diff --git a/src/ICP.h b/src/ICP.h +index 2ee8df3..2483ea1 100644 +--- a/src/ICP.h ++++ b/src/ICP.h +@@ -94,10 +94,7 @@ extern Ip::Address theIcpPublicHostID; + const char *icpGetUrl(const Ip::Address &from, const char *, const icp_common_t &); + + /// \ingroup ServerProtocolICPAPI +-HttpRequest *icpGetRequest(const char *url, int reqnum, int fd, const Ip::Address &from); +- +-/// \ingroup ServerProtocolICPAPI +-bool icpAccessAllowed(Ip::Address &from, HttpRequest * icp_request); ++HttpRequestPointer icpGetRequest(const char *url, int reqnum, int fd, const Ip::Address &from); + + /// \ingroup ServerProtocolICPAPI + void icpCreateAndSend(icp_opcode, int flags, char const *url, int reqnum, int pad, int fd, const Ip::Address &from, AccessLogEntryPointer); +diff --git a/src/icp_v2.cc b/src/icp_v2.cc +index 8b9f9b7..16f3d49 100644 +--- a/src/icp_v2.cc ++++ b/src/icp_v2.cc +@@ -440,8 +440,9 @@ icpDenyAccess(const Ip::Address &from, const char * const url, const int reqnum, + } + } + +-bool +-icpAccessAllowed(Ip::Address &from, HttpRequest * icp_request) ++/// icpGetRequest() helper that determines whether squid.conf allows the given ICP query ++static bool ++icpAccessAllowed(const Ip::Address &from, HttpRequest * icp_request) + { + /* absent any explicit rules, we deny all */ + if (!Config.accessList.icp) +@@ -486,7 +487,7 @@ icpGetUrl(const Ip::Address &from, const char * const buf, const icp_common_t &h + return url; + } + +-HttpRequest * ++HttpRequest::Pointer + icpGetRequest(const char * const url, const int reqnum, const int fd, const Ip::Address &from) + { + if (strpbrk(url, w_space)) { +@@ -495,12 +496,17 @@ icpGetRequest(const char * const url, const int reqnum, const int fd, const Ip:: + } + + const auto mx = MasterXaction::MakePortless(); +- auto *result = HttpRequest::FromUrlXXX(url, mx); +- if (!result) +- icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr); ++ if (const HttpRequest::Pointer request = HttpRequest::FromUrlXXX(url, mx)) { ++ if (!icpAccessAllowed(from, request.getRaw())) { ++ icpDenyAccess(from, url, reqnum, fd); ++ return nullptr; ++ } + +- return result; ++ return request; ++ } + ++ icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from, nullptr); ++ return nullptr; + } + + static void +@@ -516,18 +522,11 @@ doV2Query(const int fd, Ip::Address &from, const char * const buf, icp_common_t + return; + } + +- HttpRequest *icp_request = icpGetRequest(url, header.reqnum, fd, from); ++ const auto icp_request = icpGetRequest(url, header.reqnum, fd, from); + + if (!icp_request) + return; + +- HTTPMSGLOCK(icp_request); +- +- if (!icpAccessAllowed(from, icp_request)) { +- icpDenyAccess(from, url, header.reqnum, fd); +- HTTPMSGUNLOCK(icp_request); +- return; +- } + #if USE_ICMP + if (header.flags & ICP_FLAG_SRC_RTT) { + rtt = netdbHostRtt(icp_request->url.host()); +@@ -540,7 +539,7 @@ doV2Query(const int fd, Ip::Address &from, const char * const buf, icp_common_t + #endif /* USE_ICMP */ + + /* The peer is allowed to use this cache */ +- ICP2State state(header, icp_request); ++ ICP2State state(header, icp_request.getRaw()); + state.fd = fd; + state.from = from; + state.url = xstrdup(url); +@@ -569,8 +568,6 @@ doV2Query(const int fd, Ip::Address &from, const char * const buf, icp_common_t + } + + icpCreateAndSend(codeToSend, flags, url, header.reqnum, src_rtt, fd, from, state.al); +- +- HTTPMSGUNLOCK(icp_request); + } + + void +diff --git a/src/icp_v3.cc b/src/icp_v3.cc +index dc06457..70bd5e7 100644 +--- a/src/icp_v3.cc ++++ b/src/icp_v3.cc +@@ -40,19 +40,13 @@ doV3Query(int fd, Ip::Address &from, const char * const buf, icp_common_t header + return; + } + +- HttpRequest *icp_request = icpGetRequest(url, header.reqnum, fd, from); ++ const auto icp_request = icpGetRequest(url, header.reqnum, fd, from); + + if (!icp_request) + return; + +- if (!icpAccessAllowed(from, icp_request)) { +- icpDenyAccess (from, url, header.reqnum, fd); +- delete icp_request; +- return; +- } +- + /* The peer is allowed to use this cache */ +- ICP3State state(header, icp_request); ++ ICP3State state(header, icp_request.getRaw()); + state.fd = fd; + state.from = from; + state.url = xstrdup(url); +diff --git a/src/tests/stub_icp.cc b/src/tests/stub_icp.cc +index 5ef0720..44e5a19 100644 +--- a/src/tests/stub_icp.cc ++++ b/src/tests/stub_icp.cc +@@ -9,6 +9,7 @@ + #include "squid.h" + #include "AccessLogEntry.h" + #include "comm/Connection.h" ++#include "HttpRequest.h" + #include "ICP.h" + + #define STUB_API "icp_*.cc" +@@ -30,8 +31,7 @@ Comm::ConnectionPointer icpOutgoingConn; + Ip::Address theIcpPublicHostID; + + const char *icpGetUrl(const Ip::Address &, const char *, const icp_common_t &) STUB_RETVAL(nullptr) +-HttpRequest* icpGetRequest(const char *, int, int, const Ip::Address &) STUB_RETVAL(nullptr) +-bool icpAccessAllowed(Ip::Address &, HttpRequest *) STUB_RETVAL(false) ++HttpRequest::Pointer icpGetRequest(const char *, int, int, const Ip::Address &) STUB_RETVAL(nullptr) + void icpCreateAndSend(icp_opcode, int, char const *, int, int, int, const Ip::Address &, AccessLogEntryPointer) STUB + icp_opcode icpGetCommonOpcode() STUB_RETVAL(ICP_INVALID) + void icpDenyAccess(const Ip::Address &, const char *, int, int) STUB diff --git a/squid.spec b/squid.spec index 34457e8..855ab64 100644 --- a/squid.spec +++ b/squid.spec @@ -27,6 +27,7 @@ Patch0005: fix-CVE-2025-59362.patch Patch0006: fix-CVE-2025-62168.patch Patch0007: squid-6.5-CVE-2026-33515.patch Patch0008: squid-6.5-CVE-2026-33526.patch +Patch0009: squid-6.5-CVE-2026-32748.patch Patch3001: squid-4.0.11-config.patch Patch3002: squid-3.1.0.9-location.patch Patch3003: squid-6.1-perlpath.patch -- Gitee From f1016f5ee6d0eb0c68283b71db178206a6056dc0 Mon Sep 17 00:00:00 2001 From: pkgagent Date: Wed, 6 May 2026 14:16:14 +0800 Subject: [PATCH 4/5] fix CVE-2026-33515, CVE-2026-33526, CVE-2026-32748 --- squid.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/squid.spec b/squid.spec index 855ab64..03464da 100644 --- a/squid.spec +++ b/squid.spec @@ -4,7 +4,7 @@ Summary: The Squid proxy caching server Name: squid Version: 6.5 -Release: 10%{?dist} +Release: 11%{?dist} License: GPLv2+ and (LGPLv2+ and MIT and BSD and Public Domain) URL: http://www.squid-cache.org Source0: http://www.squid-cache.org/Versions/v%{maj_ver}/%{name}-%{version}.tar.xz @@ -267,6 +267,10 @@ fi %changelog +* Wed May 06 2026 PkgAgent Robot - 6.5-11 +- [Type] security +- [DESC] Fix CVE-2026-33515, CVE-2026-33526, CVE-2026-32748 + * Mon Oct 20 2025 zidonghunag - 6.5-10 - [Type] security - [DESC] fix CVE-2025-62168 -- Gitee From 9e4387e47cd27cd6151833d1f36a368290f35994 Mon Sep 17 00:00:00 2001 From: pkgagent Date: Thu, 7 May 2026 17:14:43 +0800 Subject: [PATCH 5/5] fix CVE-2026-33515, CVE-2026-33526, CVE-2026-32748 --- squid.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/squid.spec b/squid.spec index 03464da..5092427 100644 --- a/squid.spec +++ b/squid.spec @@ -4,7 +4,7 @@ Summary: The Squid proxy caching server Name: squid Version: 6.5 -Release: 11%{?dist} +Release: 12%{?dist} License: GPLv2+ and (LGPLv2+ and MIT and BSD and Public Domain) URL: http://www.squid-cache.org Source0: http://www.squid-cache.org/Versions/v%{maj_ver}/%{name}-%{version}.tar.xz @@ -267,6 +267,10 @@ fi %changelog +* Thu May 07 2026 PkgAgent Robot - 6.5-12 +- [Type] security +- [DESC] Fix CVE-2026-33515, CVE-2026-33526, CVE-2026-32748 + * Wed May 06 2026 PkgAgent Robot - 6.5-11 - [Type] security - [DESC] Fix CVE-2026-33515, CVE-2026-33526, CVE-2026-32748 -- Gitee