From e4161c3a1897c231b7df50065e70aa305303e86f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppi...@redhat.com> Date: Mon, 13 Jun 2016 10:11:01 +0200 Subject: Fix duplicating PerlIO::encoding when spawning threads
--- ...roperly-duplicate-PerlIO-encoding-objects.patch | 154 +++++++++++++++++++++ perl.spec | 11 +- 2 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 perl-5.20.3-Properly-duplicate-PerlIO-encoding-objects.patch diff --git a/perl-5.20.3-Properly-duplicate-PerlIO-encoding-objects.patch b/perl-5.20.3-Properly-duplicate-PerlIO-encoding-objects.patch new file mode 100644 index 0000000..5325b56 --- /dev/null +++ b/perl-5.20.3-Properly-duplicate-PerlIO-encoding-objects.patch @@ -0,0 +1,154 @@ +From f358580268a0098209b72f7fbaa15e92df801b34 Mon Sep 17 00:00:00 2001 +From: Vincent Pit <p...@profvince.com> +Date: Fri, 28 Aug 2015 14:17:00 -0300 +Subject: [PATCH] Properly duplicate PerlIO::encoding objects +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Upstream commit ported to 5.20.3: + +commit 0ee3fa26f660ac426e3e082f77d806c9d1471f93 +Author: Vincent Pit <p...@profvince.com> +Date: Fri Aug 28 14:17:00 2015 -0300 + + Properly duplicate PerlIO::encoding objects + + PerlIO::encoding objects are usually initialized by calling Perl methods, + essentially from the pushed() and getarg() callbacks. During cloning, the + PerlIO API will by default call these methods to initialize the duplicate + struct when the PerlIOBase parent struct is itself duplicated. This does + not behave so well because the perl interpreter is not ready to call + methods at this point, for the stacks are not set up yet. + + The proper way to duplicate the PerlIO::encoding object is to call sv_dup() + on its members from the dup() PerlIO callback. So the only catch is to make + the getarg() and pushed() calls implied by the duplication of the underlying + PerlIOBase object aware that they are called during cloning, and make them + wait that the control flow returns to the dup() callback. Fortunately, + getarg() knows since its param argument is then non-null, and its return + value is passed immediately to pushed(), so it is enough to tag this + returned value with a custom magic so that pushed() can see it is being + called during cloning. + + This fixes [RT #31923]. + +Signed-off-by: Petr Písař <ppi...@redhat.com> +--- + MANIFEST | 1 + + ext/PerlIO-encoding/encoding.xs | 25 +++++++++++++++++++++++-- + ext/PerlIO-encoding/t/threads.t | 35 +++++++++++++++++++++++++++++++++++ + 3 files changed, 59 insertions(+), 2 deletions(-) + create mode 100644 ext/PerlIO-encoding/t/threads.t + +diff --git a/MANIFEST b/MANIFEST +index af12626..f707105 100644 +--- a/MANIFEST ++++ b/MANIFEST +@@ -3758,6 +3758,7 @@ ext/PerlIO-encoding/encoding.xs PerlIO::encoding + ext/PerlIO-encoding/t/encoding.t See if PerlIO encoding conversion works + ext/PerlIO-encoding/t/fallback.t See if PerlIO fallbacks work + ext/PerlIO-encoding/t/nolooping.t Tests for PerlIO::encoding ++ext/PerlIO-encoding/t/threads.t Tests PerlIO::encoding and threads + ext/PerlIO-mmap/mmap.pm PerlIO layer for memory maps + ext/PerlIO-mmap/mmap.xs PerlIO layer for memory maps + ext/PerlIO-scalar/scalar.pm PerlIO layer for scalars +diff --git a/ext/PerlIO-encoding/encoding.xs b/ext/PerlIO-encoding/encoding.xs +index fababd1..2332615 100644 +--- a/ext/PerlIO-encoding/encoding.xs ++++ b/ext/PerlIO-encoding/encoding.xs +@@ -49,13 +49,23 @@ typedef struct { + + #define NEEDS_LINES 1 + ++static const MGVTBL PerlIOEncode_tag = { 0, 0, 0, 0, 0, 0, 0, 0 }; ++ + SV * + PerlIOEncode_getarg(pTHX_ PerlIO * f, CLONE_PARAMS * param, int flags) + { + PerlIOEncode *e = PerlIOSelf(f, PerlIOEncode); +- SV *sv = &PL_sv_undef; +- PERL_UNUSED_ARG(param); ++ SV *sv; + PERL_UNUSED_ARG(flags); ++ /* During cloning, return an undef token object so that _pushed() knows ++ * that it should not call methods and wait for _dup() to actually dup the ++ * encoding object. */ ++ if (param) { ++ sv = newSV(0); ++ sv_magicext(sv, NULL, PERL_MAGIC_ext, &PerlIOEncode_tag, 0, 0); ++ return sv; ++ } ++ sv = &PL_sv_undef; + if (e->enc) { + dSP; + /* Not 100% sure stack swap is right thing to do during dup ... */ +@@ -85,6 +95,14 @@ PerlIOEncode_pushed(pTHX_ PerlIO * f, const char *mode, SV * arg, PerlIO_funcs * + IV code = PerlIOBuf_pushed(aTHX_ f, mode, Nullsv,tab); + SV *result = Nullsv; + ++ if (SvTYPE(arg) >= SVt_PVMG ++ && mg_findext(arg, PERL_MAGIC_ext, &PerlIOEncode_tag)) { ++ e->enc = NULL; ++ e->chk = NULL; ++ e->inEncodeCall = 0; ++ return code; ++ } ++ + PUSHSTACKi(PERLSI_MAGIC); + ENTER; + SAVETMPS; +@@ -563,6 +581,9 @@ PerlIOEncode_dup(pTHX_ PerlIO * f, PerlIO * o, + if (oe->enc) { + fe->enc = PerlIO_sv_dup(aTHX_ oe->enc, params); + } ++ if (oe->chk) { ++ fe->chk = PerlIO_sv_dup(aTHX_ oe->chk, params); ++ } + } + return f; + } +diff --git a/ext/PerlIO-encoding/t/threads.t b/ext/PerlIO-encoding/t/threads.t +new file mode 100644 +index 0000000..64f0e55 +--- /dev/null ++++ b/ext/PerlIO-encoding/t/threads.t +@@ -0,0 +1,35 @@ ++#!perl ++ ++use strict; ++use warnings; ++ ++BEGIN { ++ use Config; ++ if ($Config{extensions} !~ /\bEncode\b/) { ++ print "1..0 # Skip: no Encode\n"; ++ exit 0; ++ } ++ unless ($Config{useithreads}) { ++ print "1..0 # Skip: no threads\n"; ++ exit 0; ++ } ++} ++ ++use threads; ++ ++use Test::More tests => 3 + 1; ++ ++binmode *STDOUT, ':encoding(UTF-8)'; ++ ++SKIP: { ++ local $@; ++ my $ret = eval { ++ my $thread = threads->create(sub { pass 'in thread'; return 1 }); ++ skip 'test thread could not be spawned' => 3 unless $thread; ++ $thread->join; ++ }; ++ is $@, '', 'thread did not croak'; ++ is $ret, 1, 'thread returned the right value'; ++} ++ ++pass 'passes at least one test'; +-- +2.5.5 + diff --git a/perl.spec b/perl.spec index 2fcf0c8..42be103 100644 --- a/perl.spec +++ b/perl.spec @@ -30,7 +30,7 @@ Name: perl Version: %{perl_version} # release number must be even higher, because dual-lived modules will be broken otherwise -Release: 330%{?dist} +Release: 331%{?dist} Epoch: %{perl_epoch} Summary: Practical Extraction and Report Language Group: Development/Languages @@ -117,6 +117,10 @@ Patch30: perl-5.23.8-remove-duplicate-environment-variables-from-environ. # input), bug #1329107, RT#123562, in upstream after 5.23.2 Patch31: perl-5.20.3-PATCH-perl-123562-Regexp-matching-hangs.patch +# Fix duplicating PerlIO::encoding when spawning threads, bug #1345788, +# RT#31923, in upstream after 5.23.3 +Patch32: perl-5.20.3-Properly-duplicate-PerlIO-encoding-objects.patch + # Link XS modules to libperl.so with EU::CBuilder on Linux, bug #960048 Patch200: perl-5.16.3-Link-XS-modules-to-libperl.so-with-EU-CBuilder-on-Li.patch @@ -2058,6 +2062,7 @@ tarball from perl.org. %patch29 -p1 %patch30 -p1 %patch31 -p1 +%patch32 -p1 %patch200 -p1 %patch201 -p1 @@ -2082,6 +2087,7 @@ perl -x patchlevel.h \ 'Fedora Patch29: Fix debugger y command scope level' \ 'Fedora Patch30: Fix CVE-2016-2381 (ambiguous environment variables handling)' \ 'Fedora Patch31: Fix CVE-2015-8853 (regexp matching hangs on illegal UTF-8)' \ + 'Fedora Patch32: Fix duplicating PerlIO::encoding when spawning threads (RT#31923)' \ 'Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux' \ 'Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux' \ %{nil} @@ -3935,6 +3941,9 @@ sed \ # Old changelog entries are preserved in CVS. %changelog +* Mon Jun 13 2016 Petr Pisar <ppi...@redhat.com> - 4:5.20.3-331 +- Fix duplicating PerlIO::encoding when spawning threads (bug #1345788) + * Thu Apr 21 2016 Petr Pisar <ppi...@redhat.com> - 4:5.20.3-330 - Fix CVE-2015-8853 (regexp matching hangs indefinitely on illegal UTF-8 input) (bug #1329107) -- cgit v0.12 http://pkgs.fedoraproject.org/cgit/perl.git/commit/?h=f22&id=e4161c3a1897c231b7df50065e70aa305303e86f -- Fedora Extras Perl SIG http://www.fedoraproject.org/wiki/Extras/SIGs/Perl perl-devel mailing list perl-devel@lists.fedoraproject.org https://lists.fedoraproject.org/admin/lists/perl-devel@lists.fedoraproject.org