diff --git a/SOURCES/libxml2-2.9.1-CVE-2016-4658.patch b/SOURCES/libxml2-2.9.1-CVE-2016-4658.patch
new file mode 100644
index 0000000..c2d3de1
--- /dev/null
+++ b/SOURCES/libxml2-2.9.1-CVE-2016-4658.patch
@@ -0,0 +1,249 @@
+From c1d1f7121194036608bf555f08d3062a36fd344b Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer@aevum.de>
+Date: Tue, 28 Jun 2016 18:34:52 +0200
+Subject: [PATCH] Disallow namespace nodes in XPointer ranges
+
+Namespace nodes must be copied to avoid use-after-free errors.
+But they don't necessarily have a physical representation in a
+document, so simply disallow them in XPointer ranges.
+
+Found with afl-fuzz.
+
+Fixes CVE-2016-4658.
+---
+ xpointer.c | 149 ++++++++++++++++++++---------------------------------
+ 1 file changed, 56 insertions(+), 93 deletions(-)
+
+diff --git a/xpointer.c b/xpointer.c
+index a7b03fbd..694d120e 100644
+--- a/xpointer.c
++++ b/xpointer.c
+@@ -319,6 +319,45 @@ xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
+     return(1);
+ }
+ 
++/**
++ * xmlXPtrNewRangeInternal:
++ * @start:  the starting node
++ * @startindex:  the start index
++ * @end:  the ending point
++ * @endindex:  the ending index
++ *
++ * Internal function to create a new xmlXPathObjectPtr of type range
++ *
++ * Returns the newly created object.
++ */
++static xmlXPathObjectPtr
++xmlXPtrNewRangeInternal(xmlNodePtr start, int startindex,
++                        xmlNodePtr end, int endindex) {
++    xmlXPathObjectPtr ret;
++
++    /*
++     * Namespace nodes must be copied (see xmlXPathNodeSetDupNs).
++     * Disallow them for now.
++     */
++    if ((start != NULL) && (start->type == XML_NAMESPACE_DECL))
++	return(NULL);
++    if ((end != NULL) && (end->type == XML_NAMESPACE_DECL))
++	return(NULL);
++
++    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
++    if (ret == NULL) {
++        xmlXPtrErrMemory("allocating range");
++	return(NULL);
++    }
++    memset(ret, 0, sizeof(xmlXPathObject));
++    ret->type = XPATH_RANGE;
++    ret->user = start;
++    ret->index = startindex;
++    ret->user2 = end;
++    ret->index2 = endindex;
++    return(ret);
++}
++
+ /**
+  * xmlXPtrNewRange:
+  * @start:  the starting node
+@@ -344,17 +383,7 @@ xmlXPtrNewRange(xmlNodePtr start, int startindex,
+     if (endindex < 0)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start;
+-    ret->index = startindex;
+-    ret->user2 = end;
+-    ret->index2 = endindex;
++    ret = xmlXPtrNewRangeInternal(start, startindex, end, endindex);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+@@ -381,17 +410,8 @@ xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
+     if (end->type != XPATH_POINT)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start->user;
+-    ret->index = start->index;
+-    ret->user2 = end->user;
+-    ret->index2 = end->index;
++    ret = xmlXPtrNewRangeInternal(start->user, start->index, end->user,
++                                  end->index);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+@@ -416,17 +436,7 @@ xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
+     if (start->type != XPATH_POINT)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start->user;
+-    ret->index = start->index;
+-    ret->user2 = end;
+-    ret->index2 = -1;
++    ret = xmlXPtrNewRangeInternal(start->user, start->index, end, -1);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+@@ -453,17 +463,7 @@ xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
+     if (end->type != XPATH_POINT)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start;
+-    ret->index = -1;
+-    ret->user2 = end->user;
+-    ret->index2 = end->index;
++    ret = xmlXPtrNewRangeInternal(start, -1, end->user, end->index);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+@@ -486,17 +486,7 @@ xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
+     if (end == NULL)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start;
+-    ret->index = -1;
+-    ret->user2 = end;
+-    ret->index2 = -1;
++    ret = xmlXPtrNewRangeInternal(start, -1, end, -1);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+@@ -516,17 +506,7 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) {
+     if (start == NULL)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start;
+-    ret->index = -1;
+-    ret->user2 = NULL;
+-    ret->index2 = -1;
++    ret = xmlXPtrNewRangeInternal(start, -1, NULL, -1);
+     return(ret);
+ }
+ 
+@@ -541,6 +521,8 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) {
+  */
+ xmlXPathObjectPtr
+ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
++    xmlNodePtr endNode;
++    int endIndex;
+     xmlXPathObjectPtr ret;
+ 
+     if (start == NULL)
+@@ -549,7 +531,12 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
+ 	return(NULL);
+     switch (end->type) {
+ 	case XPATH_POINT:
++	    endNode = end->user;
++	    endIndex = end->index;
++	    break;
+ 	case XPATH_RANGE:
++	    endNode = end->user2;
++	    endIndex = end->index2;
+ 	    break;
+ 	case XPATH_NODESET:
+ 	    /*
+@@ -557,39 +544,15 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
+ 	     */
+ 	    if (end->nodesetval->nodeNr <= 0)
+ 		return(NULL);
++	    endNode = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
++	    endIndex = -1;
+ 	    break;
+ 	default:
+ 	    /* TODO */
+ 	    return(NULL);
+     }
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start;
+-    ret->index = -1;
+-    switch (end->type) {
+-	case XPATH_POINT:
+-	    ret->user2 = end->user;
+-	    ret->index2 = end->index;
+-	    break;
+-	case XPATH_RANGE:
+-	    ret->user2 = end->user2;
+-	    ret->index2 = end->index2;
+-	    break;
+-	case XPATH_NODESET: {
+-	    ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
+-	    ret->index2 = -1;
+-	    break;
+-	}
+-	default:
+-	    STRANGE
+-	    return(NULL);
+-    }
++    ret = xmlXPtrNewRangeInternal(start, -1, endNode, endIndex);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+-- 
+GitLab
+
diff --git a/SPECS/libxml2.spec b/SPECS/libxml2.spec
index f2cc2e4..affdd10 100644
--- a/SPECS/libxml2.spec
+++ b/SPECS/libxml2.spec
@@ -4,7 +4,7 @@
 Summary: Library providing XML and HTML support
 Name: libxml2
 Version: 2.9.1
