Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected], [email protected], 
[email protected], [email protected]
Control: affects -1 + src:libhtml-parser-perl
User: [email protected]
Usertags: pu

Hi

[ Reason ]
libhtml-parser-perl is affected by CVE-2026-8829, which was fixed by
cherry-picking the fixing commit in unstable. As the version in trixie
was the same, do just a rebuild of the version for trixie.

[ Impact ]
Remains open to CVE-2026-8829 if not fixed.

[ Tests ]
Testsuite from the package plus a debusine work request with extensive
testing of reverse dependencies as per:
https://debusine.debian.net/debian/developers/work-request/839553/

[ Risks ]
Follows the change upstream and covered by testing as per above, so
should be low risk.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]
Fixed the heap uaf in the _decode_entities function and adds a
respective test.

[ Other info ]
None so far.

Regards,
Salvatore
diff -Nru libhtml-parser-perl-3.83/debian/changelog 
libhtml-parser-perl-3.83/debian/changelog
--- libhtml-parser-perl-3.83/debian/changelog   2024-08-03 16:37:29.000000000 
+0000
+++ libhtml-parser-perl-3.83/debian/changelog   2026-06-13 11:53:17.000000000 
+0000
@@ -1,3 +1,15 @@
+libhtml-parser-perl (3.83-2~deb13u1) trixie; urgency=medium
+
+  * Rebuild for trixie
+
+ -- Salvatore Bonaccorso <[email protected]>  Sat, 13 Jun 2026 13:53:17 +0200
+
+libhtml-parser-perl (3.83-2) unstable; urgency=medium
+
+  * Fix heap-use-after-free in _decode_entities (CVE-2026-8829)
+
+ -- Salvatore Bonaccorso <[email protected]>  Thu, 04 Jun 2026 10:05:41 +0200
+
 libhtml-parser-perl (3.83-1) unstable; urgency=medium
 
   * Team upload.
diff -Nru 
libhtml-parser-perl-3.83/debian/patches/Fix-heap-use-after-free-in-_decode_entities-CVE-2026.patch
 
libhtml-parser-perl-3.83/debian/patches/Fix-heap-use-after-free-in-_decode_entities-CVE-2026.patch
--- 
libhtml-parser-perl-3.83/debian/patches/Fix-heap-use-after-free-in-_decode_entities-CVE-2026.patch
  1970-01-01 00:00:00.000000000 +0000
+++ 
libhtml-parser-perl-3.83/debian/patches/Fix-heap-use-after-free-in-_decode_entities-CVE-2026.patch
  2026-06-13 11:53:17.000000000 +0000
@@ -0,0 +1,127 @@
+From: Paul Johnson <[email protected]>
+Date: Tue, 19 May 2026 20:24:00 +0000
+Subject: Fix heap-use-after-free in _decode_entities (CVE-2026-8829)
+Origin: 
https://github.com/libwww-perl/HTML-Parser/commit/6922552b0778c90a9587a3894e248be4d3a25e1c
+Bug: https://github.com/libwww-perl/HTML-Parser/pull/56
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/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.
+
+Co-Authored-By: Claude Opus 4.7 <[email protected]>
+---
+ 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 5f973a19b1cd..012e7bb2bfb4 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&aring;re norske tegn b&oslash;r &#230res";
+ 
+@@ -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 <[email protected]>
+ # Subject: HTML entities problem with 5.11
+ # To: [email protected]
+diff --git a/util.c b/util.c
+index ed4fd70dc9a9..0bdb3271839a 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 */
+-- 
+2.53.0
+
diff -Nru libhtml-parser-perl-3.83/debian/patches/series 
libhtml-parser-perl-3.83/debian/patches/series
--- libhtml-parser-perl-3.83/debian/patches/series      2024-08-03 
16:37:29.000000000 +0000
+++ libhtml-parser-perl-3.83/debian/patches/series      2026-06-13 
11:53:17.000000000 +0000
@@ -1 +1,2 @@
 debian_examples_location.patch
+Fix-heap-use-after-free-in-_decode_entities-CVE-2026.patch

Reply via email to