From 5df95b5923de244eaf2ddccf980d5f28d7114b1f Mon Sep 17 00:00:00 2001 From: Alex Burmashev Date: Thu, 7 Dec 2023 18:01:47 +0000 Subject: [PATCH 5/7] Backport Add Assure() as a replacement for problematic Must() This is a partial backport of b9a1bbfbc531359a87647271a282edff9ccdd206 b8ae064d94784934b3402e5db015246d1b1ca658 Needed for CVE CVE-2023-5824 fix Signed-off-by: Alex Burmashev --- src/HttpReply.cc | 1 + src/acl/Asn.cc | 1 + src/base/Assure.cc | 23 ++++++++++++++++++ src/base/Assure.h | 51 ++++++++++++++++++++++++++++++++++++++++ src/base/Makefile.am | 2 ++ src/base/Makefile.in | 8 +++++-- src/client_side_reply.cc | 1 + 7 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 src/base/Assure.cc create mode 100644 src/base/Assure.h diff --git a/src/HttpReply.cc b/src/HttpReply.cc index af2bd4d..df5bcef 100644 --- a/src/HttpReply.cc +++ b/src/HttpReply.cc @@ -10,6 +10,7 @@ #include "squid.h" #include "acl/AclSizeLimit.h" +#include "base/Assure.h" #include "acl/FilledChecklist.h" #include "base/EnumIterator.h" #include "globals.h" diff --git a/src/acl/Asn.cc b/src/acl/Asn.cc index ad450c0..bcedc82 100644 --- a/src/acl/Asn.cc +++ b/src/acl/Asn.cc @@ -17,6 +17,7 @@ #include "acl/SourceAsn.h" #include "acl/Strategised.h" #include "base/CharacterSet.h" +#include "base/Assure.h" #include "FwdState.h" #include "HttpReply.h" #include "HttpRequest.h" diff --git a/src/base/Assure.cc b/src/base/Assure.cc new file mode 100644 index 0000000..b09b848 --- /dev/null +++ b/src/base/Assure.cc @@ -0,0 +1,23 @@ +/* + * Copyright (C) 1996-2023 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#include "squid.h" +#include "base/Assure.h" +#include "base/TextException.h" +#include "sbuf/Stream.h" + +[[ noreturn ]] void +ReportAndThrow_(const int debugLevel, const char *description, const SourceLocation &location) +{ + const TextException ex(description, location); + const auto label = debugLevel <= DBG_IMPORTANT ? "ERROR: Squid BUG: " : ""; + // TODO: Consider also printing the number of BUGs reported so far. It would + // require GC, but we could even print the number of same-location reports. + debugs(0, debugLevel, label << ex); + throw ex; +} diff --git a/src/base/Assure.h b/src/base/Assure.h new file mode 100644 index 0000000..650c204 --- /dev/null +++ b/src/base/Assure.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 1996-2023 The Squid Software Foundation and contributors + * + * Squid software is distributed under GPLv2+ license and includes + * contributions from numerous individuals and organizations. + * Please see the COPYING and CONTRIBUTORS files for details. + */ + +#ifndef SQUID_SRC_BASE_ASSURE_H +#define SQUID_SRC_BASE_ASSURE_H + +#include "base/Here.h" + +/// Reports the description (at the given debugging level) and throws +/// the corresponding exception. Reduces compiled code size of Assure() and +/// Must() callers. Do not call directly; use Assure() instead. +/// \param description explains the condition (i.e. what MUST happen) +[[ noreturn ]] void ReportAndThrow_(int debugLevel, const char *description, const SourceLocation &); + +/// Calls ReportAndThrow() if needed. Reduces caller code duplication. +/// Do not call directly; use Assure() instead. +/// \param description c-string explaining the condition (i.e. what MUST happen) +#define Assure_(debugLevel, condition, description, location) \ + while (!(condition)) \ + ReportAndThrow_((debugLevel), (description), (location)) + +#if !defined(NDEBUG) + +/// Like assert() but throws an exception instead of aborting the process. Use +/// this macro to detect code logic mistakes (i.e. bugs) where aborting the +/// current AsyncJob or a similar task is unlikely to jeopardize Squid service +/// integrity. For example, this macro is _not_ appropriate for detecting bugs +/// that indicate a dangerous global state corruption which may go unnoticed by +/// other jobs after the current job or task is aborted. +#define Assure(condition) \ + Assure2((condition), #condition) + +/// Like Assure() but allows the caller to customize the exception message. +/// \param description string literal describing the condition (i.e. what MUST happen) +#define Assure2(condition, description) \ + Assure_(0, (condition), ("assurance failed: " description), Here()) + +#else + +/* do-nothing implementations for NDEBUG builds */ +#define Assure(condition) ((void)0) +#define Assure2(condition, description) ((void)0) + +#endif /* NDEBUG */ + +#endif /* SQUID_SRC_BASE_ASSURE_H */ diff --git a/src/base/Makefile.am b/src/base/Makefile.am index 9b0f4cf..c22dd0e 100644 --- a/src/base/Makefile.am +++ b/src/base/Makefile.am @@ -19,6 +19,8 @@ libbase_la_SOURCES = \ AsyncJob.cc \ AsyncJob.h \ AsyncJobCalls.h \ + Assure.cc \ + Assure.h \ ByteCounter.h \ CbcPointer.h \ CbDataList.h \ diff --git a/src/base/Makefile.in b/src/base/Makefile.in index 90a4f5b..f43e098 100644 --- a/src/base/Makefile.in +++ b/src/base/Makefile.in @@ -163,7 +163,7 @@ CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libbase_la_LIBADD = -am_libbase_la_OBJECTS = AsyncCall.lo AsyncCallQueue.lo AsyncJob.lo \ +am_libbase_la_OBJECTS = AsyncCall.lo AsyncCallQueue.lo AsyncJob.lo Assure.lo \ CharacterSet.lo File.lo Here.lo RegexPattern.lo \ RunnersRegistry.lo TextException.lo libbase_la_OBJECTS = $(am_libbase_la_OBJECTS) @@ -187,7 +187,7 @@ DEFAULT_INCLUDES = depcomp = $(SHELL) $(top_srcdir)/cfgaux/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/AsyncCall.Plo \ - ./$(DEPDIR)/AsyncCallQueue.Plo ./$(DEPDIR)/AsyncJob.Plo \ + ./$(DEPDIR)/AsyncCallQueue.Plo ./$(DEPDIR)/AsyncJob.Plo ./$(DEPDIR)/Assure.Plo \ ./$(DEPDIR)/CharacterSet.Plo ./$(DEPDIR)/File.Plo \ ./$(DEPDIR)/Here.Plo ./$(DEPDIR)/RegexPattern.Plo \ ./$(DEPDIR)/RunnersRegistry.Plo ./$(DEPDIR)/TextException.Plo @@ -737,6 +737,8 @@ libbase_la_SOURCES = \ AsyncJob.cc \ AsyncJob.h \ AsyncJobCalls.h \ + Assure.cc \ + Assure.h \ ByteCounter.h \ CbcPointer.h \ CbDataList.h \ @@ -830,6 +832,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AsyncCall.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AsyncCallQueue.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AsyncJob.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Assure.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CharacterSet.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/File.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Here.Plo@am__quote@ # am--include-marker @@ -1224,6 +1227,7 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/AsyncCall.Plo -rm -f ./$(DEPDIR)/AsyncCallQueue.Plo -rm -f ./$(DEPDIR)/AsyncJob.Plo + -rm -f ./$(DEPDIR)/Assure.Plo -rm -f ./$(DEPDIR)/CharacterSet.Plo -rm -f ./$(DEPDIR)/File.Plo -rm -f ./$(DEPDIR)/Here.Plo diff --git a/src/client_side_reply.cc b/src/client_side_reply.cc index 861f4b4..470f4bc 100644 --- a/src/client_side_reply.cc +++ b/src/client_side_reply.cc @@ -12,6 +12,7 @@ #include "acl/FilledChecklist.h" #include "acl/Gadgets.h" #include "anyp/PortCfg.h" +#include "base/Assure.h" #include "client_side_reply.h" #include "errorpage.h" #include "ETag.h" -- 2.39.3