[PATCH] contrib/xml2: backend crash in xpath_nodeset() on the namespace axis
Andrey Chernyy <andrey.cherny@tantorlabs.com>
From: Andrey Chernyy <andrey.cherny@tantorlabs.com>
To: pgsql-bugs@lists.postgresql.org
Cc: Michael Paquier <michael@paquier.xyz>
Date: 2026-06-11T00:14:36Z
Lists: pgsql-bugs
Attachments
Hi,
In the xml2 extension, xpath_nodeset() crashes the backend on an XPath
that selects namespace-axis nodes. xpath_nodeset() is executable by
PUBLIC by default, so any role that can run SQL can crash the server
with one query:
CREATE EXTENSION xml2;
SELECT xpath_nodeset('<root
xmlns:foo="http://example.com/foo"><child/></root>',
'//namespace::*');
Cause: pgxmlNodeSetToText() (contrib/xml2/xpath.c:197) calls
xmlNodeDump(buf, nodeset->nodeTab[i]->doc, nodeset->nodeTab[i], 1,
0);
with no node-type check. Namespace-axis results are XML_NAMESPACE_DECL
nodes (xmlNs structs cast to xmlNodePtr), so reading the node's ->doc
field runs past the smaller xmlNs allocation, and the bogus value is
then dereferenced as the document by xmlNodeDump(). xpath_list() and
xpath_table() already avoid this via xmlXPathCastNodeToString(); only
the xmlNodeDump() path is exposed.
Reproduced on master; the same unguarded xmlNodeDump() call in
pgxmlNodeSetToText() is present on every supported back-branch (REL_18
through REL_14).
Patch attached: render XML_NAMESPACE_DECL nodes with
xmlXPathCastNodeToString() like xpath_table() does. The repro then
returns the namespace text, ordinary node-set output is unchanged, and
the xml2 regression test passes.
--
Andrey Chernyy
Commits
-
Fix handling of namespace nodes in xpath() (xml)
- 41876c8d7783 14 (unreleased) landed
- 1d8c72b2eff6 15 (unreleased) landed
- 1740766012e6 16 (unreleased) landed
- 6c08cbb7a7b4 17 (unreleased) landed
- 4c777d6dd9c9 18 (unreleased) landed
- 8bf257aebac1 19 (unreleased) landed
-
xml2: Fix crash with namespace nodes in xpath_nodeset()
- f3f901a53a17 14 (unreleased) landed
- bc5775149f59 15 (unreleased) landed
- 18955d412c82 16 (unreleased) landed
- 4a49ab289085 17 (unreleased) landed
- 91b57eadeb0f 18 (unreleased) landed
- 9d33a5a804db 19 (unreleased) landed