Compare commits

..

No commits in common. "c9" and "c8" have entirely different histories.
c9 ... c8

9 changed files with 384 additions and 358 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
SOURCES/benchmark-tests.tar.xz
SOURCES/xmlrpc-c-1.51.0.tar.xz SOURCES/xmlrpc-c-1.51.0.tar.xz

View File

@ -1 +1,2 @@
b4fb65d500c1af5fe83917ab2976a47ae6268fdd SOURCES/benchmark-tests.tar.xz
784a3e74971f3b7d992d768c732daa891ffd2412 SOURCES/xmlrpc-c-1.51.0.tar.xz 784a3e74971f3b7d992d768c732daa891ffd2412 SOURCES/xmlrpc-c-1.51.0.tar.xz

View File

@ -1,317 +0,0 @@
From 22c63b6ca838d257ce6b044fd893f3374d038e3f Mon Sep 17 00:00:00 2001
From: Igor Gnatenko <i.gnatenko.brain@gmail.com>
Date: Sun, 18 Dec 2016 11:49:03 +0100
Subject: [PATCH] cleanup and fix libxml2 backend
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
---
src/xmlrpc_libxml2.c | 138 +++++++++++++++++++++++++++------------------------
1 file changed, 73 insertions(+), 65 deletions(-)
diff --git a/src/xmlrpc_libxml2.c b/src/xmlrpc_libxml2.c
index 207036ff..bf3d6914 100644
--- a/src/xmlrpc_libxml2.c
+++ b/src/xmlrpc_libxml2.c
@@ -43,14 +43,15 @@
#include "xmlrpc-c/base.h"
#include "xmlrpc-c/base_int.h"
#include "xmlrpc-c/string_int.h"
+#include "xmlrpc-c/util.h"
#include "xmlparser.h"
struct _xml_element {
xml_element * parentP;
const char * name;
- xmlrpc_mem_block cdata; /* char */
- xmlrpc_mem_block children; /* xml_element* */
+ xmlrpc_mem_block * cdataP; /* char */
+ xmlrpc_mem_block * childrenP; /* xml_element* */
};
#define XMLRPC_ASSERT_ELEM_OK(elem) \
@@ -102,7 +103,7 @@ xmlElementNew(xmlrpc_env * const envP,
bool childrenAreValid;
XMLRPC_ASSERT_ENV_OK(envP);
- assert(name != NULL);
+ XMLRPC_ASSERT(name != NULL);
/* Set up our error-handling preconditions. */
retval = NULL;
@@ -112,21 +113,20 @@ xmlElementNew(xmlrpc_env * const envP,
XMLRPC_FAIL_IF_NULL(retval, envP, XMLRPC_INTERNAL_ERROR,
"Couldn't allocate memory for XML element");
+ /* Set our parent field to NULL. */
retval->parentP = NULL;
-
+
/* Copy over the element name. */
- retval->name = strdup(name);
+ retval->name = xmlrpc_strdupnull(name);
XMLRPC_FAIL_IF_NULL(retval->name, envP, XMLRPC_INTERNAL_ERROR,
"Couldn't allocate memory for XML element");
nameIsValid = true;
- /* Initialize a block to hold our CDATA. */
- XMLRPC_TYPED_MEM_BLOCK_INIT(char, envP, &retval->cdata, 0);
+ retval->cdataP = XMLRPC_MEMBLOCK_NEW(char, envP, 0);
XMLRPC_FAIL_IF_FAULT(envP);
cdataIsValid = true;
- /* Initialize a block to hold our child elements. */
- XMLRPC_TYPED_MEM_BLOCK_INIT(xml_element *, envP, &retval->children, 0);
+ retval->childrenP = XMLRPC_MEMBLOCK_NEW(xml_element *, envP, 0);
XMLRPC_FAIL_IF_FAULT(envP);
childrenAreValid = true;
@@ -136,48 +136,50 @@ cleanup:
if (nameIsValid)
xmlrpc_strfree(retval->name);
if (cdataIsValid)
- xmlrpc_mem_block_clean(&retval->cdata);
+ XMLRPC_MEMBLOCK_FREE(char, retval->cdataP);
if (childrenAreValid)
- xmlrpc_mem_block_clean(&retval->children);
+ XMLRPC_MEMBLOCK_FREE(xml_element *, retval->childrenP);
free(retval);
}
- retval = NULL;
+ return NULL;
+ } else {
+ return retval;
}
- return retval;
}
-
+/*=========================================================================
+** xml_element_free
+**=========================================================================
+** Blow away an existing element & all of its child elements.
+*/
void
xml_element_free(xml_element * const elemP) {
-/*----------------------------------------------------------------------------
- Blow away an existing element & all of its child elements.
------------------------------------------------------------------------------*/
- xmlrpc_mem_block * children;
- unsigned int size;
- unsigned int i;
+
+ xmlrpc_mem_block * childrenP;
+ size_t size, i;
xml_element ** contents;
XMLRPC_ASSERT_ELEM_OK(elemP);
xmlrpc_strfree(elemP->name);
elemP->name = XMLRPC_BAD_POINTER;
- xmlrpc_mem_block_clean(&elemP->cdata);
+
+ XMLRPC_MEMBLOCK_FREE(char, elemP->cdataP);
/* Deallocate all of our children recursively. */
- children = &elemP->children;
- contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element *, children);
- size = XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element *, children);
+ childrenP = elemP->childrenP;
+ contents = XMLRPC_MEMBLOCK_CONTENTS(xml_element *, childrenP);
+ size = XMLRPC_MEMBLOCK_SIZE(xml_element *, childrenP);
for (i = 0; i < size; ++i)
xml_element_free(contents[i]);
- xmlrpc_mem_block_clean(&elemP->children);
+ XMLRPC_MEMBLOCK_FREE(xml_element *, elemP->childrenP);
free(elemP);
}
-
/*=========================================================================
** Miscellaneous Accessors
**=========================================================================
@@ -185,36 +187,47 @@ xml_element_free(xml_element * const elemP) {
** documentation on each function works.
*/
+
+
const char *
xml_element_name(const xml_element * const elemP) {
XMLRPC_ASSERT_ELEM_OK(elemP);
+
return elemP->name;
}
+
+
size_t
-xml_element_cdata_size(const xml_element * const elemP) {
- /* The result of this function is NOT VALID until the end_element handler
- has been called!
- */
+xml_element_cdata_size (const xml_element * const elemP) {
+/*----------------------------------------------------------------------------
+ The result of this function is NOT VALID until the end_element handler
+ has been called!
+-----------------------------------------------------------------------------*/
XMLRPC_ASSERT_ELEM_OK(elemP);
- return XMLRPC_TYPED_MEM_BLOCK_SIZE(char, &elemP->cdata) - 1;
+
+ return XMLRPC_MEMBLOCK_SIZE(char, elemP->cdataP) - 1;
}
const char *
xml_element_cdata(const xml_element * const elemP) {
+
XMLRPC_ASSERT_ELEM_OK(elemP);
- return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &elemP->cdata);
+
+ return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(const char, elemP->cdataP);
}
unsigned int
xml_element_children_size(const xml_element * const elemP) {
+
XMLRPC_ASSERT_ELEM_OK(elemP);
- return XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element *, &elemP->children);
+
+ return XMLRPC_MEMBLOCK_SIZE(xml_element *, elemP->childrenP);
}
@@ -222,47 +235,42 @@ xml_element_children_size(const xml_element * const elemP) {
xml_element **
xml_element_children(const xml_element * const elemP) {
XMLRPC_ASSERT_ELEM_OK(elemP);
- return XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element *, &elemP->children);
+ return XMLRPC_MEMBLOCK_CONTENTS(xml_element *, elemP->childrenP);
}
-/*=========================================================================
-** Internal xml_element Utility Functions
-**=========================================================================
-*/
+/*=============================================================================
+ Internal xml_element Utility Functions
+=============================================================================*/
static void
-xmlElementAppendCdata(xmlrpc_env * const envP,
- xml_element * const elemP,
- const char * const cdata,
- size_t const size) {
+xml_element_append_cdata(xmlrpc_env * const envP,
+ xml_element * const elemP,
+ const char * const cdata,
+ size_t const size) {
XMLRPC_ASSERT_ENV_OK(envP);
- XMLRPC_ASSERT_ELEM_OK(elemP);
+ XMLRPC_ASSERT_ELEM_OK(elemP);
- XMLRPC_TYPED_MEM_BLOCK_APPEND(char, envP, &elemP->cdata, cdata, size);
+ XMLRPC_MEMBLOCK_APPEND(char, envP, elemP->cdataP, cdata, size);
}
static void
-xmlElementAppendChild(xmlrpc_env * const envP,
- xml_element * const elemP,
- xml_element * const childP) {
-
- /* Whether or not this function succeeds, it takes ownership of the 'child'
- argument.
- WARNING - This is the exact opposite of the usual memory ownership
- rules for xmlrpc_value! So please pay attention.
- */
+xml_element_append_child(xmlrpc_env * const envP,
+ xml_element * const elemP,
+ xml_element * const childP) {
+/*----------------------------------------------------------------------------
+ Whether or not this function succeeds, it takes ownership of *childP.
+-----------------------------------------------------------------------------*/
XMLRPC_ASSERT_ENV_OK(envP);
XMLRPC_ASSERT_ELEM_OK(elemP);
XMLRPC_ASSERT_ELEM_OK(childP);
- assert(childP->parentP == NULL);
+ XMLRPC_ASSERT(childP->parentP == NULL);
- XMLRPC_TYPED_MEM_BLOCK_APPEND(xml_element *, envP, &elemP->children,
- &childP, 1);
+ XMLRPC_MEMBLOCK_APPEND(xml_element *, envP, elemP->childrenP, &childP, 1);
if (!envP->fault_occurred)
childP->parentP = elemP;
else
@@ -317,7 +325,7 @@ startElement_(void * const userData,
/* (We need to watch our error handling invariants very carefully
** here. Read the docs for xml_elementAppendChild. */
newCurrentP = elemP;
- xmlElementAppendChild(&contextP->env, contextP->currentP, elemP);
+ xml_element_append_child(&contextP->env, contextP->currentP, elemP);
elemP = NULL;
XMLRPC_FAIL_IF_FAULT(&contextP->env);
contextP->currentP = newCurrentP;
@@ -348,7 +356,7 @@ endElement_(void * const userData,
contextP->currentP == contextP->rootP);
/* Add a trailing '\0' to our cdata. */
- xmlElementAppendCdata(&contextP->env, contextP->currentP, "\0", 1);
+ xml_element_append_cdata(&contextP->env, contextP->currentP, "\0", 1);
if (!contextP->env.fault_occurred) {
/* Pop our "stack" of elements. */
contextP->currentP = contextP->currentP->parentP;
@@ -370,9 +378,9 @@ characterData(void * const userData,
/* Get our context and see if an error has already occured. */
contextP = (ParseContext*)userData;
if (!contextP->env.fault_occurred) {
- assert(contextP->currentP != NULL);
+ XMLRPC_ASSERT(contextP->currentP != NULL);
- xmlElementAppendCdata(&contextP->env,
+ xml_element_append_cdata(&contextP->env,
contextP->currentP,
(char *)s,
len);
@@ -428,7 +436,7 @@ static xmlSAXHandler const saxHandler = {
static void
-removeDocSizeLimit(xmlParserCtx * const parserP ATTR_UNUSED) {
+removeDocSizeLimit(xmlParserCtxt * const parserP ATTR_UNUSED) {
/*----------------------------------------------------------------------------
Set up *parserP to accept a document of any size.
@@ -451,13 +459,13 @@ removeDocSizeLimit(xmlParserCtx * const parserP ATTR_UNUSED) {
static void
-createParser(xmlrpc_env * const envP,
- ParseContext * const contextP,
- xmlParserCtx ** const parserPP) {
+createParser(xmlrpc_env * const envP,
+ ParseContext * const contextP,
+ xmlParserCtxt ** const parserPP) {
/*----------------------------------------------------------------------------
Create an appropriate Libxml2 parser for our purpose.
-----------------------------------------------------------------------------*/
- xmlParserCtx * parserP;
+ xmlParserCtxt * parserP;
parserP = xmlCreatePushParserCtxt((xmlSAXHandler *)&saxHandler, contextP,
NULL, 0, NULL);
--
2.11.0

View File

@ -0,0 +1,89 @@
From 6aee99f381cc5bdfb6e514ac1e82f5e7b0fa7e2d Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Fri, 25 Feb 2022 16:42:35 -0500
Subject: [PATCH 5/6] Add missing validation of encoding (CVE-2022-25235)
Backported from upstream https://github.com/libexpat/libexpat/pull/562
Resolves: #2058114
---
lib/expat/xmltok/xmltok.c | 21 +++++++++++++++------
lib/expat/xmltok/xmltok_impl.c | 8 ++++++--
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/lib/expat/xmltok/xmltok.c b/lib/expat/xmltok/xmltok.c
index 7b31fbb..3b0c950 100644
--- a/lib/expat/xmltok/xmltok.c
+++ b/lib/expat/xmltok/xmltok.c
@@ -61,12 +61,17 @@ We need 8 bits to index into pages, 3 bits to add to that index and
? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
: 0))
+#define UTF8_INVALID2(p) \
+ ((*p) < 0xC2 || ((p)[1] & 0x80) == 0 || ((p)[1] & 0xC0) == 0xC0)
+
#define UTF8_INVALID3(p) \
- ((*p) == 0xED \
- ? (((p)[1] & 0x20) != 0) \
- : ((*p) == 0xEF \
- ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \
- : 0))
+ (((p)[2] & 0x80) == 0 \
+ || ((*p) == 0xEF && (p)[1] == 0xBF ? (p)[2] > 0xBD \
+ : ((p)[2] & 0xC0) == 0xC0) \
+ || ((*p) == 0xE0 \
+ ? (p)[1] < 0xA0 || ((p)[1] & 0xC0) == 0xC0 \
+ : ((p)[1] & 0x80) == 0 \
+ || ((*p) == 0xED ? (p)[1] > 0x9F : ((p)[1] & 0xC0) == 0xC0)))
#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
@@ -104,7 +109,11 @@ int utf8_isNmstrt3(const ENCODING *enc ATTR_UNUSED, const char *p)
#define utf8_isNmstrt4 isNever
-#define utf8_isInvalid2 isNever
+static
+int utf8_isInvalid2(const ENCODING *enc ATTR_UNUSED, const char *p)
+{
+ return UTF8_INVALID2((const unsigned char *)p);
+}
static
int utf8_isInvalid3(const ENCODING *enc ATTR_UNUSED, const char *p)
diff --git a/lib/expat/xmltok/xmltok_impl.c b/lib/expat/xmltok/xmltok_impl.c
index d035527..bae79b9 100644
--- a/lib/expat/xmltok/xmltok_impl.c
+++ b/lib/expat/xmltok/xmltok_impl.c
@@ -43,7 +43,7 @@ See the file copying.txt for copying permission.
case BT_LEAD ## n: \
if (end - ptr < n) \
return XML_TOK_PARTIAL_CHAR; \
- if (!IS_NAME_CHAR(enc, ptr, n)) { \
+ if (IS_INVALID_CHAR(enc, ptr, n) || !IS_NAME_CHAR(enc, ptr, n)) { \
*nextTokPtr = ptr; \
return XML_TOK_INVALID; \
} \
@@ -71,7 +71,7 @@ See the file copying.txt for copying permission.
case BT_LEAD ## n: \
if (end - ptr < n) \
return XML_TOK_PARTIAL_CHAR; \
- if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
+ if (IS_INVALID_CHAR(enc, ptr, n) || !IS_NMSTRT_CHAR(enc, ptr, n)) { \
*nextTokPtr = ptr; \
return XML_TOK_INVALID; \
} \
@@ -1168,6 +1168,10 @@ int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
case BT_LEAD ## n: \
if (end - ptr < n) \
return XML_TOK_PARTIAL_CHAR; \
+ if (IS_INVALID_CHAR(enc, ptr, n)) { \
+ *nextTokPtr = ptr; \
+ return XML_TOK_INVALID; \
+ } \
if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
ptr += n; \
tok = XML_TOK_NAME; \
--
2.31.1

View File

@ -0,0 +1,92 @@
From ce6eddc1a167dafaac17c7bad9fa6b013fada31b Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Fri, 25 Feb 2022 13:07:07 -0500
Subject: [PATCH 5/6] lib: Prevent more integer overflows (CVE-2022-22822 to
CVE-2022-22827)
Backport fixes from https://github.com/libexpat/libexpat/pull/539
Resolves: #2058567, #2058576, #2058282, #2058589, #2058595, #2058602
---
lib/expat/xmlparse/xmlparse.c | 40 +++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)
diff --git a/lib/expat/xmlparse/xmlparse.c b/lib/expat/xmlparse/xmlparse.c
index 48adfb3..16ab82a 100644
--- a/lib/expat/xmlparse/xmlparse.c
+++ b/lib/expat/xmlparse/xmlparse.c
@@ -19,6 +19,7 @@ See the file copying.txt for copying permission.
#include <assert.h>
#include <limits.h> /* UINT_MAX */
#include <time.h> /* time() */
+#include <stdint.h>
#include "xmlrpc_config.h"
#include "c_util.h"
@@ -1076,6 +1077,9 @@ int addBinding(XML_Parser parser,
;
if (namespaceSeparator)
len++;
+ if (namespaceSeparator && (uri[len] == namespaceSeparator)) {
+ return XML_ERROR_SYNTAX;
+ }
if (freeBindingList) {
b = freeBindingList;
if (len > b->uriAlloc) {
@@ -2116,10 +2120,32 @@ storeAtts(XML_Parser const xmlParserP,
}
/* get the attributes from the tokenizer */
n = XmlGetAttributes(enc, attStr, attsSize, atts);
+
+
+ /* Detect and prevent integer overflow */
+ if (n > INT_MAX - nDefaultAtts) {
+ return XML_ERROR_NO_MEMORY;
+ }
+
if (n + nDefaultAtts > attsSize) {
int oldAttsSize = attsSize;
ATTRIBUTE *temp;
+ /* Detect and prevent integer overflow */
+ if ((nDefaultAtts > INT_MAX - INIT_ATTS_SIZE)
+ || (n > INT_MAX - (nDefaultAtts + INIT_ATTS_SIZE))) {
+ return XML_ERROR_NO_MEMORY;
+ }
attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((unsigned)parser->m_attsSize > (size_t)(-1) / sizeof(ATTRIBUTE)) {
+ attsSize = oldAttsSize;
+ return XML_ERROR_NO_MEMORY;
+ }
+#endif
temp = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
if (!temp)
return XML_ERROR_NO_MEMORY;
@@ -2297,6 +2323,20 @@ storeAtts(XML_Parser const xmlParserP,
n = i + binding->uriLen;
if (n > binding->uriAlloc) {
TAG *p;
+
+ /* Detect and prevent integer overflow */
+ if (n > INT_MAX - EXPAND_SPARE) {
+ return XML_ERROR_NO_MEMORY;
+ }
+ /* Detect and prevent integer overflow.
+ * The preprocessor guard addresses the "always false" warning
+ * from -Wtype-limits on platforms where
+ * sizeof(unsigned int) < sizeof(size_t), e.g. on x86_64. */
+#if UINT_MAX >= SIZE_MAX
+ if ((unsigned)(n + EXPAND_SPARE) > (size_t)(-1) / sizeof(XML_Char)) {
+ return XML_ERROR_NO_MEMORY;
+ }
+#endif
XML_Char *uri = malloc((n + EXPAND_SPARE) * sizeof(XML_Char));
if (!uri)
return XML_ERROR_NO_MEMORY;
--
2.31.1

View File

@ -0,0 +1,32 @@
From 06d354807ac297374973631a6418edf7e3fcbf30 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Mon, 28 Feb 2022 10:43:23 -0500
Subject: [PATCH 6/6] Prevent integer overflow on m_groupSize in doProlog
(CVE-2021-46143)
Backported from upstream https://github.com/libexpat/libexpat/pull/538
Resolves: #2058560
---
lib/expat/xmlparse/xmlparse.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/expat/xmlparse/xmlparse.c b/lib/expat/xmlparse/xmlparse.c
index 16ab82a..b9aa927 100644
--- a/lib/expat/xmlparse/xmlparse.c
+++ b/lib/expat/xmlparse/xmlparse.c
@@ -3991,6 +3991,11 @@ doProlog(XML_Parser const xmlParserP,
case XML_ROLE_GROUP_OPEN:
if (prologState.level >= groupSize) {
if (groupSize) {
+ /* Detect and prevent integer overflow */
+ if (groupSize > (unsigned int)(-1) / 2u) {
+ *errorCodeP = XML_ERROR_NO_MEMORY;
+ return;
+ }
char *temp = realloc(groupConnector, groupSize *= 2);
if (!temp) {
*errorCodeP = XML_ERROR_NO_MEMORY;
--
2.31.1

View File

@ -0,0 +1,106 @@
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

View File

@ -0,0 +1,40 @@
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

View File

@ -2,11 +2,11 @@
# Upstream libxml2 backend is completely broken since 2015 # Upstream libxml2 backend is completely broken since 2015
# https://sourceforge.net/p/xmlrpc-c/patches/49/ # https://sourceforge.net/p/xmlrpc-c/patches/49/
%bcond_without libxml2 %bcond_with libxml2
Name: xmlrpc-c Name: xmlrpc-c
Version: 1.51.0 Version: 1.51.0
Release: 16%{?dist} Release: 10%{?dist}
Summary: Lightweight RPC library based on XML and HTTP Summary: Lightweight RPC library based on XML and HTTP
# See doc/COPYING for details. # See doc/COPYING for details.
# The Python 1.5.2 license used by a few files is just BSD. # The Python 1.5.2 license used by a few files is just BSD.
@ -17,6 +17,7 @@ URL: http://xmlrpc-c.sourceforge.net/
# upstream does not tag versions so we must fetch from the branch and # upstream does not tag versions so we must fetch from the branch and
# check which version was used for it # check which version was used for it
%{?advanced_branch:Source0: xmlrpc-c-%version.tar.xz} %{?advanced_branch:Source0: xmlrpc-c-%version.tar.xz}
%{?advanced_branch:Source1: benchmark-tests.tar.xz}
# Upstreamable patches # Upstreamable patches
Patch101: 0001-xmlrpc_server_abyss-use-va_args-properly.patch Patch101: 0001-xmlrpc_server_abyss-use-va_args-properly.patch
@ -24,7 +25,11 @@ Patch102: 0002-Use-proper-datatypes-for-long-long.patch
Patch103: 0003-allow-30x-redirections.patch Patch103: 0003-allow-30x-redirections.patch
#Patch104: xmlrpc-c-printf-size_t.patch #Patch104: xmlrpc-c-printf-size_t.patch
#Patch105: xmlrpc-c-check-vasprintf-return-value.patch #Patch105: xmlrpc-c-check-vasprintf-return-value.patch
Patch106: 0001-cleanup-and-fix-libxml2-backend.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
# Backported patches # Backported patches
# https://sourceforge.net/p/xmlrpc-c/code/2981/ # https://sourceforge.net/p/xmlrpc-c/code/2981/
@ -127,11 +132,7 @@ This package contains some handy XML-RPC demo applications.
%prep %prep
%autosetup -Sgit %autosetup -Sgit
tar xf %{SOURCE1}
%if %{with libxml2}
# We want to build xmlrpc-c against libxml2, so we remove the bundled expat sources -- just to be sure
rm -Rf lib/expat
%endif
%build %build
%meson %{?with_libxml2:-Dlibxml2-backend=true} %meson %{?with_libxml2:-Dlibxml2-backend=true}
@ -197,42 +198,23 @@ rm -Rf lib/expat
%{_bindir}/xmlrpc_dumpserver %{_bindir}/xmlrpc_dumpserver
%changelog %changelog
* Thu Mar 17 2022 Michal Srb <michal@redhat.com> - 1.51.0-16 * Thu Sep 19 2024 Rob Crittenden <rcritten@redhat.com> - 1.51.0-10
- Drop bundled expat and build against libxml2 - Prevent integer overflow or wraparound, CVE-2024-4549 (RHEL-57519)
- Resolves: CVE-2022-25235
- Resolves: CVE-2022-25236
* Tue Aug 10 2021 Mohan Boddu <mboddu@redhat.com> - 1.51.0-15 * Thu Apr 25 2024 Rob Crittenden <rcritten@redhat.com> - 1.51.0-9
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags - Address segfault found in CVE-2023-52425 (RHEL-24226)
Related: rhbz#1991688
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.51.0-14 * Thu Apr 14 2022 Rob Crittenden <rcritten@redhat.com> - 1.51.0-8
- Rebuilt for RHEL 9 BETA for openssl 3.0 - Address some Coverity issues in the patch set
Related: rhbz#1971065
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.51.0-13 * Tue Apr 05 2022 Rob Crittenden <rcritten@redhat.com> - 1.51.0-7
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937 - lib: Prevent more integer overflows (CVE-2022-22822 to CVE-2022-22827)
(#2058567, #2058576, #2058582, #2058589, #2058595, #2058602)
- Prevent integer overflow on m_groupSize in doProlog
(CVE-2021-46143) (#2058560)
* Thu Jan 28 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-12 * Thu Mar 03 2022 Rob Crittenden <rcritten@redhat.com> - 1.51.0-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild - Add missing validation of encoding (CVE-2022-25235) (#2070481)
* Wed Jul 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Fri Jan 31 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Sat Jul 27 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Sun Feb 17 2019 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.51.0-8
- Rebuild for readline 8.0
* Sun Feb 03 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Sat Jul 14 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.51.0-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
* Thu Apr 19 2018 Adam Williamson <awilliam@redhat.com> - 1.51.0-5 * Thu Apr 19 2018 Adam Williamson <awilliam@redhat.com> - 1.51.0-5
- Backport upstream fix for console spam with debug messages (#1541868) - Backport upstream fix for console spam with debug messages (#1541868)