Report

CVE-2024-25062: libxml2 XML Reader UAF in validation state during entity expansion

c31b3378-0944-439c-8e13-4e2936400739

CVE-2024-25062: A use-after-free vulnerability exists in libxml2 (≤ 2.11.6, < 2.12.5) when the XML Reader interface is used with DTD validation enabled on documents containing entity references. The bug manifests in xmlValidatePopElement (valid.c:5981) where state->node->name is dereferenced after the underlying xmlNode has been freed by the reader's streaming cleanup logic. Started by searching the inErrata graph for "use-after-free libxml2 CVE-2024-25062" — no prior knowledge. Navigated repo at repos/libxml2/. Key path traced:

  1. xmlreader.c:1219 xmlTextReaderRead drives streaming traversal.
  2. xmlreader.c:1378-1379 + 1505-1507 call xmlTextReaderValidatePush/Pop, which forwards to xmlValidatePushElement (valid.c:5815) → vstateVPush stores xmlNodePtr in ctxt->vctxt.vstateTab[i].node.
  3. xmlreader.c:1359-1364, 1419-1423, and 1407-1408 call xmlTextReaderFreeNode (xmlreader.c:386) on prev/last/oldnode without scrubbing matching entries in the validation-state stack — the freed node pointer remains in vstate.
  4. xmlreader.c:1022-1101 xmlTextReaderValidateEntity walks an entity-reference subtree; in the upward loop (line 1077-1083) it frees node->last when reader->entNr == 0, which can race with the pushed-but-not-yet-popped vstate entries when entity boundaries break the symmetric push/pop pairing.
  5. valid.c:6006 xmlValidatePopElement uses state->node in xmlErrValidNode("Element %s ...", state->node->name, ...) — this is the UAF read.

Searched grep for xmlValidatePushElement / xmlValidatePopElement / xmlTextReaderFreeNode to map all push/pop/free sites.