Compare commits

...

No commits in common. "c8" and "c9s-CVE-2025-59375" have entirely different histories.

16 changed files with 243 additions and 170 deletions

View File

@ -1 +0,0 @@
03d9882ede56aa48919fbf50fe17614630257a82 SOURCES/expat-2.5.0.tar.gz

1
.fmf/version Normal file
View File

@ -0,0 +1 @@
1

24
.gitignore vendored
View File

@ -1 +1,23 @@
SOURCES/expat-2.5.0.tar.gz
expat-1.95.8.tar.gz
i386
*.rpm
clog
expat-2.0.1.tar.gz
/results_expat
/expat-2.?.?
/expat-2.1.0.tar.gz
/expat-2.1.1.tar.bz2
/expat-2.2.0.tar.bz2
/expat-2.2.1.tar.gz
/expat-2.2.2.tar.gz
/libexpat-R_*
/expat-2.2.3.tar.gz
/expat-2.2.4.tar.gz
/expat-2.2.5.tar.gz
/expat-2.2.6.tar.gz
/expat-2.2.7.tar.gz
/expat-2.2.8.tar.gz
/expat-2.2.10.tar.gz
/expat-2.4.7.tar.gz
/expat-2.4.9.tar.gz
/expat-2.5.0.tar.gz

1
ci.fmf Normal file
View File

@ -0,0 +1 @@
resultsdb-testcase: separate

View File

