Bug#1146444: trixie-pu: package libsocket-perl/2.038-1+deb13u1

gregor herrmann <[email protected]>
Newsgroups gmane.linux.debian.devel.release
Message-ID <178830078071.13006.9914218537778607085.reportbug__46539.9373950035$1788300971$gmane$org@jadzia.comodo.priv.at>
Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:libsocket-perl
User: [email protected]
Usertags: pu

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

I've uploaded libsocket-perl/2.038-1+deb13u1 to trixie, in the hope 
that in can be included in the upcoming point release.

This upload has been prepared in cooperation with ntyni and carnil 
and is part of the Perl no-DSA security fixes, as decribed in 
#1146369.                                                     

This upload fixes #1146063 aka CVE-2026-12087.

The update was prepared by Kentaro Hayashi in advance. It consists of 
two new patches:
- - CVE-2026-12087.patch: the actual fixes, taken from newer upstream
  versions of libsocket-perl;
- - CVE-2026-12087-test.patch: an additional regression test

The same upstream fix is applied to the Socket module in src:perl.

Changelog entry:

#v+
libsocket-perl (2.038-1+deb13u1) trixie; urgency=medium

  [ Kentaro Hayashi ]
  * Backport patch to fix CVE-2026-12087
    (out-of-bounds heap read in pack_ip_mreq_source()).
    - Added CVE-2026-12087.patch
    - Added CVE-2026-12087-test.patch for testing

    Closes: #1146063

 -- gregor herrmann <[email protected]>  Mon, 31 Aug 2026 15:46:55 +0200
#v-

Full debdiff attached.


Thanks in advance,
gregor


-----BEGIN PGP SIGNATURE-----

iQKTBAEBCgB9FiEE0eExbpOnYKgQTYX6uzpoAYZJqgYFAmqXTexfFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEQx
RTEzMTZFOTNBNzYwQTgxMDREODVGQUJCM0E2ODAxODY0OUFBMDYACgkQuzpoAYZJ
qgZtLBAAmj6wbKCDXFPJio8rbpyFQd781Y9iI7HGNxC3GuaxF3qptxRFc6HNGnwq
CRNX/Nj2G0rvBdEUtLdBAl/Qv4Q+vCNove6ShQY+Q/ZVX1MsMcHhbK60NrMwTpZq
81Du968ppe9xnegROBX48DmUuzHciBwPyQXb3+gHtbm+oYnt4mdCXoPyFkE4Cpli
bPsAlNg7Kq/3C96qtAzrAjqO45yhr6jOWNG74s/FXlgR2znHgNZZJsNmBE5TrRZ2
fU3zDHG8XxRc8B/DjTsDx8+9aLyW3pukoI6T7iT07mjjfgkDw7PIDbjhc/SeEb+W
T2dxQZRMKhU+oy6YkpipmNFMTvqilBv24zeJMe1V8wQEsxn6RfTmUY1swE08s4Xw
AlJX/7QdtakUoU0So400l40xxnojd+LkaIBrvvotqJW84gNeIgIbiWuRu5ipp9jc
5RSuLSrnYkNAH1xBltvXmLcFV2H+1Di6JGLA/kODL7oD8gcWg9SXH632acvWyXnK
GxVZUvezaFVCUFlKefXBU+tHbJ1CRGHoKpq7xvmU+Q+N8JB7D8Ypigw1b2B8GhWO
DRTqaTxkkYBfnRstWHWPiW5300QKtybZbKgicXps3kE5Xhjsz+uzOY7BSldxdrvE
6pPid3rJYhhdAXnYI4jinjp7zjTNqOpSjQB+8r372bi5UufbHfA=
=UYIW
-----END PGP SIGNATURE-----
libsocket-perl_2.038-1+deb13u1.diff (text/plain, 11.1 KB)
diff -Nru libsocket-perl-2.038/debian/changelog libsocket-perl-2.038/debian/changelog
--- libsocket-perl-2.038/debian/changelog	2024-04-19 16:42:09.000000000 +0200
+++ libsocket-perl-2.038/debian/changelog	2026-08-31 15:46:55.000000000 +0200
@@ -1,3 +1,15 @@
+libsocket-perl (2.038-1+deb13u1) trixie; urgency=medium
+
+  [ Kentaro Hayashi ]
+  * Backport patch to fix CVE-2026-12087
+    (out-of-bounds heap read in pack_ip_mreq_source()).
+    - Added CVE-2026-12087.patch
+    - Added CVE-2026-12087-test.patch for testing
+
+    Closes: #1146063
+
+ -- gregor herrmann <[email protected]>  Mon, 31 Aug 2026 15:46:55 +0200
+
 libsocket-perl (2.038-1) unstable; urgency=medium
 
   * Import upstream version 2.038.
