Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

null ptr deref, segfault Perl_mess_sv (util.c:1534) #15637

Closed
p5pRT opened this issue Sep 30, 2016 · 10 comments
Closed

null ptr deref, segfault Perl_mess_sv (util.c:1534) #15637

p5pRT opened this issue Sep 30, 2016 · 10 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 30, 2016

Migrated from rt.perl.org#129770 (status was 'resolved')

Searchable as RT129770$

@p5pRT
Copy link
Author

p5pRT commented Sep 30, 2016

From @geeknik

Triggered in Perl v5.25.6 (v5.25.5-42-g850e14d).

./perl -e '0,$^=0==0,0==0,$0=S$^$^D=S'
Scalar found where operator expected at -e line 1, near "$^$^D"
  (Missing operator before $^D?)
allocating op at 61500000fc48, slab 61500000fa80 at (eval 1) line 1.
allocating op at 61500000fc08, slab 61500000fa80 at (eval 1) line 1.
allocating op at 61500000fba8, slab 61500000fa80 at (eval 1) line 1.
allocating op at 61500000fb60, slab 61500000fa80 at (eval 1) line 1.
allocating op at 61500000fb20, slab 61500000fa80 at (eval 1) line 1.
free op at 61500000fb20, recorded in slab 61500000fa80 at (eval 1) line 1.
ASAN​:SIGSEGV

==10990==ERROR​: AddressSanitizer​: SEGV on unknown address 0x000000000021
(pc 0x000000800b1f bp 0x7ffe86a4ba70 sp 0x7ffe86a4b9c0 T0)
  #0 0x800b1e in Perl_mess_sv /root/perl/util.c​:1534​:6
  #1 0x80011b in Perl_vmess /root/perl/util.c​:1587​:12
  #2 0x80011b in Perl_mess /root/perl/util.c​:1417
  #3 0x4e0385 in Perl_Slab_Free /root/perl/op.c​:442​:5
  #4 0x4e20cd in Perl_op_free /root/perl/op.c​:855​:9
  #5 0x4e1d15 in Perl_op_free /root/perl/op.c​:837​:21
  #6 0xa2b5ef in Perl_leave_scope /root/perl/scope.c​:1109​:6
  #7 0xa5e405 in S_pop_eval_context_maybe_croak /root/perl/pp_ctl.c​:1605​:5
  #8 0xa5dac4 in Perl_die_unwind /root/perl/pp_ctl.c​:1733​:13
  #9 0x8027af in Perl_vcroak /root/perl/util.c​:1817​:5
  #10 0x80269c in Perl_die /root/perl/util.c​:1748​:5
  #11 0xa7e172 in S_require_file /root/perl/pp_ctl.c​:4062​:7
  #12 0xa7e172 in Perl_pp_require /root/perl/pp_ctl.c​:4138
  #13 0x7f4473 in Perl_runops_debug /root/perl/dump.c​:2239​:23
  #14 0x5a7dd8 in Perl_eval_sv /root/perl/perl.c​:2968​:2
  #15 0x5aa188 in Perl_require_pv /root/perl/perl.c​:3071​:5
  #16 0x5c1aa6 in Perl_gv_fetchmethod_pvn_flags /root/perl/gv.c​:1103​:7
  #17 0x5c09d6 in Perl_gv_fetchmethod_sv_flags /root/perl/gv.c​:996​:12
  #18 0x8e5b29 in Perl_pp_method_named /root/perl/pp_hot.c​:4298​:10
  #19 0x7f4473 in Perl_runops_debug /root/perl/dump.c​:2239​:23
  #20 0x5a11d6 in S_run_body /root/perl/perl.c​:2526​:2
  #21 0x5a11d6 in perl_run /root/perl/perl.c​:2449
  #22 0x4de5fd in main /root/perl/perlmain.c​:123​:9
  #23 0x7f4346b0ab44 in __libc_start_main
/build/glibc-daoqzt/glibc-2.19/csu/libc-start.c​:287
  #24 0x4de26c in _start (/root/perl/perl+0x4de26c)

