Fix a memory leak in list assignment from or to magic values

This commit is contained in:
Petr Písař 2017-02-17 13:12:54 +01:00
parent 044da6a72d
commit b39bdfd34d
2 changed files with 90 additions and 0 deletions

View File

@ -0,0 +1,83 @@
From 1050723fecc0e27677c39fadbb97cb892dfd27d2 Mon Sep 17 00:00:00 2001
From: David Mitchell <davem@iabyn.com>
Date: Wed, 15 Feb 2017 15:58:24 +0000
Subject: [PATCH] avoid a leak in list assign from/to magic values
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
RT #130766
A leak in list assignment was introduced by v5.23.6-89-gbeb08a1 and
extended with v5.23.6-90-g5c1db56.
Basically the code in S_aassign_copy_common() which does a mark-and-sweep
looking for common vars by temporarily setting SVf_BREAK on LHS SVs then
seeing if that flag was present on RHS vars, very temporarily removed that
flag from the RHS SV while mortal copying it, then set it again. After
those two commits, the "resetting" code could set SVf_BREAK on the RHS SV
even when it hadn't been been present earlier.
This meant that on exit from S_aassign_copy_common(), some SVs could be
left with SVf_BREAK on. When that SV was freed, the SVf_BREAK flag meant
that the SV head wasn't planted back in the arena (but PL_sv_count was
still decremented). This could lead to slow growth of the SV HEAD arenas.
The two circumstances that could trigger the leak were:
1) An SMG var on the LHS and a temporary on the RHS, e.g.
use Tie::Scalar;
my ($s, $t);
tie $s, 'Tie::StdScalar'; # $s has set magic
while (1) {
($s, $t) = ($t, map 1, 1, 2); # the map returns temporaries
}
2) A temporary on the RHS which has GMG, e.g.
my $s = "abc";
pos($s) = 1;
local our ($x, $y);
while (1) {
my $pr = \pos($s); # creates a ref to a TEMP with get magic
($x, $y) = (1, $$pr);
}
Strictly speaking a TEMP isn't required for either case; just a situation
where there's always a fresh SV on the RHS for each iteration that will
soon get freed and thus leaked.
This commit doesn't include any tests since I can't think of a way of
testing it. svleak.t relies on PL_sv_count, which in this case doesn't
show the leak.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp_hot.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pp_hot.c b/pp_hot.c
index a3ee2a7..7d6db0f 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1182,6 +1182,7 @@ S_aassign_copy_common(pTHX_ SV **firstlelem, SV **lastlelem,
assert(svr);
if (UNLIKELY(SvFLAGS(svr) & (SVf_BREAK|SVs_GMG) || copy_all)) {
+ U32 brk = (SvFLAGS(svr) & SVf_BREAK);
#ifdef DEBUGGING
if (fake) {
@@ -1217,7 +1218,7 @@ S_aassign_copy_common(pTHX_ SV **firstlelem, SV **lastlelem,
/* ... but restore afterwards in case it's needed again,
* e.g. ($a,$b,$c) = (1,$a,$a)
*/
- SvFLAGS(svr) |= SVf_BREAK;
+ SvFLAGS(svr) |= brk;
}
if (!lcount)
--
2.7.4

View File

@ -297,6 +297,10 @@ Patch84: perl-5.25.9-perl-129061-CURLYX-nodes-can-be-studied-more-than-on
# from more than one source, RT#129881, in upstream after 5.25.9
Patch85: perl-5.24.1-fix-pad-scope-issue-in-re_evals.patch
# Fix a memory leak in list assignment from or to magic values, RT#130766,
# in upstream after 5.25.9
Patch86: perl-5.25.9-avoid-a-leak-in-list-assign-from-to-magic-values.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
@ -3008,6 +3012,7 @@ popd
%patch83 -p1
%patch84 -p1
%patch85 -p1
%patch86 -p1
%patch200 -p1
%patch201 -p1
@ -3078,6 +3083,7 @@ perl -x patchlevel.h \
'Fedora Patch82: Fix a buffer overrun with format and "use bytes" (RT#130703)' \
'Fedora Patch83: Fix a buffer overflow when studying some regexps repeatedly (RT#129281, RT#129061)' \
'Fedora Patch85: Fix a heap buffer overflow when evaluating regexps with embedded code blocks from more than one source, RT#129881' \
'Fedora Patch86: Fix a memory leak in list assignment from or to magic values, (RT#130766)' \
'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}
@ -5358,6 +5364,7 @@ popd
- Adapt Compress::Raw::Zlib to zlib-1.2.11 (bug #1420326)
- Fix a heap buffer overflow when evaluating regexps with embedded code blocks
from more than one source (RT#129881)
- Fix a memory leak in list assignment from or to magic values (RT#130766)
* Fri Feb 10 2017 Petr Pisar <ppisar@redhat.com> - 4:5.24.1-388
- Adapt tests to zlib-1.2.11 (bug #1420326)