diff -Nru libsocket-perl-2.038/debian/patches/CVE-2026-12087-test.patch libsocket-perl-2.038/debian/patches/CVE-2026-12087-test.patch
--- libsocket-perl-2.038/debian/patches/CVE-2026-12087-test.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsocket-perl-2.038/debian/patches/CVE-2026-12087-test.patch	2026-08-31 15:46:55.000000000 +0200
@@ -0,0 +1,62 @@
+From: Kentaro Hayashi <[email protected]>
+Date: Mon, 17 Aug 2026 11:28:23 +0000
+Subject: Add regression test for CVE-2026-12087
+
+Description: Add a regression test for the pack_ip_mreq_source() fix
+ pack_ip_mreq_source() validated the length of $source against a stale
+ STRLEN len left over from $multiaddr, so a $source shorter than an
+ in_addr passed validation and the unconditional 4 byte Copy() into
+ imr_sourceaddr read past the end of its buffer, leaking adjacent heap
+ memory into the returned string.
+ .
+ t/cve-2026-12087.t calls pack_ip_mreq_source() with a 1 byte $source and
+ asserts that it croaks.  The test fails without CVE-2026-12087.patch and
+ passes with it; the rest of the test suite passes either way, so this is
+ the only coverage of the issue.
+ .
+ Kept separate from CVE-2026-12087.patch so that patch stays identical to
+ the referenced upstream commit.
+Forwarded: no
+Bug-Debian: https://bugs.debian.org/1146063
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-12087
+---
+ MANIFEST           |  1 +
+ t/cve-2026-12087.t | 17 +++++++++++++++++
+ 2 files changed, 18 insertions(+)
+ create mode 100644 t/cve-2026-12087.t
+
+diff --git a/MANIFEST b/MANIFEST
+index 77ee9f3..a96516e 100644
+--- a/MANIFEST
++++ b/MANIFEST
+@@ -8,6 +8,7 @@ MANIFEST			This list of files
+ MANIFEST.SKIP
+ Socket.pm
+ Socket.xs
++t/cve-2026-12087.t
+ t/getaddrinfo.t
+ t/getnameinfo.t
+ t/ip_mreq.t
+diff --git a/t/cve-2026-12087.t b/t/cve-2026-12087.t
+new file mode 100644
+index 0000000..823fe74
+--- /dev/null
++++ b/t/cve-2026-12087.t
+@@ -0,0 +1,17 @@
++use strict;
++use warnings;
++use Test::More;
++
++use Socket qw( INADDR_ANY pack_ip_mreq_source );
++
++# CVE-2026-12087: pack_ip_mreq_source() checked the length of $source against a
++# stale len left over from $multiaddr, so a short $source passed validation and
++# the 4 byte Copy() into imr_sourceaddr read past the end of its buffer.
++
++plan skip_all => "No pack_ip_mreq_source"
++    unless defined eval { pack_ip_mreq_source "\xe0\0\0\2", "\x0a\0\0\1", INADDR_ANY };
++
++plan tests => 1;
++
++eval { pack_ip_mreq_source "\xe0\0\0\2", "\x0a", INADDR_ANY };
++like( $@, qr/Bad arg length/, 'pack_ip_mreq_source rejects short source' );
diff -Nru libsocket-perl-2.038/debian/patches/CVE-2026-12087.patch libsocket-perl-2.038/debian/patches/CVE-2026-12087.patch
--- libsocket-perl-2.038/debian/patches/CVE-2026-12087.patch	1970-01-01 01:00:00.000000000 +0100
+++ libsocket-perl-2.038/debian/patches/CVE-2026-12087.patch	2026-08-31 15:46:55.000000000 +0200
@@ -0,0 +1,164 @@
+From: Kentaro Hayashi <[email protected]>
+Date: Mon, 17 Aug 2026 19:41:41 +0900
+Subject: Backport CVE-2026-12087 patch
+
+Origin: https://github.com/Perl/perl5/commit/de19a0b0ad1900fef976c5c1400bd8f11ec6c6cb
+Forwarded: not-needed
+From: "Paul \"LeoNerd\" Evans" <[email protected]>
+
+  From de19a0b0ad1900fef976c5c1400bd8f11ec6c6cb Mon Sep 17 00:00:00 2001
+  Date: Mon, 4 May 2026 16:12:49 +0100
+  Subject: [PATCH] cpan/Socket - Update to version 2.041
+
+  2.041   2026-03-26
+          [CHANGES]
+           * Modernise Pod documentation formatting
+
+          [BUGFIXES]
+           * Fix reuse of `STRLEN len` variable in pack_ip_mreq_source()
+
+
+Bug-Debian: https://bugs.debian.org/1146063
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-12087
+
+---
+ Socket.xs | 83 ++++++++++++++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 56 insertions(+), 27 deletions(-)
+
+diff --git a/Socket.xs b/Socket.xs
+index 1bd52a1..ded347e 100644
+--- a/Socket.xs
++++ b/Socket.xs
+@@ -1272,26 +1272,35 @@ pack_ip_mreq(multiaddr, interface=&PL_sv_undef)
+         struct ip_mreq mreq;
+         char * multiaddrbytes;
+         char * interfacebytes;
+-        STRLEN len;
+-        if (DO_UTF8(multiaddr) && !sv_utf8_downgrade(multiaddr, 1))
+-            croak("Wide character in %s", "Socket::pack_ip_mreq");
+-        multiaddrbytes = SvPVbyte(multiaddr, len);
+-        if (len != sizeof(mreq.imr_multiaddr))
+-            croak("Bad arg length %s, length is %" UVuf ", should be %" UVuf,
+-                    "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_multiaddr));
++
++        {
++            if (DO_UTF8(multiaddr) && !sv_utf8_downgrade(multiaddr, 1))
++                croak("Wide character in %s", "Socket::pack_ip_mreq");
++
++            STRLEN len;
++            multiaddrbytes = SvPVbyte(multiaddr, len);
++            if (len != sizeof(mreq.imr_multiaddr))
++                croak("Bad arg length %s, length is %" UVuf ", should be %" UVuf,
++                        "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_multiaddr));
++        }
++
+         Zero(&mreq, sizeof(mreq), char);
+         Copy(multiaddrbytes, &mreq.imr_multiaddr, sizeof(mreq.imr_multiaddr), char);
+         if(SvOK(interface)) {
+             if (DO_UTF8(interface) && !sv_utf8_downgrade(interface, 1))
+                 croak("Wide character in %s", "Socket::pack_ip_mreq");
++
++            STRLEN len;
+             interfacebytes = SvPVbyte(interface, len);
+             if (len != sizeof(mreq.imr_interface))
+                 croak("Bad arg length %s, length is %" UVuf ", should be %" UVuf,
+                         "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_interface));
++
+             Copy(interfacebytes, &mreq.imr_interface, sizeof(mreq.imr_interface), char);
+         }
+         else
+             mreq.imr_interface.s_addr = INADDR_ANY;
++
+         ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq)));
+ #else
+         not_here("pack_ip_mreq");
+@@ -1331,25 +1340,38 @@ pack_ip_mreq_source(multiaddr, source, interface=&PL_sv_undef)
+         char * multiaddrbytes;
+         char * sourcebytes;
+         char * interfacebytes;
+-        STRLEN len;
+-        if (DO_UTF8(multiaddr) && !sv_utf8_downgrade(multiaddr, 1))
+-            croak("Wide character in %s", "Socket::pack_ip_mreq_source");
+-        multiaddrbytes = SvPVbyte(multiaddr, len);
+-        if (len != sizeof(mreq.imr_multiaddr))
+-            croak("Bad arg length %s, length is %" UVuf ", should be %" UVuf,
+-                    "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_multiaddr));
+-        if (DO_UTF8(source) && !sv_utf8_downgrade(source, 1))
+-            croak("Wide character in %s", "Socket::pack_ip_mreq_source");
+-        if (len != sizeof(mreq.imr_sourceaddr))
+-            croak("Bad arg length %s, length is %" UVuf ", should be %" UVuf,
+-                    "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_sourceaddr));
+-        sourcebytes = SvPVbyte(source, len);
++
++        {
++            if (DO_UTF8(multiaddr) && !sv_utf8_downgrade(multiaddr, 1))
++                croak("Wide character in %s", "Socket::pack_ip_mreq_source");
++
++            STRLEN len;
++            multiaddrbytes = SvPVbyte(multiaddr, len);
++            if (len != sizeof(mreq.imr_multiaddr))
++                croak("Bad arg length %s, length is %" UVuf ", should be %" UVuf,
++                        "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_multiaddr));
++        }
++
++        {
++            if (DO_UTF8(source) && !sv_utf8_downgrade(source, 1))
++                croak("Wide character in %s", "Socket::pack_ip_mreq_source");
++
++            STRLEN len;
++            sourcebytes = SvPVbyte(source, len);
++            if (len != sizeof(mreq.imr_sourceaddr))
++                croak("Bad arg length %s, length is %" UVuf ", should be %" UVuf,
++                        "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_sourceaddr));
++        }
++
+         Zero(&mreq, sizeof(mreq), char);
+         Copy(multiaddrbytes, &mreq.imr_multiaddr, sizeof(mreq.imr_multiaddr), char);
+         Copy(sourcebytes, &mreq.imr_sourceaddr, sizeof(mreq.imr_sourceaddr), char);
++
+         if(SvOK(interface)) {
+             if (DO_UTF8(interface) && !sv_utf8_downgrade(interface, 1))
+                 croak("Wide character in %s", "Socket::pack_ip_mreq");
++
++            STRLEN len;
+             interfacebytes = SvPVbyte(interface, len);
+             if (len != sizeof(mreq.imr_interface))
+                 croak("Bad arg length %s, length is %" UVuf ", should be %" UVuf,
+@@ -1358,6 +1380,7 @@ pack_ip_mreq_source(multiaddr, source, interface=&PL_sv_undef)
+         }
+         else
+             mreq.imr_interface.s_addr = INADDR_ANY;
++
+         ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq)));
+ #else
+         PERL_UNUSED_VAR(multiaddr);
+@@ -1398,16 +1421,22 @@ pack_ipv6_mreq(multiaddr, ifindex)
+ #ifdef HAS_IPV6_MREQ
+         struct ipv6_mreq mreq;
+         char * multiaddrbytes;
+-        STRLEN len;
+-        if (DO_UTF8(multiaddr) && !sv_utf8_downgrade(multiaddr, 1))
+-            croak("Wide character in %s", "Socket::pack_ipv6_mreq");
+-        multiaddrbytes = SvPVbyte(multiaddr, len);
+-        if (len != sizeof(mreq.ipv6mr_multiaddr))
+-            croak("Bad arg length %s, length is %" UVuf ", should be %" UVuf,
+-                    "Socket::pack_ipv6_mreq", (UV)len, (UV)sizeof(mreq.ipv6mr_multiaddr));
++
++        {
++            if (DO_UTF8(multiaddr) && !sv_utf8_downgrade(multiaddr, 1))
++                croak("Wide character in %s", "Socket::pack_ipv6_mreq");
++
++            STRLEN len;
++            multiaddrbytes = SvPVbyte(multiaddr, len);
++            if (len != sizeof(mreq.ipv6mr_multiaddr))
++                croak("Bad arg length %s, length is %" UVuf ", should be %" UVuf,
++                        "Socket::pack_ipv6_mreq", (UV)len, (UV)sizeof(mreq.ipv6mr_multiaddr));
++        }
++
+         Zero(&mreq, sizeof(mreq), char);
+         Copy(multiaddrbytes, &mreq.ipv6mr_multiaddr, sizeof(mreq.ipv6mr_multiaddr), char);
+         mreq.ipv6mr_interface = ifindex;
++
+         ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq)));
+ #else
+         PERL_UNUSED_VAR(multiaddr);
diff -Nru libsocket-perl-2.038/debian/patches/series libsocket-perl-2.038/debian/patches/series
--- libsocket-perl-2.038/debian/patches/series	2024-04-19 16:42:09.000000000 +0200
+++ libsocket-perl-2.038/debian/patches/series	2026-08-31 15:46:55.000000000 +0200
@@ -1 +1,3 @@
 disable-network-tests.patch
+CVE-2026-12087.patch
+CVE-2026-12087-test.patch
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.