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

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

I've uploaded libio-compress-perl/2.213-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
        CVE-2025-15649: #1146065
        CVE-2026-48959: #1138051
        CVE-2026-48961: #1138052
        CVE-2026-48962: #1138055

All patches are identical (modulo paths and bug numbers) to the ones 
in src:perl (I copied them from there :)) and are taken from upstream 
commits which are already released in newer versions of 
libio-compress-perl

Changelog entry:

#v+
libio-compress-perl (2.213-1+deb13u1) trixie; urgency=medium

  * [Security] CVE-2025-15649: header parsing in IO::Uncompress::Unzip.
    (Closes: #1146065)
  * [Security] CVE-2026-48959: CPU exhaustion in IO::Uncompress::Unzip.
    (Closes: #1138051)
  * [Security] CVE-2026-48961: crash in zipdetails.
    (Closes: #1138052)
  * [Security] CVE-2026-48962: code execution in IO-Compress via output
    globs.
    (Closes: #1138055)
  * Add debian/source/include-binaries for CVE-2025-15649 test case.

 -- gregor herrmann <[email protected]>  Mon, 31 Aug 2026 17:20:53 +0200
#v-

Full debdiff attached, and also debian/patches/CVE-2025-15649.diff as 
it has binary changes (two tiny test zip files) not handled well by 
debdiff.


Thanks in advance,
gregor

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

iQKTBAEBCgB9FiEE0eExbpOnYKgQTYX6uzpoAYZJqgYFAmqXTh9fFIAAAAAALgAo
aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEQx
RTEzMTZFOTNBNzYwQTgxMDREODVGQUJCM0E2ODAxODY0OUFBMDYACgkQuzpoAYZJ
qgbVjg/+PiYeywBBthf6ICjqcpUUnudOu58Ib9DHgYk7UKf7AgbgfAspHA3bP2Iv
K8u9m/yBznePhcEIYN7YdQIbQL2JbxQ1fbB9jEM5W0xV40Y15kXKExqGR9hInsi5
SW+bNcamhYWqWvrOIrsy6fbRxa7Qodtx3pAhdz5ykQEKTE8Mph7F82sJ+8T1XbFP
9x2CL2qEJC6DKVQovEbkN8f+PgYDdMsDMneJChJ8xi3QXWdTf6FCTD9xQZGDjTAL
KCimtOy7x0DqjBSgd1la94FBMHNkJVYawqFgpj7MJcxlnvEBZEE5MBrwm7kM5sms
cnx7oUVTKBoewzdgR8khWJ4GF8g3j3N0/wYQQPYYH1YV6JTTl6OlDMCR5qOqU5HU
9HjUzx+Kxwd7CMziIBt3ieBRMdnSgYmmwqPbpyj4TZZtjJmdX6geOjIbMU2WfaFt
hLWlYj4Uj4H9zLrMbmrPItPE7FVkVtvlAMzg76MJyu0mqRE+lFBR2bi7GeP4kTZp
IgIXtmCM8InpUX+aaRzhc3XUywfHinA3wHAn+gzXyd0Gr4KKwexkeykcbDdMlMhT
k/BhUTSzdAIK729ZdeFa5OKPwVAdrqPNjBjZdxmF9iC3NcpPJX/8eIIe4Lk+Z+zR
XfGp47MLzSEioJgvw61C7f+vw5sNUTbeEvdxCU30UGZzAMZ+R54=
=QSK+
-----END PGP SIGNATURE-----
diff -Nru libio-compress-perl-2.213/debian/changelog 
libio-compress-perl-2.213/debian/changelog
--- libio-compress-perl-2.213/debian/changelog  2024-09-01 16:58:10.000000000 
+0200
+++ libio-compress-perl-2.213/debian/changelog  2026-08-31 17:20:53.000000000 
+0200
@@ -1,3 +1,18 @@
+libio-compress-perl (2.213-1+deb13u1) trixie; urgency=medium
+
+  * [Security] CVE-2025-15649: header parsing in IO::Uncompress::Unzip.
+    (Closes: #1146065)
+  * [Security] CVE-2026-48959: CPU exhaustion in IO::Uncompress::Unzip.
+    (Closes: #1138051)
+  * [Security] CVE-2026-48961: crash in zipdetails.
+    (Closes: #1138052)
+  * [Security] CVE-2026-48962: code execution in IO-Compress via output
+    globs.
+    (Closes: #1138055)
+  * Add debian/source/include-binaries for CVE-2025-15649 test case.
+
+ -- gregor herrmann <[email protected]>  Mon, 31 Aug 2026 17:20:53 +0200
+
 libio-compress-perl (2.213-1) unstable; urgency=medium
 
   * Import upstream version 2.213.
diff -Nru libio-compress-perl-2.213/debian/patches/CVE-2025-15649-tests.diff 
libio-compress-perl-2.213/debian/patches/CVE-2025-15649-tests.diff
--- libio-compress-perl-2.213/debian/patches/CVE-2025-15649-tests.diff  
1970-01-01 01:00:00.000000000 +0100
+++ libio-compress-perl-2.213/debian/patches/CVE-2025-15649-tests.diff  
2026-08-31 17:20:53.000000000 +0200
@@ -0,0 +1,70 @@
+From: pmqs <[email protected]>
+Date: Sat, 25 Oct 2025 19:52:01 +0100
+Subject: Add tests for handling zero and invalid datetime values in unzip
+ functionality. Fix for #65
+
+(Backported for Debian by Niko Tyni)
+
+Origin: backport, 
https://github.com/pmqs/IO-Compress/commit/739698a7b1bb6814d1aa3c4a1b81374b16a9fea5
+Bug: https://github.com/pmqs/IO-Compress/issues/65
+Bug-Debian: https://bugs.debian.org/1146065
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-15649
+---
+ t/006zip.t | 40 +++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 39 insertions(+), 1 deletion(-)
+
+diff --git a/t/006zip.t b/t/006zip.t
+index 580d950..f975e36 100644
+--- a/t/006zip.t
++++ b/t/006zip.t
+@@ -19,7 +19,7 @@ BEGIN {
+     $extra = 1
+         if eval { require Test::NoWarnings ;  Test::NoWarnings->import; 1 };
+ 
+-    plan tests => 108 + $extra ;
++    plan tests => 115 + $extra ;
+ 
+     use_ok('IO::Compress::Zip', qw(:all)) ;
+     use_ok('IO::Uncompress::Unzip', qw(unzip $UnzipError)) ;
+@@ -402,3 +402,41 @@ EOM
+ 
+     is $line, qq["key","value"\n], "got line 1 from second member";
+ }
++
++
++{
++    title "bad datetime";
++    # https://github.com/pmqs/IO-Compress/issues/65
++
++    {
++        # files/time-zero.zip has the modification time set to zero
++        my $file1 = "t/files/time-zero.zip";
++        my $u = IO::Uncompress::Unzip->new( $file1)
++            or die "Cannot open $file1: $UnzipError";
++
++        isa_ok $u, "IO::Uncompress::Unzip";
++
++        my $name = $u->getHeaderInfo()->{Name};
++
++        my $hdr = $u->getHeaderInfo();
++        is $hdr->{Name}, 'hello.txt', "Name is 'hello.txt'";
++        is $hdr->{Time}, 0, "Time is zero";
++    }
++
++
++    {
++        # files/time-invalid.zip has the modification time set to an invalid 
date
++        my $file1 = "t/files/time-invalid.zip";
++        my $u = IO::Uncompress::Unzip->new( $file1)
++            or die "Cannot open $file1: $UnzipError";
++
++        isa_ok $u, "IO::Uncompress::Unzip";
++
++        my $name = $u->getHeaderInfo()->{Name};
++
++        my $hdr = $u->getHeaderInfo();
++        is $hdr->{Name}, 'hello.txt', "Name is 'hello.txt'";
++        is $hdr->{Time}, 0, "Time is zero";
++    }
++
++}
Binary files 
/home/gregoa/tmp/NthTQUavhC/libio-compress-perl-2.213/debian/patches/CVE-2025-15649.diff
 and 
/home/gregoa/tmp/Dt4siCfALz/libio-compress-perl-2.213/debian/patches/CVE-2025-15649.diff
 differ
diff -Nru libio-compress-perl-2.213/debian/patches/CVE-2026-48959.diff 
libio-compress-perl-2.213/debian/patches/CVE-2026-48959.diff
--- libio-compress-perl-2.213/debian/patches/CVE-2026-48959.diff        
1970-01-01 01:00:00.000000000 +0100
+++ libio-compress-perl-2.213/debian/patches/CVE-2026-48959.diff        
2026-08-31 17:20:53.000000000 +0200
@@ -0,0 +1,29 @@
+From: pmqs <[email protected]>
+Date: Fri, 15 May 2026 23:18:39 +0100
+Subject: Fix typo in fastForward #72
+
+(Backported for Debian by Niko Tyni)
+
+Origin: backport, 
https://github.com/pmqs/IO-Compress/commit/68db44076f4c1a86a2ffe53a958eac6cabaf72e2
+Bug: https://github.com/pmqs/IO-Compress/issues/72
+Bug-Debian: https://bugs.debian.org/1138051
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-48959
+---
+ lib/IO/Uncompress/Unzip.pm | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/IO/Uncompress/Unzip.pm b/lib/IO/Uncompress/Unzip.pm
+index 802ee3c..65befa8 100644
+--- a/lib/IO/Uncompress/Unzip.pm
++++ b/lib/IO/Uncompress/Unzip.pm
+@@ -157,8 +157,8 @@ sub fastForward
+ 
+     while ($offset > 0)
+     {
+-        $c = length $offset
+-            if length $offset < $c ;
++        $c = $offset
++            if $offset < $c ;
+ 
+         $offset -= $c;
+ 
diff -Nru libio-compress-perl-2.213/debian/patches/CVE-2026-48961.diff 
libio-compress-perl-2.213/debian/patches/CVE-2026-48961.diff
--- libio-compress-perl-2.213/debian/patches/CVE-2026-48961.diff        
1970-01-01 01:00:00.000000000 +0100
+++ libio-compress-perl-2.213/debian/patches/CVE-2026-48961.diff        
2026-08-31 17:20:53.000000000 +0200
@@ -0,0 +1,27 @@
+From: Jah-yee <[email protected]>
+Date: Sun, 8 Mar 2026 14:53:15 +0000
+Subject: fix: correct unpackValueQ -> unpackValue_Q typo in decodeLitteEndian
+
+(Backported for Debian by Niko Tyni)
+
+Origin: backport, 
https://github.com/pmqs/zipdetails/commit/42da886f43ebd2a8c613ad431208b8df20c9cc22
+Bug: https://github.com/pmqs/zipdetails/pull/32
+Bug-Debian: https://bugs.debian.org/1138052
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-48961
+---
+ bin/zipdetails | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/bin/zipdetails b/bin/zipdetails
+index 7dd1f55..9564bab 100644
+--- a/bin/zipdetails
++++ b/bin/zipdetails
+@@ -4981,7 +4981,7 @@ sub decodeLitteEndian
+ 
+     if (length $value == 8)
+     {
+-        return unpackValueQ ($value)
++        return unpackValue_Q ($value)
+     }
+     elsif (length $value == 4)
+     {
diff -Nru libio-compress-perl-2.213/debian/patches/CVE-2026-48962.diff 
libio-compress-perl-2.213/debian/patches/CVE-2026-48962.diff
--- libio-compress-perl-2.213/debian/patches/CVE-2026-48962.diff        
1970-01-01 01:00:00.000000000 +0100
+++ libio-compress-perl-2.213/debian/patches/CVE-2026-48962.diff        
2026-08-31 17:20:53.000000000 +0200
@@ -0,0 +1,166 @@
+From: pmqs <[email protected]>
+Date: Sat, 16 May 2026 17:48:34 +0100
+Subject: remove use of eval in globmapper. #73
+
+(Backported for Debian by Niko Tyni)
+
+Origin: backport, 
https://github.com/pmqs/IO-Compress/commit/f2db247bf90d4cc7ee2710be384946081f3b4610
+Bug: https://github.com/pmqs/IO-Compress/issues/73
+Bug-Debian: https://bugs.debian.org/1138055
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2026-48962
+---
+ lib/File/GlobMapper.pm | 52 +++++++++++++++++++++++++++------
+ t/globmapper.t         | 52 ++++++++++++++++++++++++++++++++-
+ 2 files changed, 94 insertions(+), 10 deletions(-)
+
+diff --git a/lib/File/GlobMapper.pm b/lib/File/GlobMapper.pm
+index 53f957a..6454bc4 100644
+--- a/lib/File/GlobMapper.pm
++++ b/lib/File/GlobMapper.pm
+@@ -29,6 +29,11 @@ our ($VERSION, @EXPORT_OK);
+ $VERSION = '1.001';
+ @EXPORT_OK = qw( globmap );
+ 
++our $BEGIN_DELIM = "\xFF";
++our $END_DELIM   = "\xFE";
++our $BACKSLASH_ESC = "\xFD";
++our $HASH_ESC = "\xFC";
++our $STAR_ESC = "\xFB";
+ 
+ our ($noPreBS, $metachars, $matchMetaRE, %mapping, %wildCount);
+ $noPreBS = '(?<!\\\)' ; # no preceding backslash
+@@ -310,14 +315,23 @@ sub _parseOutputGlob
+     }
+ 
+     my $noPreBS = '(?<!\\\)' ; # no preceding backslash
+-    #warn "noPreBS = '$noPreBS'\n";
++    my $noPreESC = '(?<![${BEGIN_DELIM}])' ; # no preceding backslash
+ 
+-    #$string =~ s/${noPreBS}\$(\d)/\${$1}/g;
+-    $string =~ s/${noPreBS}#(\d)/\${$1}/g;
+-    $string =~ s#${noPreBS}\*#\${inFile}#g;
+-    $string = '"' . $string . '"';
++    # escape any use of the delimiter symbols
++    # $string =~ s/(${BEGIN_DELIM}|${END_DELIM}|${BACKSLASH_ESC})/$1$1/g;
++
++    # escape \# and \*
++    $string =~ s/\\#/${HASH_ESC}/g;
++    $string =~ s/\\\*/${STAR_ESC}/g;
++
++    # Transform "#3" to BEGIN_DELIM 3 END_DELIM
++    $string =~ s/${noPreESC}#(\d)/${BEGIN_DELIM}${1}${END_DELIM}/g;
++
++    $string =~ s#\*#${BEGIN_DELIM}${END_DELIM}#g;
++
++    # print "INPUT  '$self->{InputPattern}'\n";
++    # print "OUTPUT '$self->{OutputGlob}' => '$string'\n";
+ 
+-    #print "OUTPUT '$self->{OutputGlob}' => '$string'\n";
+     $self->{OutputPattern} = $string ;
+ 
+     return 1 ;
+@@ -335,11 +349,31 @@ sub _getFiles
+         next if $inFiles{$inFile} ++ ;
+ 
+         my $outFile = $inFile ;
++        my @matches ;
++
++        my $noPreESC = '(?<![${BEGIN_DELIM}])' ; # no preceding backslash
+ 
+-        if ( $inFile =~ m/$self->{InputPattern}/ )
++        if (@matches = ($inFile =~ m/$self->{InputPattern}/ ))
+         {
+-            no warnings 'uninitialized';
+-            eval "\$outFile = $self->{OutputPattern};" ;
++            $outFile = $self->{OutputPattern};
++            my $ix = 1;
++
++            # get the filename glob
++            $outFile =~ s/${noPreESC}${BEGIN_DELIM}${END_DELIM}/$inFile/g;
++
++            # now each of the #1, #2,...
++            for my $pattern (@matches)
++            {
++                $outFile =~ 
s/${noPreESC}${BEGIN_DELIM}${ix}${END_DELIM}/$pattern/g;
++
++                ++ $ix;
++            }
++
++            # unescape
++            $outFile =~ s/${BEGIN_DELIM}${BEGIN_DELIM}/${BEGIN_DELIM}/g;
++            $outFile =~ s/${END_DELIM}${END_DELIM}/${END_DELIM}/g;
++            $outFile =~ s/${HASH_ESC}/#/g;
++            $outFile =~ s/${STAR_ESC}/*/g;
+ 
+             if (defined $outInMapping{$outFile})
+             {
+diff --git a/t/globmapper.t b/t/globmapper.t
+index 75fa768..842562f 100644
+--- a/t/globmapper.t
++++ b/t/globmapper.t
+@@ -24,7 +24,7 @@ Perl $]" )
+     $extra = 1
+         if eval { require Test::NoWarnings ;  Test::NoWarnings->import; 1 };
+ 
+-    plan tests => 68 + $extra ;
++    plan tests => 76 + $extra ;
+ 
+     use_ok('File::GlobMapper') ;
+ }
+@@ -290,6 +290,56 @@ Perl $]" )
+         ], "  got mapping";
+ }
+ 
++{
++    title "check escaping";
++
++    my $tmpDir ;#= 'td';
++    my $lex = LexDir->new( $tmpDir );
++
++    my $BEGIN_DELIM = "\xFF";
++    my $END_DELIM   = "\xFE";
++
++    #mkdir $tmpDir, 0777 ;
++
++    touch map { "$tmpDir/$_.tmp" } qw( abc1 abc2 abc3 ) ;
++
++    my $map = File::GlobMapper::globmap("$tmpDir/*b*.tmp", 
"$tmpDir/X-${BEGIN_DELIM}#2-#1${END_DELIM}-X");
++    ok $map, "  got map"
++        or diag $File::GlobMapper::Error ;
++
++    is @{ $map }, 3, "  returned 3 maps";
++    is_deeply $map,
++        [ [map { "$tmpDir/$_" } ("abc1.tmp", 
"X-${BEGIN_DELIM}c1-a${END_DELIM}-X")],
++          [map { "$tmpDir/$_" } ("abc2.tmp", 
"X-${BEGIN_DELIM}c2-a${END_DELIM}-X")],
++          [map { "$tmpDir/$_" } ("abc3.tmp", 
"X-${BEGIN_DELIM}c3-a${END_DELIM}-X")],
++        ], "  got mapping";
++}
++
++{
++    title "check backslash escaping";
++
++    my $tmpDir ;#= 'td';
++    my $lex = LexDir->new( $tmpDir );
++
++    my $BEGIN_DELIM = "\xFF";
++    my $END_DELIM   = "\xFE";
++
++    #mkdir $tmpDir, 0777 ;
++
++    touch map { "$tmpDir/$_.tmp" } qw( abc1 abc2 abc3 ) ;
++
++    my $map = File::GlobMapper::globmap("$tmpDir/*b*.tmp", $tmpDir . 
'/X-#2-\\#1\\*-X');
++    ok $map, "  got map"
++        or diag $File::GlobMapper::Error ;
++
++    is @{ $map }, 3, "  returned 3 maps";
++    is_deeply $map,
++        [ [map { "$tmpDir/$_" } ("abc1.tmp", "X-c1-#1*-X")],
++          [map { "$tmpDir/$_" } ("abc2.tmp", "X-c2-#1*-X")],
++          [map { "$tmpDir/$_" } ("abc3.tmp", "X-c3-#1*-X")],
++        ], "  got mapping";
++}
++
+ # TODO
+ # test each of the wildcard metacharacters can be mapped to the output 
filename
+ #
diff -Nru libio-compress-perl-2.213/debian/patches/series 
libio-compress-perl-2.213/debian/patches/series
--- libio-compress-perl-2.213/debian/patches/series     2024-09-01 
16:58:10.000000000 +0200
+++ libio-compress-perl-2.213/debian/patches/series     2026-08-31 
17:20:53.000000000 +0200
@@ -1,2 +1,7 @@
 autopkgtest.patch
 tests-version-skew.patch
+CVE-2025-15649-tests.diff
+CVE-2025-15649.diff
+CVE-2026-48959.diff
+CVE-2026-48961.diff
+CVE-2026-48962.diff
diff -Nru libio-compress-perl-2.213/debian/source/include-binaries 
libio-compress-perl-2.213/debian/source/include-binaries
--- libio-compress-perl-2.213/debian/source/include-binaries    1970-01-01 
01:00:00.000000000 +0100
+++ libio-compress-perl-2.213/debian/source/include-binaries    2026-08-31 
17:20:53.000000000 +0200
@@ -0,0 +1 @@
+debian/patches/CVE-2025-15649.diff
From: pmqs <[email protected]>
Date: Sat, 25 Oct 2025 19:50:08 +0100
Subject: Enhance _dosToUnixTime to handle zero and invalid datetime values;
 add tests for edge cases. Fixes #65

(Backported for Debian by Niko Tyni)

Origin: backport, https://github.com/pmqs/IO-Compress/commit/fd28c1d2374eee9811f6d0c5bddc0957abdf1da8
Bug: https://github.com/pmqs/IO-Compress/issues/65
Bug-Debian: https://bugs.debian.org/1146065
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2025-15649
---
 MANIFEST                                    |   2 ++
 lib/IO/Uncompress/Unzip.pm |  16 ++++++++++++++--
 t/files/time-invalid.zip   | Bin 0 -> 122 bytes
 t/files/time-zero.zip      | Bin 0 -> 122 bytes
 4 files changed, 16 insertions(+), 2 deletions(-)
 create mode 100644 t/files/time-invalid.zip
 create mode 100644 t/files/time-zero.zip

diff --git a/lib/IO/Uncompress/Unzip.pm b/lib/IO/Uncompress/Unzip.pm
index 6dad364..802ee3c 100644
--- a/lib/IO/Uncompress/Unzip.pm
+++ b/lib/IO/Uncompress/Unzip.pm
@@ -802,7 +802,14 @@ sub filterUncompressed
 # from Archive::Zip & info-zip
 sub _dosToUnixTime
 {
+    # Returns zero when $dt is already zero or it doesn't expand to a value that Time::Local::timelocal()
+    # can handle.
+
 	my $dt = shift;
+    # warn "_dosToUnixTime dt=[$dt]\n";
+
+    # some zip files don't populate the datetime field at all
+    return 0 if ! $dt;
 
 	my $year = ( ( $dt >> 25 ) & 0x7f ) + 80;
 	my $mon  = ( ( $dt >> 21 ) & 0x0f ) - 1;
@@ -813,10 +820,15 @@ sub _dosToUnixTime
 	my $sec  = ( ( $dt << 1 ) & 0x3e );
 
     use Time::Local ;
-    my $time_t = Time::Local::timelocal( $sec, $min, $hour, $mday, $mon, $year);
+
+    my $time_t ;
+    # wrap in an eval to catch out of range errors
+    eval {
+        $time_t = Time::Local::timelocal( $sec, $min, $hour, $mday, $mon, $year);
+    } ;
+
     return 0 if ! defined $time_t;
     return $time_t;
-
 }
 
 #sub scanCentralDirectory
diff --git a/t/files/time-invalid.zip b/t/files/time-invalid.zip
new file mode 100644
index 0000000..ef8f99d
--- /dev/null
+++ b/t/files/time-invalid.zip
@@ -0,0 +1,4 @@
+PK
+ÿÿÿÿ 0:6	hello.txthello
+PK
+ÿÿÿÿ 0:6	´hello.txtPK7-
\ No newline at end of file
diff --git a/t/files/time-zero.zip b/t/files/time-zero.zip
new file mode 100644
index 0000000..cf6eeb4
--- /dev/null
+++ b/t/files/time-zero.zip
@@ -0,0 +1,4 @@
+PK
+ 0:6	hello.txthello
+PK
+ 0:6	´hello.txtPK7-
\ No newline at end of file

Reply via email to