Compare commits
No commits in common. 'c9' and 'c8' have entirely different histories.
@ -1 +1,2 @@
|
|||||||
|
SOURCES/benchmark-tests.tar.xz
|
||||||
SOURCES/xmlrpc-c-1.51.0.tar.xz
|
SOURCES/xmlrpc-c-1.51.0.tar.xz
|
||||||
|
@ -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
|
||||||
|
@ -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
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
Loading…
Reference in new issue