fix cve-2024-28757 and cve-2023-52426
This commit is contained in:
parent
64e33d6a41
commit
82bfddc8b5
72
backport-001-CVE-2023-52426.patch
Normal file
72
backport-001-CVE-2023-52426.patch
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
From 62e8805678b10ec0642ed78e15b914c01fe81699 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sebastian Pipping <sebastian@pipping.org>
|
||||||
|
Date: Thu, 26 Oct 2023 00:59:52 +0200
|
||||||
|
Subject: [PATCH] cmake: Introduce option EXPAT_GE to control macro XML_GE
|
||||||
|
|
||||||
|
Reference: https://github.com//libexpat/libexpat/commit/daa89e42c005cc7f4f7af9eee271ae0723d30300
|
||||||
|
Conflict: remove expat_config_h_cmake__expected.txt
|
||||||
|
change expat_shy_set to option in CMakeLists.txt
|
||||||
|
---
|
||||||
|
CMakeLists.txt | 9 +++++++++
|
||||||
|
expat_config.h.cmake | 3 +++
|
||||||
|
2 files changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||||
|
index 2b4c13c..4f31132 100644
|
||||||
|
--- a/CMakeLists.txt
|
||||||
|
+++ b/CMakeLists.txt
|
||||||
|
@@ -140,6 +140,8 @@ expat_shy_set(EXPAT_CONTEXT_BYTES 1024 CACHE STRING "Define to specify how much
|
||||||
|
mark_as_advanced(EXPAT_CONTEXT_BYTES)
|
||||||
|
expat_shy_set(EXPAT_DTD ON CACHE BOOL "Define to make parameter entity parsing functionality available")
|
||||||
|
mark_as_advanced(EXPAT_DTD)
|
||||||
|
+option(EXPAT_GE "Define to make general entity parsing functionality available" ON)
|
||||||
|
+mark_as_advanced(EXPAT_GE)
|
||||||
|
expat_shy_set(EXPAT_NS ON CACHE BOOL "Define to make XML Namespaces functionality available")
|
||||||
|
mark_as_advanced(EXPAT_NS)
|
||||||
|
expat_shy_set(EXPAT_WARNINGS_AS_ERRORS OFF CACHE BOOL "Treat all compiler warnings as errors")
|
||||||
|
@@ -172,6 +174,11 @@ endif()
|
||||||
|
#
|
||||||
|
# Environment checks
|
||||||
|
#
|
||||||
|
+if(EXPAT_DTD AND NOT EXPAT_GE)
|
||||||
|
+ message(SEND_ERROR "Option EXPAT_DTD requires that EXPAT_GE is also enabled.")
|
||||||
|
+ message(SEND_ERROR "Please either enable option EXPAT_GE (recommended) or disable EXPAT_DTD also.")
|
||||||
|
+endif()
|
||||||
|
+
|
||||||
|
if(EXPAT_WITH_LIBBSD)
|
||||||
|
find_library(LIB_BSD NAMES bsd)
|
||||||
|
if(NOT LIB_BSD)
|
||||||
|
@@ -274,6 +281,7 @@ endif()
|
||||||
|
|
||||||
|
_expat_copy_bool_int(EXPAT_ATTR_INFO XML_ATTR_INFO)
|
||||||
|
_expat_copy_bool_int(EXPAT_DTD XML_DTD)
|
||||||
|
+_expat_copy_bool_int(EXPAT_GE XML_GE)
|
||||||
|
_expat_copy_bool_int(EXPAT_LARGE_SIZE XML_LARGE_SIZE)
|
||||||
|
_expat_copy_bool_int(EXPAT_MIN_SIZE XML_MIN_SIZE)
|
||||||
|
_expat_copy_bool_int(EXPAT_NS XML_NS)
|
||||||
|
@@ -893,6 +901,7 @@ message(STATUS " // Advanced options, changes not advised")
|
||||||
|
message(STATUS " Attributes info .......... ${EXPAT_ATTR_INFO}")
|
||||||
|
message(STATUS " Context bytes ............ ${EXPAT_CONTEXT_BYTES}")
|
||||||
|
message(STATUS " DTD support .............. ${EXPAT_DTD}")
|
||||||
|
+message(STATUS " General entities ......... ${EXPAT_GE}")
|
||||||
|
message(STATUS " Large size ............... ${EXPAT_LARGE_SIZE}")
|
||||||
|
message(STATUS " Minimum size ............. ${EXPAT_MIN_SIZE}")
|
||||||
|
message(STATUS " Namespace support ........ ${EXPAT_NS}")
|
||||||
|
diff --git a/expat_config.h.cmake b/expat_config.h.cmake
|
||||||
|
index 78fcb4c..330945e 100644
|
||||||
|
--- a/expat_config.h.cmake
|
||||||
|
+++ b/expat_config.h.cmake
|
||||||
|
@@ -103,6 +103,9 @@
|
||||||
|
/* Define to make parameter entity parsing functionality available. */
|
||||||
|
#cmakedefine XML_DTD
|
||||||
|
|
||||||
|
+/* Define as 1/0 to enable/disable support for general entities. */
|
||||||
|
+#define XML_GE @XML_GE@
|
||||||
|
+
|
||||||
|
/* Define to make XML Namespaces functionality available. */
|
||||||
|
#cmakedefine XML_NS
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
|
|
||||||
30
backport-002-CVE-2023-52426.patch
Normal file
30
backport-002-CVE-2023-52426.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From ed87a4793404e91c0cc0c81435fcfcc64a8be9f4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sebastian Pipping <sebastian@pipping.org>
|
||||||
|
Date: Thu, 26 Oct 2023 00:45:23 +0200
|
||||||
|
Subject: [PATCH 02/17] configure.ac: Define macro XML_GE as 1
|
||||||
|
|
||||||
|
Reference: https://github.com//libexpat/libexpat/commit/ed87a4793404e91c0cc0c81435fcfcc64a8be9f4
|
||||||
|
Conflict: remove expat_config_h_in__expected.txt
|
||||||
|
|
||||||
|
---
|
||||||
|
configure.ac | 2 ++
|
||||||
|
2 files changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/expat/configure.ac b/expat/configure.ac
|
||||||
|
index c9f95bca..fec4ecd0 100644
|
||||||
|
--- a/configure.ac
|
||||||
|
+++ b/configure.ac
|
||||||
|
@@ -303,6 +303,8 @@ AC_SUBST(FILEMAP)
|
||||||
|
dnl Some basic configuration:
|
||||||
|
AC_DEFINE([XML_NS], 1,
|
||||||
|
[Define to make XML Namespaces functionality available.])
|
||||||
|
+AC_DEFINE([XML_GE], 1,
|
||||||
|
+ [Define as 1/0 to enable/disable support for general entities.])
|
||||||
|
AC_DEFINE([XML_DTD], 1,
|
||||||
|
[Define to make parameter entity parsing functionality available.])
|
||||||
|
AC_DEFINE([XML_DEV_URANDOM], 1,
|
||||||
|
--
|
||||||
|
2.37.3.windows.1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
399
backport-003-CVE-2023-52426.patch
Normal file
399
backport-003-CVE-2023-52426.patch
Normal file
@ -0,0 +1,399 @@
|
|||||||
|
From 34ef2a26ab33c724c666b33ce08f13983c79c612 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sebastian Pipping <sebastian@pipping.org>
|
||||||
|
Date: Thu, 26 Oct 2023 00:43:22 +0200
|
||||||
|
Subject: [PATCH] lib|xmlwf|cmake: Extend scope of billion laughs attack
|
||||||
|
protection
|
||||||
|
|
||||||
|
.. from "defined(XML_DTD)" to "defined(XML_DTD) || XML_GE==1".
|
||||||
|
|
||||||
|
Reference: https://github.com//libexpat/libexpat/commit/ff958ebde28854845b28167695a678cc49a50c4b
|
||||||
|
Conflict: remove _expat_def_file_toggle in CMakeLists.txt of win32
|
||||||
|
remove _EXPAT_COMMENT_DTD_OR_GE in libexpat.def.cmake of MS VC++
|
||||||
|
adapt entityValueInitProcessor
|
||||||
|
adapt internalEntityProcessor
|
||||||
|
---
|
||||||
|
lib/expat.h | 8 +++---
|
||||||
|
lib/internal.h | 2 +-
|
||||||
|
lib/xmlparse.c | 71 ++++++++++++++++++++++++++------------------------
|
||||||
|
xmlwf/xmlwf.c | 18 +++++++------
|
||||||
|
4 files changed, 53 insertions(+), 46 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/expat.h b/lib/expat.h
|
||||||
|
index 1c83563..33c94af 100644
|
||||||
|
--- a/lib/expat.h
|
||||||
|
+++ b/lib/expat.h
|
||||||
|
@@ -1038,13 +1038,15 @@ typedef struct {
|
||||||
|
XMLPARSEAPI(const XML_Feature *)
|
||||||
|
XML_GetFeatureList(void);
|
||||||
|
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
-/* Added in Expat 2.4.0. */
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
+/* Added in Expat 2.4.0 for XML_DTD defined and
|
||||||
|
+ * added in Expat 2.6.0 for XML_GE == 1. */
|
||||||
|
XMLPARSEAPI(XML_Bool)
|
||||||
|
XML_SetBillionLaughsAttackProtectionMaximumAmplification(
|
||||||
|
XML_Parser parser, float maximumAmplificationFactor);
|
||||||
|
|
||||||
|
-/* Added in Expat 2.4.0. */
|
||||||
|
+/* Added in Expat 2.4.0 for XML_DTD defined and
|
||||||
|
+ * added in Expat 2.6.0 for XML_GE == 1. */
|
||||||
|
XMLPARSEAPI(XML_Bool)
|
||||||
|
XML_SetBillionLaughsAttackProtectionActivationThreshold(
|
||||||
|
XML_Parser parser, unsigned long long activationThresholdBytes);
|
||||||
|
diff --git a/lib/internal.h b/lib/internal.h
|
||||||
|
index e09f533..1851925 100644
|
||||||
|
--- a/lib/internal.h
|
||||||
|
+++ b/lib/internal.h
|
||||||
|
@@ -154,7 +154,7 @@ extern "C" {
|
||||||
|
void _INTERNAL_trim_to_complete_utf8_characters(const char *from,
|
||||||
|
const char **fromLimRef);
|
||||||
|
|
||||||
|
-#if defined(XML_DTD)
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
unsigned long long testingAccountingGetCountBytesDirect(XML_Parser parser);
|
||||||
|
unsigned long long testingAccountingGetCountBytesIndirect(XML_Parser parser);
|
||||||
|
const char *unsignedCharToPrintable(unsigned char c);
|
||||||
|
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
|
||||||
|
index 9458b09..ecc09e9 100644
|
||||||
|
--- a/lib/xmlparse.c
|
||||||
|
+++ b/lib/xmlparse.c
|
||||||
|
@@ -408,7 +408,7 @@ enum XML_Account {
|
||||||
|
XML_ACCOUNT_NONE /* i.e. do not account, was accounted already */
|
||||||
|
};
|
||||||
|
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
typedef unsigned long long XmlBigCount;
|
||||||
|
typedef struct accounting {
|
||||||
|
XmlBigCount countBytesDirect;
|
||||||
|
@@ -424,7 +424,7 @@ typedef struct entity_stats {
|
||||||
|
unsigned int maximumDepthSeen;
|
||||||
|
int debugLevel;
|
||||||
|
} ENTITY_STATS;
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+#endif /* defined(XML_DTD) || XML_GE == 1 */
|
||||||
|
|
||||||
|
typedef enum XML_Error PTRCALL Processor(XML_Parser parser, const char *start,
|
||||||
|
const char *end, const char **endPtr);
|
||||||
|
@@ -562,7 +562,7 @@ static XML_Parser parserCreate(const XML_Char *encodingName,
|
||||||
|
|
||||||
|
static void parserInit(XML_Parser parser, const XML_Char *encodingName);
|
||||||
|
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
static float accountingGetCurrentAmplification(XML_Parser rootParser);
|
||||||
|
static void accountingReportStats(XML_Parser originParser, const char *epilog);
|
||||||
|
static void accountingOnAbort(XML_Parser originParser);
|
||||||
|
@@ -585,7 +585,7 @@ static void entityTrackingOnClose(XML_Parser parser, ENTITY *entity,
|
||||||
|
|
||||||
|
static XML_Parser getRootParserOf(XML_Parser parser,
|
||||||
|
unsigned int *outLevelDiff);
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+#endif /* defined(XML_DTD) || XML_GE == 1 */
|
||||||
|
|
||||||
|
static unsigned long getDebugLevel(const char *variableName,
|
||||||
|
unsigned long defaultDebugLevel);
|
||||||
|
@@ -703,7 +703,7 @@ struct XML_ParserStruct {
|
||||||
|
enum XML_ParamEntityParsing m_paramEntityParsing;
|
||||||
|
#endif
|
||||||
|
unsigned long m_hash_secret_salt;
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
ACCOUNTING m_accounting;
|
||||||
|
ENTITY_STATS m_entity_stats;
|
||||||
|
#endif
|
||||||
|
@@ -1163,7 +1163,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
|
||||||
|
#endif
|
||||||
|
parser->m_hash_secret_salt = 0;
|
||||||
|
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
memset(&parser->m_accounting, 0, sizeof(ACCOUNTING));
|
||||||
|
parser->m_accounting.debugLevel = getDebugLevel("EXPAT_ACCOUNTING_DEBUG", 0u);
|
||||||
|
parser->m_accounting.maximumAmplificationFactor
|
||||||
|
@@ -2522,8 +2522,9 @@ XML_GetFeatureList(void) {
|
||||||
|
#ifdef XML_ATTR_INFO
|
||||||
|
{XML_FEATURE_ATTR_INFO, XML_L("XML_ATTR_INFO"), 0},
|
||||||
|
#endif
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
- /* Added in Expat 2.4.0. */
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
+ /* Added in Expat 2.4.0 for XML_DTD defined and
|
||||||
|
+ * added in Expat 2.6.0 for XML_GE == 1. */
|
||||||
|
{XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_MAXIMUM_AMPLIFICATION_DEFAULT,
|
||||||
|
XML_L("XML_BLAP_MAX_AMP"),
|
||||||
|
(long int)
|
||||||
|
@@ -2537,7 +2538,7 @@ XML_GetFeatureList(void) {
|
||||||
|
return features;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
XML_Bool XMLCALL
|
||||||
|
XML_SetBillionLaughsAttackProtectionMaximumAmplification(
|
||||||
|
XML_Parser parser, float maximumAmplificationFactor) {
|
||||||
|
@@ -2559,7 +2560,7 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(
|
||||||
|
parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
|
||||||
|
return XML_TRUE;
|
||||||
|
}
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+#endif /* defined(XML_DTD) || XML_GE == 1 */
|
||||||
|
|
||||||
|
/* Initially tag->rawName always points into the parse buffer;
|
||||||
|
for those TAG instances opened while the current parse buffer was
|
||||||
|
@@ -2645,13 +2646,13 @@ externalEntityInitProcessor2(XML_Parser parser, const char *start,
|
||||||
|
int tok = XmlContentTok(parser->m_encoding, start, end, &next);
|
||||||
|
switch (tok) {
|
||||||
|
case XML_TOK_BOM:
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
if (! accountingDiffTolerated(parser, tok, start, next, __LINE__,
|
||||||
|
XML_ACCOUNT_DIRECT)) {
|
||||||
|
accountingOnAbort(parser);
|
||||||
|
return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
|
||||||
|
}
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+#endif /* defined(XML_DTD) || XML_GE == 1 */
|
||||||
|
|
||||||
|
/* If we are at the end of the buffer, this would cause the next stage,
|
||||||
|
i.e. externalEntityInitProcessor3, to pass control directly to
|
||||||
|
@@ -2765,7 +2766,7 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
|
||||||
|
for (;;) {
|
||||||
|
const char *next = s; /* XmlContentTok doesn't always set the last arg */
|
||||||
|
int tok = XmlContentTok(enc, s, end, &next);
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
const char *accountAfter
|
||||||
|
= ((tok == XML_TOK_TRAILING_RSQB) || (tok == XML_TOK_TRAILING_CR))
|
||||||
|
? (haveMore ? s /* i.e. 0 bytes */ : end)
|
||||||
|
@@ -2831,14 +2832,14 @@ doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
|
||||||
|
XML_Char ch = (XML_Char)XmlPredefinedEntityName(
|
||||||
|
enc, s + enc->minBytesPerChar, next - enc->minBytesPerChar);
|
||||||
|
if (ch) {
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
/* NOTE: We are replacing 4-6 characters original input for 1 character
|
||||||
|
* so there is no amplification and hence recording without
|
||||||
|
* protection. */
|
||||||
|
accountingDiffTolerated(parser, tok, (char *)&ch,
|
||||||
|
((char *)&ch) + sizeof(XML_Char), __LINE__,
|
||||||
|
XML_ACCOUNT_ENTITY_EXPANSION);
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+#endif /* defined(XML_DTD) || XML_GE == 1 */
|
||||||
|
if (parser->m_characterDataHandler)
|
||||||
|
parser->m_characterDataHandler(parser->m_handlerArg, &ch, 1);
|
||||||
|
else if (parser->m_defaultHandler)
|
||||||
|
@@ -4040,7 +4041,7 @@ doCdataSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
|
||||||
|
for (;;) {
|
||||||
|
const char *next = s; /* in case of XML_TOK_NONE or XML_TOK_PARTIAL */
|
||||||
|
int tok = XmlCdataSectionTok(enc, s, end, &next);
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
|
||||||
|
accountingOnAbort(parser);
|
||||||
|
return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
|
||||||
|
@@ -4192,7 +4193,7 @@ doIgnoreSection(XML_Parser parser, const ENCODING *enc, const char **startPtr,
|
||||||
|
*eventPP = s;
|
||||||
|
*startPtr = NULL;
|
||||||
|
tok = XmlIgnoreSectionTok(enc, s, end, &next);
|
||||||
|
-# ifdef XML_DTD
|
||||||
|
+# if defined(XML_DTD) || XML_GE == 1
|
||||||
|
if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
|
||||||
|
XML_ACCOUNT_DIRECT)) {
|
||||||
|
accountingOnAbort(parser);
|
||||||
|
@@ -4284,7 +4285,7 @@ processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *s,
|
||||||
|
const XML_Char *storedversion = NULL;
|
||||||
|
int standalone = -1;
|
||||||
|
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
if (! accountingDiffTolerated(parser, XML_TOK_XML_DECL, s, next, __LINE__,
|
||||||
|
XML_ACCOUNT_DIRECT)) {
|
||||||
|
accountingOnAbort(parser);
|
||||||
|
@@ -4491,7 +4492,7 @@ entityValueInitProcessor(XML_Parser parser, const char *s, const char *end,
|
||||||
|
*/
|
||||||
|
else if (tok == XML_TOK_BOM && next == end
|
||||||
|
&& ! parser->m_parsingStatus.finalBuffer) {
|
||||||
|
-# ifdef XML_DTD
|
||||||
|
+# if defined(XML_DTD) || XML_GE == 1
|
||||||
|
if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
|
||||||
|
XML_ACCOUNT_DIRECT)) {
|
||||||
|
accountingOnAbort(parser);
|
||||||
|
@@ -4707,11 +4708,13 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
role = XmlTokenRole(&parser->m_prologState, tok, s, next, enc);
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
switch (role) {
|
||||||
|
case XML_ROLE_INSTANCE_START: // bytes accounted in contentProcessor
|
||||||
|
case XML_ROLE_XML_DECL: // bytes accounted in processXmlDecl
|
||||||
|
- case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl
|
||||||
|
+# ifdef XML_DTD
|
||||||
|
+ case XML_ROLE_TEXT_DECL: // bytes accounted in processXmlDecl
|
||||||
|
+# endif
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (! accountingDiffTolerated(parser, tok, s, next, __LINE__, account)) {
|
||||||
|
@@ -5648,7 +5651,7 @@ epilogProcessor(XML_Parser parser, const char *s, const char *end,
|
||||||
|
for (;;) {
|
||||||
|
const char *next = NULL;
|
||||||
|
int tok = XmlPrologTok(parser->m_encoding, s, end, &next);
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
if (! accountingDiffTolerated(parser, tok, s, next, __LINE__,
|
||||||
|
XML_ACCOUNT_DIRECT)) {
|
||||||
|
accountingOnAbort(parser);
|
||||||
|
@@ -5728,7 +5731,7 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
|
||||||
|
return XML_ERROR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
entity->open = XML_TRUE;
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
entityTrackingOnOpen(parser, entity, __LINE__);
|
||||||
|
#endif
|
||||||
|
entity->processed = 0;
|
||||||
|
@@ -5762,9 +5765,9 @@ processInternalEntity(XML_Parser parser, ENTITY *entity, XML_Bool betweenDecl) {
|
||||||
|
entity->processed = (int)(next - textStart);
|
||||||
|
parser->m_processor = internalEntityProcessor;
|
||||||
|
} else {
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
entityTrackingOnClose(parser, entity, __LINE__);
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+#endif /* defined(XML_DTD) || XML_GE == 1 */
|
||||||
|
entity->open = XML_FALSE;
|
||||||
|
parser->m_openInternalEntities = openEntity->next;
|
||||||
|
/* put openEntity back in list of free instances */
|
||||||
|
@@ -5813,7 +5816,7 @@ internalEntityProcessor(XML_Parser parser, const char *s, const char *end,
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
entityTrackingOnClose(parser, entity, __LINE__);
|
||||||
|
#endif
|
||||||
|
entity->open = XML_FALSE;
|
||||||
|
@@ -5892,7 +5895,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
|
||||||
|
const char *next
|
||||||
|
= ptr; /* XmlAttributeValueTok doesn't always set the last arg */
|
||||||
|
int tok = XmlAttributeValueTok(enc, ptr, end, &next);
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
if (! accountingDiffTolerated(parser, tok, ptr, next, __LINE__, account)) {
|
||||||
|
accountingOnAbort(parser);
|
||||||
|
return XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
|
||||||
|
@@ -5957,14 +5960,14 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
|
||||||
|
XML_Char ch = (XML_Char)XmlPredefinedEntityName(
|
||||||
|
enc, ptr + enc->minBytesPerChar, next - enc->minBytesPerChar);
|
||||||
|
if (ch) {
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
/* NOTE: We are replacing 4-6 characters original input for 1 character
|
||||||
|
* so there is no amplification and hence recording without
|
||||||
|
* protection. */
|
||||||
|
accountingDiffTolerated(parser, tok, (char *)&ch,
|
||||||
|
((char *)&ch) + sizeof(XML_Char), __LINE__,
|
||||||
|
XML_ACCOUNT_ENTITY_EXPANSION);
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+#endif /* defined(XML_DTD) || XML_GE == 1 */
|
||||||
|
if (! poolAppendChar(pool, ch))
|
||||||
|
return XML_ERROR_NO_MEMORY;
|
||||||
|
break;
|
||||||
|
@@ -6042,14 +6045,14 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
|
||||||
|
enum XML_Error result;
|
||||||
|
const XML_Char *textEnd = entity->textPtr + entity->textLen;
|
||||||
|
entity->open = XML_TRUE;
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
entityTrackingOnOpen(parser, entity, __LINE__);
|
||||||
|
#endif
|
||||||
|
result = appendAttributeValue(parser, parser->m_internalEncoding,
|
||||||
|
isCdata, (const char *)entity->textPtr,
|
||||||
|
(const char *)textEnd, pool,
|
||||||
|
XML_ACCOUNT_ENTITY_EXPANSION);
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
entityTrackingOnClose(parser, entity, __LINE__);
|
||||||
|
#endif
|
||||||
|
entity->open = XML_FALSE;
|
||||||
|
@@ -6105,7 +6108,7 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
|
||||||
|
= entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */
|
||||||
|
int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
|
||||||
|
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__,
|
||||||
|
account)) {
|
||||||
|
accountingOnAbort(parser);
|
||||||
|
@@ -7651,7 +7654,7 @@ copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
|
||||||
|
static float
|
||||||
|
accountingGetCurrentAmplification(XML_Parser rootParser) {
|
||||||
|
@@ -8386,7 +8389,7 @@ unsignedCharToPrintable(unsigned char c) {
|
||||||
|
assert(0); /* never gets here */
|
||||||
|
}
|
||||||
|
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+#endif /* defined(XML_DTD) || XML_GE == 1 */
|
||||||
|
|
||||||
|
static unsigned long
|
||||||
|
getDebugLevel(const char *variableName, unsigned long defaultDebugLevel) {
|
||||||
|
diff --git a/xmlwf/xmlwf.c b/xmlwf/xmlwf.c
|
||||||
|
index 471f2a2..be23f5a 100644
|
||||||
|
--- a/xmlwf/xmlwf.c
|
||||||
|
+++ b/xmlwf/xmlwf.c
|
||||||
|
@@ -1062,9 +1062,10 @@ tmain(int argc, XML_Char **argv) {
|
||||||
|
" (needs a floating point number greater or equal than 1.0)"));
|
||||||
|
exit(XMLWF_EXIT_USAGE_ERROR);
|
||||||
|
}
|
||||||
|
-#ifndef XML_DTD
|
||||||
|
- ftprintf(stderr, T("Warning: Given amplification limit ignored") T(
|
||||||
|
- ", xmlwf has been compiled without DTD support.\n"));
|
||||||
|
+#if ! defined(XML_DTD) && XML_GE == 0
|
||||||
|
+ ftprintf(stderr,
|
||||||
|
+ T("Warning: Given amplification limit ignored")
|
||||||
|
+ T(", xmlwf has been compiled without DTD/GE support.\n"));
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1083,9 +1084,10 @@ tmain(int argc, XML_Char **argv) {
|
||||||
|
exit(XMLWF_EXIT_USAGE_ERROR);
|
||||||
|
}
|
||||||
|
attackThresholdGiven = XML_TRUE;
|
||||||
|
-#ifndef XML_DTD
|
||||||
|
- ftprintf(stderr, T("Warning: Given attack threshold ignored") T(
|
||||||
|
- ", xmlwf has been compiled without DTD support.\n"));
|
||||||
|
+#if ! defined(XML_DTD) && XML_GE == 0
|
||||||
|
+ ftprintf(stderr,
|
||||||
|
+ T("Warning: Given attack threshold ignored")
|
||||||
|
+ T(", xmlwf has been compiled without DTD/GE support.\n"));
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1120,13 +1122,13 @@ tmain(int argc, XML_Char **argv) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attackMaximumAmplification != -1.0f) {
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
XML_SetBillionLaughsAttackProtectionMaximumAmplification(
|
||||||
|
parser, attackMaximumAmplification);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (attackThresholdGiven) {
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
XML_SetBillionLaughsAttackProtectionActivationThreshold(
|
||||||
|
parser, attackThresholdBytes);
|
||||||
|
#else
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
|
|
||||||
185
backport-004-CVE-2023-52426.patch
Normal file
185
backport-004-CVE-2023-52426.patch
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
From 2b127c20b220b673cf52c6be8bef725bf04cbeaf Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sebastian Pipping <sebastian@pipping.org>
|
||||||
|
Date: Thu, 26 Oct 2023 18:32:11 +0200
|
||||||
|
Subject: [PATCH 07/17] lib: Make XML_GE==0 use self-references as entity
|
||||||
|
replacement text
|
||||||
|
|
||||||
|
Reference: https://github.com//libexpat/libexpat/commit/2b127c20b220b673cf52c6be8bef725bf04cbeaf
|
||||||
|
Conflict: NA
|
||||||
|
|
||||||
|
---
|
||||||
|
lib/xmlparse.c | 81 +++++++++++++++++++++++++++++++++++++++-----
|
||||||
|
1 file changed, 72 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/xmlparse.c b/lib/xmlparse.c
|
||||||
|
index db148b21..6a38dbe2 100644
|
||||||
|
--- a/lib/xmlparse.c
|
||||||
|
+++ b/lib/xmlparse.c
|
||||||
|
@@ -512,9 +512,13 @@ static enum XML_Error appendAttributeValue(XML_Parser parser, const ENCODING *,
|
||||||
|
static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc,
|
||||||
|
const char *start, const char *end);
|
||||||
|
static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
|
||||||
|
+#if XML_GE == 1
|
||||||
|
static enum XML_Error storeEntityValue(XML_Parser parser, const ENCODING *enc,
|
||||||
|
const char *start, const char *end,
|
||||||
|
enum XML_Account account);
|
||||||
|
+#else
|
||||||
|
+static enum XML_Error storeSelfEntityValue(XML_Parser parser, ENTITY *entity);
|
||||||
|
+#endif
|
||||||
|
static int reportProcessingInstruction(XML_Parser parser, const ENCODING *enc,
|
||||||
|
const char *start, const char *end);
|
||||||
|
static int reportComment(XML_Parser parser, const ENCODING *enc,
|
||||||
|
@@ -5053,6 +5057,9 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
|
||||||
|
break;
|
||||||
|
case XML_ROLE_ENTITY_VALUE:
|
||||||
|
if (dtd->keepProcessing) {
|
||||||
|
+#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
+ // This will store the given replacement text in
|
||||||
|
+ // parser->m_declEntity->textPtr.
|
||||||
|
enum XML_Error result
|
||||||
|
= storeEntityValue(parser, enc, s + enc->minBytesPerChar,
|
||||||
|
next - enc->minBytesPerChar, XML_ACCOUNT_NONE);
|
||||||
|
@@ -5073,6 +5080,25 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
|
||||||
|
poolDiscard(&dtd->entityValuePool);
|
||||||
|
if (result != XML_ERROR_NONE)
|
||||||
|
return result;
|
||||||
|
+#else
|
||||||
|
+ // This will store "&entity123;" in parser->m_declEntity->textPtr
|
||||||
|
+ // to end up as "&entity123;" in the handler.
|
||||||
|
+ if (parser->m_declEntity != NULL) {
|
||||||
|
+ const enum XML_Error result
|
||||||
|
+ = storeSelfEntityValue(parser, parser->m_declEntity);
|
||||||
|
+ if (result != XML_ERROR_NONE)
|
||||||
|
+ return result;
|
||||||
|
+
|
||||||
|
+ if (parser->m_entityDeclHandler) {
|
||||||
|
+ *eventEndPP = s;
|
||||||
|
+ parser->m_entityDeclHandler(
|
||||||
|
+ parser->m_handlerArg, parser->m_declEntity->name,
|
||||||
|
+ parser->m_declEntity->is_param, parser->m_declEntity->textPtr,
|
||||||
|
+ parser->m_declEntity->textLen, parser->m_curBase, 0, 0, 0);
|
||||||
|
+ handleDefault = XML_FALSE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XML_ROLE_DOCTYPE_SYSTEM_ID:
|
||||||
|
@@ -5131,6 +5157,16 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XML_ROLE_ENTITY_COMPLETE:
|
||||||
|
+#if XML_GE == 0
|
||||||
|
+ // This will store "&entity123;" in entity->textPtr
|
||||||
|
+ // to end up as "&entity123;" in the handler.
|
||||||
|
+ if (parser->m_declEntity != NULL) {
|
||||||
|
+ const enum XML_Error result
|
||||||
|
+ = storeSelfEntityValue(parser, parser->m_declEntity);
|
||||||
|
+ if (result != XML_ERROR_NONE)
|
||||||
|
+ return result;
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
if (dtd->keepProcessing && parser->m_declEntity
|
||||||
|
&& parser->m_entityDeclHandler) {
|
||||||
|
*eventEndPP = s;
|
||||||
|
@@ -6103,6 +6139,7 @@ appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
|
||||||
|
/* not reached */
|
||||||
|
}
|
||||||
|
|
||||||
|
+#if XML_GE == 1
|
||||||
|
static enum XML_Error
|
||||||
|
storeEntityValue(XML_Parser parser, const ENCODING *enc,
|
||||||
|
const char *entityTextPtr, const char *entityTextEnd,
|
||||||
|
@@ -6110,12 +6147,12 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
|
||||||
|
DTD *const dtd = parser->m_dtd; /* save one level of indirection */
|
||||||
|
STRING_POOL *pool = &(dtd->entityValuePool);
|
||||||
|
enum XML_Error result = XML_ERROR_NONE;
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+# ifdef XML_DTD
|
||||||
|
int oldInEntityValue = parser->m_prologState.inEntityValue;
|
||||||
|
parser->m_prologState.inEntityValue = 1;
|
||||||
|
-#else
|
||||||
|
+# else
|
||||||
|
UNUSED_P(account);
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+# endif /* XML_DTD */
|
||||||
|
/* never return Null for the value argument in EntityDeclHandler,
|
||||||
|
since this would indicate an external entity; therefore we
|
||||||
|
have to make sure that entityValuePool.start is not null */
|
||||||
|
@@ -6129,18 +6166,18 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
|
||||||
|
= entityTextPtr; /* XmlEntityValueTok doesn't always set the last arg */
|
||||||
|
int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
|
||||||
|
|
||||||
|
-#if defined(XML_DTD) || XML_GE == 1
|
||||||
|
+# if defined(XML_DTD) || XML_GE == 1
|
||||||
|
if (! accountingDiffTolerated(parser, tok, entityTextPtr, next, __LINE__,
|
||||||
|
account)) {
|
||||||
|
accountingOnAbort(parser);
|
||||||
|
result = XML_ERROR_AMPLIFICATION_LIMIT_BREACH;
|
||||||
|
goto endEntityValue;
|
||||||
|
}
|
||||||
|
-#endif
|
||||||
|
+# endif
|
||||||
|
|
||||||
|
switch (tok) {
|
||||||
|
case XML_TOK_PARAM_ENTITY_REF:
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+# ifdef XML_DTD
|
||||||
|
if (parser->m_isParamEntity || enc != parser->m_encoding) {
|
||||||
|
const XML_Char *name;
|
||||||
|
ENTITY *entity;
|
||||||
|
@@ -6202,7 +6239,7 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+# endif /* XML_DTD */
|
||||||
|
/* In the internal subset, PE references are not legal
|
||||||
|
within markup declarations, e.g entity values in this case. */
|
||||||
|
parser->m_eventPtr = entityTextPtr;
|
||||||
|
@@ -6283,12 +6320,38 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
|
||||||
|
entityTextPtr = next;
|
||||||
|
}
|
||||||
|
endEntityValue:
|
||||||
|
-#ifdef XML_DTD
|
||||||
|
+# ifdef XML_DTD
|
||||||
|
parser->m_prologState.inEntityValue = oldInEntityValue;
|
||||||
|
-#endif /* XML_DTD */
|
||||||
|
+# endif /* XML_DTD */
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#else /* XML_GE == 0 */
|
||||||
|
+
|
||||||
|
+static enum XML_Error
|
||||||
|
+storeSelfEntityValue(XML_Parser parser, ENTITY *entity) {
|
||||||
|
+ // This will store "&entity123;" in entity->textPtr
|
||||||
|
+ // to end up as "&entity123;" in the handler.
|
||||||
|
+ const char *const entity_start = "&";
|
||||||
|
+ const char *const entity_end = ";";
|
||||||
|
+
|
||||||
|
+ STRING_POOL *const pool = &(parser->m_dtd->entityValuePool);
|
||||||
|
+ if (! poolAppendString(pool, entity_start)
|
||||||
|
+ || ! poolAppendString(pool, entity->name)
|
||||||
|
+ || ! poolAppendString(pool, entity_end)) {
|
||||||
|
+ poolDiscard(pool);
|
||||||
|
+ return XML_ERROR_NO_MEMORY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ entity->textPtr = poolStart(pool);
|
||||||
|
+ entity->textLen = (int)(poolLength(pool));
|
||||||
|
+ poolFinish(pool);
|
||||||
|
+
|
||||||
|
+ return XML_ERROR_NONE;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* XML_GE == 0 */
|
||||||
|
+
|
||||||
|
static void FASTCALL
|
||||||
|
normalizeLines(XML_Char *s) {
|
||||||
|
XML_Char *p;
|
||||||
|
--
|
||||||
|
2.37.3.windows.1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
58
backport-CVE-2024-28757-001.patch
Normal file
58
backport-CVE-2024-28757-001.patch
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
From 1d50b80cf31de87750103656f6eb693746854aa8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sebastian Pipping <sebastian@pipping.org>
|
||||||
|
Date: Mon, 4 Mar 2024 23:49:06 +0100
|
||||||
|
Subject: [PATCH] lib/xmlparse.c: Detect billion laughs attack with isolated
|
||||||
|
external parser
|
||||||
|
|
||||||
|
When parsing DTD content with code like ..
|
||||||
|
|
||||||
|
XML_Parser parser = XML_ParserCreate(NULL);
|
||||||
|
XML_Parser ext_parser = XML_ExternalEntityParserCreate(parser, NULL, NULL);
|
||||||
|
enum XML_Status status = XML_Parse(ext_parser, doc, (int)strlen(doc), XML_TRUE);
|
||||||
|
|
||||||
|
.. there are 0 bytes accounted as direct input and all input from accounted
|
||||||
|
as indirect input. Now function accountingGetCurrentAmplification cannot calculate
|
||||||
|
the current amplification ratio as "(direct + indirect) / direct", and it did refuse
|
||||||
|
to divide by 0 as one would expect, but it returned 1.0 for this case to indicate
|
||||||
|
no amplification over direct input. As a result, billion laughs attacks from
|
||||||
|
DTD-only input were not detected with this isolated way of using an external parser.
|
||||||
|
|
||||||
|
The new approach is to assume direct input of length not 0 but 22 -- derived from
|
||||||
|
ghost input "<!ENTITY a SYSTEM 'b'>", the shortest possible way to include an external
|
||||||
|
DTD --, and do the usual "(direct + indirect) / direct" math with "direct := 22".
|
||||||
|
|
||||||
|
GitHub issue #839 has more details on this issue and its origin in ClusterFuzz
|
||||||
|
finding 66812.
|
||||||
|
---
|
||||||
|
expat/lib/xmlparse.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||||
|
index b884d82b..d44baa68 100644
|
||||||
|
--- a/lib/xmlparse.c
|
||||||
|
+++ b/lib/xmlparse.c
|
||||||
|
@@ -7787,6 +7787,8 @@ copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
|
||||||
|
|
||||||
|
static float
|
||||||
|
accountingGetCurrentAmplification(XML_Parser rootParser) {
|
||||||
|
+ // 1.........1.........12 => 22
|
||||||
|
+ const size_t lenOfShortestInclude = sizeof("<!ENTITY a SYSTEM 'b'>") - 1;
|
||||||
|
const XmlBigCount countBytesOutput
|
||||||
|
= rootParser->m_accounting.countBytesDirect
|
||||||
|
+ rootParser->m_accounting.countBytesIndirect;
|
||||||
|
@@ -7794,7 +7796,9 @@ accountingGetCurrentAmplification(XML_Parser rootParser) {
|
||||||
|
= rootParser->m_accounting.countBytesDirect
|
||||||
|
? (countBytesOutput
|
||||||
|
/ (float)(rootParser->m_accounting.countBytesDirect))
|
||||||
|
- : 1.0f;
|
||||||
|
+ : ((lenOfShortestInclude
|
||||||
|
+ + rootParser->m_accounting.countBytesIndirect)
|
||||||
|
+ / (float)lenOfShortestInclude);
|
||||||
|
assert(! rootParser->m_parentParser);
|
||||||
|
return amplificationFactor;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
27
backport-CVE-2024-28757-002.patch
Normal file
27
backport-CVE-2024-28757-002.patch
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
From a4c86a395ee447c59175c762af3d17f7107b2261 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sebastian Pipping <sebastian@pipping.org>
|
||||||
|
Date: Sun, 3 Mar 2024 02:19:58 +0100
|
||||||
|
Subject: [PATCH] lib/xmlparse.c: Reject directly recursive parameter entities
|
||||||
|
|
||||||
|
---
|
||||||
|
expat/lib/xmlparse.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/lib/xmlparse.c b/expat/lib/xmlparse.c
|
||||||
|
index b884d82b..8e667fcb 100644
|
||||||
|
--- a/lib/xmlparse.c
|
||||||
|
+++ b/lib/xmlparse.c
|
||||||
|
@@ -6240,7 +6240,7 @@ storeEntityValue(XML_Parser parser, const ENCODING *enc,
|
||||||
|
dtd->keepProcessing = dtd->standalone;
|
||||||
|
goto endEntityValue;
|
||||||
|
}
|
||||||
|
- if (entity->open) {
|
||||||
|
+ if (entity->open || (entity == parser->m_declEntity)) {
|
||||||
|
if (enc == parser->m_encoding)
|
||||||
|
parser->m_eventPtr = entityTextPtr;
|
||||||
|
result = XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
86
backport-CVE-2024-28757-003.patch
Normal file
86
backport-CVE-2024-28757-003.patch
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
From a1c0c15892c89c69d64ca8e5d0322d3f37b08307 Mon Sep 17 00:00:00 2001
|
||||||
|
From: caixiaomeng 00662745 <caixiaomeng2@huawei.com>
|
||||||
|
Date: Thu, 21 Mar 2024 20:29:49 +0800
|
||||||
|
Subject: [PATCH] tests-Cover-amplification-tracking-for-isolated-exte
|
||||||
|
|
||||||
|
---
|
||||||
|
tests/runtests.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 55 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/tests/runtests.c b/tests/runtests.c
|
||||||
|
index 915fa52..1d83237 100644
|
||||||
|
--- a/tests/runtests.c
|
||||||
|
+++ b/tests/runtests.c
|
||||||
|
@@ -12094,6 +12094,59 @@ START_TEST(test_helper_unsigned_char_to_printable) {
|
||||||
|
END_TEST
|
||||||
|
#endif // defined(XML_DTD)
|
||||||
|
|
||||||
|
+START_TEST(test_amplification_isolated_external_parser) {
|
||||||
|
+ // NOTE: Length 44 is precisely twice the length of "<!ENTITY a SYSTEM 'b'>"
|
||||||
|
+ // (22) that is used in function accountingGetCurrentAmplification in
|
||||||
|
+ // xmlparse.c.
|
||||||
|
+ // 1.........1.........1.........1.........1..4 => 44
|
||||||
|
+ const char doc[] = "<!ENTITY % p1 '123456789_123456789_1234567'>";
|
||||||
|
+ const int docLen = (int)sizeof(doc) - 1;
|
||||||
|
+ const float maximumToleratedAmplification = 2.0f;
|
||||||
|
+
|
||||||
|
+ struct TestCase {
|
||||||
|
+ int offsetOfThreshold;
|
||||||
|
+ enum XML_Status expectedStatus;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ struct TestCase cases[] = {
|
||||||
|
+ {-2, XML_STATUS_ERROR}, {-1, XML_STATUS_ERROR}, {0, XML_STATUS_ERROR},
|
||||||
|
+ {+1, XML_STATUS_OK}, {+2, XML_STATUS_OK},
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||||
|
+ const int offsetOfThreshold = cases[i].offsetOfThreshold;
|
||||||
|
+ const enum XML_Status expectedStatus = cases[i].expectedStatus;
|
||||||
|
+ const unsigned long long activationThresholdBytes
|
||||||
|
+ = docLen + offsetOfThreshold;
|
||||||
|
+
|
||||||
|
+ XML_Parser parser = XML_ParserCreate(NULL);
|
||||||
|
+ assert(parser != NULL);
|
||||||
|
+
|
||||||
|
+ assert(XML_SetBillionLaughsAttackProtectionMaximumAmplification(
|
||||||
|
+ parser, maximumToleratedAmplification)
|
||||||
|
+ == XML_TRUE);
|
||||||
|
+ assert(XML_SetBillionLaughsAttackProtectionActivationThreshold(
|
||||||
|
+ parser, activationThresholdBytes)
|
||||||
|
+ == XML_TRUE);
|
||||||
|
+
|
||||||
|
+ XML_Parser ext_parser = XML_ExternalEntityParserCreate(parser, NULL, NULL);
|
||||||
|
+ assert(ext_parser != NULL);
|
||||||
|
+
|
||||||
|
+ const enum XML_Status actualStatus
|
||||||
|
+ = _XML_Parse_SINGLE_BYTES(ext_parser, doc, docLen, XML_TRUE);
|
||||||
|
+
|
||||||
|
+ assert(actualStatus == expectedStatus);
|
||||||
|
+ if (actualStatus != XML_STATUS_OK) {
|
||||||
|
+ assert(XML_GetErrorCode(ext_parser)
|
||||||
|
+ == XML_ERROR_AMPLIFICATION_LIMIT_BREACH);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ XML_ParserFree(ext_parser);
|
||||||
|
+ XML_ParserFree(parser);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+END_TEST
|
||||||
|
+
|
||||||
|
static Suite *
|
||||||
|
make_suite(void) {
|
||||||
|
Suite *s = suite_create("basic");
|
||||||
|
@@ -12334,6 +12387,8 @@ make_suite(void) {
|
||||||
|
tcase_add_test(tc_basic, test_bad_notation);
|
||||||
|
tcase_add_test(tc_basic, test_default_doctype_handler);
|
||||||
|
tcase_add_test(tc_basic, test_empty_element_abort);
|
||||||
|
+ tcase_add_test__ifdef_xml_dtd(tc_basic,
|
||||||
|
+ test_amplification_isolated_external_parser);
|
||||||
|
tcase_add_test__ifdef_xml_dtd(tc_basic,
|
||||||
|
test_pool_integrity_with_unfinished_attr);
|
||||||
|
tcase_add_test(tc_basic, test_nested_entity_suspend);
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
|
|
||||||
75
backport-CVE-2024-28757-004.patch
Normal file
75
backport-CVE-2024-28757-004.patch
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
From cce551e4e1f75b8a3e8dd087bfd6685a2c431cd0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: caixiaomeng 00662745 <caixiaomeng2@huawei.com>
|
||||||
|
Date: Thu, 21 Mar 2024 20:40:48 +0800
|
||||||
|
Subject: [PATCH] tests-Cover-rejection-of-direct-parameter-entity-rec
|
||||||
|
|
||||||
|
---
|
||||||
|
tests/runtests.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 44 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/tests/runtests.c b/tests/runtests.c
|
||||||
|
index 1d83237..03350f4 100644
|
||||||
|
--- a/tests/runtests.c
|
||||||
|
+++ b/tests/runtests.c
|
||||||
|
@@ -12147,6 +12147,48 @@ START_TEST(test_amplification_isolated_external_parser) {
|
||||||
|
}
|
||||||
|
END_TEST
|
||||||
|
|
||||||
|
+START_TEST(test_recursive_external_parameter_entity_2) {
|
||||||
|
+ struct TestCase {
|
||||||
|
+ const char *doc;
|
||||||
|
+ enum XML_Status expectedStatus;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ struct TestCase cases[] = {
|
||||||
|
+ {"<!ENTITY % p1 '%p1;'>", XML_STATUS_ERROR},
|
||||||
|
+ {"<!ENTITY % p1 '%p1;'>"
|
||||||
|
+ "<!ENTITY % p1 'first declaration wins'>",
|
||||||
|
+ XML_STATUS_ERROR},
|
||||||
|
+ {"<!ENTITY % p1 'first declaration wins'>"
|
||||||
|
+ "<!ENTITY % p1 '%p1;'>",
|
||||||
|
+ XML_STATUS_OK},
|
||||||
|
+ {"<!ENTITY % p1 '%p1;'>", XML_STATUS_OK},
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ for (size_t i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
|
||||||
|
+ const char *const doc = cases[i].doc;
|
||||||
|
+ const enum XML_Status expectedStatus = cases[i].expectedStatus;
|
||||||
|
+
|
||||||
|
+ XML_Parser parser = XML_ParserCreate(NULL);
|
||||||
|
+ assert(parser != NULL);
|
||||||
|
+
|
||||||
|
+ XML_Parser ext_parser = XML_ExternalEntityParserCreate(parser, NULL, NULL);
|
||||||
|
+ assert(ext_parser != NULL);
|
||||||
|
+
|
||||||
|
+ const enum XML_Status actualStatus
|
||||||
|
+ = _XML_Parse_SINGLE_BYTES(ext_parser, doc, (int)strlen(doc), XML_TRUE);
|
||||||
|
+
|
||||||
|
+ assert(actualStatus == expectedStatus);
|
||||||
|
+ if (actualStatus != XML_STATUS_OK) {
|
||||||
|
+ assert(XML_GetErrorCode(ext_parser)
|
||||||
|
+ == XML_ERROR_RECURSIVE_ENTITY_REF);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ XML_ParserFree(ext_parser);
|
||||||
|
+ XML_ParserFree(parser);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+END_TEST
|
||||||
|
+
|
||||||
|
static Suite *
|
||||||
|
make_suite(void) {
|
||||||
|
Suite *s = suite_create("basic");
|
||||||
|
@@ -12389,6 +12431,8 @@ make_suite(void) {
|
||||||
|
tcase_add_test(tc_basic, test_empty_element_abort);
|
||||||
|
tcase_add_test__ifdef_xml_dtd(tc_basic,
|
||||||
|
test_amplification_isolated_external_parser);
|
||||||
|
+ tcase_add_test__ifdef_xml_dtd(tc_basic,
|
||||||
|
+ test_recursive_external_parameter_entity_2);
|
||||||
|
tcase_add_test__ifdef_xml_dtd(tc_basic,
|
||||||
|
test_pool_integrity_with_unfinished_attr);
|
||||||
|
tcase_add_test(tc_basic, test_nested_entity_suspend);
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
|
|
||||||
14
expat.spec
14
expat.spec
@ -1,12 +1,21 @@
|
|||||||
%define Rversion %(echo %{version} | sed -e 's/\\./_/g' -e 's/^/R_/')
|
%define Rversion %(echo %{version} | sed -e 's/\\./_/g' -e 's/^/R_/')
|
||||||
Name: expat
|
Name: expat
|
||||||
Version: 2.5.0
|
Version: 2.5.0
|
||||||
Release: 1
|
Release: 2
|
||||||
Summary: An XML parser library
|
Summary: An XML parser library
|
||||||
License: MIT
|
License: MIT
|
||||||
URL: https://libexpat.github.io/
|
URL: https://libexpat.github.io/
|
||||||
Source0: https://github.com/libexpat/libexpat/releases/download/%{Rversion}/expat-%{version}.tar.gz
|
Source0: https://github.com/libexpat/libexpat/releases/download/%{Rversion}/expat-%{version}.tar.gz
|
||||||
|
|
||||||
|
Patch01: backport-CVE-2024-28757-001.patch
|
||||||
|
Patch02: backport-CVE-2024-28757-002.patch
|
||||||
|
Patch03: backport-CVE-2024-28757-003.patch
|
||||||
|
Patch04: backport-CVE-2024-28757-004.patch
|
||||||
|
Patch05: backport-001-CVE-2023-52426.patch
|
||||||
|
Patch06: backport-002-CVE-2023-52426.patch
|
||||||
|
Patch07: backport-003-CVE-2023-52426.patch
|
||||||
|
Patch08: backport-004-CVE-2023-52426.patch
|
||||||
|
|
||||||
BuildRequires: sed,autoconf,automake,gcc-c++,libtool,xmlto
|
BuildRequires: sed,autoconf,automake,gcc-c++,libtool,xmlto
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@ -59,6 +68,9 @@ make check
|
|||||||
%{_mandir}/man1/*
|
%{_mandir}/man1/*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Apr 8 2024 caixiaomeng <caixiaomeng2@huawei.com> - 2.5.0-2
|
||||||
|
- fix cve-2024-28757 and cve-2023-52426
|
||||||
|
|
||||||
* Tue Jan 31 2023 zhoupengcheng <zhoupengcheng11@huawei.com> - 2.5.0-1
|
* Tue Jan 31 2023 zhoupengcheng <zhoupengcheng11@huawei.com> - 2.5.0-1
|
||||||
- expat update to 2.5.0
|
- expat update to 2.5.0
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user