new file mode 100644
@@ -0,0 +1,165 @@
+From: Paul LeoNerd Evans <leonerd@leonerd.org.uk>
+Date: Mon, 4 May 2026 16:12:49 +0100
+Subject: 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()
+
+Backport changes:
+- Adjusted the upstream hunks to match the perl 5.38.4 code layout.
+- Drop not code files from the backport.
+
+CVE: CVE-2026-12087
+Upstream-Status: Backport [https://github.com/Perl/perl5/commit/de19a0b0ad1900fef976c5c1400bd8f11ec6c6cb]
+
+Signed-off-by: Jakub Szczudlo <jakub.szczudlo@nokia.com>
+---
+ cpan/Socket/Socket.xs | 87 +++++++++++++++++++++++++++++++++------------------
+ 1 file changed, 56 insertions(+), 31 deletions(-)
+
+diff --git a/cpan/Socket/Socket.xs b/cpan/Socket/Socket.xs
+index b4bccb7..5fc558b 100644
+--- a/cpan/Socket/Socket.xs
++++ b/cpan/Socket/Socket.xs
+@@ -1270,28 +1270,36 @@ 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");
+@@ -1332,27 +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
+@@ -1362,6 +1381,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);
+@@ -1403,17 +1423,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);
@@ -25,6 +25,7 @@ SRC_URI = "https://www.cpan.org/src/5.0/perl-${PV}.tar.gz;name=perl \
file://CVE-2026-57432-02.patch \
file://CVE-2025-40909.patch \
file://CVE-2026-19487.patch \
+ file://CVE-2026-12087.patch \
"
SRC_URI:append:class-native = " \
file://perl-configpm-switch.patch \
References: https://nvd.nist.gov/vuln/detail/CVE-2026-12087 Upstream fix: https://github.com/Perl/perl5/commit/de19a0b0ad1900fef976c5c1400bd8f11ec6c6cb Tested with ptest Signed-off-by: Jakub Szczudlo <jakub.szczudlo@nokia.com> --- .../perl/files/CVE-2026-12087.patch | 165 ++++++++++++++++++ meta/recipes-devtools/perl/perl_5.38.4.bb | 1 + 2 files changed, 166 insertions(+) create mode 100644 meta/recipes-devtools/perl/files/CVE-2026-12087.patch