parent
abcdcc82c9
commit
c861f20ebe
341
libxml2-2.9.13-CVE-2022-29824.patch
Normal file
341
libxml2-2.9.13-CVE-2022-29824.patch
Normal file
@ -0,0 +1,341 @@
|
||||
From ecc43dce8e2cd19f635841e788421d0f4bd72cce Mon Sep 17 00:00:00 2001
|
||||
From: Nick Wellnhofer <wellnhofer@aevum.de>
|
||||
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 24368d37..40a5ee06 100644
|
||||
--- a/buf.c
|
||||
+++ b/buf.c
|
||||
@@ -30,6 +30,10 @@
|
||||
#include <libxml/parserInternals.h> /* 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 9d94aa42..86afb7d6 100644
|
||||
--- a/tree.c
|
||||
+++ b/tree.c
|
||||
@@ -7104,6 +7104,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");
|
||||
@@ -7111,7 +7113,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) {
|
||||
@@ -7171,6 +7173,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) {
|
||||
@@ -7318,28 +7322,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;
|
||||
@@ -7466,7 +7465,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 : 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");
|
||||
@@ -7476,7 +7478,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)
|
||||
@@ -7494,7 +7496,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
|
||||
break;
|
||||
|
||||
default:
|
||||
- newSize = size+10;
|
||||
+ newSize = (size > UINT_MAX - 10 ? UINT_MAX : size + 10);;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -7580,8 +7582,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;
|
||||
@@ -7694,29 +7698,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.0
|
||||
|
@ -1,6 +1,6 @@
|
||||
Name: libxml2
|
||||
Version: 2.9.13
|
||||
Release: 1%{?dist}
|
||||
Release: 2%{?dist}
|
||||
Summary: Library providing XML and HTML support
|
||||
|
||||
License: MIT
|
||||
@ -10,6 +10,8 @@ Patch0: libxml2-multilib.patch
|
||||
# Patch from openSUSE.
|
||||
# See: https://bugzilla.gnome.org/show_bug.cgi?id=789714
|
||||
Patch1: libxml2-2.9.8-python3-unicode-errors.patch
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=2082300
|
||||
Patch2: libxml2-2.9.13-CVE-2022-29824.patch
|
||||
|
||||
BuildRequires: cmake-rpm-macros
|
||||
BuildRequires: gcc
|
||||
@ -138,6 +140,9 @@ gzip -9 -c doc/libxml2-api.xml > doc/libxml2-api.xml.gz
|
||||
%{python3_sitearch}/libxml2mod.so
|
||||
|
||||
%changelog
|
||||
* Tue May 10 2022 David King <amigadave@amigadave.com> - 2.9.13-2
|
||||
- Fix CVE-2022-29824 (#2082300)
|
||||
|
||||
* Thu Feb 24 2022 David King <amigadave@amigadave.com> - 2.9.13-1
|
||||
- Update to 2.9.13 (#2057665)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user