• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From b1319c902f6e44d08f8cb33f1fc28847f2bc8aeb Mon Sep 17 00:00:00 2001
2From: Nick Wellnhofer <wellnhofer@aevum.de>
3Date: Sat, 18 Mar 2023 16:34:01 +0100
4Subject: [PATCH] malloc-fail: Check for malloc failures when creating XPath
5 strings
6
7Prevent null derefs.
8
9Found by OSS-Fuzz, see #344.
10
11Reference:https://github.com/GNOME/libxml2/commit/b1319c902f6e44d08f8cb33f1fc28847f2bc8aeb
12Conflict:xpath.c
13
14---
15 xpath.c | 111 +++++++++++++++++++++-----------------------------------
16 1 file changed, 42 insertions(+), 69 deletions(-)
17
18diff --git a/xpath.c b/xpath.c
19index 005a6a2..2eceb5b 100644
20--- a/xpath.c
21+++ b/xpath.c
22@@ -2476,17 +2476,17 @@ xmlXPathCacheNewNodeSet(xmlXPathContextPtr ctxt, xmlNodePtr val)
23 }
24
25 /**
26- * xmlXPathCacheNewCString:
27+ * xmlXPathCacheNewString:
28  * @ctxt: the XPath context
29- * @val:  the char * value
30+ * @val:  the xmlChar * value
31  *
32- * This is the cached version of xmlXPathNewCString().
33+ * This is the cached version of xmlXPathNewString().
34  * Acquire an xmlXPathObjectPtr of type string and of value @val
35  *
36  * Returns the created or reused object.
37  */
38 static xmlXPathObjectPtr
39-xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
40+xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
41 {
42     if ((ctxt != NULL) && (ctxt->cache)) {
43 	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
44@@ -2495,12 +2495,20 @@ xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
45 	    (cache->stringObjs->number != 0))
46 	{
47 	    xmlXPathObjectPtr ret;
48+            xmlChar *copy;
49+
50+            if (val == NULL)
51+                val = BAD_CAST "";
52+            copy = xmlStrdup(val);
53+            if (copy == NULL) {
54+                xmlXPathErrMemory(ctxt, NULL);
55+                return(NULL);
56+            }
57
58 	    ret = (xmlXPathObjectPtr)
59 		cache->stringObjs->items[--cache->stringObjs->number];
60-
61 	    ret->type = XPATH_STRING;
62-	    ret->stringval = xmlStrdup(BAD_CAST val);
63+            ret->stringval = copy;
64 #ifdef XP_DEBUG_OBJ_USAGE
65 	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
66 #endif
67@@ -2509,73 +2517,44 @@ xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
68 	    (cache->miscObjs->number != 0))
69 	{
70 	    xmlXPathObjectPtr ret;
71+            xmlChar *copy;
72+
73+            if (val == NULL)
74+                val = BAD_CAST "";
75+            copy = xmlStrdup(val);
76+            if (copy == NULL) {
77+                xmlXPathErrMemory(ctxt, NULL);
78+                return(NULL);
79+            }
80
81 	    ret = (xmlXPathObjectPtr)
82 		cache->miscObjs->items[--cache->miscObjs->number];
83
84 	    ret->type = XPATH_STRING;
85-	    ret->stringval = xmlStrdup(BAD_CAST val);
86+            ret->stringval = copy;
87 #ifdef XP_DEBUG_OBJ_USAGE
88 	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
89 #endif
90 	    return(ret);
91 	}
92     }
93-    return(xmlXPathNewCString(val));
94+    return(xmlXPathNewString(val));
95 }
96
97 /**
98- * xmlXPathCacheNewString:
99+ * xmlXPathCacheNewCString:
100  * @ctxt: the XPath context
101- * @val:  the xmlChar * value
102+ * @val:  the char * value
103  *
104- * This is the cached version of xmlXPathNewString().
105+ * This is the cached version of xmlXPathNewCString().
106  * Acquire an xmlXPathObjectPtr of type string and of value @val
107  *
108  * Returns the created or reused object.
109  */
110 static xmlXPathObjectPtr
111-xmlXPathCacheNewString(xmlXPathContextPtr ctxt, const xmlChar *val)
112+xmlXPathCacheNewCString(xmlXPathContextPtr ctxt, const char *val)
113 {
114-    if ((ctxt != NULL) && (ctxt->cache)) {
115-	xmlXPathContextCachePtr cache = (xmlXPathContextCachePtr) ctxt->cache;
116-
117-	if ((cache->stringObjs != NULL) &&
118-	    (cache->stringObjs->number != 0))
119-	{
120-	    xmlXPathObjectPtr ret;
121-
122-	    ret = (xmlXPathObjectPtr)
123-		cache->stringObjs->items[--cache->stringObjs->number];
124-	    ret->type = XPATH_STRING;
125-	    if (val != NULL)
126-		ret->stringval = xmlStrdup(val);
127-	    else
128-		ret->stringval = xmlStrdup((const xmlChar *)"");
129-#ifdef XP_DEBUG_OBJ_USAGE
130-	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
131-#endif
132-	    return(ret);
133-	} else if ((cache->miscObjs != NULL) &&
134-	    (cache->miscObjs->number != 0))
135-	{
136-	    xmlXPathObjectPtr ret;
137-
138-	    ret = (xmlXPathObjectPtr)
139-		cache->miscObjs->items[--cache->miscObjs->number];
140-
141-	    ret->type = XPATH_STRING;
142-	    if (val != NULL)
143-		ret->stringval = xmlStrdup(val);
144-	    else
145-		ret->stringval = xmlStrdup((const xmlChar *)"");
146-#ifdef XP_DEBUG_OBJ_USAGE
147-	    xmlXPathDebugObjUsageRequested(ctxt, XPATH_STRING);
148-#endif
149-	    return(ret);
150-	}
151-    }
152-    return(xmlXPathNewString(val));
153+    return xmlXPathCacheNewString(ctxt, BAD_CAST val);
154 }
155
156 /**
157@@ -5291,10 +5270,13 @@ xmlXPathNewString(const xmlChar *val) {
158     }
159     memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
160     ret->type = XPATH_STRING;
161-    if (val != NULL)
162-	ret->stringval = xmlStrdup(val);
163-    else
164-	ret->stringval = xmlStrdup((const xmlChar *)"");
165+    if (val == NULL)
166+        val = BAD_CAST "";
167+    ret->stringval = xmlStrdup(val);
168+    if (ret->stringval == NULL) {
169+        xmlFree(ret);
170+        return(NULL);
171+    }
172 #ifdef XP_DEBUG_OBJ_USAGE
173     xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
174 #endif
175@@ -5340,20 +5322,7 @@ xmlXPathWrapString (xmlChar *val) {
176  */
177 xmlXPathObjectPtr
178 xmlXPathNewCString(const char *val) {
179-    xmlXPathObjectPtr ret;
180-
181-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
182-    if (ret == NULL) {
183-        xmlXPathErrMemory(NULL, "creating string object\n");
184-	return(NULL);
185-    }
186-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
187-    ret->type = XPATH_STRING;
188-    ret->stringval = xmlStrdup(BAD_CAST val);
189-#ifdef XP_DEBUG_OBJ_USAGE
190-    xmlXPathDebugObjUsageRequested(NULL, XPATH_STRING);
191-#endif
192-    return(ret);
193+    return(xmlXPathNewString(BAD_CAST val));
194 }
195
196 /**
197@@ -5427,6 +5396,10 @@ xmlXPathObjectCopy(xmlXPathObjectPtr val) {
198 	    break;
199 	case XPATH_STRING:
200 	    ret->stringval = xmlStrdup(val->stringval);
201+            if (ret->stringval == NULL) {
202+                xmlFree(ret);
203+                return(NULL);
204+            }
205 	    break;
206 	case XPATH_XSLT_TREE:
207 #if 0
208--
2092.27.0
210
211