Compare commits
No commits in common. "c8" and "c8-beta" have entirely different histories.
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1 @@
|
||||
SOURCES/benchmark-tests.tar.xz
|
||||
SOURCES/xmlrpc-c-1.51.0.tar.xz
|
||||
|
@ -1,2 +1 @@
|
||||
b4fb65d500c1af5fe83917ab2976a47ae6268fdd SOURCES/benchmark-tests.tar.xz
|
||||
784a3e74971f3b7d992d768c732daa891ffd2412 SOURCES/xmlrpc-c-1.51.0.tar.xz
|
||||
|
@ -1,106 +0,0 @@
|
||||
From 66e6f8700959f7a54056ed7946c179d808e838e8 Mon Sep 17 00:00:00 2001
|
||||
From: Rob Crittenden <rcritten@redhat.com>
|
||||
Date: Thu, 25 Apr 2024 09:26:04 -0400
|
||||
Subject: [PATCH] Address segfault found in CVE-2023-52425
|
||||
|
||||
The CVE addresses a possible DoS when unreasonably large tokens
|
||||
are passed into the XML parser for processing. These were taking
|
||||
upwards of 8 seconds per file processed with the exception of
|
||||
aaaaaa_cdata.xml which caused a segmentation fault. The XML
|
||||
processor was effectively losing the start of the string, setting
|
||||
it to NULL. This caused a cascade of errors trying to parse both
|
||||
the next token and in handling errors if a new token was not found.
|
||||
|
||||
This handles both those cases but not the underlying reason why
|
||||
the pointer to inputStart is lost.
|
||||
|
||||
Trying to backport the libexpat changes to address the performance
|
||||
issue would be enormous since the xmlrpc-c custom version of libexpat
|
||||
is extremely old. Since xmlrpc-c is mostly used as a client passing
|
||||
in random values is less of an issue.
|
||||
|
||||
Include the libexpat upstream benchmark test to validate that the
|
||||
tests pass, albeit slowly.
|
||||
|
||||
To run the benchmarks:
|
||||
extract the sources
|
||||
cd xmlrpc-c-1.51.0
|
||||
make
|
||||
cd test
|
||||
make
|
||||
cd benchmark
|
||||
for file in *.xml; do ./benchmark $file 4096 1; done
|
||||
|
||||
One test will error out but this is expected as part of the fix.
|
||||
|
||||
The tests will be extracted as a Source because of their
|
||||
uncompressed size (~48M)
|
||||
|
||||
Fixes: RHEL-24226
|
||||
---
|
||||
lib/expat/xmlparse/xmlparse.c | 3 +++
|
||||
lib/expat/xmltok/xmltok_impl.c | 4 ++++
|
||||
test/Makefile | 7 +++++--
|
||||
3 files changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/expat/xmlparse/xmlparse.c b/lib/expat/xmlparse/xmlparse.c
|
||||
index 16ab82a..6621d18 100644
|
||||
--- a/lib/expat/xmlparse/xmlparse.c
|
||||
+++ b/lib/expat/xmlparse/xmlparse.c
|
||||
@@ -35,6 +35,9 @@ extractXmlSample(const char * const start,
|
||||
size_t const maximumLen) {
|
||||
|
||||
size_t const len = MIN(maximumLen, (size_t)(end - start));
|
||||
+ if (start == NULL) {
|
||||
+ return strdup("");
|
||||
+ }
|
||||
|
||||
return xmlrpc_makePrintable_lp(start, len);
|
||||
}
|
||||
diff --git a/lib/expat/xmltok/xmltok_impl.c b/lib/expat/xmltok/xmltok_impl.c
|
||||
index bae79b9..80da94f 100644
|
||||
--- a/lib/expat/xmltok/xmltok_impl.c
|
||||
+++ b/lib/expat/xmltok/xmltok_impl.c
|
||||
@@ -871,6 +871,10 @@ PREFIX(contentTok)(const ENCODING * const enc,
|
||||
*/
|
||||
PREFIX(chopToWholeCharacters)(inputStart, inputEnd, &end);
|
||||
|
||||
+ if (inputStart == NULL) {
|
||||
+ *nextTokPtr = NULL;
|
||||
+ return XML_TOK_INVALID;
|
||||
+ }
|
||||
if (end == inputStart) {
|
||||
*nextTokPtr = inputStart;
|
||||
return XML_TOK_PARTIAL;
|
||||
diff --git a/test/Makefile b/test/Makefile
|
||||
index 4fce824..1242910 100644
|
||||
--- a/test/Makefile
|
||||
+++ b/test/Makefile
|
||||
@@ -7,7 +7,7 @@ SUBDIR := test
|
||||
|
||||
include $(BLDDIR)/config.mk
|
||||
|
||||
-SUBDIRS = cpp
|
||||
+SUBDIRS = cpp benchmark
|
||||
|
||||
XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test
|
||||
|
||||
@@ -98,11 +98,14 @@ runtests_local: test cgitest1
|
||||
./test
|
||||
|
||||
.PHONY: runtests
|
||||
-runtests: runtests_local cpp/runtests
|
||||
+runtests: runtests_local cpp/runtests benchmark/runtests
|
||||
|
||||
cpp/runtests: FORCE
|
||||
$(MAKE) -C $(dir $@) $(notdir $@)
|
||||
|
||||
+benchmark/runtests:
|
||||
+ $(MAKE) -C $(dir $@) $(notdir $@)
|
||||
+
|
||||
.PHONY: install
|
||||
install:
|
||||
|
||||
--
|
||||
2.42.0
|
||||
|
@ -1,40 +0,0 @@
|
||||
From d15ba056c15db75c9153fda27a62b1a6cfb8196e Mon Sep 17 00:00:00 2001
|
||||
From: Rob Crittenden <rcritten@redhat.com>
|
||||
Date: Mon, 9 Sep 2024 14:35:28 -0400
|
||||
Subject: [PATCH] Prevent integer overflow or wraparound CVE-2024-45491
|
||||
|
||||
An issue was discovered in libexpat before 2.6.3. dtdCopy in
|
||||
xmlparse.c can have an integer overflow for nDefaultAtts on
|
||||
32-bit platforms (where UINT_MAX equals SIZE_MAX).
|
||||
|
||||
Backported from upstream https://github.com/libexpat/libexpat/pull/891
|
||||
|
||||
Resolves: RHEL-57519
|
||||
---
|
||||
lib/expat/xmlparse/xmlparse.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/lib/expat/xmlparse/xmlparse.c b/lib/expat/xmlparse/xmlparse.c
|
||||
index 359267a..40f753b 100644
|
||||
--- a/lib/expat/xmlparse/xmlparse.c
|
||||
+++ b/lib/expat/xmlparse/xmlparse.c
|
||||
@@ -1020,6 +1020,16 @@ static int dtdCopy(XML_Parser oldParser, DTD *newDtd, const DTD *oldDtd)
|
||||
if (!newE)
|
||||
return 0;
|
||||
if (oldE->nDefaultAtts) {
|
||||
+ /* Detect and prevent integer overflow.
|
||||
+ * The preprocessor guard addresses the "always false" warning
|
||||
+ * from -Wtype-limits on platforms where
|
||||
+ * sizeof(int) < sizeof(size_t), e.g. on x86_64. */
|
||||
+#if UINT_MAX >= SIZE_MAX
|
||||
+ if ((size_t)oldE->nDefaultAtts
|
||||
+ > ((size_t)(-1) / sizeof(DEFAULT_ATTRIBUTE))) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+#endif
|
||||
newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
|
||||
malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
|
||||
if (!newE->defaultAtts)
|
||||
--
|
||||
2.45.0
|
||||
|
@ -1,473 +0,0 @@
|
||||
From 6d8259c43c7d675987d96bf990b6b57402d27f28 Mon Sep 17 00:00:00 2001
|
||||
From: root <root@vm-10-0-185-207.hosted.upshift.rdu2.redhat.com>
|
||||
Date: Wed, 19 Mar 2025 12:52:04 -0400
|
||||
Subject: [PATCH 09/10] Restrict XML Entity Expansion Depth in libexpat
|
||||
CVE-2024-8176
|
||||
|
||||
The embedded libexpat library is vulnerable to a stack overflow
|
||||
due to uncontrolled recursion when processing deeply nested XML
|
||||
entities. This can cause the application to crash, resulting in
|
||||
a denial of service (DoS) or potentially leading to memory
|
||||
corruption, depending on the user's environment and how the
|
||||
library is used. The issue is triggered by supplying a specially
|
||||
crafted XML document designed to create a long chain of recursive
|
||||
entities.
|
||||
|
||||
libexpat addressed this upstream in
|
||||
https://github.com/libexpat/libexpat/pull/973
|
||||
but the embedded copy within xmlrpc-c is so old there is no chance
|
||||
of applying this without rebasing it. Instead a recursion counter
|
||||
is added to the parser to limit the depth.
|
||||
|
||||
Resolves: RHEL-57536
|
||||
---
|
||||
lib/expat/xmlparse/xmlparse.c | 40 +++++++++++++---
|
||||
test/Makefile | 30 ++++++++++--
|
||||
test/overflow_attr_test.c | 88 +++++++++++++++++++++++++++++++++++
|
||||
test/overflow_entity_test.c | 86 ++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 234 insertions(+), 10 deletions(-)
|
||||
create mode 100644 test/overflow_attr_test.c
|
||||
create mode 100644 test/overflow_entity_test.c
|
||||
|
||||
diff --git a/lib/expat/xmlparse/xmlparse.c b/lib/expat/xmlparse/xmlparse.c
|
||||
index c440ac7..467910a 100644
|
||||
--- a/lib/expat/xmlparse/xmlparse.c
|
||||
+++ b/lib/expat/xmlparse/xmlparse.c
|
||||
@@ -29,6 +29,8 @@ See the file copying.txt for copying permission.
|
||||
#include "xmldef.h"
|
||||
#include "xmlparse.h"
|
||||
|
||||
+#define MAX_RECURSE 28
|
||||
+
|
||||
static const char *
|
||||
extractXmlSample(const char * const start,
|
||||
const char * const end,
|
||||
@@ -312,6 +314,7 @@ typedef struct {
|
||||
enum XML_ParamEntityParsing m_paramEntityParsing;
|
||||
XML_Parser m_parentParser;
|
||||
unsigned long m_hash_secret_salt;
|
||||
+ int m_recurse_lock;
|
||||
} Parser;
|
||||
|
||||
#define userData (((Parser *)parser)->m_userData)
|
||||
@@ -388,6 +391,7 @@ typedef struct {
|
||||
#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
|
||||
#define parentParser (((Parser *)parser)->m_parentParser)
|
||||
#define hash_secret_salt (((Parser *)parser)->m_hash_secret_salt)
|
||||
+#define recurse_lock (((Parser *)parser)->m_recurse_lock)
|
||||
|
||||
|
||||
|
||||
@@ -515,7 +519,7 @@ poolGrow(STRING_POOL * const poolP,
|
||||
size_t const newSize =
|
||||
offsetof(BLOCK, s) + blockSize * sizeof(XML_Char);
|
||||
|
||||
- BLOCK * const newBlocksP = malloc(newSize);
|
||||
+ BLOCK * const newBlocksP = calloc(offsetof(BLOCK, s) + blockSize, sizeof(XML_Char));
|
||||
|
||||
if (newBlocksP) {
|
||||
newBlocksP->size = blockSize;
|
||||
@@ -1143,6 +1147,7 @@ const XML_Char *getContext(XML_Parser parser)
|
||||
{
|
||||
HASH_TABLE_ITER iter;
|
||||
int needSep = 0;
|
||||
+ Parser * const parserP = (Parser *) parser;
|
||||
|
||||
if (dtd.defaultPrefix.binding) {
|
||||
int i;
|
||||
@@ -1191,7 +1196,7 @@ const XML_Char *getContext(XML_Parser parser)
|
||||
ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
|
||||
if (!e)
|
||||
break;
|
||||
- if (!e->open)
|
||||
+ if (!e->open || parserP->m_recurse_lock > MAX_RECURSE)
|
||||
continue;
|
||||
if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
|
||||
return 0;
|
||||
@@ -1210,6 +1215,7 @@ static
|
||||
int setContext(XML_Parser parser, const XML_Char *context)
|
||||
{
|
||||
const XML_Char *s = context;
|
||||
+ Parser * const parserP = (Parser *) parser;
|
||||
|
||||
while (*context != XML_T('\0')) {
|
||||
if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
|
||||
@@ -1218,8 +1224,9 @@ int setContext(XML_Parser parser, const XML_Char *context)
|
||||
return 0;
|
||||
e = (ENTITY *)lookup(parser, &dtd.generalEntities, poolStart(&tempPool),
|
||||
0);
|
||||
- if (e)
|
||||
+ if (e) {
|
||||
e->open = 1;
|
||||
+ }
|
||||
if (*s != XML_T('\0'))
|
||||
s++;
|
||||
context = s;
|
||||
@@ -1860,7 +1867,7 @@ appendAttributeValue(XML_Parser const xmlParserP,
|
||||
return XML_ERROR_UNDEFINED_ENTITY;
|
||||
}
|
||||
}
|
||||
- else if (entity->open) {
|
||||
+ else if (entity->open || parser->m_recurse_lock > MAX_RECURSE) {
|
||||
if (enc == parser->m_encoding)
|
||||
eventPtr = ptr;
|
||||
return XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||
@@ -1879,10 +1886,12 @@ appendAttributeValue(XML_Parser const xmlParserP,
|
||||
enum XML_Error result;
|
||||
const XML_Char *textEnd = entity->textPtr + entity->textLen;
|
||||
entity->open = 1;
|
||||
+ parser->m_recurse_lock++;
|
||||
result = appendAttributeValue(xmlParserP, internalEncoding,
|
||||
isCdata, (char *)entity->textPtr,
|
||||
(char *)textEnd, pool);
|
||||
entity->open = 0;
|
||||
+ parser->m_recurse_lock--;
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
@@ -1952,7 +1961,7 @@ storeEntityValue(XML_Parser const xmlParserP,
|
||||
eventPtr = entityTextPtr;
|
||||
return XML_ERROR_UNDEFINED_ENTITY;
|
||||
}
|
||||
- if (entity->open) {
|
||||
+ if (entity->open || parser->m_recurse_lock > MAX_RECURSE) {
|
||||
if (enc == parser->m_encoding)
|
||||
eventPtr = entityTextPtr;
|
||||
return XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||
@@ -2641,8 +2650,13 @@ doInternalEntityRef(XML_Parser const xmlParserP,
|
||||
*errorP = NULL;
|
||||
} else {
|
||||
OPEN_INTERNAL_ENTITY openEntity;
|
||||
+ if (entityP->open || parserP->m_recurse_lock > MAX_RECURSE) {
|
||||
+ *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
entityP->open = 1; /* recursion control */
|
||||
+ parserP->m_recurse_lock++;
|
||||
|
||||
openEntity.next = parserP->m_openInternalEntities;
|
||||
|
||||
@@ -2659,6 +2673,7 @@ doInternalEntityRef(XML_Parser const xmlParserP,
|
||||
0, errorCodeP, errorP);
|
||||
|
||||
entityP->open = 0; /* recursion control */
|
||||
+ parserP->m_recurse_lock--;
|
||||
parserP->m_openInternalEntities = openEntity.next;
|
||||
}
|
||||
}
|
||||
@@ -2681,8 +2696,14 @@ doExternalEntityRef(XML_Parser const xmlParserP,
|
||||
if (parserP->m_externalEntityRefHandler) {
|
||||
const XML_Char * contextP;
|
||||
|
||||
+ if (entityP->open || parserP->m_recurse_lock > MAX_RECURSE) {
|
||||
+ *errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||
+ return;
|
||||
+ }
|
||||
entityP->open = 1;
|
||||
+ parserP->m_recurse_lock++;
|
||||
contextP = getContext(xmlParserP);
|
||||
+ parserP->m_recurse_lock--;
|
||||
entityP->open = 0;
|
||||
|
||||
if (!contextP)
|
||||
@@ -2753,7 +2774,7 @@ doEntityRef(XML_Parser const xmlParserP,
|
||||
*errorCodeP = XML_ERROR_NONE;
|
||||
}
|
||||
} else {
|
||||
- if (entityP->open)
|
||||
+ if (entityP->open || parserP->m_recurse_lock > MAX_RECURSE)
|
||||
*errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||
else if (entityP->notation)
|
||||
*errorCodeP = XML_ERROR_BINARY_ENTITY_REF;
|
||||
@@ -4059,7 +4080,7 @@ doProlog(XML_Parser const xmlParserP,
|
||||
*errorCodeP = XML_ERROR_UNDEFINED_ENTITY;
|
||||
return;
|
||||
}
|
||||
- if (entity->open) {
|
||||
+ if (entity->open || parser->m_recurse_lock > MAX_RECURSE) {
|
||||
*errorCodeP = XML_ERROR_RECURSIVE_ENTITY_REF;
|
||||
return;
|
||||
}
|
||||
@@ -4076,16 +4097,19 @@ doProlog(XML_Parser const xmlParserP,
|
||||
if (externalEntityRefHandler) {
|
||||
dtd.complete = 0;
|
||||
entity->open = 1;
|
||||
+ parser->m_recurse_lock++;
|
||||
if (!externalEntityRefHandler(externalEntityRefHandlerArg,
|
||||
0,
|
||||
entity->base,
|
||||
entity->systemId,
|
||||
entity->publicId)) {
|
||||
entity->open = 0;
|
||||
+ parser->m_recurse_lock--;
|
||||
*errorCodeP = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
|
||||
return;
|
||||
}
|
||||
entity->open = 0;
|
||||
+ parser->m_recurse_lock--;
|
||||
if (dtd.complete)
|
||||
break;
|
||||
}
|
||||
@@ -4199,6 +4223,7 @@ processInternalParamEntity(XML_Parser const parser,
|
||||
const char *s, *end, *next;
|
||||
int tok;
|
||||
OPEN_INTERNAL_ENTITY openEntity;
|
||||
+ Parser * const parserP = (Parser *) parser;
|
||||
|
||||
entity->open = 1;
|
||||
openEntity.next = openInternalEntities;
|
||||
@@ -4292,6 +4317,7 @@ xmlrpc_XML_ParserCreate(const XML_Char * const encodingName) {
|
||||
parser->m_paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
|
||||
parser->m_hash_secret_salt = 0;
|
||||
parser->m_ns = 0;
|
||||
+ parser->m_recurse_lock = 0;
|
||||
poolInit(&parser->m_tempPool);
|
||||
poolInit(&parser->m_temp2Pool);
|
||||
parser->m_protocolEncodingName =
|
||||
diff --git a/test/Makefile b/test/Makefile
|
||||
index 1242910..59c698c 100644
|
||||
--- a/test/Makefile
|
||||
+++ b/test/Makefile
|
||||
@@ -16,9 +16,9 @@ LDADD_CGI_SERVER = \
|
||||
|
||||
default: all
|
||||
|
||||
-INCLUDES = -I$(BLDDIR) -Isrcdir/include -Isrcdir/lib/util/include \
|
||||
+INCLUDES = -I$(BLDDIR) -I$(SRCDIR)/include -I$(SRCDIR)/lib/util/include \
|
||||
|
||||
-PROGS = test cgitest1
|
||||
+PROGS = test cgitest1 overflow_attr_test overflow_entity_test
|
||||
|
||||
all: $(PROGS) $(SUBDIRS:%=%/all)
|
||||
|
||||
@@ -86,6 +86,28 @@ OBJS = $(TEST_OBJS) cgitest1.o
|
||||
$(OBJS):%.o:%.c
|
||||
$(CC) -c $(INCLUDES) $(CFLAGS_ALL) $<
|
||||
|
||||
+OVERFLOW_ATTR_OBJS = overflow_attr_test.o
|
||||
+
|
||||
+overflow_attr_test: $(OVERFLOW_ATTR_OBJS) $(LIBXMLRPC_SERVER_A) \
|
||||
+ $(LIBXMLRPC_A) $(LIBXMLRPC_UTIL_A) $(LIBXMLRPC_XML)
|
||||
+ $(CCLD) -o $@ $(LDFLAGS_ALL) \
|
||||
+ $(OVERFLOW_ATTR_OBJS) $(LDADD_CLIENT) $(LDADD_ABYSS_SERVER) $(CASPRINTF)
|
||||
+OBJS = overflow_attr_test.o
|
||||
+
|
||||
+$(OBJS):%.o:%.c
|
||||
+ $(CC) -c $(INCLUDES) -I$(SRCDIR)/lib/expat/xmlparse/ $(CFLAGS_ALL) $<
|
||||
+
|
||||
+OVERFLOW_ENTITY_OBJS = overflow_entity_test.o
|
||||
+
|
||||
+overflow_entity_test: $(OVERFLOW_ENTITY_OBJS) $(LIBXMLRPC_SERVER_A) \
|
||||
+ $(LIBXMLRPC_A) $(LIBXMLRPC_UTIL_A) $(LIBXMLRPC_XML)
|
||||
+ $(CCLD) -o $@ $(LDFLAGS_ALL) \
|
||||
+ $(OVERFLOW_ENTITY_OBJS) $(LDADD_CLIENT) $(LDADD_ABYSS_SERVER) $(CASPRINTF)
|
||||
+OBJS = overflow_entity_test.o
|
||||
+
|
||||
+$(OBJS):%.o:%.c
|
||||
+ $(CC) -c $(INCLUDES) -I$(SRCDIR)/lib/expat/xmlparse/ $(CFLAGS_ALL) $<
|
||||
+
|
||||
# Note the difference between 'check' and 'runtests'. 'check' means to check
|
||||
# our own correctness. 'runtests' means to run the tests that check our
|
||||
# parent's correctness
|
||||
@@ -94,8 +116,10 @@ $(OBJS):%.o:%.c
|
||||
check:
|
||||
|
||||
.PHONY: runtests_local
|
||||
-runtests_local: test cgitest1
|
||||
+runtests_local: test cgitest1 overflow_attr_test overflow_entity_test
|
||||
./test
|
||||
+ ./overflow_attr_test
|
||||
+ ./overflow_entity_test
|
||||
|
||||
.PHONY: runtests
|
||||
runtests: runtests_local cpp/runtests benchmark/runtests
|
||||
diff --git a/test/overflow_attr_test.c b/test/overflow_attr_test.c
|
||||
new file mode 100644
|
||||
index 0000000..eb06556
|
||||
--- /dev/null
|
||||
+++ b/test/overflow_attr_test.c
|
||||
@@ -0,0 +1,88 @@
|
||||
+/* gcc -g -std=c11 -D_POSIX_C_SOURCE=200809L -I lib/expat/xmlparse -lxmlrpc_xmlparse -lxmlrpc_xmltok overflow_attr_test.c -o overflow_attr_test */
|
||||
+
|
||||
+#include <err.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include "xmlparse.h"
|
||||
+#include <string.h>
|
||||
+
|
||||
+#define XML_STATUS_OK 1
|
||||
+#define XML_STATUS_ERROR 0
|
||||
+
|
||||
+typedef unsigned char XML_Bool;
|
||||
+#define XML_TRUE ((XML_Bool)1)
|
||||
+#define XML_FALSE ((XML_Bool)0)
|
||||
+
|
||||
+#define SIZE_PER_LINE 50
|
||||
+
|
||||
+static int
|
||||
+doParse(int N_LINES) {
|
||||
+ XML_Parser parser;
|
||||
+ char tmp[SIZE_PER_LINE];
|
||||
+ int ret = 0;
|
||||
+ int rval = 0;
|
||||
+
|
||||
+ if ((parser = xmlrpc_XML_ParserCreate(NULL)) == NULL)
|
||||
+ errx(1, "XML_ParserCreate");
|
||||
+
|
||||
+ char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE);
|
||||
+ if (text == NULL) {
|
||||
+ printf("malloc failed");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ // Create the XML
|
||||
+ snprintf(text, SIZE_PER_LINE,
|
||||
+ "<!DOCTYPE foo [\n"
|
||||
+ " <!ENTITY s0 'deepText'>\n");
|
||||
+
|
||||
+ for (size_t i = 1; i < N_LINES; ++i) {
|
||||
+ snprintf(tmp, SIZE_PER_LINE, " <!ENTITY s%lu '&s%lu;'>\n",
|
||||
+ (long unsigned)i, (long unsigned)(i - 1));
|
||||
+ strncat(text, tmp, SIZE_PER_LINE);
|
||||
+ }
|
||||
+
|
||||
+ snprintf(tmp, SIZE_PER_LINE, "]> <foo name='&s%lu;'>mainText</foo>\n",
|
||||
+ (long unsigned)(N_LINES - 1));
|
||||
+ strncat(text, tmp, SIZE_PER_LINE);
|
||||
+
|
||||
+ ret = xmlrpc_XML_Parse(parser, text, strlen(text), XML_TRUE);
|
||||
+ if (ret == XML_STATUS_ERROR) {
|
||||
+ int err = xmlrpc_XML_GetErrorCode(parser);
|
||||
+ if (err == XML_ERROR_RECURSIVE_ENTITY_REF) {
|
||||
+ if (N_LINES <= 28) {
|
||||
+ printf("%d Unexpected FAIL (%s)\n", N_LINES, xmlrpc_XML_ErrorString(err));
|
||||
+ } else {
|
||||
+ printf("%d expected failure OK (%s)\n", N_LINES, xmlrpc_XML_ErrorString(err));
|
||||
+ }
|
||||
+ } else {
|
||||
+ printf("%d Unexpected FAIL (%s)\n", N_LINES, xmlrpc_XML_ErrorString(err));
|
||||
+ rval = 1;
|
||||
+ }
|
||||
+ } else {
|
||||
+ printf("%d OK\n", N_LINES);
|
||||
+ }
|
||||
+ free(text);
|
||||
+ xmlrpc_XML_ParserFree(parser);
|
||||
+ return rval;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char *argv[]) {
|
||||
+ int status = 0;
|
||||
+
|
||||
+ for (int i = 2; i <= 28; i++ )
|
||||
+ status += doParse(i);
|
||||
+
|
||||
+ status += doParse(29);
|
||||
+ status += doParse(30);
|
||||
+ status += doParse(100);
|
||||
+ status += doParse(1000);
|
||||
+ status += doParse(10000);
|
||||
+ status += doParse(60000);
|
||||
+
|
||||
+ if (status == 0)
|
||||
+ printf("PASSED\n");
|
||||
+ return (status != 0);
|
||||
+}
|
||||
diff --git a/test/overflow_entity_test.c b/test/overflow_entity_test.c
|
||||
new file mode 100644
|
||||
index 0000000..d0d1290
|
||||
--- /dev/null
|
||||
+++ b/test/overflow_entity_test.c
|
||||
@@ -0,0 +1,86 @@
|
||||
+/* gcc -g -std=c11 -D_POSIX_C_SOURCE=200809L -I lib/expat/xmlparse -lxmlrpc_xmlparse -lxmlrpc_xmltok overflow_entity_test.c -o overflow_entity_test */
|
||||
+
|
||||
+#include <err.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include "xmlparse.h"
|
||||
+#include <string.h>
|
||||
+
|
||||
+#define XML_STATUS_OK 1
|
||||
+#define XML_STATUS_ERROR 0
|
||||
+
|
||||
+typedef unsigned char XML_Bool;
|
||||
+#define XML_TRUE ((XML_Bool)1)
|
||||
+#define XML_FALSE ((XML_Bool)0)
|
||||
+
|
||||
+#define SIZE_PER_LINE 50
|
||||
+
|
||||
+static int
|
||||
+doParse(int N_LINES) {
|
||||
+ XML_Parser parser;
|
||||
+ char tmp[SIZE_PER_LINE];
|
||||
+ int ret = 0;
|
||||
+ int rval = 0;
|
||||
+
|
||||
+ if ((parser = xmlrpc_XML_ParserCreate(NULL)) == NULL)
|
||||
+ errx(1, "XML_ParserCreate");
|
||||
+
|
||||
+ char *const text = (char *)malloc((N_LINES + 4) * SIZE_PER_LINE);
|
||||
+ if (text == NULL) {
|
||||
+ printf("malloc failed");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ // Create the XML
|
||||
+ snprintf(text, SIZE_PER_LINE,
|
||||
+ "<!DOCTYPE foo [\n"
|
||||
+ " <!ENTITY s0 'deepText'>\n");
|
||||
+
|
||||
+ for (size_t i = 1; i < N_LINES; ++i) {
|
||||
+ snprintf(tmp, SIZE_PER_LINE, " <!ENTITY s%lu '&s%lu;'>\n",
|
||||
+ (long unsigned)i, (long unsigned)(i - 1));
|
||||
+ strncat(text, tmp, SIZE_PER_LINE);
|
||||
+ }
|
||||
+
|
||||
+ snprintf(tmp, SIZE_PER_LINE, "]> <foo>&s%lu;</foo>\n",
|
||||
+ (long unsigned)(N_LINES - 1));
|
||||
+ strncat(text, tmp, SIZE_PER_LINE);
|
||||
+
|
||||
+ ret = xmlrpc_XML_Parse(parser, text, strlen(text), XML_TRUE);
|
||||
+ if (ret == XML_STATUS_ERROR){
|
||||
+ int err = xmlrpc_XML_GetErrorCode(parser);
|
||||
+ if (err == XML_ERROR_RECURSIVE_ENTITY_REF) {
|
||||
+ if (N_LINES <= 28) {
|
||||
+ printf("%d Unexpected FAIL (%s)\n", N_LINES, xmlrpc_XML_ErrorString(err));
|
||||
+ rval = 1;
|
||||
+ } else {
|
||||
+ printf("%d expected failure OK (%s)\n", N_LINES, xmlrpc_XML_ErrorString(err));
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ printf("%d OK\n", N_LINES);
|
||||
+ }
|
||||
+ free(text);
|
||||
+ xmlrpc_XML_ParserFree(parser);
|
||||
+ return rval;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char *argv[]) {
|
||||
+ int status = 0;
|
||||
+
|
||||
+ for (int i = 2; i <= 28; i++ )
|
||||
+ status += doParse(i);
|
||||
+
|
||||
+ status += doParse(29);
|
||||
+ status += doParse(30);
|
||||
+ status += doParse(100);
|
||||
+ status += doParse(1000);
|
||||
+ status += doParse(10000);
|
||||
+ status += doParse(60000);
|
||||
+
|
||||
+ if (status == 0)
|
||||
+ printf("PASSED\n");
|
||||
+ return (status != 0);
|
||||
+}
|
||||
--
|
||||
2.43.5
|
||||
|
@ -1,286 +0,0 @@
|
||||
From 0f3661572b50df9878412181dc600e69eafbd868 Mon Sep 17 00:00:00 2001
|
||||
From: root <root@vm-10-0-185-207.hosted.upshift.rdu2.redhat.com>
|
||||
Date: Wed, 19 Mar 2025 13:54:48 -0400
|
||||
Subject: [PATCH] Add missing files for the benchmark tests
|
||||
|
||||
The SOURCES tarball needs to be manually unpacked.
|
||||
---
|
||||
test/benchmark/Makefile | 82 ++++++++++++++++++++
|
||||
test/benchmark/README.txt | 16 ++++
|
||||
test/benchmark/benchmark.c | 152 +++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 250 insertions(+)
|
||||
create mode 100644 test/benchmark/Makefile
|
||||
create mode 100644 test/benchmark/README.txt
|
||||
create mode 100644 test/benchmark/benchmark.c
|
||||
|
||||
diff --git a/test/benchmark/Makefile b/test/benchmark/Makefile
|
||||
new file mode 100644
|
||||
index 0000000..20e648c
|
||||
--- /dev/null
|
||||
+++ b/test/benchmark/Makefile
|
||||
@@ -0,0 +1,82 @@
|
||||
+ifeq ($(SRCDIR),)
|
||||
+ updir = $(shell echo $(dir $(1)) | sed 's/.$$//')
|
||||
+ testDIR := $(call updir,$(CURDIR))
|
||||
+ SRCDIR := $(call updir,$(testDIR))
|
||||
+ BLDDIR := $(SRCDIR)
|
||||
+endif
|
||||
+SUBDIR := test/benchmark
|
||||
+
|
||||
+include $(BLDDIR)/config.mk
|
||||
+
|
||||
+PROGS = benchmark
|
||||
+
|
||||
+default: all
|
||||
+
|
||||
+all: $(PROGS)
|
||||
+
|
||||
+XMLRPC_C_CONFIG = $(BLDDIR)/xmlrpc-c-config.test
|
||||
+
|
||||
+LIBS :=
|
||||
+
|
||||
+LIBS += $(SOCKETLIBOPT) $(THREAD_LIBS)
|
||||
+
|
||||
+INCLUDES = -Isrcdir/include -I$(BLDDIR) -Isrcdir -Isrcdir/lib/util/include -Isrcdir/lib/expat/xmlparse
|
||||
+
|
||||
+# This 'common.mk' dependency makes sure the symlinks get built before
|
||||
+# this make file is used for anything.
|
||||
+
|
||||
+$(SRCDIR)/common.mk: srcdir blddir
|
||||
+
|
||||
+include $(SRCDIR)/common.mk
|
||||
+
|
||||
+CFLAGS += $(INCLUDES)
|
||||
+
|
||||
+TEST_OBJS = benchmark.o
|
||||
+
|
||||
+#-----------------------------------------------------------------------------
|
||||
+# TEST_LIBS
|
||||
+#-----------------------------------------------------------------------------
|
||||
+TEST_LIBS =
|
||||
+TEST_LIBS += $(LIBXMLRPC_UTIL_A)
|
||||
+TEST_LIBS += $(LIBXMLRPC_XMLPARSE_A)
|
||||
+TEST_LIBS += $(LIBXMLRPC_XMLTOK_A)
|
||||
+
|
||||
+benchmark: $(TEST_OBJS) $(TEST_LIBS)
|
||||
+ $(CXXLD) -o $@ $(INCLUDES) $(LDFLAGS_ALL) $^ $(LIB_XML) $(TEST_LIBS)
|
||||
+
|
||||
+%.o:%.cpp
|
||||
+ $(CC) -c $(INCLUDES) $(CXXFLAGS_ALL) $(D_INTERNAL_EXPAT) $<
|
||||
+
|
||||
+# Note the difference between 'check' and 'runtests'. 'check' means to check
|
||||
+# our own correctness. 'runtests' means to run the tests that check our
|
||||
+# parent's correctness
|
||||
+
|
||||
+.PHONY: check
|
||||
+check:
|
||||
+
|
||||
+.PHONY: runtests
|
||||
+runtests: benchmark
|
||||
+ ./benchmark aaaaaa_attr.xml 4096 1
|
||||
+ ./benchmark aaaaaa_comment.xml 4096 1
|
||||
+ ./benchmark aaaaaa_tag.xml 4096 1
|
||||
+ ./benchmark aaaaaa_text.xml 4096 1
|
||||
+ -./benchmark aaaaaa_cdata.xml 4096 1
|
||||
+ echo "PASSED"
|
||||
+
|
||||
+.PHONY: install
|
||||
+install:
|
||||
+
|
||||
+.PHONY: uninstall
|
||||
+uninstall:
|
||||
+
|
||||
+.PHONY: clean clean-local distclean
|
||||
+clean: clean-common clean-local
|
||||
+clean-local:
|
||||
+ rm -f $(PROGS)
|
||||
+
|
||||
+distclean: clean distclean-common
|
||||
+
|
||||
+.PHONY: dep
|
||||
+dep: dep-common
|
||||
+
|
||||
+include depend.mk
|
||||
diff --git a/test/benchmark/README.txt b/test/benchmark/README.txt
|
||||
new file mode 100644
|
||||
index 0000000..86414d5
|
||||
--- /dev/null
|
||||
+++ b/test/benchmark/README.txt
|
||||
@@ -0,0 +1,16 @@
|
||||
+Use this benchmark command line utility as follows:
|
||||
+
|
||||
+ benchmark [-n] <file name> <buffer size> <# iterations>
|
||||
+
|
||||
+The command line arguments are:
|
||||
+
|
||||
+ -n ... optional; if supplied, namespace processing is turned on
|
||||
+ <file name> ... name/path of test xml file
|
||||
+ <buffer size> ... size of processing buffer;
|
||||
+ the file is parsed in chunks of this size
|
||||
+ <# iterations> ... how often will the file be parsed
|
||||
+
|
||||
+Returns:
|
||||
+
|
||||
+ The time (in seconds) it takes to parse the test file,
|
||||
+ averaged over the number of iterations.@
|
||||
diff --git a/test/benchmark/benchmark.c b/test/benchmark/benchmark.c
|
||||
new file mode 100644
|
||||
index 0000000..3864280
|
||||
--- /dev/null
|
||||
+++ b/test/benchmark/benchmark.c
|
||||
@@ -0,0 +1,152 @@
|
||||
+/*
|
||||
+ __ __ _
|
||||
+ ___\ \/ /_ __ __ _| |_
|
||||
+ / _ \\ /| '_ \ / _` | __|
|
||||
+ | __// \| |_) | (_| | |_
|
||||
+ \___/_/\_\ .__/ \__,_|\__|
|
||||
+ |_| XML parser
|
||||
+
|
||||
+ Copyright (c) 2003-2006 Karl Waclawek <karl@waclawek.net>
|
||||
+ Copyright (c) 2005-2007 Steven Solie <steven@solie.ca>
|
||||
+ Copyright (c) 2017 Sebastian Pipping <sebastian@pipping.org>
|
||||
+ Copyright (c) 2017 Rhodri James <rhodri@wildebeest.org.uk>
|
||||
+ Licensed under the MIT license:
|
||||
+
|
||||
+ Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ a copy of this software and associated documentation files (the
|
||||
+ "Software"), to deal in the Software without restriction, including
|
||||
+ without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
+ persons to whom the Software is furnished to do so, subject to the
|
||||
+ following conditions:
|
||||
+
|
||||
+ The above copyright notice and this permission notice shall be included
|
||||
+ in all copies or substantial portions of the Software.
|
||||
+
|
||||
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
+ USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+*/
|
||||
+
|
||||
+#include <sys/stat.h>
|
||||
+#include <assert.h>
|
||||
+#include <stddef.h> // ptrdiff_t
|
||||
+#include <stdlib.h>
|
||||
+#include <stdio.h>
|
||||
+#include <time.h>
|
||||
+#include "xmlparse.h"
|
||||
+
|
||||
+#ifdef XML_LARGE_SIZE
|
||||
+# define XML_FMT_INT_MOD "ll"
|
||||
+#else
|
||||
+# define XML_FMT_INT_MOD "l"
|
||||
+#endif
|
||||
+
|
||||
+#ifdef XML_UNICODE_WCHAR_T
|
||||
+# define XML_FMT_STR "ls"
|
||||
+#else
|
||||
+# define XML_FMT_STR "s"
|
||||
+#endif
|
||||
+
|
||||
+static void
|
||||
+usage(const char *prog, int rc) {
|
||||
+ fprintf(stderr, "usage: %s [-n] filename bufferSize nr_of_loops\n", prog);
|
||||
+ exit(rc);
|
||||
+}
|
||||
+
|
||||
+int
|
||||
+main(int argc, char *argv[]) {
|
||||
+ XML_Parser parser;
|
||||
+ char *XMLBuf, *XMLBufEnd, *XMLBufPtr;
|
||||
+ FILE *fd;
|
||||
+ struct stat fileAttr;
|
||||
+ int nrOfLoops, bufferSize, i, isFinal;
|
||||
+ size_t fileSize;
|
||||
+ int j = 0, ns = 0;
|
||||
+ clock_t tstart, tend;
|
||||
+ double cpuTime = 0.0;
|
||||
+
|
||||
+ if (argc > 1) {
|
||||
+ if (argv[1][0] == '-') {
|
||||
+ if (argv[1][1] == 'n' && argv[1][2] == '\0') {
|
||||
+ ns = 1;
|
||||
+ j = 1;
|
||||
+ } else
|
||||
+ usage(argv[0], 1);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (argc != j + 4)
|
||||
+ usage(argv[0], 1);
|
||||
+
|
||||
+ if (stat(argv[j + 1], &fileAttr) != 0) {
|
||||
+ fprintf(stderr, "could not access file '%s'\n", argv[j + 1]);
|
||||
+ return 2;
|
||||
+ }
|
||||
+
|
||||
+ fd = fopen(argv[j + 1], "r");
|
||||
+ if (! fd) {
|
||||
+ fprintf(stderr, "could not open file '%s'\n", argv[j + 1]);
|
||||
+ exit(2);
|
||||
+ }
|
||||
+
|
||||
+ bufferSize = atoi(argv[j + 2]);
|
||||
+ nrOfLoops = atoi(argv[j + 3]);
|
||||
+ if (bufferSize <= 0 || nrOfLoops <= 0) {
|
||||
+ fprintf(stderr, "buffer size and nr of loops must be greater than zero.\n");
|
||||
+ exit(3);
|
||||
+ }
|
||||
+
|
||||
+ XMLBuf = malloc(fileAttr.st_size);
|
||||
+ fileSize = fread(XMLBuf, sizeof(char), fileAttr.st_size, fd);
|
||||
+ fclose(fd);
|
||||
+
|
||||
+ if (ns)
|
||||
+ parser = xmlrpc_XML_ParserCreateNS(NULL, '!');
|
||||
+ else
|
||||
+ parser = xmlrpc_XML_ParserCreate(NULL);
|
||||
+
|
||||
+ i = 0;
|
||||
+ XMLBufEnd = XMLBuf + fileSize;
|
||||
+ while (i < nrOfLoops) {
|
||||
+ XMLBufPtr = XMLBuf;
|
||||
+ isFinal = 0;
|
||||
+ tstart = clock();
|
||||
+ do {
|
||||
+ ptrdiff_t parseBufferSize = XMLBufEnd - XMLBufPtr;
|
||||
+ if (parseBufferSize <= (ptrdiff_t)bufferSize)
|
||||
+ isFinal = 1;
|
||||
+ else
|
||||
+ parseBufferSize = bufferSize;
|
||||
+ assert(parseBufferSize <= (ptrdiff_t)bufferSize);
|
||||
+ if (! xmlrpc_XML_Parse(parser, XMLBufPtr, (int)parseBufferSize, isFinal)) {
|
||||
+ fprintf(stderr,
|
||||
+ "error '%" XML_FMT_STR "' at line %" XML_FMT_INT_MOD
|
||||
+ "u character %" XML_FMT_INT_MOD "u\n",
|
||||
+ xmlrpc_XML_ErrorString(xmlrpc_XML_GetErrorCode(parser)),
|
||||
+ xmlrpc_XML_GetCurrentLineNumber(parser),
|
||||
+ xmlrpc_XML_GetCurrentColumnNumber(parser));
|
||||
+ free(XMLBuf);
|
||||
+ xmlrpc_XML_ParserFree(parser);
|
||||
+ exit(4);
|
||||
+ }
|
||||
+ XMLBufPtr += bufferSize;
|
||||
+ } while (! isFinal);
|
||||
+ tend = clock();
|
||||
+ cpuTime += ((double)(tend - tstart)) / CLOCKS_PER_SEC;
|
||||
+ //xmlrpc-c lacks XML_ParserReset
|
||||
+ //xmlrpc_XML_ParserReset(parser, NULL);
|
||||
+ i++;
|
||||
+ }
|
||||
+
|
||||
+ xmlrpc_XML_ParserFree(parser);
|
||||
+ free(XMLBuf);
|
||||
+
|
||||
+ printf("%d loops, with buffer size %d. Average time per loop: %f\n",
|
||||
+ nrOfLoops, bufferSize, cpuTime / (double)nrOfLoops);
|
||||
+ return 0;
|
||||
+}
|
||||
--
|
||||
2.43.5
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
Name: xmlrpc-c
|
||||
Version: 1.51.0
|
||||
Release: 11%{?dist}
|
||||
Release: 8%{?dist}
|
||||
Summary: Lightweight RPC library based on XML and HTTP
|
||||
# See doc/COPYING for details.
|
||||
# The Python 1.5.2 license used by a few files is just BSD.
|
||||
@ -17,7 +17,6 @@ URL: http://xmlrpc-c.sourceforge.net/
|
||||
# upstream does not tag versions so we must fetch from the branch and
|
||||
# check which version was used for it
|
||||
%{?advanced_branch:Source0: xmlrpc-c-%version.tar.xz}
|
||||
%{?advanced_branch:Source1: benchmark-tests.tar.xz}
|
||||
|
||||
# Upstreamable patches
|
||||
Patch101: 0001-xmlrpc_server_abyss-use-va_args-properly.patch
|
||||
@ -28,10 +27,6 @@ Patch103: 0003-allow-30x-redirections.patch
|
||||
Patch104: 0004-Add-missing-validation-of-encoding-CVE-2022-25235.patch
|
||||
Patch105: 0005-lib-Prevent-more-integer-overflows-CVE-2022-22822-to.patch
|
||||
Patch106: 0006-Prevent-integer-overflow-on-m_groupSize-in-doProlog-.patch
|
||||
Patch107: 0007-Address-segfault-found-in-CVE-2023-52425.patch
|
||||
Patch108: 0008-Prevent-integer-overflow-or-wraparound-CVE-2024-4549.patch
|
||||
Patch109: 0009-Restrict-XML-Entity-Expansion-Depth-in-libexpat-CVE-.patch
|
||||
Patch110: 0010-Add-missing-files-for-the-benchmark-tests.patch
|
||||
|
||||
# Backported patches
|
||||
# https://sourceforge.net/p/xmlrpc-c/code/2981/
|
||||
@ -134,7 +129,6 @@ This package contains some handy XML-RPC demo applications.
|
||||
|
||||
%prep
|
||||
%autosetup -Sgit
|
||||
tar xf %{SOURCE1}
|
||||
|
||||
%build
|
||||
%meson %{?with_libxml2:-Dlibxml2-backend=true}
|
||||
@ -200,15 +194,6 @@ tar xf %{SOURCE1}
|
||||
%{_bindir}/xmlrpc_dumpserver
|
||||
|
||||
%changelog
|
||||
* Wed Mar 19 2025 Rob Crittenden <rcritten@redhat.com> - 1.51.0-11
|
||||
- Restrict XML Entity Expansion Depth in libexpat CVE-2024-8176
|
||||
|
||||
* Thu Sep 19 2024 Rob Crittenden <rcritten@redhat.com> - 1.51.0-10
|
||||
- Prevent integer overflow or wraparound, CVE-2024-4549 (RHEL-57519)
|
||||
|
||||
* Thu Apr 25 2024 Rob Crittenden <rcritten@redhat.com> - 1.51.0-9
|
||||
- Address segfault found in CVE-2023-52425 (RHEL-24226)
|
||||
|
||||
* Thu Apr 14 2022 Rob Crittenden <rcritten@redhat.com> - 1.51.0-8
|
||||
- Address some Coverity issues in the patch set
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user