153aa9179Sopenharmony_ciFrom 0f112d02890c218965235b8d1c42573fcaeec051 Mon Sep 17 00:00:00 2001
253aa9179Sopenharmony_ciFrom: Nick Wellnhofer <wellnhofer@aevum.de>
353aa9179Sopenharmony_ciDate: Fri, 24 Feb 2023 18:00:03 +0100
453aa9179Sopenharmony_ciSubject: [PATCH] malloc-fail: Fix use-after-free related to
553aa9179Sopenharmony_ci xmlXPathNodeSetFilter
653aa9179Sopenharmony_ci
753aa9179Sopenharmony_ciFound with libFuzzer, see #344.
853aa9179Sopenharmony_ci
953aa9179Sopenharmony_ciReference:https://github.com/GNOME/libxml2/commit/0f112d02890c218965235b8d1c42573fcaeec051
1053aa9179Sopenharmony_ciConflict:xpath.c
1153aa9179Sopenharmony_ci---
1253aa9179Sopenharmony_ci xpath.c | 21 +++++++++++++++++++--
1353aa9179Sopenharmony_ci 1 file changed, 19 insertions(+), 2 deletions(-)
1453aa9179Sopenharmony_ci
1553aa9179Sopenharmony_cidiff --git a/xpath.c b/xpath.c
1653aa9179Sopenharmony_ciindex 7f2c92a..d63bdd7 100644
1753aa9179Sopenharmony_ci--- a/xpath.c
1853aa9179Sopenharmony_ci+++ b/xpath.c
1953aa9179Sopenharmony_ci@@ -12876,6 +12876,7 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
2053aa9179Sopenharmony_ci {
2153aa9179Sopenharmony_ci     int total = 0;
2253aa9179Sopenharmony_ci     xmlXPathCompExprPtr comp;
2353aa9179Sopenharmony_ci+    xmlXPathObjectPtr obj;
2453aa9179Sopenharmony_ci     xmlNodeSetPtr set;
2553aa9179Sopenharmony_ci 
2653aa9179Sopenharmony_ci     CHECK_ERROR0;
2753aa9179Sopenharmony_ci@@ -12943,13 +12944,20 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt,
2853aa9179Sopenharmony_ci     }
2953aa9179Sopenharmony_ci #endif /* LIBXML_XPTR_ENABLED */
3053aa9179Sopenharmony_ci 
3153aa9179Sopenharmony_ci+    /*
3253aa9179Sopenharmony_ci+     * In case of errors, xmlXPathNodeSetFilter can pop additional nodes from
3353aa9179Sopenharmony_ci+     * the stack. We have to temporarily remove the nodeset object from the
3453aa9179Sopenharmony_ci+     * stack to avoid freeing it prematurely.
3553aa9179Sopenharmony_ci+     */
3653aa9179Sopenharmony_ci     CHECK_TYPE0(XPATH_NODESET);
3753aa9179Sopenharmony_ci-    set = ctxt->value->nodesetval;
3853aa9179Sopenharmony_ci+    obj = valuePop(ctxt);
3953aa9179Sopenharmony_ci+    set = obj->nodesetval;
4053aa9179Sopenharmony_ci     if (set != NULL) {
4153aa9179Sopenharmony_ci         xmlXPathNodeSetFilter(ctxt, set, op->ch2, 1, 1, 1);
4253aa9179Sopenharmony_ci         if (set->nodeNr > 0)
4353aa9179Sopenharmony_ci             *first = set->nodeTab[0];
4453aa9179Sopenharmony_ci     }
4553aa9179Sopenharmony_ci+    valuePush(ctxt, obj);
4653aa9179Sopenharmony_ci 
4753aa9179Sopenharmony_ci     return (total);
4853aa9179Sopenharmony_ci }
4953aa9179Sopenharmony_ci@@ -13247,6 +13255,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
5053aa9179Sopenharmony_ci             break;
5153aa9179Sopenharmony_ci         case XPATH_OP_PREDICATE:
5253aa9179Sopenharmony_ci         case XPATH_OP_FILTER:{
5353aa9179Sopenharmony_ci+                xmlXPathObjectPtr obj;
5453aa9179Sopenharmony_ci                 xmlNodeSetPtr set;
5553aa9179Sopenharmony_ci 
5653aa9179Sopenharmony_ci                 /*
5753aa9179Sopenharmony_ci@@ -13361,11 +13370,19 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op)
5853aa9179Sopenharmony_ci                 }
5953aa9179Sopenharmony_ci #endif /* LIBXML_XPTR_ENABLED */
6053aa9179Sopenharmony_ci 
6153aa9179Sopenharmony_ci+                /*
6253aa9179Sopenharmony_ci+                 * In case of errors, xmlXPathNodeSetFilter can pop additional
6353aa9179Sopenharmony_ci+                 * nodes from the stack. We have to temporarily remove the
6453aa9179Sopenharmony_ci+                 * nodeset object from the stack to avoid freeing it
6553aa9179Sopenharmony_ci+                 * prematurely.
6653aa9179Sopenharmony_ci+                 */
6753aa9179Sopenharmony_ci                 CHECK_TYPE0(XPATH_NODESET);
6853aa9179Sopenharmony_ci-                set = ctxt->value->nodesetval;
6953aa9179Sopenharmony_ci+                obj = valuePop(ctxt);
7053aa9179Sopenharmony_ci+                set = obj->nodesetval;
7153aa9179Sopenharmony_ci                 if (set != NULL)
7253aa9179Sopenharmony_ci                     xmlXPathNodeSetFilter(ctxt, set, op->ch2,
7353aa9179Sopenharmony_ci                                           1, set->nodeNr, 1);
7453aa9179Sopenharmony_ci+                valuePush(ctxt, obj);
7553aa9179Sopenharmony_ci                 break;
7653aa9179Sopenharmony_ci             }
7753aa9179Sopenharmony_ci         case XPATH_OP_SORT:
7853aa9179Sopenharmony_ci-- 
7953aa9179Sopenharmony_ci2.27.0
8053aa9179Sopenharmony_ci
81