mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-11-12 15:31:03 +00:00
squid: patch CVE-2026-32748
Pick SQUID-2026:2 patch per [1]. [1] https://github.com/squid-cache/squid/security/advisories/GHSA-f9p7-3jqg-hhvq Signed-off-by: Peter Marko <peter.marko@siemens.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
1 parent
d657b86f28
commit
9c598b5eff
2 files changed
+183
No files matched your search
@@ -0,0 +1,182 @@
|
||||
From 703e07d25ca6fa11f52d20bf0bb879e22ab7481b Mon Sep 17 00:00:00 2001
|
||||
From: Alex Rousskov <rousskov@measurement-factory.com>
|
||||
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.
|
||||
|
||||
CVE: CVE-2026-32748
|
||||
Upstream-Status: Backport [https://github.com/squid-cache/squid/commit/703e07d25ca6fa11f52d20bf0bb879e22ab7481b]
|
||||
Signed-off-by: Peter Marko <peter.marko@siemens.com>
|
||||
---
|
||||
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 e9ad8d0ce..a042d2d74 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 312104024..33baf9787 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<XactionInitiator::initIcp>();
|
||||
- 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 844768aa0..3864b0b74 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 d148ab66d..4c9037495 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
|
||||
@@ -24,6 +24,7 @@ SRC_URI = "https://github.com/squid-cache/${BPN}/releases/download/SQUID_${PV_U}
|
||||
file://CVE-2025-62168.patch \
|
||||
file://CVE-2026-33526.patch \
|
||||
file://CVE-2026-33515.patch \
|
||||
file://CVE-2026-32748.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "9eafe06f58a199b918e79d33d8aa03afb9ae0c11d18974dca0b44c2669cab6dd"
|
||||
|
||||
Reference in new issue
Block a user