Fix a memory leak in list assignment from or to magic values
This commit is contained in:
		
							parent
							
								
									044da6a72d
								
							
						
					
					
						commit
						b39bdfd34d
					
				| @ -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 | ||||||
|  | 
 | ||||||
| @ -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 | # 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 | 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 | # 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 | Patch200:       perl-5.16.3-Link-XS-modules-to-libperl.so-with-EU-CBuilder-on-Li.patch | ||||||
| 
 | 
 | ||||||
| @ -3008,6 +3012,7 @@ popd | |||||||
| %patch83 -p1 | %patch83 -p1 | ||||||
| %patch84 -p1 | %patch84 -p1 | ||||||
| %patch85 -p1 | %patch85 -p1 | ||||||
|  | %patch86 -p1 | ||||||
| %patch200 -p1 | %patch200 -p1 | ||||||
| %patch201 -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 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 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 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 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' \ |     'Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux' \ | ||||||
|     %{nil} |     %{nil} | ||||||
| @ -5358,6 +5364,7 @@ popd | |||||||
| - Adapt Compress::Raw::Zlib to zlib-1.2.11 (bug #1420326) | - Adapt Compress::Raw::Zlib to zlib-1.2.11 (bug #1420326) | ||||||
| - Fix a heap buffer overflow when evaluating regexps with embedded code blocks | - Fix a heap buffer overflow when evaluating regexps with embedded code blocks | ||||||
|   from more than one source (RT#129881) |   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 | * Fri Feb 10 2017 Petr Pisar <ppisar@redhat.com> - 4:5.24.1-388 | ||||||
| - Adapt tests to zlib-1.2.11 (bug #1420326) | - Adapt tests to zlib-1.2.11 (bug #1420326) | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user