Skip to content

Commit 46b0b75

Browse files
[AutoPR- Security] Patch perl for CVE-2026-48962, CVE-2026-48959, CVE-2026-42496, CVE-2025-15649 [HIGH] (microsoft#17602)
Co-authored-by: Aditya Singh <v-aditysing@microsoft.com>
1 parent a983093 commit 46b0b75

9 files changed

Lines changed: 835 additions & 495 deletions

File tree

SPECS/perl/CVE-2025-15649.patch

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
From 2be341be8403ed34f41340405ce56529270a4c96 Mon Sep 17 00:00:00 2001
2+
From: pmqs <pmqs@cpan.org>
3+
Date: Sat, 25 Oct 2025 19:50:08 +0100
4+
Subject: [PATCH] Enhance _dosToUnixTime to handle zero and invalid datetime
5+
values; add tests for edge cases. Fixes #65
6+
7+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
8+
Upstream-reference: https://github.com/pmqs/IO-Compress/commit/fd28c1d2374eee9811f6d0c5bddc0957abdf1da8.patch
9+
---
10+
cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm | 17 +++++++++++++++--
11+
1 file changed, 15 insertions(+), 2 deletions(-)
12+
13+
diff --git a/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm b/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm
14+
index f1d806b..2b97b6e 100644
15+
--- a/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm
16+
+++ b/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm
17+
@@ -802,8 +802,16 @@ sub filterUncompressed
18+
# from Archive::Zip & info-zip
19+
sub _dosToUnixTime
20+
{
21+
+ # Returns zero when $dt is already zero or it doesn't expand to a value that Time::Local::timelocal()
22+
+ # can handle.
23+
+
24+
my $dt = shift;
25+
26+
+ # warn "_dosToUnixTime dt=[$dt]\n";
27+
+
28+
+ # some zip files don't populate the datetime field at all
29+
+ return 0 if ! $dt;
30+
+
31+
my $year = ( ( $dt >> 25 ) & 0x7f ) + 80;
32+
my $mon = ( ( $dt >> 21 ) & 0x0f ) - 1;
33+
my $mday = ( ( $dt >> 16 ) & 0x1f );
34+
@@ -813,10 +821,15 @@ sub _dosToUnixTime
35+
my $sec = ( ( $dt << 1 ) & 0x3e );
36+
37+
use Time::Local ;
38+
- my $time_t = Time::Local::timelocal( $sec, $min, $hour, $mday, $mon, $year);
39+
+
40+
+ my $time_t ;
41+
+ # wrap in an eval to catch out of range errors
42+
+ eval {
43+
+ $time_t = Time::Local::timelocal( $sec, $min, $hour, $mday, $mon, $year);
44+
+ } ;
45+
+
46+
return 0 if ! defined $time_t;
47+
return $time_t;
48+
-
49+
}
50+
51+
#sub scanCentralDirectory
52+
--
53+
2.45.4
54+

SPECS/perl/CVE-2026-42496.patch

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
From 2a8c5c216e721aae28ad5c7456fe74158955c62b Mon Sep 17 00:00:00 2001
2+
From: Stig Palmquist <stig@stig.io>
3+
Date: Thu, 21 May 2026 19:59:21 +0100
4+
Subject: [PATCH] Validate symlink and hardlink linkname in SECURE MODE
5+
6+
Signed-off-by: Chris 'BinGOs' Williams <chris@bingosnet.co.uk>
7+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
8+
Upstream-reference: https://github.com/jib/archive-tar-new/commit/17c873492a05eddc0de18c1485e0b2cccd5a9158.patch
9+
---
10+
cpan/Archive-Tar/lib/Archive/Tar.pm | 30 +++++++++++++++++++++++++
11+
cpan/Archive-Tar/t/04_resolved_issues.t | 2 ++
12+
2 files changed, 32 insertions(+)
13+
14+
diff --git a/cpan/Archive-Tar/lib/Archive/Tar.pm b/cpan/Archive-Tar/lib/Archive/Tar.pm
15+
index 476e646..4c73823 100644
16+
--- a/cpan/Archive-Tar/lib/Archive/Tar.pm
17+
+++ b/cpan/Archive-Tar/lib/Archive/Tar.pm
18+
@@ -944,6 +944,19 @@ sub _make_special_file {
19+
my $err;
20+
21+
if( $entry->is_symlink ) {
22+
+ if( !$INSECURE_EXTRACT_MODE ) {
23+
+ my $linkname = $entry->linkname;
24+
+ if( File::Spec->file_name_is_absolute($linkname) ) {
25+
+ $self->_error( qq[Symlink '] . $entry->full_path .
26+
+ qq[' has absolute target. Not extracting under SECURE EXTRACT MODE] );
27+
+ return;
28+
+ }
29+
+ if( grep { $_ eq '..' } File::Spec->splitdir($linkname) ) {
30+
+ $self->_error( qq[Symlink '] . $entry->full_path .
31+
+ qq[' target attempts traversal. Not extracting under SECURE EXTRACT MODE] );
32+
+ return;
33+
+ }
34+
+ }
35+
my $fail;
36+
if( ON_UNIX ) {
37+
symlink( $entry->linkname, $file ) or $fail++;
38+
@@ -957,6 +970,23 @@ sub _make_special_file {
39+
$entry->linkname .q[' failed] if $fail;
40+
41+
} elsif ( $entry->is_hardlink ) {
42+
+ if( !$INSECURE_EXTRACT_MODE ) {
43+
+ my $linkname = $entry->linkname;
44+
+ if( File::Spec->file_name_is_absolute($linkname) ) {
45+
+ $self->_error( qq[Hardlink '] . $entry->full_path .
46+
+ qq[' has absolute target '$linkname'. Not extracting ] .
47+
+ qq[under SECURE EXTRACT MODE: extraction itself chmods ] .
48+
+ qq[the shared inode.] );
49+
+ return;
50+
+ }
51+
+ if( grep { $_ eq '..' } File::Spec->splitdir($linkname) ) {
52+
+ $self->_error( qq[Hardlink '] . $entry->full_path .
53+
+ qq[' target '$linkname' attempts traversal. Not ] .
54+
+ qq[extracting under SECURE EXTRACT MODE: extraction ] .
55+
+ qq[itself chmods the shared inode.] );
56+
+ return;
57+
+ }
58+
+ }
59+
my $fail;
60+
if( ON_UNIX ) {
61+
link( $entry->linkname, $file ) or $fail++;
62+
diff --git a/cpan/Archive-Tar/t/04_resolved_issues.t b/cpan/Archive-Tar/t/04_resolved_issues.t
63+
index fc713cd..a0ce3d9 100644
64+
--- a/cpan/Archive-Tar/t/04_resolved_issues.t
65+
+++ b/cpan/Archive-Tar/t/04_resolved_issues.t
66+
@@ -219,6 +219,7 @@ SKIP: {
67+
}
68+
69+
{ #use case 1 - in memory extraction
70+
+ local $Archive::Tar::INSECURE_EXTRACT_MODE=1;
71+
my $t=Archive::Tar->new;
72+
$t->read( $archname );
73+
my $r = eval{ $t->extract };
74+
@@ -230,6 +231,7 @@ SKIP: {
75+
76+
{ #use case 2 - iter extraction
77+
#$DB::single = 2;
78+
+ local $Archive::Tar::INSECURE_EXTRACT_MODE=1;
79+
my $next=Archive::Tar->iter( $archname, 1 );
80+
my $failed = 0;
81+
#use Data::Dumper;
82+
--
83+
2.45.4
84+

SPECS/perl/CVE-2026-48959.patch

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
From ea1152d046eb5a747f3ab0b5e3922ba4749227ca Mon Sep 17 00:00:00 2001
2+
From: pmqs <pmqs@cpan.org>
3+
Date: Fri, 15 May 2026 23:18:39 +0100
4+
Subject: [PATCH] Fix typo in fastForward #72
5+
6+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
7+
Upstream-reference: https://github.com/pmqs/IO-Compress/commit/68db44076f4c1a86a2ffe53a958eac6cabaf72e2.patch
8+
---
9+
cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm | 4 ++--
10+
1 file changed, 2 insertions(+), 2 deletions(-)
11+
12+
diff --git a/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm b/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm
13+
index 981c4e9..e867944 100644
14+
--- a/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm
15+
+++ b/cpan/IO-Compress/lib/IO/Uncompress/Unzip.pm
16+
@@ -157,8 +157,8 @@ sub fastForward
17+
18+
while ($offset > 0)
19+
{
20+
- $c = length $offset
21+
- if length $offset < $c ;
22+
+ $c = $offset
23+
+ if $offset < $c ;
24+
25+
$offset -= $c;
26+
27+
--
28+
2.45.4
29+

SPECS/perl/CVE-2026-48962.patch

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
From 80dbc85d1a78dd2ab85e3c0e325d38359d66e0dc Mon Sep 17 00:00:00 2001
2+
From: pmqs <pmqs@cpan.org>
3+
Date: Sat, 16 May 2026 17:48:34 +0100
4+
Subject: [PATCH] remove use of eval in globmapper. #73
5+
6+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
7+
Upstream-reference: https://github.com/pmqs/IO-Compress/commit/f2db247bf90d4cc7ee2710be384946081f3b4610.patch
8+
---
9+
cpan/IO-Compress/lib/File/GlobMapper.pm | 52 ++++++++++++++++++++-----
10+
cpan/IO-Compress/t/globmapper.t | 52 ++++++++++++++++++++++++-
11+
2 files changed, 94 insertions(+), 10 deletions(-)
12+
13+
diff --git a/cpan/IO-Compress/lib/File/GlobMapper.pm b/cpan/IO-Compress/lib/File/GlobMapper.pm
14+
index f015b16..8936146 100644
15+
--- a/cpan/IO-Compress/lib/File/GlobMapper.pm
16+
+++ b/cpan/IO-Compress/lib/File/GlobMapper.pm
17+
@@ -29,6 +29,11 @@ our ($VERSION, @EXPORT_OK);
18+
$VERSION = '1.001';
19+
@EXPORT_OK = qw( globmap );
20+
21+
+our $BEGIN_DELIM = "\xFF";
22+
+our $END_DELIM = "\xFE";
23+
+our $BACKSLASH_ESC = "\xFD";
24+
+our $HASH_ESC = "\xFC";
25+
+our $STAR_ESC = "\xFB";
26+
27+
our ($noPreBS, $metachars, $matchMetaRE, %mapping, %wildCount);
28+
$noPreBS = '(?<!\\\)' ; # no preceding backslash
29+
@@ -310,14 +315,23 @@ sub _parseOutputGlob
30+
}
31+
32+
my $noPreBS = '(?<!\\\)' ; # no preceding backslash
33+
- #warn "noPreBS = '$noPreBS'\n";
34+
+ my $noPreESC = '(?<![${BEGIN_DELIM}])' ; # no preceding backslash
35+
36+
- #$string =~ s/${noPreBS}\$(\d)/\${$1}/g;
37+
- $string =~ s/${noPreBS}#(\d)/\${$1}/g;
38+
- $string =~ s#${noPreBS}\*#\${inFile}#g;
39+
- $string = '"' . $string . '"';
40+
+ # escape any use of the delimiter symbols
41+
+ # $string =~ s/(${BEGIN_DELIM}|${END_DELIM}|${BACKSLASH_ESC})/$1$1/g;
42+
+
43+
+ # escape \# and \*
44+
+ $string =~ s/\\#/${HASH_ESC}/g;
45+
+ $string =~ s/\\\*/${STAR_ESC}/g;
46+
+
47+
+ # Transform "#3" to BEGIN_DELIM 3 END_DELIM
48+
+ $string =~ s/${noPreESC}#(\d)/${BEGIN_DELIM}${1}${END_DELIM}/g;
49+
+
50+
+ $string =~ s#\*#${BEGIN_DELIM}${END_DELIM}#g;
51+
+
52+
+ # print "INPUT '$self->{InputPattern}'\n";
53+
+ # print "OUTPUT '$self->{OutputGlob}' => '$string'\n";
54+
55+
- #print "OUTPUT '$self->{OutputGlob}' => '$string'\n";
56+
$self->{OutputPattern} = $string ;
57+
58+
return 1 ;
59+
@@ -335,11 +349,31 @@ sub _getFiles
60+
next if $inFiles{$inFile} ++ ;
61+
62+
my $outFile = $inFile ;
63+
+ my @matches ;
64+
+
65+
+ my $noPreESC = '(?<![${BEGIN_DELIM}])' ; # no preceding backslash
66+
67+
- if ( $inFile =~ m/$self->{InputPattern}/ )
68+
+ if (@matches = ($inFile =~ m/$self->{InputPattern}/ ))
69+
{
70+
- no warnings 'uninitialized';
71+
- eval "\$outFile = $self->{OutputPattern};" ;
72+
+ $outFile = $self->{OutputPattern};
73+
+ my $ix = 1;
74+
+
75+
+ # get the filename glob
76+
+ $outFile =~ s/${noPreESC}${BEGIN_DELIM}${END_DELIM}/$inFile/g;
77+
+
78+
+ # now each of the #1, #2,...
79+
+ for my $pattern (@matches)
80+
+ {
81+
+ $outFile =~ s/${noPreESC}${BEGIN_DELIM}${ix}${END_DELIM}/$pattern/g;
82+
+
83+
+ ++ $ix;
84+
+ }
85+
+
86+
+ # unescape
87+
+ $outFile =~ s/${BEGIN_DELIM}${BEGIN_DELIM}/${BEGIN_DELIM}/g;
88+
+ $outFile =~ s/${END_DELIM}${END_DELIM}/${END_DELIM}/g;
89+
+ $outFile =~ s/${HASH_ESC}/#/g;
90+
+ $outFile =~ s/${STAR_ESC}/*/g;
91+
92+
if (defined $outInMapping{$outFile})
93+
{
94+
diff --git a/cpan/IO-Compress/t/globmapper.t b/cpan/IO-Compress/t/globmapper.t
95+
index c97beb6..926b5e3 100644
96+
--- a/cpan/IO-Compress/t/globmapper.t
97+
+++ b/cpan/IO-Compress/t/globmapper.t
98+
@@ -24,7 +24,7 @@ Perl $]" )
99+
$extra = 1
100+
if eval { require Test::NoWarnings ; import Test::NoWarnings; 1 };
101+
102+
- plan tests => 68 + $extra ;
103+
+ plan tests => 76 + $extra ;
104+
105+
use_ok('File::GlobMapper') ;
106+
}
107+
@@ -290,6 +290,56 @@ Perl $]" )
108+
], " got mapping";
109+
}
110+
111+
+{
112+
+ title "check escaping";
113+
+
114+
+ my $tmpDir ;#= 'td';
115+
+ my $lex = LexDir->new( $tmpDir );
116+
+
117+
+ my $BEGIN_DELIM = "\xFF";
118+
+ my $END_DELIM = "\xFE";
119+
+
120+
+ #mkdir $tmpDir, 0777 ;
121+
+
122+
+ touch map { "$tmpDir/$_.tmp" } qw( abc1 abc2 abc3 ) ;
123+
+
124+
+ my $map = File::GlobMapper::globmap("$tmpDir/*b*.tmp", "$tmpDir/X-${BEGIN_DELIM}#2-#1${END_DELIM}-X");
125+
+ ok $map, " got map"
126+
+ or diag $File::GlobMapper::Error ;
127+
+
128+
+ is @{ $map }, 3, " returned 3 maps";
129+
+ is_deeply $map,
130+
+ [ [map { "$tmpDir/$_" } ("abc1.tmp", "X-${BEGIN_DELIM}c1-a${END_DELIM}-X")],
131+
+ [map { "$tmpDir/$_" } ("abc2.tmp", "X-${BEGIN_DELIM}c2-a${END_DELIM}-X")],
132+
+ [map { "$tmpDir/$_" } ("abc3.tmp", "X-${BEGIN_DELIM}c3-a${END_DELIM}-X")],
133+
+ ], " got mapping";
134+
+}
135+
+
136+
+{
137+
+ title "check backslash escaping";
138+
+
139+
+ my $tmpDir ;#= 'td';
140+
+ my $lex = LexDir->new( $tmpDir );
141+
+
142+
+ my $BEGIN_DELIM = "\xFF";
143+
+ my $END_DELIM = "\xFE";
144+
+
145+
+ #mkdir $tmpDir, 0777 ;
146+
+
147+
+ touch map { "$tmpDir/$_.tmp" } qw( abc1 abc2 abc3 ) ;
148+
+
149+
+ my $map = File::GlobMapper::globmap("$tmpDir/*b*.tmp", $tmpDir . '/X-#2-\\#1\\*-X');
150+
+ ok $map, " got map"
151+
+ or diag $File::GlobMapper::Error ;
152+
+
153+
+ is @{ $map }, 3, " returned 3 maps";
154+
+ is_deeply $map,
155+
+ [ [map { "$tmpDir/$_" } ("abc1.tmp", "X-c1-#1*-X")],
156+
+ [map { "$tmpDir/$_" } ("abc2.tmp", "X-c2-#1*-X")],
157+
+ [map { "$tmpDir/$_" } ("abc3.tmp", "X-c3-#1*-X")],
158+
+ ], " got mapping";
159+
+}
160+
+
161+
# TODO
162+
# test each of the wildcard metacharacters can be mapped to the output filename
163+
#
164+
--
165+
2.45.4
166+

SPECS/perl/perl.spec

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ License: GPL+ or Artistic
127127
Epoch: %{perl_epoch}
128128
Version: %{perl_version}
129129
# release number must be even higher, because dual-lived modules will be broken otherwise
130-
Release: 509%{?dist}
130+
Release: 510%{?dist}
131131
Summary: Practical Extraction and Report Language
132132
Url: https://www.perl.org/
133133
Vendor: Microsoft Corporation
@@ -190,6 +190,10 @@ Patch202: perl-5.36.0-Add-definition-of-OPTIMIZE-to-.ph-files.patch
190190
Patch203: CVE-2024-56406.patch
191191

192192
Patch204: CVE-2025-40909.patch
193+
Patch205: CVE-2025-15649.patch
194+
Patch206: CVE-2026-42496.patch
195+
Patch207: CVE-2026-48959.patch
196+
Patch208: CVE-2026-48962.patch
193197

194198
# Update some of the bundled modules
195199
# see http://fedoraproject.org/wiki/Perl/perl.spec for instructions
@@ -6846,6 +6850,9 @@ popd
68466850

68476851
# Old changelog entries are preserved in CVS.
68486852
%changelog
6853+
* Tue Jun 02 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 4:5.38.2-510
6854+
- Patch for CVE-2026-48962, CVE-2026-48959, CVE-2026-42496, CVE-2025-15649
6855+
68496856
* Wed Jun 04 2025 Aninda Pradhan <v-anipradhan@microsoft.com> - 4:5.38.2-509
68506857
- Patch CVE-2025-40909
68516858

0 commit comments

Comments
 (0)