@ -1,6 +1,6 @@
commit e16f2e3d9c3fa181dcaeed312ea9bc7de8257942
commit a98f5a8fbed712493420fc7d5377f20d7bc6c65a
Author: Tomas Korbar <tkorbar@redhat.com>
Date: Tue Nov 18 13:01:31 2025 +0100
Date: Fri Nov 14 11:06:12 2025 +0100
Fix CVE-2025-59375
@ -235,18 +235,10 @@ index 69b0ba1..6eae1d6 100644
/* Added in Expat 2.6.0. */
diff --git a/expat/lib/internal.h b/expat/lib/internal.h
index e2709c8..1d1e7da 100644
index e2709c8..b1243d5 100644
--- a/expat/lib/internal.h
+++ b/expat/lib/internal.h
@@ -107,6 +107,7 @@
#endif
#include <limits.h> // ULONG_MAX
+#include <stddef.h> // size_t
#if defined(_WIN32) \
&& (! defined(__USE_MINGW_ANSI_STDIO) \
@@ -144,6 +145,16 @@
@@ -144,6 +144,11 @@
100.0f
#define EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT \
8388608 // 8 MiB, 2^23
@ -254,16 +246,11 @@ index e2709c8..1d1e7da 100644
+#define EXPAT_ALLOC_TRACKER_MAXIMUM_AMPLIFICATION_DEFAULT 100.0f
+#define EXPAT_ALLOC_TRACKER_ACTIVATION_THRESHOLD_DEFAULT \
+ 67108864 // 64 MiB, 2^26
+
+// NOTE: If function expat_alloc was user facing, EXPAT_MALLOC_ALIGNMENT would
+// have to take sizeof(long double) into account
+#define EXPAT_MALLOC_ALIGNMENT sizeof(long long) // largest parser (sub)member
+#define EXPAT_MALLOC_PADDING ((EXPAT_MALLOC_ALIGNMENT) - sizeof(size_t))
+
/* NOTE END */
#include "expat.h" // so we can use type XML_Parser below
@@ -163,6 +174,9 @@ const char *unsignedCharToPrintable(unsigned char c);
@@ -163,6 +168,9 @@ const char *unsignedCharToPrintable(unsigned char c);
extern XML_Bool g_reparseDeferralEnabledDefault; // written ONLY in runtests.c
extern unsigned int g_parseAttempts; // used for testing only
@ -274,7 +261,7 @@ index e2709c8..1d1e7da 100644
#ifdef __cplusplus
}
diff --git a/expat/lib/xmlparse.c b/expat/lib/xmlparse.c
index d68d2c8..cba41f4 100644
index d68d2c8..e962048 100644
--- a/expat/lib/xmlparse.c
+++ b/expat/lib/xmlparse.c
@@ -214,7 +214,7 @@ typedef struct {
@ -362,7 +349,7 @@ index d68d2c8..cba41f4 100644
static void parserInit(XML_Parser parser, const XML_Char *encodingName);
@@ -734,14 +739,215 @@ struct XML_ParserStruct {
@@ -734,14 +739,209 @@ struct XML_ParserStruct {
unsigned long m_hash_secret_salt;
#ifdef XML_DTD
ACCOUNTING m_accounting;
@ -429,14 +416,14 @@ index d68d2c8..cba41f4 100644
+
+void *expat_malloc(XML_Parser parser, size_t size, int sourceLine) {
+ // Detect integer overflow
+ if (SIZE_MAX - size < sizeof(size_t) + EXPAT_MALLOC_PADDING) {
+ if (SIZE_MAX - size < sizeof(size_t)) {
+ return NULL;
+ }
+
+ const XML_Parser rootParser = getRootParserOf(parser, NULL);
+ assert(rootParser->m_parentParser == NULL);
+
+ const size_t bytesToAllocate = sizeof(size_t) + EXPAT_MALLOC_PADDING + size;
+ const size_t bytesToAllocate = sizeof(size_t) + size;
+
+ if ((XmlBigCount)-1 - rootParser->m_alloc_tracker.bytesAllocated
+ < bytesToAllocate) {
@ -473,7 +460,7 @@ index d68d2c8..cba41f4 100644
+ rootParser->m_alloc_tracker.peakBytesAllocated, sourceLine);
+ }
+
+ return (char *)mallocedPtr + sizeof(size_t) + EXPAT_MALLOC_PADDING;
+ return (char *)mallocedPtr + sizeof(size_t);
+}
+
+void expat_free(XML_Parser parser, void *ptr, int sourceLine) {
@ -488,9 +475,8 @@ index d68d2c8..cba41f4 100644
+
+ // Extract size (to the eyes of malloc_fcn/realloc_fcn) and
+ // the original pointer returned by malloc/realloc
+ void *const mallocedPtr = (char *)ptr - EXPAT_MALLOC_PADDING - sizeof(size_t);
+ const size_t bytesAllocated
+ = sizeof(size_t) + EXPAT_MALLOC_PADDING + *(size_t *)mallocedPtr;
+ void *const mallocedPtr = (char *)ptr - sizeof(size_t);
+ const size_t bytesAllocated = sizeof(size_t) + *(size_t *)mallocedPtr;
+
+ // Update accounting
+ assert(rootParser->m_alloc_tracker.bytesAllocated >= bytesAllocated);
@ -524,7 +510,7 @@ index d68d2c8..cba41f4 100644
+
+ // Extract original size (to the eyes of the caller) and the original
+ // pointer returned by malloc/realloc
+ void *mallocedPtr = (char *)ptr - EXPAT_MALLOC_PADDING - sizeof(size_t);
+ void *mallocedPtr = (char *)ptr - sizeof(size_t);
+ const size_t prevSize = *(size_t *)mallocedPtr;
+
+ // Classify upcoming change
@ -539,13 +525,8 @@ index d68d2c8..cba41f4 100644
+ }
+ }
+
+ // NOTE: Integer overflow detection has already been done for us
+ // by expat_heap_increase_tolerable(..) above
+ assert(SIZE_MAX - sizeof(size_t) - EXPAT_MALLOC_PADDING >= size);
+
+ // Actually allocate
+ mallocedPtr = parser->m_mem.realloc_fcn(
+ mallocedPtr, sizeof(size_t) + EXPAT_MALLOC_PADDING + size);
+ mallocedPtr = parser->m_mem.realloc_fcn(mallocedPtr, sizeof(size_t) + size);
+
+ if (mallocedPtr == NULL) {
+ return NULL;
@ -576,12 +557,12 @@ index d68d2c8..cba41f4 100644
+ // Update in-block recorded size
+ *(size_t *)mallocedPtr = size;
+
+ return (char *)mallocedPtr + sizeof(size_t) + EXPAT_MALLOC_PADDING;
+ return (char *)mallocedPtr + sizeof(size_t);
+}
XML_Parser XMLCALL
XML_ParserCreate(const XML_Char *encodingName) {
@@ -1059,19 +1265,34 @@ XML_Parser XMLCALL
@@ -1059,19 +1259,31 @@ XML_Parser XMLCALL
XML_ParserCreate_MM(const XML_Char *encodingName,
const XML_Memory_Handling_Suite *memsuite,
const XML_Char *nameSep) {
@ -597,8 +578,7 @@ index d68d2c8..cba41f4 100644
+ DTD *dtd, XML_Parser parentParser) {
+ XML_Parser parser = NULL;
+
+ const size_t increase
+ = sizeof(size_t) + EXPAT_MALLOC_PADDING + sizeof(struct XML_ParserStruct);
+ const size_t increase = sizeof(size_t) + sizeof(struct XML_ParserStruct);
+
+ if (parentParser != NULL) {
+ const XML_Parser rootParser = getRootParserOf(parentParser, NULL);
@ -611,28 +591,25 @@ index d68d2c8..cba41f4 100644
XML_Memory_Handling_Suite *mtemp;
- parser = memsuite->malloc_fcn(sizeof(struct XML_ParserStruct));
- if (parser != NULL) {
+ void *const sizeAndParser
+ = memsuite->malloc_fcn(sizeof(size_t) + EXPAT_MALLOC_PADDING
+ + sizeof(struct XML_ParserStruct));
+ void *const sizeAndParser = memsuite->malloc_fcn(
+ sizeof(size_t) + sizeof(struct XML_ParserStruct));
+ if (sizeAndParser != NULL) {
+ *(size_t *)sizeAndParser = sizeof(struct XML_ParserStruct);
+ parser = (XML_Parser)((char *)sizeAndParser + sizeof(size_t)
+ + EXPAT_MALLOC_PADDING);
+ parser = (XML_Parser)((char *)sizeAndParser + sizeof(size_t));
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
mtemp->malloc_fcn = memsuite->malloc_fcn;
mtemp->realloc_fcn = memsuite->realloc_fcn;
@@ -1079,18 +1300,59 @@ parserCreate(const XML_Char *encodingName,
@@ -1079,18 +1291,58 @@ parserCreate(const XML_Char *encodingName,
}
} else {
XML_Memory_Handling_Suite *mtemp;
- parser = (XML_Parser)malloc(sizeof(struct XML_ParserStruct));
- if (parser != NULL) {
+ void *const sizeAndParser = malloc(sizeof(size_t) + EXPAT_MALLOC_PADDING
+ + sizeof(struct XML_ParserStruct));
+ void *const sizeAndParser
+ = (XML_Parser)malloc(sizeof(size_t) + sizeof(struct XML_ParserStruct));
+ if (sizeAndParser != NULL) {
+ *(size_t *)sizeAndParser = sizeof(struct XML_ParserStruct);
+ parser = (XML_Parser)((char *)sizeAndParser + sizeof(size_t)
+ + EXPAT_MALLOC_PADDING);
+ parser = (XML_Parser)((char *)sizeAndParser + sizeof(size_t));
mtemp = (XML_Memory_Handling_Suite *)&(parser->m_mem);
mtemp->malloc_fcn = malloc;
mtemp->realloc_fcn = realloc;
@ -684,7 +661,7 @@ index d68d2c8..cba41f4 100644
parser->m_buffer = NULL;
parser->m_bufferLim = NULL;
@@ -1125,7 +1387,7 @@ parserCreate(const XML_Char *encodingName,
@@ -1125,7 +1377,7 @@ parserCreate(const XML_Char *encodingName,
if (dtd)
parser->m_dtd = dtd;
else {
@ -693,7 +670,7 @@ index d68d2c8..cba41f4 100644
if (parser->m_dtd == NULL) {
FREE(parser, parser->m_dataBuf);
FREE(parser, parser->m_atts);
@@ -1159,8 +1421,8 @@ parserCreate(const XML_Char *encodingName,
@@ -1159,8 +1411,8 @@ parserCreate(const XML_Char *encodingName,
parser->m_protocolEncodingName = NULL;
@ -704,7 +681,7 @@ index d68d2c8..cba41f4 100644
parserInit(parser, encodingName);
if (encodingName && ! parser->m_protocolEncodingName) {
@@ -1192,7 +1454,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
@@ -1192,7 +1444,7 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
parser->m_processor = prologInitProcessor;
XmlPrologStateInit(&parser->m_prologState);
if (encodingName != NULL) {
@ -713,7 +690,7 @@ index d68d2c8..cba41f4 100644
}
parser->m_curBase = NULL;
XmlInitEncoding(&parser->m_initEncoding, &parser->m_encoding, 0);
@@ -1254,7 +1516,6 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
@@ -1254,7 +1506,6 @@ parserInit(XML_Parser parser, const XML_Char *encodingName) {
parser->m_unknownEncodingMem = NULL;
parser->m_unknownEncodingRelease = NULL;
parser->m_unknownEncodingData = NULL;
@ -721,7 +698,7 @@ index d68d2c8..cba41f4 100644
parser->m_parsingStatus.parsing = XML_INITIALIZED;
// Reentry can only be triggered inside m_processor calls
parser->m_reenter = XML_FALSE;
@@ -1344,7 +1605,7 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
@@ -1344,7 +1595,7 @@ XML_ParserReset(XML_Parser parser, const XML_Char *encodingName) {
FREE(parser, (void *)parser->m_protocolEncodingName);
parser->m_protocolEncodingName = NULL;
parserInit(parser, encodingName);
@ -730,7 +707,7 @@ index d68d2c8..cba41f4 100644
return XML_TRUE;
}
@@ -1380,7 +1641,7 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
@@ -1380,7 +1631,7 @@ XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName) {
parser->m_protocolEncodingName = NULL;
else {
/* Copy the new encoding name into allocated memory */
@ -739,7 +716,7 @@ index d68d2c8..cba41f4 100644
if (! parser->m_protocolEncodingName)
return XML_STATUS_ERROR;
}
@@ -1489,9 +1750,10 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
@@ -1489,9 +1740,10 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
*/
if (parser->m_ns) {
XML_Char tmp[2] = {parser->m_namespaceSeparator, 0};
@ -752,7 +729,7 @@ index d68d2c8..cba41f4 100644
}
if (! parser)
@@ -1535,7 +1797,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
@@ -1535,7 +1787,7 @@ XML_ExternalEntityParserCreate(XML_Parser oldParser, const XML_Char *context,
parser->m_prologState.inEntityValue = oldInEntityValue;
if (context) {
#endif /* XML_DTD */
@ -761,7 +738,7 @@ index d68d2c8..cba41f4 100644
|| ! setContext(parser, context)) {
XML_ParserFree(parser);
return NULL;
@@ -1647,14 +1909,16 @@ XML_ParserFree(XML_Parser parser) {
@@ -1647,14 +1899,16 @@ XML_ParserFree(XML_Parser parser) {
#else
if (parser->m_dtd)
#endif /* XML_DTD */
@ -781,7 +758,7 @@ index d68d2c8..cba41f4 100644
FREE(parser, parser->m_dataBuf);
FREE(parser, parser->m_nsAtts);
FREE(parser, parser->m_unknownEncodingMem);
@@ -2246,7 +2510,9 @@ XML_GetBuffer(XML_Parser parser, int len) {
@@ -2246,7 +2500,9 @@ XML_GetBuffer(XML_Parser parser, int len) {
parser->m_errorCode = XML_ERROR_NO_MEMORY;
return NULL;
}
@ -792,7 +769,7 @@ index d68d2c8..cba41f4 100644
if (newBuf == 0) {
parser->m_errorCode = XML_ERROR_NO_MEMORY;
return NULL;
@@ -2257,7 +2523,10 @@ XML_GetBuffer(XML_Parser parser, int len) {
@@ -2257,7 +2513,10 @@ XML_GetBuffer(XML_Parser parser, int len) {
memcpy(newBuf, &parser->m_bufferPtr[-keep],
EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr)
+ keep);
@ -804,7 +781,7 @@ index d68d2c8..cba41f4 100644
parser->m_buffer = newBuf;
parser->m_bufferEnd
= parser->m_buffer
@@ -2273,7 +2542,10 @@ XML_GetBuffer(XML_Parser parser, int len) {
@@ -2273,7 +2532,10 @@ XML_GetBuffer(XML_Parser parser, int len) {
if (parser->m_bufferPtr) {
memcpy(newBuf, parser->m_bufferPtr,
EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr));
@ -816,7 +793,7 @@ index d68d2c8..cba41f4 100644
parser->m_bufferEnd
= newBuf
+ EXPAT_SAFE_PTR_DIFF(parser->m_bufferEnd, parser->m_bufferPtr);
@@ -2451,28 +2723,43 @@ XML_GetCurrentColumnNumber(XML_Parser parser) {
@@ -2451,28 +2713,43 @@ XML_GetCurrentColumnNumber(XML_Parser parser) {
void XMLCALL
XML_FreeContentModel(XML_Parser parser, XML_Content *model) {
@ -866,7 +843,7 @@ index d68d2c8..cba41f4 100644
}
void XMLCALL
@@ -2669,6 +2956,13 @@ XML_GetFeatureList(void) {
@@ -2669,6 +2946,13 @@ XML_GetFeatureList(void) {
{XML_FEATURE_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT,
XML_L("XML_BLAP_ACT_THRES"),
EXPAT_BILLION_LAUGHS_ATTACK_PROTECTION_ACTIVATION_THRESHOLD_DEFAULT},
@ -880,7 +857,7 @@ index d68d2c8..cba41f4 100644
#endif
{XML_FEATURE_END, NULL, 0}};
@@ -2697,6 +2991,29 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(
@@ -2697,6 +2981,29 @@ XML_SetBillionLaughsAttackProtectionActivationThreshold(
parser->m_accounting.activationThresholdBytes = activationThresholdBytes;
return XML_TRUE;
}
@ -910,7 +887,7 @@ index d68d2c8..cba41f4 100644
#endif /* XML_DTD */
XML_Bool XMLCALL
@@ -5652,8 +5969,12 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
@@ -5652,8 +5959,12 @@ doProlog(XML_Parser parser, const ENCODING *enc, const char *s, const char *end,
case XML_ROLE_CONTENT_EMPTY:
if (dtd->in_eldecl) {
if (parser->m_elementDeclHandler) {
@ -924,7 +901,7 @@ index d68d2c8..cba41f4 100644
if (! content)
return XML_ERROR_NO_MEMORY;
content->quant = XML_CQUANT_NONE;
@@ -7009,19 +7330,19 @@ normalizePublicId(XML_Char *publicId) {
@@ -7009,19 +7320,19 @@ normalizePublicId(XML_Char *publicId) {
}
static DTD *
@ -953,7 +930,7 @@ index d68d2c8..cba41f4 100644
#endif /* XML_DTD */
p->defaultPrefix.name = NULL;
p->defaultPrefix.binding = NULL;
@@ -7041,7 +7362,7 @@ dtdCreate(const XML_Memory_Handling_Suite *ms) {
@@ -7041,7 +7352,7 @@ dtdCreate(const XML_Memory_Handling_Suite *ms) {
}
static void
@ -962,7 +939,7 @@ index d68d2c8..cba41f4 100644
HASH_TABLE_ITER iter;
hashTableIterInit(&iter, &(p->elementTypes));
for (;;) {
@@ -7049,7 +7370,7 @@ dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
@@ -7049,7 +7360,7 @@ dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
if (! e)
break;
if (e->allocDefaultAtts != 0)
@ -971,7 +948,7 @@ index d68d2c8..cba41f4 100644
}
hashTableClear(&(p->generalEntities));
#ifdef XML_DTD
@@ -7066,9 +7387,9 @@ dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
@@ -7066,9 +7377,9 @@ dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
p->in_eldecl = XML_FALSE;
@ -983,7 +960,7 @@ index d68d2c8..cba41f4 100644
p->scaffold = NULL;
p->scaffLevel = 0;
@@ -7082,7 +7403,7 @@ dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
@@ -7082,7 +7393,7 @@ dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms) {
}
static void
@ -992,7 +969,7 @@ index d68d2c8..cba41f4 100644
HASH_TABLE_ITER iter;
hashTableIterInit(&iter, &(p->elementTypes));
for (;;) {
@@ -7090,7 +7411,7 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
@@ -7090,7 +7401,7 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
if (! e)
break;
if (e->allocDefaultAtts != 0)
@ -1001,7 +978,7 @@ index d68d2c8..cba41f4 100644
}
hashTableDestroy(&(p->generalEntities));
#ifdef XML_DTD
@@ -7102,10 +7423,10 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
@@ -7102,10 +7413,10 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
poolDestroy(&(p->pool));
poolDestroy(&(p->entityValuePool));
if (isDocEntity) {
@ -1015,7 +992,7 @@ index d68d2c8..cba41f4 100644
}
/* Do a deep copy of the DTD. Return 0 for out of memory, non-zero otherwise.
@@ -7113,7 +7434,7 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
@@ -7113,7 +7424,7 @@ dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms) {
*/
static int
dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
@ -1024,7 +1001,7 @@ index d68d2c8..cba41f4 100644
HASH_TABLE_ITER iter;
/* Copy the prefix table. */
@@ -7194,7 +7515,7 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
@@ -7194,7 +7505,7 @@ dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd,
}
#endif
newE->defaultAtts
@ -1033,7 +1010,7 @@ index d68d2c8..cba41f4 100644
if (! newE->defaultAtts) {
return 0;
}
@@ -7356,7 +7677,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
@@ -7356,7 +7667,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
/* table->size is a power of 2 */
table->size = (size_t)1 << INIT_POWER;
tsize = table->size * sizeof(NAMED *);
@ -1042,7 +1019,7 @@ index d68d2c8..cba41f4 100644
if (! table->v) {
table->size = 0;
return NULL;
@@ -7396,7 +7717,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
@@ -7396,7 +7707,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
}
size_t tsize = newSize * sizeof(NAMED *);
@ -1051,7 +1028,7 @@ index d68d2c8..cba41f4 100644
if (! newV)
return NULL;
memset(newV, 0, tsize);
@@ -7412,7 +7733,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
@@ -7412,7 +7723,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
}
newV[j] = table->v[i];
}
@ -1060,7 +1037,7 @@ index d68d2c8..cba41f4 100644
table->v = newV;
table->power = newPower;
table->size = newSize;
@@ -7425,7 +7746,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
@@ -7425,7 +7736,7 @@ lookup(XML_Parser parser, HASH_TABLE *table, KEY name, size_t createSize) {
}
}
}
@ -1069,7 +1046,7 @@ index d68d2c8..cba41f4 100644
if (! table->v[i])
return NULL;
memset(table->v[i], 0, createSize);
@@ -7438,7 +7759,7 @@ static void FASTCALL
@@ -7438,7 +7749,7 @@ static void FASTCALL
hashTableClear(HASH_TABLE *table) {
size_t i;
for (i = 0; i < table->size; i++) {
@ -1078,7 +1055,7 @@ index d68d2c8..cba41f4 100644
table->v[i] = NULL;
}
table->used = 0;
@@ -7448,17 +7769,17 @@ static void FASTCALL
@@ -7448,17 +7759,17 @@ static void FASTCALL
hashTableDestroy(HASH_TABLE *table) {
size_t i;
for (i = 0; i < table->size; i++)
@ -1100,7 +1077,7 @@ index d68d2c8..cba41f4 100644
}
static void FASTCALL
@@ -7478,13 +7799,13 @@ hashTableIterNext(HASH_TABLE_ITER *iter) {
@@ -7478,13 +7789,13 @@ hashTableIterNext(HASH_TABLE_ITER *iter) {
}
static void FASTCALL
@ -1116,7 +1093,7 @@ index d68d2c8..cba41f4 100644
}
static void FASTCALL
@@ -7511,13 +7832,13 @@ poolDestroy(STRING_POOL *pool) {
@@ -7511,13 +7822,13 @@ poolDestroy(STRING_POOL *pool) {
BLOCK *p = pool->blocks;
while (p) {
BLOCK *tem = p->next;
@ -1132,7 +1109,7 @@ index d68d2c8..cba41f4 100644
p = tem;
}
}
@@ -7672,8 +7993,8 @@ poolGrow(STRING_POOL *pool) {
@@ -7672,8 +7983,8 @@ poolGrow(STRING_POOL *pool) {
if (bytesToAllocate == 0)
return XML_FALSE;
@ -1143,7 +1120,7 @@ index d68d2c8..cba41f4 100644
if (temp == NULL)
return XML_FALSE;
pool->blocks = temp;
@@ -7713,7 +8034,7 @@ poolGrow(STRING_POOL *pool) {
@@ -7713,7 +8024,7 @@ poolGrow(STRING_POOL *pool) {
if (bytesToAllocate == 0)
return XML_FALSE;
@ -1152,7 +1129,7 @@ index d68d2c8..cba41f4 100644
if (! tem)
return XML_FALSE;
tem->size = blockSize;
@@ -7828,7 +8149,10 @@ build_model(XML_Parser parser) {
@@ -7828,7 +8139,10 @@ build_model(XML_Parser parser) {
const size_t allocsize = (dtd->scaffCount * sizeof(XML_Content)
+ (dtd->contentStringLen * sizeof(XML_Char)));
@ -1164,7 +1141,7 @@ index d68d2c8..cba41f4 100644
if (! ret)
return NULL;
@@ -7949,7 +8273,7 @@ getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
@@ -7949,7 +8263,7 @@ getElementType(XML_Parser parser, const ENCODING *enc, const char *ptr,
}
static XML_Char *
@ -1173,7 +1150,7 @@ index d68d2c8..cba41f4 100644
size_t charsRequired = 0;
XML_Char *result;
@@ -7961,7 +8285,7 @@ copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
@@ -7961,7 +8275,7 @@ copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
charsRequired++;
/* Now allocate space for the copy */
@ -1183,7 +1160,7 @@ index d68d2c8..cba41f4 100644
return NULL;
/* Copy the original into place */
diff --git a/expat/tests/runtests.c b/expat/tests/runtests.c
index 5db384d..4a0a2e3 100644
index 5db384d..0be1427 100644
--- a/expat/tests/runtests.c
+++ b/expat/tests/runtests.c
@@ -51,6 +51,9 @@
@ -1207,15 +1184,10 @@ index 5db384d..4a0a2e3 100644
#include "chardata.h"
#include "structdata.h"
#include "internal.h"
@@ -11420,6 +11426,209 @@ START_TEST(test_alloc_reset_after_external_entity_parser_create_fail) {
@@ -11420,6 +11426,190 @@ START_TEST(test_alloc_reset_after_external_entity_parser_create_fail) {
}
END_TEST
+static size_t
+sizeRecordedFor(void *ptr) {
+ return *(size_t *)((char *)ptr - EXPAT_MALLOC_PADDING - sizeof(size_t));
+}
+
+START_TEST(test_alloc_tracker_size_recorded) {
+ XML_Memory_Handling_Suite memsuite = {malloc, realloc, free};
+
@ -1229,16 +1201,16 @@ index 5db384d..4a0a2e3 100644
+ void *ptr = expat_malloc(parser, 10, -1);
+
+ assert_true(ptr != NULL);
+ assert_true(sizeRecordedFor(ptr) == 10);
+ assert_true(*((size_t *)ptr - 1) == 10);
+
+ assert_true(expat_realloc(parser, ptr, SIZE_MAX / 2, -1) == NULL);
+
+ assert_true(sizeRecordedFor(ptr) == 10); // i.e. unchanged
+ assert_true(*((size_t *)ptr - 1) == 10); // i.e. unchanged
+
+ ptr = expat_realloc(parser, ptr, 20, -1);
+
+ assert_true(ptr != NULL);
+ assert_true(sizeRecordedFor(ptr) == 20);
+ assert_true(*((size_t *)ptr - 1) == 20);
+
+ expat_free(parser, ptr, -1);
+
@ -1247,20 +1219,6 @@ index 5db384d..4a0a2e3 100644
+}
+END_TEST
+
+START_TEST(test_alloc_tracker_pointer_alignment) {
+ XML_Parser parser = XML_ParserCreate(NULL);
+ assert_true(sizeof(long long) >= sizeof(size_t)); // self-test
+ long long *const ptr
+ = (long long *)expat_malloc(parser, 4 * sizeof(long long), -1);
+ ptr[0] = 0LL;
+ ptr[1] = 1LL;
+ ptr[2] = 2LL;
+ ptr[3] = 3LL;
+ expat_free(parser, ptr, -1);
+ XML_ParserFree(parser);
+}
+END_TEST
+
+START_TEST(test_alloc_tracker_maximum_amplification) {
+ if (g_reparseDeferralEnabledDefault == XML_TRUE) {
+ return;
@ -1417,7 +1375,7 @@ index 5db384d..4a0a2e3 100644
static void
nsalloc_setup(void) {
XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
@@ -11820,10 +12029,8 @@ START_TEST(test_nsalloc_realloc_attributes) {
@@ -11820,10 +12010,8 @@ START_TEST(test_nsalloc_realloc_attributes) {
nsalloc_teardown();
nsalloc_setup();
}
@ -1430,12 +1388,11 @@ index 5db384d..4a0a2e3 100644
}
END_TEST
@@ -13694,6 +13901,18 @@ make_suite(void) {
@@ -13694,6 +13882,17 @@ make_suite(void) {
tcase_add_test__ifdef_xml_dtd(
tc_alloc, test_alloc_reset_after_external_entity_parser_create_fail);
+ tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_tracker_size_recorded);
+ tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_tracker_pointer_alignment);
+ tcase_add_test__ifdef_xml_dtd(tc_alloc,
+ test_alloc_tracker_maximum_amplification);
+ tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_tracker_threshold);

View File

@ -3,7 +3,7 @@
Summary: An XML parser library
Name: expat
Version: %(echo %{unversion} | sed 's/_/./g')
Release: 1%{?dist}
Release: 6%{?dist}
Source: https://github.com/libexpat/libexpat/archive/R_%{unversion}.tar.gz#/expat-%{version}.tar.gz
URL: https://libexpat.github.io/
License: MIT
@ -23,7 +23,7 @@ Patch4: expat-2.5.0-CVE-2024-45492.patch
Patch5: expat-2.5.0-CVE-2024-50602.patch
# https://issues.redhat.com/browse/RHEL-57489
Patch6: expat-2.5.0-CVE-2024-8176.patch
# https://issues.redhat.com/browse/RHEL-114618
# https://issues.redhat.com/browse/RHEL-114643
Patch7: expat-2.5.0-CVE-2025-59375.patch
%description
@ -70,21 +70,21 @@ sed -i 's/install-data-hook/do-nothing-please/' lib/Makefile.am
export CFLAGS="$RPM_OPT_FLAGS -fPIC"
export DOCBOOK_TO_MAN="xmlto man --skip-validation"
%configure
make %{?_smp_mflags}
%make_build
%install
make install DESTDIR=$RPM_BUILD_ROOT
%make_install
rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
%check
bash -c "for i in {1..500000}; do printf AAAAAAAAAAAAAAAAAAAA >> achars.txt; done"
for testfile in ../testdata/largefiles/aaaaaa_*; do
first_part="$(sed 's/\(.*\)ACHARS.*/\1/g' $testfile)"
second_part="$(sed 's/.*ACHARS\(.*\)/\1/g' $testfile)"
printf "$first_part" > "$testfile"
cat achars.txt >> "$testfile"
printf "$second_part" >> "$testfile"
first_part="$(sed 's/\(.*\)ACHARS.*/\1/g' $testfile)"
second_part="$(sed 's/.*ACHARS\(.*\)/\1/g' $testfile)"
printf "$first_part" > "$testfile"
cat achars.txt >> "$testfile"
printf "$second_part" >> "$testfile"
done
make check
@ -92,7 +92,6 @@ make check
%ldconfig_scriptlets
%files
%{!?_licensedir:%global license %%doc}
%doc AUTHORS Changes
%license COPYING
%{_bindir}/*
@ -110,61 +109,50 @@ make check
%{_libdir}/lib*.a
%changelog
* Wed Nov 19 2025 Tomas Korbar <tkorbar@redhat.com> - 2.5.0-1
- Rebase to version 2.5.0
* Fri Nov 14 2025 Tomas Korbar <tkorbar@redhat.com> - 2.5.0-6
- Fix CVE-2025-59375
- Resolves: RHEL-114618
- Resolves: RHEL-114643
* Mon Apr 07 2025 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-17
* Mon Mar 31 2025 Tomas Korbar <tkorbar@redhat.com> - 2.5.0-5
- Fix CVE-2024-8176
- Resolves: RHEL-57477
- Resolves: RHEL-57489
* Fri Nov 08 2024 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-16
* Thu Nov 07 2024 Tomas Korbar <tkorbar@redhat.com> - 2.5.0-4
- Fix CVE-2024-50602
- Resolves: RHEL-65062
- Resolves: RHEL-65066
* Wed Sep 11 2024 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-15
- Rebuild for test reconfiguration
* Wed Oct 09 2024 Tomas Korbar <tkorbar@redhat.com> - 2.5.0-3
- Fix CVE-2024-45490, CVE-2024-45491, CVE-2024-45492
- Resolves: RHEL-56761
- Resolves: RHEL-57520
- Resolves: RHEL-57511
* Wed Sep 11 2024 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-14
- Fix multiple CVEs
- Fix CVE-2024-45492 integer overflow
- Fix CVE-2024-45491 Integer Overflow or Wraparound
- Fix CVE-2024-45490 Negative Length Parsing Vulnerability
- Resolves: RHEL-57505
- Resolves: RHEL-57493
- Resolves: RHEL-56751
* Tue Feb 13 2024 Tomas Korbar <tkorbar@redhat.com> - 2.5.0-2
- Fix parsing of large tokens
- Reject direct parameter entity recursion
- Resolves: RHEL-29699
- Resolves: RHEL-29696
* Tue Mar 26 2024 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-13
- Fix wrongly exposed variables
- Resolves: RHEL-29321
* Thu Mar 21 2024 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-12
- CVE-2023-52425 expat: parsing large tokens can trigger a denial of service
- Resolves: RHEL-29321
* Mon Nov 14 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-11
- CVE-2022-43680 expat: use-after free caused by overeager destruction of a shared DTD in XML_ExternalEntityParserCreate
* Thu Nov 10 2022 Tomas Korbar <tkorbar@redhat.com> - 2.5.0-1
- Rebase to version 2.5.0
- Resolves: CVE-2022-43680
* Fri Sep 30 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-10
- Ensure raw tagnames are safe exiting internalEntityParser
* Thu Sep 29 2022 Tomas Korbar <tkorbar@redhat.com> - 2.4.9-1
- Rebase to version 2.4.9
- Resolves: CVE-2022-40674
* Fri May 06 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-9
- Fix multiple CVEs
- Resolves: CVE-2022-25314
* Tue Apr 26 2022 Tomas Korbar <tkorbar@redhat.com> - 2.4.7-1
- Rebase to version 2.4.7
- Resolves: rhbz#2067201
- Resolves: CVE-2022-25313
- Resolves: CVE-2022-25314
- Resolves: CVE-2022-25236
* Mon Mar 14 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-8
- Improve patch for CVE-2022-25236
* Mon Mar 14 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-11
- Improve fix for CVE-2022-25236
- Related: CVE-2022-25236
* Fri Mar 04 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-7
- Fix patch for CVE-2022-25235
- Resolves: CVE-2022-25235
* Thu Mar 03 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-6
* Mon Feb 28 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-10
- Fix multiple CVEs
- CVE-2022-25236 expat: namespace-separator characters in "xmlns[:prefix]" attribute values can lead to arbitrary code execution
- CVE-2022-25235 expat: malformed 2- and 3-byte UTF-8 sequences can lead to arbitrary code execution
@ -173,20 +161,25 @@ make check
- Resolves: CVE-2022-25235
- Resolves: CVE-2022-25315
* Fri Feb 14 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.5-5
- Fix multiple CVEs
* Thu Feb 10 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-9
- CVE-2022-23852 expat: integer overflow in function XML_GetBuffer
- Resolves: CVE-2022-23852
* Thu Feb 10 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-8
- CVE-2021-45960 expat: Large number of prefixed XML attributes on a single tag can crash libexpat
- Resolves: CVE-2021-45960
* Wed Feb 09 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-7
- CVE-2021-46143 expat: Integer overflow in doProlog in xmlparse.c
- Resolves: CVE-2021-46143
* Wed Feb 09 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-6
- CVE-2022-22827 Integer overflow in storeAtts in xmlparse.c
- CVE-2022-22826 Integer overflow in nextScaffoldPart in xmlparse.c
- CVE-2022-22825 Integer overflow in lookup in xmlparse.c
- CVE-2022-22824 Integer overflow in defineAttribute in xmlparse.c
- CVE-2022-22823 Integer overflow in build_model in xmlparse.c
- CVE-2022-22822 Integer overflow in addBinding in xmlparse.c
- Resolves: CVE-2022-23852
- Resolves: CVE-2021-45960
- Resolves: CVE-2021-46143
- Resolves: CVE-2022-22827
- Resolves: CVE-2022-22826
- Resolves: CVE-2022-22825
@ -194,8 +187,46 @@ make check
- Resolves: CVE-2022-22823
- Resolves: CVE-2022-22822
* Fri Apr 24 2020 Joe Orton <jorton@redhat.com> - 2.2.5-4
- add security fixes for CVE-2018-20843, CVE-2019-15903
* Mon Feb 07 2022 Tomas Korbar <tkorbar@redhat.com> - 2.2.10-5
- CVE-2022-23990 expat: integer overflow in the doProlog function
- Resolve: rhbz#2050503
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 2.2.10-4
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 2.2.10-3
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.10-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Fri Nov 13 2020 Joe Orton <jorton@redhat.com> - 2.2.10-1
- update to 2.2.10 (#1884940)
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.8-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.8-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Mon Sep 16 2019 Joe Orton <jorton@redhat.com> - 2.2.8-1
- update to 2.2.8 (#1752167)
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.7-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Thu Jun 27 2019 Joe Orton <jorton@redhat.com> - 2.2.7-1
- update to 2.2.7 (#1723724, #1722224)
* Thu Jan 31 2019 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.6-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Wed Aug 15 2018 Joe Orton <jorton@redhat.com> - 2.2.6-1
- update to 2.2.6
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.5-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 2.2.5-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild

25
gating.yaml Normal file
View File

@ -0,0 +1,25 @@
--- !Policy
product_versions:
- fedora-*
decision_context: bodhi_update_push_testing
subject_type: koji_build
rules:
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/tier1-public.functional}
#Rawhide
--- !Policy
product_versions:
- fedora-*
decision_context: bodhi_update_push_stable
subject_type: koji_build
rules:
- !PassingTestCaseRule {test_case_name: fedora-ci.koji-build./plans/tier1-public.functional}
#gating rhel
--- !Policy
product_versions:
- rhel-*
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-public.functional}
- !PassingTestCaseRule {test_case_name: osci.brew-build./plans/tier1-internal.functional}

36
plans.fmf Normal file
View File

@ -0,0 +1,36 @@
/tier1-internal:
plan:
import:
url: https://src.fedoraproject.org/tests/expat.git
name: /plans/tier1/internal
/tier1-public:
plan:
import:
url: https://src.fedoraproject.org/tests/expat.git
name: /plans/tier1/public
/tier2-tier3-internal:
plan:
import:
url: https://src.fedoraproject.org/tests/expat.git
name: /plans/tier2-tier3/internal
/tier2-tier3-public:
plan:
import:
url: https://src.fedoraproject.org/tests/expat.git
name: /plans/tier2-tier3/public
/others-internal:
plan:
import:
url: https://src.fedoraproject.org/tests/expat.git
name: /plans/others/internal
/others-public:
plan:
import:
url: https://src.fedoraproject.org/tests/expat.git
name: /plans/others/public

1
sources Normal file
View File

@ -0,0 +1 @@
SHA512 (expat-2.5.0.tar.gz) = 779f0d0f3f2d8b33db0fd044864ab5ab1a40f20501f792fe90ad0d18de536c4765c3749f120e21fec11a0e6c89af1dc576d1fe261c871ca44a594f7b61fd1d9e