diff --git a/SOURCES/libxml2-2.9.13-CVE-2022-29824.patch b/SOURCES/libxml2-2.9.13-CVE-2022-29824.patch
new file mode 100644
index 0000000..314ab93
--- /dev/null
+++ b/SOURCES/libxml2-2.9.13-CVE-2022-29824.patch
@@ -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
+
diff --git a/SPECS/libxml2.spec b/SPECS/libxml2.spec
index 55616cb..fa9d053 100644
--- a/SPECS/libxml2.spec
+++ b/SPECS/libxml2.spec
@@ -1,6 +1,6 @@
 Name:           libxml2
 Version:        2.9.13
-Release:        1%{?dist}
+Release:        1%{?dist}.1
 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=2082299
+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
+* Fri May 13 2022 David King <dking@redhat.com> - 2.9.13-1.1
+- Fix CVE-2022-29824 (#2082299)
+
 * Thu Feb 24 2022 David King <amigadave@amigadave.com> - 2.9.13-1
 - Update to 2.9.13 (#2057665)