From 29c2b194e677878868eb1624f3465287df2c29d8 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 27 Sep 2022 16:24:19 -0400 Subject: [PATCH] import libxml2-2.9.7-14.el8 --- SOURCES/libxml2-2.9.7-CVE-2022-29824.patch | 341 +++++++++++++++++++++ SPECS/libxml2.spec | 7 +- 2 files changed, 347 insertions(+), 1 deletion(-) create mode 100644 SOURCES/libxml2-2.9.7-CVE-2022-29824.patch diff --git a/SOURCES/libxml2-2.9.7-CVE-2022-29824.patch b/SOURCES/libxml2-2.9.7-CVE-2022-29824.patch new file mode 100644 index 0000000..516d391 --- /dev/null +++ b/SOURCES/libxml2-2.9.7-CVE-2022-29824.patch @@ -0,0 +1,341 @@ +From d410ac5b7ef6ecf1254606408d55f98547c22bda Mon Sep 17 00:00:00 2001 +From: Nick Wellnhofer +Date: Tue, 8 Mar 2022 20:10:02 +0100 +Subject: [PATCH] [CVE-2022-29824] Fix integer overflows in xmlBuf and + xmlBuffer + +In several places, the code handling string buffers didn't check for +integer overflow or used wrong types for buffer sizes. This could +result in out-of-bounds writes or other memory errors when working on +large, multi-gigabyte buffers. + +Thanks to Felix Wilhelm for the report. +--- + buf.c | 86 +++++++++++++++++++++++----------------------------------- + tree.c | 72 ++++++++++++++++++------------------------------ + 2 files changed, 61 insertions(+), 97 deletions(-) + +diff --git a/buf.c b/buf.c +index 21cb9d80..f861d79b 100644 +--- a/buf.c ++++ b/buf.c +@@ -30,6 +30,10 @@ + #include /* for XML_MAX_TEXT_LENGTH */ + #include "buf.h" + ++#ifndef SIZE_MAX ++#define SIZE_MAX ((size_t) -1) ++#endif ++ + #define WITH_BUFFER_COMPAT + + /** +@@ -156,6 +160,8 @@ xmlBufPtr + xmlBufCreateSize(size_t size) { + xmlBufPtr ret; + ++ if (size == SIZE_MAX) ++ return(NULL); + ret = (xmlBufPtr) xmlMalloc(sizeof(xmlBuf)); + if (ret == NULL) { + xmlBufMemoryError(NULL, "creating buffer"); +@@ -166,8 +172,8 @@ xmlBufCreateSize(size_t size) { + ret->error = 0; + ret->buffer = NULL; + ret->alloc = xmlBufferAllocScheme; +- ret->size = (size ? size+2 : 0); /* +1 for ending null */ +- ret->compat_size = (int) ret->size; ++ ret->size = (size ? size + 1 : 0); /* +1 for ending null */ ++ ret->compat_size = (ret->size > INT_MAX ? INT_MAX : ret->size); + if (ret->size){ + ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar)); + if (ret->content == NULL) { +@@ -442,23 +448,17 @@ xmlBufGrowInternal(xmlBufPtr buf, size_t len) { + CHECK_COMPAT(buf) + + if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); +- if (buf->use + len < buf->size) ++ if (len < buf->size - buf->use) + return(buf->size - buf->use); ++ if (len > SIZE_MAX - buf->use) ++ return(0); + +- /* +- * Windows has a BIG problem on realloc timing, so we try to double +- * the buffer size (if that's enough) (bug 146697) +- * Apparently BSD too, and it's probably best for linux too +- * On an embedded system this may be something to change +- */ +-#if 1 +- if (buf->size > (size_t) len) +- size = buf->size * 2; +- else +- size = buf->use + len + 100; +-#else +- size = buf->use + len + 100; +-#endif ++ if (buf->size > (size_t) len) { ++ size = buf->size > SIZE_MAX / 2 ? SIZE_MAX : buf->size * 2; ++ } else { ++ size = buf->use + len; ++ size = size > SIZE_MAX - 100 ? SIZE_MAX : size + 100; ++ } + + if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { + /* +@@ -744,7 +744,7 @@ xmlBufIsEmpty(const xmlBufPtr buf) + int + xmlBufResize(xmlBufPtr buf, size_t size) + { +- unsigned int newSize; ++ size_t newSize; + xmlChar* rebuf = NULL; + size_t start_buf; + +@@ -772,9 +772,13 @@ xmlBufResize(xmlBufPtr buf, size_t size) + case XML_BUFFER_ALLOC_IO: + case XML_BUFFER_ALLOC_DOUBLEIT: + /*take care of empty case*/ +- newSize = (buf->size ? buf->size*2 : size + 10); ++ if (buf->size == 0) { ++ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10); ++ } else { ++ newSize = buf->size; ++ } + while (size > newSize) { +- if (newSize > UINT_MAX / 2) { ++ if (newSize > SIZE_MAX / 2) { + xmlBufMemoryError(buf, "growing buffer"); + return 0; + } +@@ -782,15 +786,15 @@ xmlBufResize(xmlBufPtr buf, size_t size) + } + break; + case XML_BUFFER_ALLOC_EXACT: +- newSize = size+10; ++ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10); + break; + case XML_BUFFER_ALLOC_HYBRID: + if (buf->use < BASE_BUFFER_SIZE) + newSize = size; + else { +- newSize = buf->size * 2; ++ newSize = buf->size; + while (size > newSize) { +- if (newSize > UINT_MAX / 2) { ++ if (newSize > SIZE_MAX / 2) { + xmlBufMemoryError(buf, "growing buffer"); + return 0; + } +@@ -800,7 +804,7 @@ xmlBufResize(xmlBufPtr buf, size_t size) + break; + + default: +- newSize = size+10; ++ newSize = (size > SIZE_MAX - 10 ? SIZE_MAX : size + 10); + break; + } + +@@ -866,7 +870,7 @@ xmlBufResize(xmlBufPtr buf, size_t size) + */ + int + xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) { +- unsigned int needSize; ++ size_t needSize; + + if ((str == NULL) || (buf == NULL) || (buf->error)) + return -1; +@@ -888,8 +892,10 @@ xmlBufAdd(xmlBufPtr buf, const xmlChar *str, int len) { + if (len < 0) return -1; + if (len == 0) return 0; + +- needSize = buf->use + len + 2; +- if (needSize > buf->size){ ++ if ((size_t) len >= buf->size - buf->use) { ++ if ((size_t) len >= SIZE_MAX - buf->use) ++ return(-1); ++ needSize = buf->use + len + 1; + if (buf->alloc == XML_BUFFER_ALLOC_BOUNDED) { + /* + * Used to provide parsing limits +@@ -1025,31 +1031,7 @@ xmlBufCat(xmlBufPtr buf, const xmlChar *str) { + */ + int + xmlBufCCat(xmlBufPtr buf, const char *str) { +- const char *cur; +- +- if ((buf == NULL) || (buf->error)) +- return(-1); +- CHECK_COMPAT(buf) +- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1; +- if (str == NULL) { +-#ifdef DEBUG_BUFFER +- xmlGenericError(xmlGenericErrorContext, +- "xmlBufCCat: str == NULL\n"); +-#endif +- return -1; +- } +- for (cur = str;*cur != 0;cur++) { +- if (buf->use + 10 >= buf->size) { +- if (!xmlBufResize(buf, buf->use+10)){ +- xmlBufMemoryError(buf, "growing buffer"); +- return XML_ERR_NO_MEMORY; +- } +- } +- buf->content[buf->use++] = *cur; +- } +- buf->content[buf->use] = 0; +- UPDATE_COMPAT(buf) +- return 0; ++ return xmlBufCat(buf, (const xmlChar *) str); + } + + /** +diff --git a/tree.c b/tree.c +index 86a8da79..fc75f962 100644 +--- a/tree.c ++++ b/tree.c +@@ -7049,6 +7049,8 @@ xmlBufferPtr + xmlBufferCreateSize(size_t size) { + xmlBufferPtr ret; + ++ if (size >= UINT_MAX) ++ return(NULL); + ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer)); + if (ret == NULL) { + xmlTreeErrMemory("creating buffer"); +@@ -7056,7 +7058,7 @@ xmlBufferCreateSize(size_t size) { + } + ret->use = 0; + ret->alloc = xmlBufferAllocScheme; +- ret->size = (size ? size+2 : 0); /* +1 for ending null */ ++ ret->size = (size ? size + 1 : 0); /* +1 for ending null */ + if (ret->size){ + ret->content = (xmlChar *) xmlMallocAtomic(ret->size * sizeof(xmlChar)); + if (ret->content == NULL) { +@@ -7116,6 +7118,8 @@ xmlBufferCreateStatic(void *mem, size_t size) { + + if ((mem == NULL) || (size == 0)) + return(NULL); ++ if (size > UINT_MAX) ++ return(NULL); + + ret = (xmlBufferPtr) xmlMalloc(sizeof(xmlBuffer)); + if (ret == NULL) { +@@ -7263,28 +7267,23 @@ xmlBufferShrink(xmlBufferPtr buf, unsigned int len) { + */ + int + xmlBufferGrow(xmlBufferPtr buf, unsigned int len) { +- int size; ++ unsigned int size; + xmlChar *newbuf; + + if (buf == NULL) return(-1); + + if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return(0); +- if (len + buf->use < buf->size) return(0); ++ if (len < buf->size - buf->use) ++ return(0); ++ if (len > UINT_MAX - buf->use) ++ return(-1); + +- /* +- * Windows has a BIG problem on realloc timing, so we try to double +- * the buffer size (if that's enough) (bug 146697) +- * Apparently BSD too, and it's probably best for linux too +- * On an embedded system this may be something to change +- */ +-#if 1 +- if (buf->size > len) +- size = buf->size * 2; +- else +- size = buf->use + len + 100; +-#else +- size = buf->use + len + 100; +-#endif ++ if (buf->size > (size_t) len) { ++ size = buf->size > UINT_MAX / 2 ? UINT_MAX : buf->size * 2; ++ } else { ++ size = buf->use + len; ++ size = size > UINT_MAX - 100 ? UINT_MAX : size + 100; ++ } + + if ((buf->alloc == XML_BUFFER_ALLOC_IO) && (buf->contentIO != NULL)) { + size_t start_buf = buf->content - buf->contentIO; +@@ -7406,7 +7405,10 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) + case XML_BUFFER_ALLOC_IO: + case XML_BUFFER_ALLOC_DOUBLEIT: + /*take care of empty case*/ +- newSize = (buf->size ? buf->size*2 : size + 10); ++ if (buf->size == 0) ++ newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10); ++ else ++ newSize = buf->size; + while (size > newSize) { + if (newSize > UINT_MAX / 2) { + xmlTreeErrMemory("growing buffer"); +@@ -7416,7 +7418,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) + } + break; + case XML_BUFFER_ALLOC_EXACT: +- newSize = size+10; ++ newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);; + break; + case XML_BUFFER_ALLOC_HYBRID: + if (buf->use < BASE_BUFFER_SIZE) +@@ -7434,7 +7436,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size) + break; + + default: +- newSize = size+10; ++ newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);; + break; + } + +@@ -7520,8 +7522,10 @@ xmlBufferAdd(xmlBufferPtr buf, const xmlChar *str, int len) { + if (len < 0) return -1; + if (len == 0) return 0; + +- needSize = buf->use + len + 2; +- if (needSize > buf->size){ ++ if ((unsigned) len >= buf->size - buf->use) { ++ if ((unsigned) len >= UINT_MAX - buf->use) ++ return XML_ERR_NO_MEMORY; ++ needSize = buf->use + len + 1; + if (!xmlBufferResize(buf, needSize)){ + xmlTreeErrMemory("growing buffer"); + return XML_ERR_NO_MEMORY; +@@ -7634,29 +7638,7 @@ xmlBufferCat(xmlBufferPtr buf, const xmlChar *str) { + */ + int + xmlBufferCCat(xmlBufferPtr buf, const char *str) { +- const char *cur; +- +- if (buf == NULL) +- return(-1); +- if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return -1; +- if (str == NULL) { +-#ifdef DEBUG_BUFFER +- xmlGenericError(xmlGenericErrorContext, +- "xmlBufferCCat: str == NULL\n"); +-#endif +- return -1; +- } +- for (cur = str;*cur != 0;cur++) { +- if (buf->use + 10 >= buf->size) { +- if (!xmlBufferResize(buf, buf->use+10)){ +- xmlTreeErrMemory("growing buffer"); +- return XML_ERR_NO_MEMORY; +- } +- } +- buf->content[buf->use++] = *cur; +- } +- buf->content[buf->use] = 0; +- return 0; ++ return xmlBufferCat(buf, (const xmlChar *) str); + } + + /** +-- +2.36.1 + diff --git a/SPECS/libxml2.spec b/SPECS/libxml2.spec index 7998fe6..18d854c 100644 --- a/SPECS/libxml2.spec +++ b/SPECS/libxml2.spec @@ -7,7 +7,7 @@ Name: libxml2 Version: 2.9.7 -Release: 13%{?dist} +Release: 14%{?dist} Summary: Library providing XML and HTML support License: MIT @@ -48,6 +48,8 @@ Patch14: libxml2-2.9.7-CVE-2021-3537.patch Patch15: libxml2-2.9.7-CVE-2021-3541.patch # https://bugzilla.redhat.com/show_bug.cgi?id=2057664 Patch16: libxml2-2.9.7-CVE-2022-23308.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=2082298 +Patch17: libxml2-2.9.7-CVE-2022-29824.patch BuildRequires: gcc BuildRequires: cmake-rpm-macros @@ -219,6 +221,9 @@ gzip -9 -c doc/libxml2-api.xml > doc/libxml2-api.xml.gz %{python3_sitearch}/libxml2mod.so %changelog +* Thu May 12 2022 David King - 2.9.7-14 +- Fix CVE-2022-29824 (#2082298) + * Thu Feb 24 2022 David King - 2.9.7-13 - Bump release (#2057664)