AddressSanitizer can not provide additional info.
SUMMARY​: AddressSanitizer​: SEGV /root/perl/util.c​:1534 Perl_mess_sv
==10990==ABORTING

@p5pRT
Copy link
Author

p5pRT commented Oct 12, 2016

From @geeknik

v5.25.6 (v5.25.5-76-g91dca83)

valgrind -q perl -e 'k$$^D=$^'
Scalar found where operator expected at -e line 1, near "$
$^D"
  (Missing operator before $^D?)
invalid option -DO, use -D'' to see choices
invalid option -D_, use -D'' to see choices
invalid option -DO, use -D'' to see choices
### 1​:LEX_NORMAL/XSTATE "require q"
### <== REQUIRE

### 1​:LEX_NORMAL/XTERM "q"
allocating op at 5f85298, slab 5f850d0 at (eval 1) line 1.
### <== THING(opval=op_const) PV("IO/File.pm"\0)

### 1​:LEX_NORMAL/XOPERATOR "\n;"
### <== ';'

allocating op at 5f85258, slab 5f850d0 at (eval 1) line 1.
allocating op at 5f851f8, slab 5f850d0 at (eval 1) line 1.
allocating op at 5f851b0, slab 5f850d0 at (eval 1) line 1.
### 1​:LEX_NORMAL/XSTATE ""
### Tokener got EOF
### <== EOF

allocating op at 5f85170, slab 5f850d0 at (eval 1) line 1.
free op at 5f85170, recorded in slab 5f850d0 at (eval 1) line 1.
==30738== Invalid read of size 1
==30738== at 0x4DA2DA​: Perl_mess_sv (util.c​:1534)
==30738== by 0x4DA98D​: Perl_mess (util.c​:1417)
==30738== by 0x424C59​: Perl_Slab_Free (op.c​:442)
==30738== by 0x425785​: Perl_op_free (op.c​:855)
==30738== by 0x4258BB​: Perl_op_free (op.c​:837)
==30738== by 0x568070​: Perl_leave_scope (scope.c​:1109)
==30738== by 0x56ADA4​: S_pop_eval_context_maybe_croak (pp_ctl.c​:1593)
==30738== by 0x579A15​: Perl_die_unwind (pp_ctl.c​:1721)
==30738== by 0x4D9297​: Perl_vcroak (util.c​:1817)
==30738== by 0x4D93C8​: Perl_die (util.c​:1748)
==30738== by 0x580DB6​: S_require_file (pp_ctl.c​:4050)
==30738== by 0x580DB6​: Perl_pp_require (pp_ctl.c​:4126)
==30738== by 0x4D7131​: Perl_runops_debug (dump.c​:2246)
==30738== Address 0x21 is not stack'd, malloc'd or (recently) free'd
==30738==
==30738==
==30738== Process terminating with default action of signal 11 (SIGSEGV)
==30738== Access not within mapped region at address 0x21
==30738== at 0x4DA2DA​: Perl_mess_sv (util.c​:1534)
==30738== by 0x4DA98D​: Perl_mess (util.c​:1417)
==30738== by 0x424C59​: Perl_Slab_Free (op.c​:442)
==30738== by 0x425785​: Perl_op_free (op.c​:855)
==30738== by 0x4258BB​: Perl_op_free (op.c​:837)
==30738== by 0x568070​: Perl_leave_scope (scope.c​:1109)
==30738== by 0x56ADA4​: S_pop_eval_context_maybe_croak (pp_ctl.c​:1593)
==30738== by 0x579A15​: Perl_die_unwind (pp_ctl.c​:1721)
==30738== by 0x4D9297​: Perl_vcroak (util.c​:1817)
==30738== by 0x4D93C8​: Perl_die (util.c​:1748)
==30738== by 0x580DB6​: S_require_file (pp_ctl.c​:4050)
==30738== by 0x580DB6​: Perl_pp_require (pp_ctl.c​:4126)
==30738== by 0x4D7131​: Perl_runops_debug (dump.c​:2246)
==30738== If you believe this happened as a result of a stack
==30738== overflow in your program's main thread (unlikely but
==30738== possible), you can try to increase the size of the
==30738== main thread stack using the --main-stacksize= flag.
==30738== The main thread stack size used in this run was 8388608.
Segmentation fault

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

