Fix a use-after-free when processing scalar variables in forms

This commit is contained in:
Petr Písař 2017-01-20 09:58:45 +01:00
parent 96616c59c9
commit 64c060a679
2 changed files with 114 additions and 0 deletions

View File

@ -0,0 +1,107 @@
From 0c43d46cd570d2a19edfa54b9c637dea5c0a3514 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Thu, 19 Jan 2017 16:28:03 +1100
Subject: [PATCH] (perl #129125) copy form data if it might be freed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ported to 5.24.1:
commit 86191aed6f092273950ebdd48f886d4ec0c5e85e
Author: Tony Cook <tony@develop-help.com>
Date: Thu Jan 19 16:28:03 2017 +1100
(perl #129125) copy form data if it might be freed
If the format SV also appeared as an argument, and the FF_CHOP
operator modified that argument, the magic and hence the compiled
format would be freed, and the next iteration of the processing
the compiled format would read freed memory.
Unlike my original patch this copies the formsv too, since
that is also stored in the magic, and is needed for presenting
literal text from the format.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
pp_ctl.c | 18 ++++++++++++++++++
t/op/write.t | 19 ++++++++++++++++++-
2 files changed, 36 insertions(+), 1 deletion(-)
diff --git a/pp_ctl.c b/pp_ctl.c
index b94c09a..e859e01 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -490,6 +490,7 @@ PP(pp_formline)
U8 *source; /* source of bytes to append */
STRLEN to_copy; /* how may bytes to append */
char trans; /* what chars to translate */
+ bool copied_form = false; /* have we duplicated the form? */
mg = doparseform(tmpForm);
@@ -687,6 +688,23 @@ PP(pp_formline)
case FF_CHOP: /* (for ^*) chop the current item */
if (sv != &PL_sv_no) {
const char *s = chophere;
+ if (!copied_form &&
+ ((sv == tmpForm || SvSMAGICAL(sv))
+ || (SvGMAGICAL(tmpForm) && !sv_only_taint_gmagic(tmpForm))) ) {
+ /* sv and tmpForm are either the same SV, or magic might allow modification
+ of tmpForm when sv is modified, so copy */
+ SV *newformsv = sv_mortalcopy(formsv);
+ U32 *new_compiled;
+
+ f = SvPV_nolen(newformsv) + (f - SvPV_nolen(formsv));
+ Newx(new_compiled, mg->mg_len / sizeof(U32), U32);
+ memcpy(new_compiled, mg->mg_ptr, mg->mg_len);
+ SAVEFREEPV(new_compiled);
+ fpc = new_compiled + (fpc - (U32*)mg->mg_ptr);
+ formsv = newformsv;
+
+ copied_form = true;
+ }
if (chopspace) {
while (isSPACE(*s))
s++;
diff --git a/t/op/write.t b/t/op/write.t
index 590d658..ab2733f 100644
--- a/t/op/write.t
+++ b/t/op/write.t
@@ -98,7 +98,7 @@ for my $tref ( @NumTests ){
my $bas_tests = 21;
# number of tests in section 3
-my $bug_tests = 66 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 4 + 2 + 3 + 96 + 11 + 3;
+my $bug_tests = 66 + 3 * 3 * 5 * 2 * 3 + 2 + 66 + 6 + 2 + 3 + 96 + 11 + 3;
# number of tests in section 4
my $hmb_tests = 37;
@@ -1637,6 +1637,23 @@ printf ">%s<\n", ref $zamm;
print "$zamm->[0]\n";
EOP
+# [perl #129125] - detected by -fsanitize=address or valgrind
+# the compiled format would be freed when the format string was modified
+# by the chop operator
+fresh_perl_is(<<'EOP', "^", { stderr => 1 }, '#129125 - chop on format');
+my $x = '^@';
+formline$x=>$x;
+print $^A;
+EOP
+
+fresh_perl_is(<<'EOP', '<^< xx AA><xx ^<><>', { stderr => 1 }, '#129125 - chop on format, later values');
+my $x = '^< xx ^<';
+my $y = 'AA';
+formline $x => $x, $y;
+print "<$^A><$x><$y>";
+EOP
+
+
# [perl #73690]
select +(select(RT73690), do {
--
2.7.4

View File

@ -244,6 +244,10 @@ Patch66: perl-5.24.1-perl-130262-split-scalar-context-stack-overflow-fix.
Patch67: perl-5.25.8-perl-129149-avoid-a-heap-buffer-overflow-with-pack-W.patch
Patch68: perl-5.25.8-perl-129149-fix-the-test-so-skip-has-a-SKIP-to-work-.patch
# Fix a use-after-free when processing scalar variables in forms, RT#129125,
# in upstream after 5.25.8
Patch69: perl-5.24.1-perl-129125-copy-form-data-if-it-might-be-freed.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
@ -2936,6 +2940,7 @@ Perl extension for Version Objects
%patch66 -p1
%patch67 -p1
%patch68 -p1
%patch69 -p1
%patch200 -p1
%patch201 -p1
@ -2992,6 +2997,7 @@ perl -x patchlevel.h \
'Fedora Patch65: Fix regular expression matching (RT#130307)' \
'Fedora Patch66: Fix a buffer overflow in split in scalar context (RT#130262)' \
'Fedora Patch67: Fix a heap overflow with pack "W" (RT129149)' \
'Fedora Patch69: Fix a use-after-free when processing scalar variables in forms (RT#129125)' \
'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}
@ -5271,6 +5277,7 @@ popd
* Fri Jan 20 2017 Petr Pisar <ppisar@redhat.com> - 4:5.24.1-386
- Fix a buffer overflow in split in scalar context (RT#130262)
- Fix a heap overflow with pack "W" (RT129149)
- Fix a use-after-free when processing scalar variables in forms (RT#129125)
* Mon Jan 16 2017 Jitka Plesnikova <jplesnik@redhat.com> - 4:5.24.1-385
- 5.24.1 bump (see <http://search.cpan.org/dist/perl-5.24.1/pod/perldelta.pod>