* [scarthgap][PATCH] libxml2: fix CVE-2025-49795 @ 2025-07-11 9:15 roland.kovacs 2025-07-16 15:04 ` [OE-core] " Steve Sakoman 0 siblings, 1 reply; 3+ messages in thread From: roland.kovacs @ 2025-07-11 9:15 UTC (permalink / raw) To: openembedded-core; +Cc: Roland Kovacs 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" ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [OE-core] [scarthgap][PATCH] libxml2: fix CVE-2025-49795 2025-07-11 9:15 [scarthgap][PATCH] libxml2: fix CVE-2025-49795 roland.kovacs @ 2025-07-16 15:04 ` Steve Sakoman 2025-07-17 7:04 ` Roland Kovács 0 siblings, 1 reply; 3+ messages in thread From: Steve Sakoman @ 2025-07-16 15:04 UTC (permalink / raw) To: roland.kovacs; +Cc: openembedded-core 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 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] > -=-=-=-=-=-=-=-=-=-=-=- > ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [OE-core] [scarthgap][PATCH] libxml2: fix CVE-2025-49795 2025-07-16 15:04 ` [OE-core] " Steve Sakoman @ 2025-07-17 7:04 ` Roland Kovács 0 siblings, 0 replies; 3+ messages in thread From: Roland Kovács @ 2025-07-17 7:04 UTC (permalink / raw) To: steve@sakoman.com; +Cc: openembedded-core@lists.openembedded.org 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] > > -=-=-=-=-=-=-=-=-=-=-=- > > ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-07-17 7:05 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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 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.