-Release: 6%{?dist}%{?extra_release}.5
+Release: 6%{?dist}%{?extra_release}.6
 License: MIT
 Group: Development/Libraries
 Source: ftp://xmlsoft.org/libxml2/libxml2-%{version}.tar.gz
@@ -74,6 +74,8 @@ patch147: libxml2-2.9.1-CVE-2019-20388.patch
 patch148: libxml2-2.9.1-CVE-2020-7595.patch
 # https://bugzilla.redhat.com/show_bug.cgi?id=1812145
 patch149: libxml2-2.9.1-xsd-any.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=1966916
+patch150: libxml2-2.9.1-CVE-2016-4658.patch
 
 
 %description
@@ -187,6 +189,7 @@ at parse time or later once the document has been modified.
 %patch147 -p1
 %patch148 -p1
 %patch149 -p1
+%patch150 -p1
 
 %build
 %configure
@@ -269,6 +272,9 @@ rm -fr %{buildroot}
 %doc doc/python.html
 
 %changelog
+* Mon Sep 27 2021 David King <dking@redhat.com> - 2.9.1-6.6
+- Fix CVE-2016-4658 (#1966916)
+
 * Wed Apr 22 2020 David King <dking@redhat.com> - 2.9.1-6.5
 - Fix CVE-2019-19956 (#1793000)
 - Fix CVE-2019-20388 (#1810057)