From: "Roland Kovács" <roland.kovacs@est.tech>
To: "steve@sakoman.com" <steve@sakoman.com>
Cc: "openembedded-core@lists.openembedded.org"
<openembedded-core@lists.openembedded.org>
Subject: Re: [OE-core] [scarthgap][PATCH] libxml2: fix CVE-2025-49795
Date: Thu, 17 Jul 2025 07:04:59 +0000 [thread overview]
Message-ID: <2bd2f4c8d55c280f8db213d89ae8f7fc8aca0a97.camel@est.tech> (raw)
In-Reply-To: <CAOSpxdaRkeNgh0E=m76vMOMsLhn4B2MoKgbpJEa-GtxXFqP-og@mail.gmail.com>
On Wed, 2025-07-16 at 08:04 -0700, Steve Sakoman wrote:
> I'm getting ptest failures with this patch:
>
> WARNING: core-image-ptest-libxml2-1.0-r0 do_testimage: There were
> failing ptests.
> Traceback (most recent call last):
> File "/srv/pokybuild/yocto-worker/qemux86-64-
> ptest/build/meta/lib/oeqa/core/decorator/__init__.py",
> line 35, in wrapped_f
> return func(*args, **kwargs)
> ^^^^^^^^^^^^^^^^^^^^^
> File "/srv/pokybuild/yocto-worker/qemux86-64-
> ptest/build/meta/lib/oeqa/core/decorator/__init__.py",
> line 35, in wrapped_f
> return func(*args, **kwargs)
> ^^^^^^^^^^^^^^^^^^^^^
> File "/srv/pokybuild/yocto-worker/qemux86-64-
> ptest/build/meta/lib/oeqa/core/decorator/__init__.py",
> line 35, in wrapped_f
> return func(*args, **kwargs)
> ^^^^^^^^^^^^^^^^^^^^^
> File "/srv/pokybuild/yocto-worker/qemux86-64-ptest/build/meta/lib/oeqa/runtime/cases/ptest.py",
> line 27, in test_ptestrunner_expectfail
> self.do_ptestrunner()
> File "/srv/pokybuild/yocto-worker/qemux86-64-ptest/build/meta/lib/oeqa/runtime/cases/ptest.py",
> line 120, in do_ptestrunner
> self.fail(failmsg)
> AssertionError:
> Failed ptests:
> {'libxml2': ['runtest']}
>
> I'm seeing it on both x86-64 and arm64:
>
> https://autobuilder.yoctoproject.org/valkyrie/?#/builders/73/builds/1900/steps/12/logs/stdio
> https://autobuilder.yoctoproject.org/valkyrie/?#/builders/61/builds/1897/steps/12/logs/stdio
>
> I do not see the same issue with the walnascar version of the patch,
> so perhaps that is a clue that will aid your debugging.
>
> Steve
>
I'll look into it, and thanks for the pointers!
Cheers,
Roland
> On Fri, Jul 11, 2025 at 2:15 AM roland.kovacs via
> lists.openembedded.org <roland.kovacs=est.tech@lists.openembedded.org>
> wrote:
> >
> > From: Roland Kovacs <roland.kovacs@est.tech>
> >
> > A NULL pointer dereference vulnerability was found in libxml2 when processing
> > XPath XML expressions. This flaw allows an attacker to craft a malicious XML
> > input to libxml2, leading to a denial of service.
> >
> > Signed-off-by: Roland Kovacs <roland.kovacs@est.tech>
> > ---
> > .../libxml/libxml2/CVE-2025-49795.patch | 238 ++++++++++++++++++
> > meta/recipes-core/libxml/libxml2_2.12.10.bb | 1 +
> > 2 files changed, 239 insertions(+)
> > create mode 100644 meta/recipes-core/libxml/libxml2/CVE-2025-49795.patch
> >
> > diff --git a/meta/recipes-core/libxml/libxml2/CVE-2025-49795.patch b/meta/recipes-
> > core/libxml/libxml2/CVE-2025-49795.patch
> > new file mode 100644
> > index 0000000000..fd784ea45b
> > --- /dev/null
> > +++ b/meta/recipes-core/libxml/libxml2/CVE-2025-49795.patch
> > @@ -0,0 +1,238 @@
> > +From 68ce19940f8e08c85f9c8ce65180cdb90bf4b0d2 Mon Sep 17 00:00:00 2001
> > +From: Michael Mann <mmann78@netscape.net>
> > +Date: Sat, 21 Jun 2025 12:11:30 -0400
> > +Subject: [PATCH] Schematron: Fix null pointer dereference leading to DoS
> > +
> > +(CVE-2025-49795)
> > +
> > +Fixes #932
> > +
> > +Upstream-Status: Backport
> > [https://gitlab.gnome.org/GNOME/libxml2/-/commit/c24909ba2601848825b49a60f988222da3019667]
> > +CVE: CVE-2025-49795
> > +
> > +(cherry picked from commit c24909ba2601848825b49a60f988222da3019667)
> > +Signed-off-by: Roland Kovacs <roland.kovacs@est.tech>
> > +---
> > + result/schematron/zvon16_0.err | 3 +
> > + runtest.c | 139 +++++++++++++++++++++++++++++++++
> > + schematron.c | 5 ++
> > + test/schematron/zvon16.sct | 7 ++
> > + test/schematron/zvon16_0.xml | 5 ++
> > + 5 files changed, 159 insertions(+)
> > + create mode 100644 result/schematron/zvon16_0.err
> > + create mode 100644 test/schematron/zvon16.sct
> > + create mode 100644 test/schematron/zvon16_0.xml
> > +
> > +diff --git a/result/schematron/zvon16_0.err b/result/schematron/zvon16_0.err
> > +new file mode 100644
> > +index 00000000..3d052409
> > +--- /dev/null
> > ++++ b/result/schematron/zvon16_0.err
> > +@@ -0,0 +1,3 @@
> > ++XPath error : Unregistered function
> > ++./test/schematron/zvon16_0.xml:2: element book: schematron error : /library/book line 2: Book
> > ++./test/schematron/zvon16_0.xml fails to validate
> > +diff --git a/runtest.c b/runtest.c
> > +index c78eec81..736cae5e 100644
> > +--- a/runtest.c
> > ++++ b/runtest.c
> > +@@ -52,6 +52,10 @@
> > + #include <libxml/xmlschemastypes.h>
> > + #endif
> > +
> > ++#ifdef LIBXML_SCHEMATRON_ENABLED
> > ++#include <libxml/schematron.h>
> > ++#endif
> > ++
> > + #ifdef LIBXML_PATTERN_ENABLED
> > + #include <libxml/pattern.h>
> > + #endif
> > +@@ -3881,6 +3885,136 @@ rngStreamTest(const char *filename,
> > +
> > + #endif
> > +
> > ++/************************************************************************
> > ++ * *
> > ++ * Schematron tests *
> > ++ * *
> > ++ ************************************************************************/
> > ++
> > ++#ifdef LIBXML_SCHEMATRON_ENABLED
> > ++static int
> > ++schematronOneTest(const char *sch, const char *filename, int options,
> > ++ xmlSchematronPtr schematron) {
> > ++ xmlDocPtr doc;
> > ++ xmlSchematronValidCtxtPtr ctxt;
> > ++ int ret;
> > ++
> > ++ doc = xmlReadFile(filename, NULL, options);
> > ++ if (doc == NULL) {
> > ++ fprintf(stderr, "failed to parse instance %s for %s\n", filename, sch);
> > ++ return(-1);
> > ++ }
> > ++
> > ++ ctxt = xmlSchematronNewValidCtxt(schematron, XML_SCHEMATRON_OUT_ERROR);
> > ++ xmlSchematronSetValidStructuredErrors(ctxt, testStructuredErrorHandler,
> > ++ NULL);
> > ++ ret = xmlSchematronValidateDoc(ctxt, doc);
> > ++ if (ret == 0) {
> > ++ testErrorHandler(NULL, "%s validates\n", filename);
> > ++ } else if (ret > 0) {
> > ++ testErrorHandler(NULL, "%s fails to validate\n", filename);
> > ++ } else {
> > ++ testErrorHandler(NULL, "%s validation generated an internal error\n",
> > ++ filename);
> > ++ }
> > ++
> > ++ xmlSchematronFreeValidCtxt(ctxt);
> > ++ xmlFreeDoc(doc);
> > ++ return(0);
> > ++}
> > ++
> > ++/**
> > ++ * schematronTest:
> > ++ * @filename: the schemas file
> > ++ * @result: the file with expected result
> > ++ * @err: the file with error messages
> > ++ *
> > ++ * Returns 0 in case of success, an error code otherwise
> > ++ */
> > ++static int
> > ++schematronTest(const char *filename,
> > ++ const char *resul ATTRIBUTE_UNUSED,
> > ++ const char *errr ATTRIBUTE_UNUSED,
> > ++ int options) {
> > ++ const char *base = baseFilename(filename);
> > ++ const char *base2;
> > ++ const char *instance;
> > ++ xmlSchematronParserCtxtPtr pctxt;
> > ++ xmlSchematronPtr schematron;
> > ++ int res = 0, len, ret = 0;
> > ++ int parseErrorsSize;
> > ++ char pattern[500];
> > ++ char prefix[500];
> > ++ char err[500];
> > ++ glob_t globbuf;
> > ++ size_t i;
> > ++ char count = 0;
> > ++
> > ++ /* Redirect XPath errors */
> > ++ xmlSetStructuredErrorFunc(NULL, testStructuredErrorHandler);
> > ++
> > ++ pctxt = xmlSchematronNewParserCtxt(filename);
> > ++ schematron = xmlSchematronParse(pctxt);
> > ++ xmlSchematronFreeParserCtxt(pctxt);
> > ++ if (schematron == NULL)
> > ++ testErrorHandler(NULL, "Schematron schema %s failed to compile\n",
> > ++ filename);
> > ++ parseErrorsSize = testErrorsSize;
> > ++
> > ++ /*
> > ++ * most of the mess is about the output filenames generated by the Makefile
> > ++ */
> > ++ len = strlen(base);
> > ++ if ((len > 499) || (len < 5)) {
> > ++ ret = -1;
> > ++ goto done;
> > ++ }
> > ++ len -= 4; /* remove trailing .sct */
> > ++ memcpy(prefix, base, len);
> > ++ prefix[len] = 0;
> > ++
> > ++ if (snprintf(pattern, 499, "./test/schematron/%s_?.xml", prefix) >= 499)
> > ++ pattern[499] = 0;
> > ++
> > ++ globbuf.gl_offs = 0;
> > ++ glob(pattern, GLOB_DOOFFS, NULL, &globbuf);
> > ++ for (i = 0;i < globbuf.gl_pathc;i++) {
> > ++ testErrorsSize = parseErrorsSize;
> > ++ testErrors[parseErrorsSize] = 0;
> > ++ instance = globbuf.gl_pathv[i];
> > ++ base2 = baseFilename(instance);
> > ++ len = strlen(base2);
> > ++ if ((len > 6) && (base2[len - 6] == '_')) {
> > ++ count = base2[len - 5];
> > ++ res = snprintf(err, 499, "result/schematron/%s_%c.err",
> > ++ prefix, count);
> > ++ if (res >= 499)
> > ++ err[499] = 0;
> > ++ } else {
> > ++ fprintf(stderr, "don't know how to process %s\n", instance);
> > ++ continue;
> > ++ }
> > ++ if (schematron != NULL) {
> > ++ nb_tests++;
> > ++ res = schematronOneTest(filename, instance, options, schematron);
> > ++ if (res != 0)
> > ++ ret = res;
> > ++ }
> > ++ if (compareFileMem(err, testErrors, testErrorsSize)) {
> > ++ fprintf(stderr, "Error for %s on %s failed\n", instance,
> > ++ filename);
> > ++ ret = 1;
> > ++ }
> > ++ }
> > ++ globfree(&globbuf);
> > ++
> > ++done:
> > ++ xmlSchematronFree(schematron);
> > ++ xmlSetStructuredErrorFunc(NULL, NULL);
> > ++ return(ret);
> > ++}
> > ++#endif /* LIBXML_SCHEMATRON_ENABLED */
> > ++
> > + #ifdef LIBXML_PATTERN_ENABLED
> > + #ifdef LIBXML_READER_ENABLED
> > + /************************************************************************
> > +@@ -5117,6 +5251,11 @@ testDesc testDescriptions[] = {
> > + rngStreamTest, "./test/relaxng/*.rng", NULL, NULL, NULL,
> > + XML_PARSE_DTDATTR | XML_PARSE_NOENT },
> > + #endif
> > ++#if defined(LIBXML_SCHEMATRON_ENABLED)
> > ++ { "Schematron regression tests" ,
> > ++ schematronTest, "./test/schematron/*.sct", NULL, NULL, NULL,
> > ++ 0 },
> > ++#endif
> > + #endif
> > + #ifdef LIBXML_PATTERN_ENABLED
> > + #ifdef LIBXML_READER_ENABLED
> > +diff --git a/schematron.c b/schematron.c
> > +index 411a515c..c970d31f 100644
> > +--- a/schematron.c
> > ++++ b/schematron.c
> > +@@ -1484,6 +1484,11 @@ xmlSchematronFormatReport(xmlSchematronValidCtxtPtr ctxt,
> > + select = xmlGetNoNsProp(child, BAD_CAST "select");
> > + comp = xmlXPathCtxtCompile(ctxt->xctxt, select);
> > + eval = xmlXPathCompiledEval(comp, ctxt->xctxt);
> > ++ if (eval == NULL) {
> > ++ xmlXPathFreeCompExpr(comp);
> > ++ xmlFree(select);
> > ++ return ret;
> > ++ }
> > +
> > + switch (eval->type) {
> > + case XPATH_NODESET: {
> > +diff --git a/test/schematron/zvon16.sct b/test/schematron/zvon16.sct
> > +new file mode 100644
> > +index 00000000..f03848aa
> > +--- /dev/null
> > ++++ b/test/schematron/zvon16.sct
> > +@@ -0,0 +1,7 @@
> > ++<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron">
> > ++ <sch:pattern id="TestPattern">
> > ++ <sch:rule context="book">
> > ++ <sch:report test="not(@available)">Book <sch:value-of select="falae()"/>
> > test</sch:report>
> > ++ </sch:rule>
> > ++ </sch:pattern>
> > ++</sch:schema>
> > +diff --git a/test/schematron/zvon16_0.xml b/test/schematron/zvon16_0.xml
> > +new file mode 100644
> > +index 00000000..551e2d65
> > +--- /dev/null
> > ++++ b/test/schematron/zvon16_0.xml
> > +@@ -0,0 +1,5 @@
> > ++<library>
> > ++ <book title="Test Book" id="bk101">
> > ++ <author>Test Author</author>
> > ++ </book>
> > ++</library>
> > diff --git a/meta/recipes-core/libxml/libxml2_2.12.10.bb b/meta/recipes-
> > core/libxml/libxml2_2.12.10.bb
> > index 2eea65732b..ea40ca68ed 100644
> > --- a/meta/recipes-core/libxml/libxml2_2.12.10.bb
> > +++ b/meta/recipes-core/libxml/libxml2_2.12.10.bb
> > @@ -20,6 +20,7 @@ SRC_URI +=
> > "http://www.w3.org/XML/Test/xmlts20130923.tar;subdir=${BP};name=testt
> > file://install-tests.patch \
> > file://CVE-2025-32414.patch \
> > file://CVE-2025-32415.patch \
> > + file://CVE-2025-49795.patch \
> > "
> >
> > SRC_URI[archive.sha256sum] = "c3d8c0c34aa39098f66576fe51969db12a5100b956233dc56506f7a8679be995"
> >
> > -=-=-=-=-=-=-=-=-=-=-=-
> > Links: You receive all messages sent to this group.
> > View/Reply Online (#220138): https://lists.openembedded.org/g/openembedded-core/message/220138
> > Mute This Topic: https://lists.openembedded.org/mt/114097487/3620601
> > Group Owner: openembedded-core+owner@lists.openembedded.org
> > Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [steve@sakoman.com]
> > -=-=-=-=-=-=-=-=-=-=-=-
> >
prev parent reply other threads:[~2025-07-17 7:05 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-11 9:15 [scarthgap][PATCH] libxml2: fix CVE-2025-49795 roland.kovacs
2025-07-16 15:04 ` [OE-core] " Steve Sakoman
2025-07-17 7:04 ` Roland Kovács [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=2bd2f4c8d55c280f8db213d89ae8f7fc8aca0a97.camel@est.tech \
--to=roland.kovacs@est.tech \
--cc=openembedded-core@lists.openembedded.org \
--cc=steve@sakoman.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.