From 0f112d02890c218965235b8d1c42573fcaeec051 Mon Sep 17 00:00:00 2001 From: Nick Wellnhofer Date: Fri, 24 Feb 2023 18:00:03 +0100 Subject: [PATCH] malloc-fail: Fix use-after-free related to xmlXPathNodeSetFilter Found with libFuzzer, see #344. Reference:https://github.com/GNOME/libxml2/commit/0f112d02890c218965235b8d1c42573fcaeec051 Conflict:xpath.c --- xpath.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/xpath.c b/xpath.c index 7f2c92a..d63bdd7 100644 --- a/xpath.c +++ b/xpath.c @@ -12876,6 +12876,7 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, { int total = 0; xmlXPathCompExprPtr comp; + xmlXPathObjectPtr obj; xmlNodeSetPtr set; CHECK_ERROR0; @@ -12943,13 +12944,20 @@ xmlXPathCompOpEvalFilterFirst(xmlXPathParserContextPtr ctxt, } #endif /* LIBXML_XPTR_ENABLED */ + /* + * In case of errors, xmlXPathNodeSetFilter can pop additional nodes from + * the stack. We have to temporarily remove the nodeset object from the + * stack to avoid freeing it prematurely. + */ CHECK_TYPE0(XPATH_NODESET); - set = ctxt->value->nodesetval; + obj = valuePop(ctxt); + set = obj->nodesetval; if (set != NULL) { xmlXPathNodeSetFilter(ctxt, set, op->ch2, 1, 1, 1); if (set->nodeNr > 0) *first = set->nodeTab[0]; } + valuePush(ctxt, obj); return (total); } @@ -13247,6 +13255,7 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) break; case XPATH_OP_PREDICATE: case XPATH_OP_FILTER:{ + xmlXPathObjectPtr obj; xmlNodeSetPtr set; /* @@ -13361,11 +13370,19 @@ xmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) } #endif /* LIBXML_XPTR_ENABLED */ + /* + * In case of errors, xmlXPathNodeSetFilter can pop additional + * nodes from the stack. We have to temporarily remove the + * nodeset object from the stack to avoid freeing it + * prematurely. + */ CHECK_TYPE0(XPATH_NODESET); - set = ctxt->value->nodesetval; + obj = valuePop(ctxt); + set = obj->nodesetval; if (set != NULL) xmlXPathNodeSetFilter(ctxt, set, op->ch2, 1, set->nodeNr, 1); + valuePush(ctxt, obj); break; } case XPATH_OP_SORT: -- 2.27.0