From @hvds

On Wed, 12 Oct 2016 15​:46​:18 -0700, brian.carpenter@​gmail.com wrote​:

v5.25.6 (v5.25.5-76-g91dca83)

valgrind -q perl -e 'k$~$^D=$^'

The trigger here is enabling -DS; we end up attempting to report the freeing of an op when PL_curcop == NULL. I believe that's a legitimate situation, so I propose the patch below to cater for PL_curcop==NULL in mess_sv().

With that in place, we see​:
% ./miniperl -DS -e 'k $~' 2>&1 | perl -ne 'print if /EXECUTING/.../locate/'
EXECUTING...

allocating op at 177e9d8, slab 177e810 at (eval 1) line 1.
allocating op at 177e998, slab 177e810 at (eval 1) line 1.
allocating op at 177e938, slab 177e810 at (eval 1) line 1.
allocating op at 177e8f0, slab 177e810 at (eval 1) line 1.
allocating op at 177e8b0, slab 177e810 at (eval 1) line 1.
free op at 177e8b0, recorded in slab 177e810 at (eval 1) line 1.
free op at 177e938, recorded in slab 177e810.
free op at 177e8f0, recorded in slab 177e810.
free op at 177e9d8, recorded in slab 177e810.
free op at 177e998, recorded in slab 177e810.
freeing slab 177e810.
Can't locate object method "k" via package "IO​::File" at -e line 1.
%
.. which seems more useful than a SEGV.

Hugo

commit db4872386066192185409657dcd15f5c114dae9f
Author​: Hugo van der Sanden <hv@​crypt.org>
Date​: Tue Dec 6 12​:28​:19 2016 +0000

  [perl #129770] Allow for PL_curcop == NULL in mess_sv()
 
  This avoids coredumps in pathological cases such as​: perl -DS -e 'k $~'

Inline Patch
diff --git a/util.c b/util.c
index 02c84c8..0917747 100644
--- a/util.c
+++ b/util.c
@@ -1518,14 +1518,15 @@ Perl_mess_sv(pTHX_ SV *basemsg, bool consume)
         * from the sibling of PL_curcop.
         */
 
-       const COP *cop =
-           closest_cop(PL_curcop, OpSIBLING(PL_curcop), PL_op, FALSE);
+       const COP *cop = PL_curcop
+            ? closest_cop(PL_curcop, OpSIBLING(PL_curcop), PL_op, FALSE)
+            : NULL;
        if (!cop)
            cop = PL_curcop;
-
-       if (CopLINE(cop))
+       if (cop && CopLINE(cop))
            Perl_sv_catpvf(aTHX_ sv, " at %s line %" IVdf,
-           OutCopFILE(cop), (IV)CopLINE(cop));
+                   OutCopFILE(cop), (IV)CopLINE(cop));
+
        /* Seems that GvIO() can be untrustworthy during global destruction. */
        if (GvIO(PL_last_in_gv) && (SvTYPE(GvIOp(PL_last_in_gv)) == SVt_PVIO)
                && IoLINES(GvIOp(PL_last_in_gv)))

@p5pRT
Copy link
Author

p5pRT commented Dec 6, 2016

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2016

From @hvds

I should clarify that I proposed rather than applied this patch only because mess_sv() seems quite a critical function, so I'd like a second opinion on the sanity of this change.

Hugo

On Tue, 06 Dec 2016 04​:59​:14 -0800, hv wrote​:

On Wed, 12 Oct 2016 15​:46​:18 -0700, brian.carpenter@​gmail.com wrote​:

v5.25.6 (v5.25.5-76-g91dca83)

valgrind -q perl -e 'k$~$^D=$^'

The trigger here is enabling -DS; we end up attempting to report the
freeing of an op when PL_curcop == NULL. I believe that's a legitimate
situation, so I propose the patch below to cater for PL_curcop==NULL
in mess_sv().

With that in place, we see​:
% ./miniperl -DS -e 'k $~' 2>&1 | perl -ne 'print if
/EXECUTING/.../locate/'
EXECUTING...

