153aa9179Sopenharmony_ciFrom 08f9d319ebe99f41f71336ea01767b9c652ef34f Mon Sep 17 00:00:00 2001 253aa9179Sopenharmony_ciFrom: Nick Wellnhofer <wellnhofer@aevum.de> 353aa9179Sopenharmony_ciDate: Thu, 16 Mar 2023 17:01:05 +0100 453aa9179Sopenharmony_ciSubject: [PATCH] valid: Make xmlValidateElement non-recursive 553aa9179Sopenharmony_ci 653aa9179Sopenharmony_ciFixes call stack overflows when validating deeply nested documents. 753aa9179Sopenharmony_ci 853aa9179Sopenharmony_ciFound by OSS-Fuzz. 953aa9179Sopenharmony_ci 1053aa9179Sopenharmony_ciReference:https://github.com/GNOME/libxml2/commit/08f9d319ebe99f41f71336ea01767b9c652ef34f 1153aa9179Sopenharmony_ciConflict:NA 1253aa9179Sopenharmony_ci 1353aa9179Sopenharmony_ci--- 1453aa9179Sopenharmony_ci valid.c | 86 ++++++++++++++++++++++++++++----------------------------- 1553aa9179Sopenharmony_ci 1 file changed, 43 insertions(+), 43 deletions(-) 1653aa9179Sopenharmony_ci 1753aa9179Sopenharmony_cidiff --git a/valid.c b/valid.c 1853aa9179Sopenharmony_ciindex 9a2c708..3c0a869 100644 1953aa9179Sopenharmony_ci--- a/valid.c 2053aa9179Sopenharmony_ci+++ b/valid.c 2153aa9179Sopenharmony_ci@@ -6480,60 +6480,60 @@ name_ok: 2253aa9179Sopenharmony_ci */ 2353aa9179Sopenharmony_ci 2453aa9179Sopenharmony_ci int 2553aa9179Sopenharmony_ci-xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr elem) { 2653aa9179Sopenharmony_ci- xmlNodePtr child; 2753aa9179Sopenharmony_ci+xmlValidateElement(xmlValidCtxtPtr ctxt, xmlDocPtr doc, xmlNodePtr root) { 2853aa9179Sopenharmony_ci+ xmlNodePtr elem; 2953aa9179Sopenharmony_ci xmlAttrPtr attr; 3053aa9179Sopenharmony_ci xmlNsPtr ns; 3153aa9179Sopenharmony_ci const xmlChar *value; 3253aa9179Sopenharmony_ci int ret = 1; 3353aa9179Sopenharmony_ci 3453aa9179Sopenharmony_ci- if (elem == NULL) return(0); 3553aa9179Sopenharmony_ci- 3653aa9179Sopenharmony_ci- /* 3753aa9179Sopenharmony_ci- * XInclude elements were added after parsing in the infoset, 3853aa9179Sopenharmony_ci- * they don't really mean anything validation wise. 3953aa9179Sopenharmony_ci- */ 4053aa9179Sopenharmony_ci- if ((elem->type == XML_XINCLUDE_START) || 4153aa9179Sopenharmony_ci- (elem->type == XML_XINCLUDE_END) || 4253aa9179Sopenharmony_ci- (elem->type == XML_NAMESPACE_DECL)) 4353aa9179Sopenharmony_ci- return(1); 4453aa9179Sopenharmony_ci+ if (root == NULL) return(0); 4553aa9179Sopenharmony_ci 4653aa9179Sopenharmony_ci CHECK_DTD; 4753aa9179Sopenharmony_ci 4853aa9179Sopenharmony_ci- /* 4953aa9179Sopenharmony_ci- * Entities references have to be handled separately 5053aa9179Sopenharmony_ci- */ 5153aa9179Sopenharmony_ci- if (elem->type == XML_ENTITY_REF_NODE) { 5253aa9179Sopenharmony_ci- return(1); 5353aa9179Sopenharmony_ci- } 5453aa9179Sopenharmony_ci+ elem = root; 5553aa9179Sopenharmony_ci+ while (1) { 5653aa9179Sopenharmony_ci+ ret &= xmlValidateOneElement(ctxt, doc, elem); 5753aa9179Sopenharmony_ci+ 5853aa9179Sopenharmony_ci+ if (elem->type == XML_ELEMENT_NODE) { 5953aa9179Sopenharmony_ci+ attr = elem->properties; 6053aa9179Sopenharmony_ci+ while (attr != NULL) { 6153aa9179Sopenharmony_ci+ value = xmlNodeListGetString(doc, attr->children, 0); 6253aa9179Sopenharmony_ci+ ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value); 6353aa9179Sopenharmony_ci+ if (value != NULL) 6453aa9179Sopenharmony_ci+ xmlFree((char *)value); 6553aa9179Sopenharmony_ci+ attr= attr->next; 6653aa9179Sopenharmony_ci+ } 6753aa9179Sopenharmony_ci 6853aa9179Sopenharmony_ci- ret &= xmlValidateOneElement(ctxt, doc, elem); 6953aa9179Sopenharmony_ci- if (elem->type == XML_ELEMENT_NODE) { 7053aa9179Sopenharmony_ci- attr = elem->properties; 7153aa9179Sopenharmony_ci- while (attr != NULL) { 7253aa9179Sopenharmony_ci- value = xmlNodeListGetString(doc, attr->children, 0); 7353aa9179Sopenharmony_ci- ret &= xmlValidateOneAttribute(ctxt, doc, elem, attr, value); 7453aa9179Sopenharmony_ci- if (value != NULL) 7553aa9179Sopenharmony_ci- xmlFree((char *)value); 7653aa9179Sopenharmony_ci- attr= attr->next; 7753aa9179Sopenharmony_ci- } 7853aa9179Sopenharmony_ci- ns = elem->nsDef; 7953aa9179Sopenharmony_ci- while (ns != NULL) { 8053aa9179Sopenharmony_ci- if (elem->ns == NULL) 8153aa9179Sopenharmony_ci- ret &= xmlValidateOneNamespace(ctxt, doc, elem, NULL, 8253aa9179Sopenharmony_ci- ns, ns->href); 8353aa9179Sopenharmony_ci- else 8453aa9179Sopenharmony_ci- ret &= xmlValidateOneNamespace(ctxt, doc, elem, 8553aa9179Sopenharmony_ci- elem->ns->prefix, ns, ns->href); 8653aa9179Sopenharmony_ci- ns = ns->next; 8753aa9179Sopenharmony_ci- } 8853aa9179Sopenharmony_ci- } 8953aa9179Sopenharmony_ci- child = elem->children; 9053aa9179Sopenharmony_ci- while (child != NULL) { 9153aa9179Sopenharmony_ci- ret &= xmlValidateElement(ctxt, doc, child); 9253aa9179Sopenharmony_ci- child = child->next; 9353aa9179Sopenharmony_ci+ ns = elem->nsDef; 9453aa9179Sopenharmony_ci+ while (ns != NULL) { 9553aa9179Sopenharmony_ci+ if (elem->ns == NULL) 9653aa9179Sopenharmony_ci+ ret &= xmlValidateOneNamespace(ctxt, doc, elem, NULL, 9753aa9179Sopenharmony_ci+ ns, ns->href); 9853aa9179Sopenharmony_ci+ else 9953aa9179Sopenharmony_ci+ ret &= xmlValidateOneNamespace(ctxt, doc, elem, 10053aa9179Sopenharmony_ci+ elem->ns->prefix, ns, 10153aa9179Sopenharmony_ci+ ns->href); 10253aa9179Sopenharmony_ci+ ns = ns->next; 10353aa9179Sopenharmony_ci+ } 10453aa9179Sopenharmony_ci+ 10553aa9179Sopenharmony_ci+ if (elem->children != NULL) { 10653aa9179Sopenharmony_ci+ elem = elem->children; 10753aa9179Sopenharmony_ci+ continue; 10853aa9179Sopenharmony_ci+ } 10953aa9179Sopenharmony_ci+ } 11053aa9179Sopenharmony_ci+ 11153aa9179Sopenharmony_ci+ while (1) { 11253aa9179Sopenharmony_ci+ if (elem == root) 11353aa9179Sopenharmony_ci+ goto done; 11453aa9179Sopenharmony_ci+ if (elem->next != NULL) 11553aa9179Sopenharmony_ci+ break; 11653aa9179Sopenharmony_ci+ elem = elem->parent; 11753aa9179Sopenharmony_ci+ } 11853aa9179Sopenharmony_ci+ elem = elem->next; 11953aa9179Sopenharmony_ci } 12053aa9179Sopenharmony_ci 12153aa9179Sopenharmony_ci+done: 12253aa9179Sopenharmony_ci return(ret); 12353aa9179Sopenharmony_ci } 12453aa9179Sopenharmony_ci 12553aa9179Sopenharmony_ci-- 12653aa9179Sopenharmony_ci2.27.0 12753aa9179Sopenharmony_ci 128