fix CVE-2023-5824 CVE-2023-46846 CVE-2023-46847 CVE-2023-46848

This commit is contained in:
yangl777 2023-10-31 16:16:03 +08:00
parent 47b90c54eb
commit f242cc483a
6 changed files with 3653 additions and 1 deletions

View File

@ -0,0 +1,122 @@
From 5921355e474ffbff2cb577c3622ce0e686e8996a Mon Sep 17 00:00:00 2001
From: Alex Rousskov <rousskov@measurement-factory.com>
Date: Sat, 11 Mar 2023 05:48:14 +0000
Subject: [PATCH] Replaced clientReplyContext::tempBuffer with old_reqofs
(#1304)
The tempBuffer data member was not actually used as a buffer. We only
used its offset field, and only for saving reqofs (which has a different
type than tempBuffer.offset!). Replaced the buffer with old_reqofs,
consistent with the rest of the "saved stale entry state" code.
Also fixed old_reqsize type to match reqsize and grouped that member
with the other private "saved stale entry state" fields.
Bad old types probably did not trigger runtime failures because the
associated saved numbers are saved at the very beginning of fetching the
entry, when all these accumulation-related counters are still small.
The remaining reqofs and reqsize types are wrong for platforms where
size_t is not uint64_t, but fixing that deserves a dedicated change. For
now, we just made the types of "old_" and "current" members consistent.
Reference:https://github.com/squid-cache/squid/commit/5921355e474ffbff2cb577c3622ce0e686e8996a
Conflict:NA
---
src/client_side_reply.cc | 12 ++++++------
src/client_side_reply.h | 6 +++---
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc
index 0004137cbc9..606a3ecafff 100644
--- a/src/client_side_reply.cc
+++ b/src/client_side_reply.cc
@@ -66,7 +66,6 @@ clientReplyContext::~clientReplyContext()
/* old_entry might still be set if we didn't yet get the reply
* code in HandleIMSReply() */
removeStoreReference(&old_sc, &old_entry);
- safe_free(tempBuffer.data);
cbdataReferenceDone(http);
HTTPMSGUNLOCK(reply);
}
@@ -76,7 +75,6 @@ clientReplyContext::clientReplyContext(ClientHttpRequest *clientContext) :
http(cbdataReference(clientContext)),
headers_sz(0),
sc(nullptr),
- old_reqsize(0),
reqsize(0),
reqofs(0),
ourNode(nullptr),
@@ -84,6 +82,8 @@ clientReplyContext::clientReplyContext(ClientHttpRequest *clientContext) :
old_entry(nullptr),
old_sc(nullptr),
old_lastmod(-1),
+ old_reqofs(0),
+ old_reqsize(0),
deleting(false),
collapsedRevalidation(crNone)
{
@@ -202,7 +202,7 @@ clientReplyContext::saveState()
old_lastmod = http->request->lastmod;
old_etag = http->request->etag;
old_reqsize = reqsize;
- tempBuffer.offset = reqofs;
+ old_reqofs = reqofs;
/* Prevent accessing the now saved entries */
http->storeEntry(nullptr);
sc = nullptr;
@@ -219,7 +219,7 @@ clientReplyContext::restoreState()
http->storeEntry(old_entry);
sc = old_sc;
reqsize = old_reqsize;
- reqofs = tempBuffer.offset;
+ reqofs = old_reqofs;
http->request->lastmod = old_lastmod;
http->request->etag = old_etag;
/* Prevent accessed the old saved entries */
@@ -228,7 +228,7 @@ clientReplyContext::restoreState()
old_lastmod = -1;
old_etag.clean();
old_reqsize = 0;
- tempBuffer.offset = 0;
+ old_reqofs = 0;
}
void
@@ -377,7 +377,7 @@ clientReplyContext::sendClientUpstreamResponse()
http->storeEntry()->clearPublicKeyScope();
/* here the data to send is the data we just received */
- tempBuffer.offset = 0;
+ old_reqofs = 0;
old_reqsize = 0;
/* sendMoreData tracks the offset as well.
* Force it back to zero */
diff --git a/src/client_side_reply.h b/src/client_side_reply.h
index 68b45715b33..32a38bc95e1 100644
--- a/src/client_side_reply.h
+++ b/src/client_side_reply.h
@@ -74,8 +74,6 @@ class clientReplyContext : public RefCountable, public StoreClient
/// Not to be confused with ClientHttpRequest::Out::headers_sz.
int headers_sz;
store_client *sc; /* The store_client we're using */
- StoreIOBuffer tempBuffer; /* For use in validating requests via IMS */
- int old_reqsize; /* ... again, for the buffer */
size_t reqsize;
size_t reqofs;
char tempbuf[HTTP_REQBUF_SZ]; ///< a temporary buffer if we need working storage
@@ -135,11 +133,13 @@ class clientReplyContext : public RefCountable, public StoreClient
/// TODO: Exclude internal Store match bans from the "mismatch" category.
const char *firstStoreLookup_ = nullptr;
+ /* (stale) cache hit information preserved during IMS revalidation */
StoreEntry *old_entry;
- /* ... for entry to be validated */
store_client *old_sc;
time_t old_lastmod;
String old_etag;
+ size_t old_reqofs;
+ size_t old_reqsize;
bool deleting;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,180 @@
From 6cfa10d94ca15a764a1d975597d8024582ef19be Mon Sep 17 00:00:00 2001
From: Amos Jeffries <yadij@users.noreply.github.com>
Date: Fri, 13 Oct 2023 08:44:16 +0000
Subject: [PATCH] RFC 9112: Improve HTTP chunked encoding compliance (#1498)
Reference:http://www.squid-cache.org/Versions/v6/SQUID-2023_1.patch
Conflict:NA
---
src/http/one/Parser.cc | 8 +-------
src/http/one/Parser.h | 4 +---
src/http/one/TeChunkedParser.cc | 23 ++++++++++++++++++-----
src/parser/Tokenizer.cc | 12 ++++++++++++
src/parser/Tokenizer.h | 7 +++++++
5 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/src/http/one/Parser.cc b/src/http/one/Parser.cc
index 964371b4e..b1908316a 100644
--- a/src/http/one/Parser.cc
+++ b/src/http/one/Parser.cc
@@ -65,16 +65,10 @@ Http::One::Parser::DelimiterCharacters()
void
Http::One::Parser::skipLineTerminator(Tokenizer &tok) const
{
- if (tok.skip(Http1::CrLf()))
- return;
-
if (Config.onoff.relaxed_header_parser && tok.skipOne(CharacterSet::LF))
return;
- if (tok.atEnd() || (tok.remaining().length() == 1 && tok.remaining().at(0) == '\r'))
- throw InsufficientInput();
-
- throw TexcHere("garbage instead of CRLF line terminator");
+ tok.skipRequired("line-terminating CRLF", Http1::CrLf());
}
/// all characters except the LF line terminator
diff --git a/src/http/one/Parser.h b/src/http/one/Parser.h
index 5892a7a59..503c61d3f 100644
--- a/src/http/one/Parser.h
+++ b/src/http/one/Parser.h
@@ -124,9 +124,7 @@ protected:
* detect and skip the CRLF or (if tolerant) LF line terminator
* consume from the tokenizer.
*
- * \throws exception on bad or InsuffientInput.
- * \retval true only if line terminator found.
- * \retval false incomplete or missing line terminator, need more data.
+ * \throws exception on bad or InsufficientInput
*/
void skipLineTerminator(Tokenizer &) const;
diff --git a/src/http/one/TeChunkedParser.cc b/src/http/one/TeChunkedParser.cc
index d9138fe9a..9cce10fdc 100644
--- a/src/http/one/TeChunkedParser.cc
+++ b/src/http/one/TeChunkedParser.cc
@@ -91,6 +91,11 @@ Http::One::TeChunkedParser::parseChunkSize(Tokenizer &tok)
{
Must(theChunkSize <= 0); // Should(), really
+ static const SBuf bannedHexPrefixLower("0x");
+ static const SBuf bannedHexPrefixUpper("0X");
+ if (tok.skip(bannedHexPrefixLower) || tok.skip(bannedHexPrefixUpper))
+ throw TextException("chunk starts with 0x", Here());
+
int64_t size = -1;
if (tok.int64(size, 16, false) && !tok.atEnd()) {
if (size < 0)
@@ -121,7 +126,7 @@ Http::One::TeChunkedParser::parseChunkMetadataSuffix(Tokenizer &tok)
// bad or insufficient input, like in the code below. TODO: Expand up.
try {
parseChunkExtensions(tok); // a possibly empty chunk-ext list
- skipLineTerminator(tok);
+ tok.skipRequired("CRLF after [chunk-ext]", Http1::CrLf());
buf_ = tok.remaining();
parsingStage_ = theChunkSize ? Http1::HTTP_PARSE_CHUNK : Http1::HTTP_PARSE_MIME;
return true;
@@ -132,12 +137,14 @@ Http::One::TeChunkedParser::parseChunkMetadataSuffix(Tokenizer &tok)
// other exceptions bubble up to kill message parsing
}
-/// Parses the chunk-ext list (RFC 7230 section 4.1.1 and its Errata #4667):
+/// Parses the chunk-ext list (RFC 9112 section 7.1.1:
/// chunk-ext = *( BWS ";" BWS chunk-ext-name [ BWS "=" BWS chunk-ext-val ] )
void
-Http::One::TeChunkedParser::parseChunkExtensions(Tokenizer &tok)
+Http::One::TeChunkedParser::parseChunkExtensions(Tokenizer &callerTok)
{
do {
+ auto tok = callerTok;
+
ParseBws(tok); // Bug 4492: IBM_HTTP_Server sends SP after chunk-size
if (!tok.skip(';'))
@@ -145,6 +152,7 @@ Http::One::TeChunkedParser::parseChunkExtensions(Tokenizer &tok)
parseOneChunkExtension(tok);
buf_ = tok.remaining(); // got one extension
+ callerTok = tok;
} while (true);
}
@@ -158,11 +166,14 @@ Http::One::ChunkExtensionValueParser::Ignore(Tokenizer &tok, const SBuf &extName
/// Parses a single chunk-ext list element:
/// chunk-ext = *( BWS ";" BWS chunk-ext-name [ BWS "=" BWS chunk-ext-val ] )
void
-Http::One::TeChunkedParser::parseOneChunkExtension(Tokenizer &tok)
+Http::One::TeChunkedParser::parseOneChunkExtension(Tokenizer &callerTok)
{
+ auto tok = callerTok;
+
ParseBws(tok); // Bug 4492: ICAP servers send SP before chunk-ext-name
const auto extName = tok.prefix("chunk-ext-name", CharacterSet::TCHAR);
+ callerTok = tok; // in case we determine that this is a valueless chunk-ext
ParseBws(tok);
@@ -176,6 +187,8 @@ Http::One::TeChunkedParser::parseOneChunkExtension(Tokenizer &tok)
customExtensionValueParser->parse(tok, extName);
else
ChunkExtensionValueParser::Ignore(tok, extName);
+
+ callerTok = tok;
}
bool
@@ -209,7 +222,7 @@ Http::One::TeChunkedParser::parseChunkEnd(Tokenizer &tok)
Must(theLeftBodySize == 0); // Should(), really
try {
- skipLineTerminator(tok);
+ tok.skipRequired("chunk CRLF", Http1::CrLf());
buf_ = tok.remaining(); // parse checkpoint
theChunkSize = 0; // done with the current chunk
parsingStage_ = Http1::HTTP_PARSE_CHUNK_SZ;
diff --git a/src/parser/Tokenizer.cc b/src/parser/Tokenizer.cc
index 2bac7fb1f..2843a44af 100644
--- a/src/parser/Tokenizer.cc
+++ b/src/parser/Tokenizer.cc
@@ -147,6 +147,18 @@ Parser::Tokenizer::skipAll(const CharacterSet &tokenChars)
return success(prefixLen);
}
+void
+Parser::Tokenizer::skipRequired(const char *description, const SBuf &tokenToSkip)
+{
+ if (skip(tokenToSkip) || tokenToSkip.isEmpty())
+ return;
+
+ if (tokenToSkip.startsWith(buf_))
+ throw InsufficientInput();
+
+ throw TextException(ToSBuf("cannot skip ", description), Here());
+}
+
bool
Parser::Tokenizer::skipOne(const CharacterSet &chars)
{
diff --git a/src/parser/Tokenizer.h b/src/parser/Tokenizer.h
index 7bae1ccbb..3cfa7dd6c 100644
--- a/src/parser/Tokenizer.h
+++ b/src/parser/Tokenizer.h
@@ -115,6 +115,13 @@ public:
*/
SBuf::size_type skipAll(const CharacterSet &discardables);
+ /** skips a given character sequence (string);
+ * does nothing if the sequence is empty
+ *
+ * \throws exception on mismatching prefix or InsufficientInput
+ */
+ void skipRequired(const char *description, const SBuf &tokenToSkip);
+
/** Removes a single trailing character from the set.
*
* \return whether a character was removed
--
2.25.1

View File

@ -0,0 +1,42 @@
From dc0e10bec3334053c1a5297e50dd7052ea18aef0 Mon Sep 17 00:00:00 2001
From: Alex Bason <nonsleepr@gmail.com>
Date: Sun, 15 Oct 2023 13:04:47 +0000
Subject: [PATCH] Fix stack buffer overflow when parsing Digest Authorization
(#1517)
The bug was discovered and detailed by Joshua Rogers at
https://megamansec.github.io/Squid-Security-Audit/digest-overflow.html
where it was filed as "Stack Buffer Overflow in Digest Authentication".
Reference:http://www.squid-cache.org/Versions/v6/SQUID-2023_3.patch
Conflict:NA
---
src/auth/digest/Config.cc | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/auth/digest/Config.cc b/src/auth/digest/Config.cc
index f00e2ba68..3c070d242 100644
--- a/src/auth/digest/Config.cc
+++ b/src/auth/digest/Config.cc
@@ -827,11 +827,15 @@ Auth::Digest::Config::decode(char const *proxy_auth, const HttpRequest *request,
break;
case DIGEST_NC:
- if (value.size() != 8) {
+ if (value.size() == 8) {
+ // for historical reasons, the nc value MUST be exactly 8 bytes
+ static_assert(sizeof(digest_request->nc) == 8 + 1);
+ xstrncpy(digest_request->nc, value.rawBuf(), value.size() + 1);
+ debugs(29, 9, "Found noncecount '" << digest_request->nc << "'");
+ } else {
debugs(29, 9, "Invalid nc '" << value << "' in '" << temp << "'");
+ digest_request->nc[0] = 0;
}
- xstrncpy(digest_request->nc, value.rawBuf(), value.size() + 1);
- debugs(29, 9, "Found noncecount '" << digest_request->nc << "'");
break;
case DIGEST_CNONCE:
--
2.25.1

View File

@ -0,0 +1,49 @@
From 7de01969a793b2fdb476e354a9fcda272d400d27 Mon Sep 17 00:00:00 2001
From: Alex Rousskov <rousskov@measurement-factory.com>
Date: Thu, 25 May 2023 02:10:28 +0000
Subject: [PATCH] Fix userinfo percent-encoding (#1367)
%X expects an unsigned int, and that is what we were giving it. However,
to get to the correct unsigned int value from a (signed) char, one has
to cast to an unsigned char (or equivalent) first.
Broken since inception in commit 7b75100.
Also adjusted similar (commented out) ext_edirectory_userip_acl code.
Reference:http://www.squid-cache.org/Versions/v6/SQUID-2023_5.patch
Conflict:NA
---
src/acl/external/eDirectory_userip/ext_edirectory_userip_acl.cc | 2 +-
src/anyp/Uri.cc | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/acl/external/eDirectory_userip/ext_edirectory_userip_acl.cc b/src/acl/external/eDirectory_userip/ext_edirectory_userip_acl.cc
index bf124d24f..e3f33e209 100644
--- a/src/acl/external/eDirectory_userip/ext_edirectory_userip_acl.cc
+++ b/src/acl/external/eDirectory_userip/ext_edirectory_userip_acl.cc
@@ -1555,7 +1555,7 @@ MainSafe(int argc, char **argv)
/* BINARY DEBUGGING *
local_printfx("while() -> bufa[%" PRIuSIZE "]: %s", k, bufa);
for (i = 0; i < k; ++i)
- local_printfx("%02X", bufa[i]);
+ local_printfx("%02X", static_cast<unsigned int>(static_cast<unsigned char>(bufa[i])));
local_printfx("\n");
* BINARY DEBUGGING */
/* Check for CRLF */
diff --git a/src/anyp/Uri.cc b/src/anyp/Uri.cc
index e37293996..eca2c2357 100644
--- a/src/anyp/Uri.cc
+++ b/src/anyp/Uri.cc
@@ -71,7 +71,7 @@ AnyP::Uri::Encode(const SBuf &buf, const CharacterSet &ignore)
while (!tk.atEnd()) {
// TODO: Add Tokenizer::parseOne(void).
const auto ch = tk.remaining()[0];
- output.appendf("%%%02X", static_cast<unsigned int>(ch)); // TODO: Optimize using a table
+ output.appendf("%%%02X", static_cast<unsigned int>(static_cast<unsigned char>(ch))); // TODO: Optimize using a table
(void)tk.skip(ch);
if (tk.prefix(goodSection, ignore))
--
2.25.1

View File

@ -2,7 +2,7 @@
Name: squid Name: squid
Version: 6.1 Version: 6.1
Release: 1 Release: 2
Summary: The Squid proxy caching server Summary: The Squid proxy caching server
Epoch: 7 Epoch: 7
License: GPLv2+ and (LGPLv2+ and MIT and BSD and Public Domain) License: GPLv2+ and (LGPLv2+ and MIT and BSD and Public Domain)
@ -21,6 +21,11 @@ Patch0: squid-4.0.11-config.patch
Patch1: squid-3.1.0.9-location.patch Patch1: squid-3.1.0.9-location.patch
Patch2: squid-3.0.STABLE1-perlpath.patch Patch2: squid-3.0.STABLE1-perlpath.patch
Patch3: backport-squid-6.1-symlink-lang-err.patch Patch3: backport-squid-6.1-symlink-lang-err.patch
Patch4: backport-0001-CVE-2023-5824.patch
Patch5: backport-0002-CVE-2023-5824.patch
Patch6: backport-CVE-2023-46846.patch
Patch7: backport-CVE-2023-46847.patch
Patch8: backport-CVE-2023-46848.patch
Requires: bash Requires: bash
Requires: httpd-filesystem Requires: httpd-filesystem
@ -43,6 +48,7 @@ non-blocking, I/O-driven process and keeps meta data and implements negative cac
sed -i 's|@SYSCONFDIR@/squid.conf.documented|%{_pkgdocdir}/squid.conf.documented|' src/squid.8.in sed -i 's|@SYSCONFDIR@/squid.conf.documented|%{_pkgdocdir}/squid.conf.documented|' src/squid.8.in
%build %build
autoreconf -fi
%configure \ %configure \
--libexecdir=%{_libdir}/squid --datadir=%{_datadir}/squid \ --libexecdir=%{_libdir}/squid --datadir=%{_datadir}/squid \
--sysconfdir=%{_sysconfdir}/squid --with-logdir='%{_localstatedir}/log/squid' \ --sysconfdir=%{_sysconfdir}/squid --with-logdir='%{_localstatedir}/log/squid' \
@ -242,6 +248,12 @@ fi
chgrp squid /var/cache/samba/winbindd_privileged >/dev/null 2>&1 || : chgrp squid /var/cache/samba/winbindd_privileged >/dev/null 2>&1 || :
%changelog %changelog
* Tue Oct 31 2023 yanglu <yanglu72@h-partners.com> - 7:6.1-2
- Type:cves
- ID:CVE-2023-5824 CVE-2023-46846 CVE-2023-46847 CVE-2023-46848
- SUG:NA
- DESC:fix CVE-2023-5824 CVE-2023-46846 CVE-2023-46847 CVE-2023-46848
* Tue Jul 25 2023 xinghe <xinghe2@h-partners.com> - 7:6.1-1 * Tue Jul 25 2023 xinghe <xinghe2@h-partners.com> - 7:6.1-1
- Type:requirements - Type:requirements
- ID:NA - ID:NA