allocating op at 177e9d8, slab 177e810 at (eval 1) line 1.
allocating op at 177e998, slab 177e810 at (eval 1) line 1.
allocating op at 177e938, slab 177e810 at (eval 1) line 1.
allocating op at 177e8f0, slab 177e810 at (eval 1) line 1.
allocating op at 177e8b0, slab 177e810 at (eval 1) line 1.
free op at 177e8b0, recorded in slab 177e810 at (eval 1) line 1.
free op at 177e938, recorded in slab 177e810.
free op at 177e8f0, recorded in slab 177e810.
free op at 177e9d8, recorded in slab 177e810.
free op at 177e998, recorded in slab 177e810.
freeing slab 177e810.
Can't locate object method "k" via package "IO​::File" at -e line 1.
%
.. which seems more useful than a SEGV.

Hugo

commit db4872386066192185409657dcd15f5c114dae9f
Author​: Hugo van der Sanden <hv@​crypt.org>
Date​: Tue Dec 6 12​:28​:19 2016 +0000

[perl #129770] Allow for PL_curcop == NULL in mess_sv()

This avoids coredumps in pathological cases such as​: perl -DS -e 'k
$~'

diff --git a/util.c b/util.c
index 02c84c8..0917747 100644
--- a/util.c
+++ b/util.c
@​@​ -1518,14 +1518,15 @​@​ Perl_mess_sv(pTHX_ SV *basemsg, bool consume)
* from the sibling of PL_curcop.
*/

- const COP *cop =
- closest_cop(PL_curcop, OpSIBLING(PL_curcop), PL_op,
FALSE);
+ const COP *cop = PL_curcop
+ ? closest_cop(PL_curcop, OpSIBLING(PL_curcop), PL_op,
FALSE)
+ : NULL;
if (!cop)
cop = PL_curcop;
-
- if (CopLINE(cop))
+ if (cop && CopLINE(cop))
Perl_sv_catpvf(aTHX_ sv, " at %s line %" IVdf,
- OutCopFILE(cop), (IV)CopLINE(cop));
+ OutCopFILE(cop), (IV)CopLINE(cop));
+
/* Seems that GvIO() can be untrustworthy during global
destruction. */
if (GvIO(PL_last_in_gv) && (SvTYPE(GvIOp(PL_last_in_gv)) ==
SVt_PVIO)
&& IoLINES(GvIOp(PL_last_in_gv)))

@p5pRT
Copy link
Author

p5pRT commented Jan 23, 2017

From @hvds

On Mon, 12 Dec 2016 08​:42​:03 -0800, hv wrote​:

I should clarify that I proposed rather than applied this patch only
because mess_sv() seems quite a critical function, so I'd like a
second opinion on the sanity of this change.

I guess Dave never saw this, since he has just committed a functionally identical change in f4c6177 for [perl #130621].

Marking as fixed pending release.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Jan 23, 2017

@hvds - Status changed from 'open' to 'pending release'

@p5pRT
Copy link
Author

p5pRT commented Jan 24, 2017

From @iabyn

On Mon, Jan 23, 2017 at 11​:19​:26AM -0800, Hugo van der Sanden via RT wrote​:

On Mon, 12 Dec 2016 08​:42​:03 -0800, hv wrote​:

I should clarify that I proposed rather than applied this patch only
because mess_sv() seems quite a critical function, so I'd like a
second opinion on the sanity of this change.

I guess Dave never saw this, since he has just committed a functionally
identical change in f4c6177 for [perl #130621].

Oh yeah. Sorry!

--
In my day, we used to edit the inodes by hand. With magnets.

@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

From @khwilliamson

Thank you for filing this report. You have helped make Perl better.

With the release today of Perl 5.26.0, this and 210 other issues have been
resolved.

Perl 5.26.0 may be downloaded via​:
https://metacpan.org/release/XSAWYERX/perl-5.26.0

If you find that the problem persists, feel free to reopen this ticket.

@p5pRT p5pRT closed this as completed May 30, 2017
@p5pRT
Copy link
Author

p5pRT commented May 30, 2017

@khwilliamson - Status changed from 'pending release' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant