200 lines
7.0 KiB
Diff
200 lines
7.0 KiB
Diff
commit 5a9d42417ff63a20c5a7736323aef5117999d555
|
|
Author: Tomas Korbar <tkorbar@redhat.com>
|
|
Date: Tue Apr 7 16:22:05 2026 +0200
|
|
|
|
Fix CVE-2026-32748
|
|
|
|
diff --git a/src/ICP.h b/src/ICP.h
|
|
index a45455b..aa3ab57 100644
|
|
--- a/src/ICP.h
|
|
+++ b/src/ICP.h
|
|
@@ -104,10 +104,7 @@ extern Comm::ConnectionPointer icpOutgoingConn;
|
|
extern Ip::Address theIcpPublicHostID;
|
|
|
|
/// \ingroup ServerProtocolICPAPI
|
|
-HttpRequest* icpGetRequest(char *url, int reqnum, int fd, 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);
|
|
@@ -122,7 +119,7 @@ int icpUdpSend(int, const Ip::Address &, icp_common_t *, const LogTags &, int);
|
|
LogTags icpLogFromICPCode(icp_opcode opcode);
|
|
|
|
/// \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 eb63899..4f6a8fd 100644
|
|
--- a/src/icp_v2.cc
|
|
+++ b/src/icp_v2.cc
|
|
@@ -394,7 +394,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 << ".");
|
|
|
|
@@ -409,8 +409,9 @@ icpDenyAccess(Ip::Address &from, char *url, int reqnum, int fd)
|
|
}
|
|
}
|
|
|
|
-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)
|
|
@@ -431,8 +432,8 @@ icpGetUrlToSend(char *url)
|
|
return url;
|
|
}
|
|
|
|
-HttpRequest *
|
|
-icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from)
|
|
+HttpRequest::Pointer
|
|
+icpGetRequest(const char *url, int reqnum, int fd, const Ip::Address &from)
|
|
{
|
|
if (strpbrk(url, w_space)) {
|
|
icpCreateAndSend(ICP_ERR, 0, rfc1738_escape(url), reqnum, 0, fd, from);
|
|
@@ -440,12 +441,17 @@ icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from)
|
|
}
|
|
|
|
const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcp);
|
|
- auto *result = HttpRequest::FromUrlXXX(url, mx);
|
|
- if (!result)
|
|
- icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from);
|
|
-
|
|
- return result;
|
|
+ if (const HttpRequest::Pointer request = HttpRequest::FromUrlXXX(url, mx)) {
|
|
+ if (!icpAccessAllowed(from, request.getRaw())) {
|
|
+ icpDenyAccess(from, url, reqnum, fd);
|
|
+ return nullptr;
|
|
+ }
|
|
|
|
+ return request;
|
|
+ }
|
|
+
|
|
+ icpCreateAndSend(ICP_ERR, 0, url, reqnum, 0, fd, from);
|
|
+ return nullptr;
|
|
}
|
|
|
|
static void
|
|
@@ -456,18 +462,11 @@ doV2Query(int fd, Ip::Address &from, char *buf, icp_common_t header)
|
|
uint32_t flags = 0;
|
|
/* We have a valid packet */
|
|
char *url = buf + sizeof(icp_common_t) + sizeof(uint32_t);
|
|
- 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());
|
|
@@ -480,7 +479,7 @@ doV2Query(int fd, Ip::Address &from, char *buf, icp_common_t header)
|
|
#endif /* USE_ICMP */
|
|
|
|
/* The peer is allowed to use this cache */
|
|
- ICP2State *state = new ICP2State(header, icp_request);
|
|
+ ICP2State *state = new ICP2State(header, icp_request.getRaw());
|
|
state->fd = fd;
|
|
state->from = from;
|
|
state->url = xstrdup(url);
|
|
@@ -489,8 +488,6 @@ doV2Query(int fd, Ip::Address &from, char *buf, icp_common_t header)
|
|
state->src_rtt = src_rtt;
|
|
|
|
StoreEntry::getPublic(state, url, Http::METHOD_GET);
|
|
-
|
|
- HTTPMSGUNLOCK(icp_request);
|
|
}
|
|
|
|
void
|
|
diff --git a/src/icp_v3.cc b/src/icp_v3.cc
|
|
index 5dd6709..b48f7d8 100644
|
|
--- a/src/icp_v3.cc
|
|
+++ b/src/icp_v3.cc
|
|
@@ -36,19 +36,13 @@ doV3Query(int fd, Ip::Address &from, char *buf, icp_common_t header)
|
|
{
|
|
/* We have a valid packet */
|
|
char *url = buf + sizeof(icp_common_t) + sizeof(uint32_t);
|
|
- 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 = new ICP3State (header, icp_request);
|
|
+ ICP3State *state = new ICP3State (header, icp_request.getRaw());
|
|
state->fd = fd;
|
|
state->from = from;
|
|
state->url = xstrdup(url);
|
|
diff --git a/src/store_key_md5.h b/src/store_key_md5.h
|
|
index dffaad7..3e9bd42 100644
|
|
--- a/src/store_key_md5.h
|
|
+++ b/src/store_key_md5.h
|
|
@@ -12,11 +12,9 @@
|
|
#define SQUID_STORE_KEY_MD5_H_
|
|
|
|
#include "hash.h"
|
|
+#include "http/forward.h"
|
|
#include "store/forward.h"
|
|
|
|
-class HttpRequestMethod;
|
|
-class HttpRequest;
|
|
-
|
|
typedef enum {
|
|
ksDefault = 0,
|
|
ksRevalidation
|
|
diff --git a/src/tests/stub_icp.cc b/src/tests/stub_icp.cc
|
|
index 9c0f60f..4429ccb 100644
|
|
--- a/src/tests/stub_icp.cc
|
|
+++ b/src/tests/stub_icp.cc
|
|
@@ -8,6 +8,7 @@
|
|
|
|
#include "squid.h"
|
|
#include "comm/Connection.h"
|
|
+#include "HttpRequest.h"
|
|
#include "ICP.h"
|
|
|
|
#define STUB_API "icp_*.cc"
|
|
@@ -27,13 +28,12 @@ Comm::ConnectionPointer icpIncomingConn;
|
|
Comm::ConnectionPointer icpOutgoingConn;
|
|
Ip::Address theIcpPublicHostID;
|
|
|
|
-HttpRequest* icpGetRequest(char *url, int reqnum, int fd, Ip::Address &from) STUB_RETVAL(NULL)
|
|
-bool icpAccessAllowed(Ip::Address &from, HttpRequest * icp_request) STUB_RETVAL(false)
|
|
+HttpRequest::Pointer icpGetRequest(const char *, int, int, const Ip::Address &) STUB_RETVAL(nullptr)
|
|
void icpCreateAndSend(icp_opcode, int flags, char const *url, int reqnum, int pad, int fd, const Ip::Address &from) STUB
|
|
icp_opcode icpGetCommonOpcode() STUB_RETVAL(ICP_INVALID)
|
|
int icpUdpSend(int, const Ip::Address &, icp_common_t *, LogTags, int) STUB_RETVAL(0)
|
|
LogTags icpLogFromICPCode(icp_opcode opcode) STUB_RETVAL(LOG_TAG_NONE)
|
|
-void icpDenyAccess(Ip::Address &from, char *url, int reqnum, int fd) STUB
|
|
+void icpDenyAccess(const Ip::Address &, const char *, int, int) STUB
|
|
void icpHandleIcpV3(int, Ip::Address &, char *, int) STUB
|
|
int icpCheckUdpHit(StoreEntry *, HttpRequest * request) STUB_RETVAL(0)
|
|
void icpConnectionsOpen(void) STUB
|