[dunfell,06/11] libxml2: Fix CVE-2022-29824 for libxml2

Message ID 096ca5fa8cc4672e5e9b25dffe81b176b252d570.1654136888.git.steve@sakoman.com
State Accepted, archived
Commit 096ca5fa8cc4672e5e9b25dffe81b176b252d570
Headers show
Series [dunfell,01/11] ruby: Upgrade ruby to 2.7.6 for security fix | expand

Commit Message

Steve Sakoman June 2, 2022, 2:30 a.m. UTC
From: Riyaz <Riyaz.Khan@kpit.com>

Add patch for CVE issue: CVE-2022-29824

CVE-2022-29824
Link: [https://gitlab.gnome.org/GNOME/libxml2/-/commit/2554a2408e09f13652049e5ffb0d26196b02ebab]
Dependent patch: [https://gitlab.gnome.org/GNOME/libxml2/-/commit/b07251215ef48c70c6e56f7351406c47cfca4d5b]

Signed-off-by: Riyaz <Riyaz.Khan@kpit.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
---
 .../libxml2/CVE-2022-29824-dependent.patch    |  53 +++
 .../libxml/libxml2/CVE-2022-29824.patch       | 348 ++++++++++++++++++
 meta/recipes-core/libxml/libxml2_2.9.10.bb    |   2 +
 3 files changed, 403 insertions(+)
 create mode 100644 meta/recipes-core/libxml/libxml2/CVE-2022-29824-dependent.patch
 create mode 100644 meta/recipes-core/libxml/libxml2/CVE-2022-29824.patch

Patch

diff --git a/meta/recipes-core/libxml/libxml2/CVE-2022-29824-dependent.patch b/meta/recipes-core/libxml/libxml2/CVE-2022-29824-dependent.patch
new file mode 100644
index 0000000000..63d613cc21
--- /dev/null
+++ b/meta/recipes-core/libxml/libxml2/CVE-2022-29824-dependent.patch
@@ -0,0 +1,53 @@ 
+From b07251215ef48c70c6e56f7351406c47cfca4d5b Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Fri, 10 Jan 2020 15:55:07 +0100
+Subject: [PATCH] Fix integer overflow in xmlBufferResize
+
+Found by OSS-Fuzz.
+
+CVE: CVE-2022-29824
+
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/b07251215ef48c70c6e56f7351406c47cfca4d5b]
+
+Signed-off-by: Riyaz Ahmed Khan <Riyaz.Khan@kpit.com>
+
+---
+ tree.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/tree.c b/tree.c
+index 0d7fc98c..f43f6de1 100644
+--- a/tree.c
++++ b/tree.c
+@@ -7424,12 +7424,17 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
+     if (size < buf->size)
+         return 1;
+ 
++    if (size > UINT_MAX - 10) {
++        xmlTreeErrMemory("growing buffer");
++        return 0;
++    }
++
+     /* figure out new size */
+     switch (buf->alloc){
+ 	case XML_BUFFER_ALLOC_IO:
+ 	case XML_BUFFER_ALLOC_DOUBLEIT:
+ 	    /*take care of empty case*/
+-	    newSize = (buf->size ? buf->size*2 : size + 10);
++	    newSize = (buf->size ? buf->size : size + 10);
+ 	    while (size > newSize) {
+ 	        if (newSize > UINT_MAX / 2) {
+ 	            xmlTreeErrMemory("growing buffer");
+@@ -7445,7 +7450,7 @@ xmlBufferResize(xmlBufferPtr buf, unsigned int size)
+             if (buf->use < BASE_BUFFER_SIZE)
+                 newSize = size;
+             else {
+-                newSize = buf->size * 2;
++                newSize = buf->size;
+                 while (size > newSize) {
+                     if (newSize > UINT_MAX / 2) {
+                         xmlTreeErrMemory("growing buffer");
+-- 
+GitLab
+
+
diff --git a/meta/recipes-core/libxml/libxml2/CVE-2022-29824.patch b/meta/recipes-core/libxml/libxml2/CVE-2022-29824.patch
new file mode 100644
index 0000000000..ad7b87dbc6
--- /dev/null
+++ b/meta/recipes-core/libxml/libxml2/CVE-2022-29824.patch
@@ -0,0 +1,348 @@ 
+From 2554a2408e09f13652049e5ffb0d26196b02ebab 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.
+
+CVE: CVE-2022-29824
+
+Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/-/commit/2554a2408e09f13652049e5ffb0d26196b02ebab]
+
+Signed-off-by: Riyaz Ahmed Khan <Riyaz.Khan@kpit.com>
+
+---
+ 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);
+ }
+ 
+ /**
+-- 
+GitLab
+
diff --git a/meta/recipes-core/libxml/libxml2_2.9.10.bb b/meta/recipes-core/libxml/libxml2_2.9.10.bb
index c4bb8f29e0..b3ebf15751 100644
--- a/meta/recipes-core/libxml/libxml2_2.9.10.bb
+++ b/meta/recipes-core/libxml/libxml2_2.9.10.bb
@@ -30,6 +30,8 @@  SRC_URI += "http://www.w3.org/XML/Test/xmlts20080827.tar.gz;subdir=${BP};name=te
            file://CVE-2021-3541.patch \
            file://CVE-2022-23308.patch \
            file://CVE-2022-23308-fix-regression.patch \
+           file://CVE-2022-29824-dependent.patch \
+           file://CVE-2022-29824.patch \
            "
 
 SRC_URI[archive.sha256sum] = "593b7b751dd18c2d6abcd0c4bcb29efc203d0b4373a6df98e3a455ea74ae2813"