diff --git a/SOURCES/YAML-LibYAML-0.903-Use-3-arg-form-of-open-in-LoadFile.patch b/SOURCES/YAML-LibYAML-0.903-Use-3-arg-form-of-open-in-LoadFile.patch new file mode 100644 index 0000000..9e3497d --- /dev/null +++ b/SOURCES/YAML-LibYAML-0.903-Use-3-arg-form-of-open-in-LoadFile.patch @@ -0,0 +1,27 @@ +From 5fe9daed726c06900c3cd41a739460057bec6dc3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tina=20M=C3=BCller?= +Date: Wed, 29 Jan 2025 21:17:28 +0100 +Subject: [PATCH] Use 3-arg form of open in LoadFile + +Fixes https://github.com/ingydotnet/yaml-libyaml-pm/issues/120 + +Otherwise `$filename = ">file.yaml"; LoadFile($filename)` will truncate a file. + +One should check untrusted filenames in any case, though. +--- + lib/YAML/XS.pm | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/YAML/XS.pm b/lib/YAML/XS.pm +index 66ff5ba..e8df694 100644 +--- a/lib/YAML/XS.pm ++++ b/lib/YAML/XS.pm +@@ -54,7 +54,7 @@ sub LoadFile { + $IN = $filename; + } + else { +- open $IN, $filename ++ open $IN, '<', $filename + or die "Can't open '$filename' for input:\n$!"; + } + return YAML::XS::LibYAML::Load(do { local $/; local $_ = <$IN> }); diff --git a/SOURCES/YAML-LibYAML-0.903-regress-test-for-3args-open.patch b/SOURCES/YAML-LibYAML-0.903-regress-test-for-3args-open.patch new file mode 100644 index 0000000..635a385 --- /dev/null +++ b/SOURCES/YAML-LibYAML-0.903-regress-test-for-3args-open.patch @@ -0,0 +1,76 @@ +From d287c87f41d5b0438d94d8fad1f285d17530fc69 Mon Sep 17 00:00:00 2001 +From: Shlomi Fish +Date: Fri, 7 Feb 2025 15:08:56 +0200 +Subject: [PATCH] regress test for GH#120. 3args open. + +--- + Makefile.PL | 4 ++++ + t/security-gh120.t | 28 ++++++++++++++++++++++++++++ + 2 files changed, 32 insertions(+) + create mode 100644 t/security-gh120.t + +#diff --git a/Makefile.PL b/Makefile.PL +#index 49a917d..371533a 100644 +#--- a/Makefile.PL +#+++ b/Makefile.PL +#@@ -26,10 +26,12 @@ my %WriteMakefileArgs = ( +# "warnings" => 0 +# }, +# "TEST_REQUIRES" => { +#+ "Cwd" => 0, +# "Devel::Peek" => 0, +# "Encode" => 0, +# "File::Find" => 0, +# "File::Path" => 0, +#+ "File::Temp" => 0, +# "FindBin" => 0, +# "IO::File" => 0, +# "IO::Pipe" => 0, +#@@ -50,11 +52,13 @@ my %WriteMakefileArgs = ( +# +# my %FallbackPrereqs = ( +# "B::Deparse" => 0, +#+ "Cwd" => 0, +# "Devel::Peek" => 0, +# "Encode" => 0, +# "Exporter" => 0, +# "File::Find" => 0, +# "File::Path" => 0, +#+ "File::Temp" => 0, +# "FindBin" => 0, +# "IO::File" => 0, +# "IO::Pipe" => 0, +diff --git a/t/security-gh120.t b/t/security-gh120.t +new file mode 100644 +index 0000000..1102550 +--- /dev/null ++++ b/t/security-gh120.t +@@ -0,0 +1,28 @@ ++use FindBin '$Bin'; ++use lib $Bin; ++use TestYAMLTests tests => 1; ++ ++# https://github.com/ingydotnet/yaml-libyaml-pm/issues/120 ++# ++ ++use YAML::XS qw/DumpFile LoadFile/; ++use File::Temp qw/ tempdir /; ++ ++use Cwd qw/ getcwd /; ++ ++my $PWD = getcwd(); ++my $dir = tempdir( CLEANUP => 1 ); ++ ++chdir($dir); ++ ++my $fn = "dont-clobber-me"; ++open my $fh, ">", ">$fn"; ++$fh->print( "$fn\n" x 500 ); ++close($fh); ++ ++my $ret = LoadFile(">$fn"); ++ ++my $size = ( -s ">$fn" ); ++ok( scalar( $size > 2000 ), "file was not clobbered; size = '$size'" ); ++ ++chdir($PWD); diff --git a/SPECS/perl-YAML-LibYAML.spec b/SPECS/perl-YAML-LibYAML.spec index a6655a9..1a3d26c 100644 --- a/SPECS/perl-YAML-LibYAML.spec +++ b/SPECS/perl-YAML-LibYAML.spec @@ -8,11 +8,14 @@ Name: perl-YAML-LibYAML Epoch: 1 Version: 0.70 -Release: 1%{?dist} +Release: 2%{?dist} Summary: Perl YAML Serialization using XS and libyaml License: GPL+ or Artistic URL: https://metacpan.org/release/YAML-LibYAML Source0: https://cpan.metacpan.org/authors/id/T/TI/TINITA/YAML-LibYAML-%{version}.tar.gz +# Use 3-arg form of open in LoadFile (CVE-2025-40908) +Patch1: YAML-LibYAML-0.903-Use-3-arg-form-of-open-in-LoadFile.patch +Patch2: YAML-LibYAML-0.903-regress-test-for-3args-open.patch # Build BuildRequires: coreutils @@ -39,11 +42,13 @@ BuildRequires: perl(XSLoader) BuildRequires: perl(B) BuildRequires: perl(blib) BuildRequires: perl(Carp) +BuildRequires: perl(Cwd) BuildRequires: perl(Data::Dumper) BuildRequires: perl(Devel::Peek) BuildRequires: perl(Encode) BuildRequires: perl(File::Find) BuildRequires: perl(File::Path) +BuildRequires: perl(File::Temp) BuildRequires: perl(Filter::Util::Call) BuildRequires: perl(FindBin) BuildRequires: perl(IO::File) @@ -72,14 +77,37 @@ Provides: bundled(libyaml) = 0.1.7 # Avoid provides for perl shared objects %{?perl_default_filter} +# Filter modules bundled for tests +%global __provides_exclude_from %{?__provides_exclude_from:%__provides_exclude_from|}^%{_libexecdir} +%global __requires_exclude %{?__requires_exclude:%__requires_exclude|}^perl\\(Spiffy\\) +%global __requires_exclude %{?__requires_exclude:%__requires_exclude|}^perl\\(TestYAML.*\\) +%global __requires_exclude %{?__requires_exclude:%__requires_exclude|}^perl\\(Test::Base.*\\) %description Kirill Siminov's "libyaml" is arguably the best YAML implementation. The C library is written precisely to the YAML 1.1 specification. It was originally bound to Python and was later bound to Ruby. +%package tests +Summary: Tests for %{name} +Requires: %{name} = %{?epoch:%{epoch}:}%{version}-%{release} +Requires: perl-Test-Harness +Requires: perl(Filter::Util::Call) + +%description tests +Tests from %{name}. Execute them +with "%{_libexecdir}/%{name}/test". + %prep %setup -q -n YAML-LibYAML-%{version} +%patch -P1 -p1 +%patch -P2 -p1 + +# Help generators to recognize Perl scripts +for F in t/*.t; do + perl -i -MConfig -ple 'print $Config{startperl} if $. == 1 && !s{\A#!.*perl\b}{$Config{startperl}}' "$F" + chmod +x "$F" +done %build perl Makefile.PL INSTALLDIRS=vendor OPTIMIZE="%{optflags}" NO_PACKLIST=1 @@ -90,7 +118,32 @@ make pure_install DESTDIR=%{buildroot} find %{buildroot} -type f -name '*.bs' -empty -delete %{_fixperms} -c %{buildroot} +# Install tests +mkdir -p %{buildroot}%{_libexecdir}/%{name} +cp -a t inc %{buildroot}%{_libexecdir}/%{name} +# It needs libraries in lib/ not in system directories +rm %{buildroot}%{_libexecdir}/%{name}/t/000-require-modules.t +# Remove author test +rm %{buildroot}%{_libexecdir}/%{name}/t/author-pod-syntax.t +# Don't use blib +perl -i -pe 's{^use blib;}{#use blib;}' %{buildroot}%{_libexecdir}/%{name}/t/TestYAML.pm +perl -i -pe 's{^use_blib: 1}{use_blib: 0}' %{buildroot}%{_libexecdir}/%{name}/t/yaml_tests.yaml +cat > %{buildroot}%{_libexecdir}/%{name}/test << 'EOF' +#!/bin/bash +set -e +# Some tests write into temporary files/directories. The solution is to +# copy the tests into a writable directory and execute them from there. +DIR=$(mktemp -d) +pushd "$DIR" +cp -a %{_libexecdir}/%{name}/* ./ +prove -I . -I inc -j "$(getconf _NPROCESSORS_ONLN)" +popd +rm -rf "$DIR" +EOF +chmod +x %{buildroot}%{_libexecdir}/%{name}/test + %check +export HARNESS_OPTIONS=j$(perl -e 'if ($ARGV[0] =~ /.*-j([0-9][0-9]*).*/) {print $1} else {print 1}' -- '%{?_smp_mflags}') make test %files @@ -102,7 +155,13 @@ make test %{_mandir}/man3/YAML::XS.3* %{_mandir}/man3/YAML::XS::LibYAML.3* +%files tests +%{_libexecdir}/%{name} + %changelog +* Thu Jun 05 2025 Jitka Plesnikova - 1:0.70-2 +- Use 3-arg form of open in LoadFile (CVE-2025-40908) + * Sun Jun 10 2018 Paul Howarth - 1:0.70-1 - Update to 0.70 - Fix format specifier/argument mismatch (GH#79)