diff --git a/meta-perl/recipes-perl/libhtml/files/CVE-2026-8829.patch b/meta-perl/recipes-perl/libhtml/files/CVE-2026-8829.patch new file mode 100644 index 0000000000..fa8ba70999 --- /dev/null +++ b/meta-perl/recipes-perl/libhtml/files/CVE-2026-8829.patch @@ -0,0 +1,127 @@ +From 91b79f0d83dafc47f4387a50cd8bbf43c879a492 Mon Sep 17 00:00:00 2001 +From: Paul Johnson +Date: Tue, 19 May 2026 20:24:00 +0000 +Subject: [PATCH] Fix heap-use-after-free in _decode_entities (CVE-2026-8829) + +When the input SV passed to _decode_entities is the same SV stored as a +self-referential value in the entity hash, grow_gap() could realloc the +SV's PV buffer, leaving repl pointing at freed memory. Copy the entity +value into an owned buffer when the hash entry SV aliases the input SV. + +CVE: CVE-2026-8829 +Upstream-Status: Backport [https://github.com/libwww-perl/HTML-Parser/commit/6922552b0778c90a9587a3894e248be4d3a25e1c] + +Co-Authored-By: Claude Opus 4.7 +(cherry picked from commit 6922552b0778c90a9587a3894e248be4d3a25e1c) +Signed-off-by: Darsh Kelaiya +--- + t/entities.t | 20 ++++++++++++++++++-- + util.c | 28 +++++++++++++++++++++++++--- + 2 files changed, 43 insertions(+), 5 deletions(-) + +diff --git a/t/entities.t b/t/entities.t +index 5f973a1..012e7bb 100644 +--- a/t/entities.t ++++ b/t/entities.t +@@ -2,8 +2,9 @@ use strict; + use warnings; + use utf8; + +-use HTML::Entities qw(decode_entities encode_entities encode_entities_numeric); +-use Test::More tests => 31; ++use HTML::Entities ++ qw(_decode_entities decode_entities encode_entities encode_entities_numeric); ++use Test::More tests => 32; + + my $x = "Våre norske tegn bør æres"; + +@@ -96,6 +97,21 @@ is($x, $ent); + is($got, (values %hash)[0], "decode_entities() decodes a key properly"); + } + ++# CVE-2026-8829 ++# _decode_entities heap-use-after-free when the input SV is the same SV as ++# a self-referential entity value. The payload must be large enough to ++# force grow_gap() to realloc the SV's PV; the fix copies the entity value ++# into an owned buffer so repl is not left pointing at the freed allocation. ++{ ++ my $prefix_a = "A" x 32; ++ my $suffix_b = "B" x 8192; ++ my %h; ++ $h{foo} = $prefix_a . "&foo;" . $suffix_b; ++ _decode_entities($h{foo}, \%h); ++ is($h{foo}, ("A" x 64) . "&foo;" . ("B" x 16384), ++ "_decode_entities() with self-aliased entity hash value"); ++} ++ + # From: Bill Simpson-Young + # Subject: HTML entities problem with 5.11 + # To: libwww-perl@ics.uci.edu +diff --git a/util.c b/util.c +index ed4fd70..0bdb327 100644 +--- a/util.c ++++ b/util.c +@@ -72,6 +72,7 @@ decode_entities(pTHX_ SV* sv, HV* entity2char, bool expand_prefix) + + char *repl; + STRLEN repl_len; ++ char *repl_allocated = 0; + char buf[UTF8_MAXLEN]; + int repl_utf8; + int high_surrogate = 0; +@@ -89,6 +90,7 @@ decode_entities(pTHX_ SV* sv, HV* entity2char, bool expand_prefix) + + ent_start = s; + repl = 0; ++ repl_allocated = 0; + + if (s < end && *s == '#') { + UV num = 0; +@@ -176,16 +178,34 @@ decode_entities(pTHX_ SV* sv, HV* entity2char, bool expand_prefix) + (*s == ';' && (svp = hv_fetch(entity2char, ent_name, s - ent_name + 1, 0))) + ) + { +- repl = SvPV(*svp, repl_len); ++ char *src = SvPV(*svp, repl_len); + repl_utf8 = SvUTF8(*svp); ++ if ((SV*)*svp == sv) { ++ /* Self-aliased: hash entry SV == input SV. ++ * grow_gap() may realloc sv's PV later; copy ++ * the entity value into an owned buffer first. ++ * Freed by the repl_allocated cleanup below. */ ++ Newx(repl_allocated, repl_len ? repl_len : 1, char); ++ Copy(src, repl_allocated, repl_len, char); ++ repl = repl_allocated; ++ } else { ++ repl = src; ++ } + } + else if (expand_prefix) { + char *ss = s - 1; + while (ss > ent_name) { + svp = hv_fetch(entity2char, ent_name, ss - ent_name, 0); + if (svp) { +- repl = SvPV(*svp, repl_len); ++ char *src = SvPV(*svp, repl_len); + repl_utf8 = SvUTF8(*svp); ++ if ((SV*)*svp == sv) { ++ Newx(repl_allocated, repl_len ? repl_len : 1, char); ++ Copy(src, repl_allocated, repl_len, char); ++ repl = repl_allocated; ++ } else { ++ repl = src; ++ } + s = ss; + break; + } +@@ -197,7 +217,9 @@ decode_entities(pTHX_ SV* sv, HV* entity2char, bool expand_prefix) + } + + if (repl) { +- char *repl_allocated = 0; ++ /* repl_allocated is now function-scoped; set by the ++ * named-entity self-alias path above or by the UTF8 mismatch ++ * branch below. Same cleanup in either case. */ + if (s < end && *s == ';') + s++; + t--; /* '&' already copied, undo it */ diff --git a/meta-perl/recipes-perl/libhtml/libhtml-parser-perl_3.83.bb b/meta-perl/recipes-perl/libhtml/libhtml-parser-perl_3.83.bb index 2fb16a5672..e585cc4ccf 100644 --- a/meta-perl/recipes-perl/libhtml/libhtml-parser-perl_3.83.bb +++ b/meta-perl/recipes-perl/libhtml/libhtml-parser-perl_3.83.bb @@ -7,7 +7,9 @@ LIC_FILES_CHKSUM = "file://README;beginline=996;endline=1000;md5=cab05784294bb47 DEPENDS += "perl" -SRC_URI = "${CPAN_MIRROR}/authors/id/O/OA/OALDERS/HTML-Parser-${PV}.tar.gz" +SRC_URI = "${CPAN_MIRROR}/authors/id/O/OA/OALDERS/HTML-Parser-${PV}.tar.gz \ + file://CVE-2026-8829.patch \ + " SRC_URI[sha256sum] = "7278ce9791256132b26a71a5719451844704bb9674b58302c3486df43584f8c0"