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

Segmentation fault in Perl_sv_setpvn() #14460

Closed
p5pRT opened this issue Feb 1, 2015 · 15 comments
Closed

Segmentation fault in Perl_sv_setpvn() #14460

p5pRT opened this issue Feb 1, 2015 · 15 comments

Comments

@p5pRT
Copy link

p5pRT commented Feb 1, 2015

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

Searchable as RT123710$

@p5pRT
Copy link
Author

p5pRT commented Feb 1, 2015

From thecrux@gmail.com

Simple test case produced sigsegv​:

  $ perl -e '$x|=*x=0'

(gdb) bt
#0 Perl_sv_setpvn (sv=0xe59e10, ptr=0xbe35e9 "", len=0) at sv.c​:4915
#1 0x000000000097df87 in Perl_do_vop (optype=94, sv=0xe59e10, left=0xe59e10, right=0xe59df8) at doop.c​:1022
#2 0x00000000008478b9 in Perl_pp_bit_or () at pp.c​:2257
#3 0x000000000077382b in Perl_runops_standard () at run.c​:41
#4 0x00000000004e5e1f in S_run_body (oldscope=1) at perl.c​:2423
#5 perl_run (my_perl=<optimized out>) at perl.c​:2346
#6 0x0000000000426c7c in main (argc=3, argv=0x7fffffffe488, env=0x7fffffffe4a8) at perlmain.c​:116
#7 0x00007ffff70d4ec5 in __libc_start_main (main=0x426870 <main>, argc=3, argv=0x7fffffffe488,
  init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe478)
  at libc-start.c​:287
#8 0x0000000000426cf3 in _start ()

(gdb) list
4910 }
4911 SvUPGRADE(sv, SVt_PV);
4912
4913 dptr = SvGROW(sv, len + 1);
4914 Move(ptr,dptr,len,char);
4915 dptr[len] = '\0';
4916 SvCUR_set(sv, len);
4917 (void)SvPOK_only_UTF8(sv); /* validate pointer */
4918 SvTAINT(sv);
4919 if (SvTYPE(sv) == SVt_PVCV) CvAUTOLOAD_off(sv);

Crash reproduced with perl 5.12, 5.16, 5.18, 5.21.8
Bug was found by afl fuzzer (http​://lcamtuf.coredump.cx/afl/)

@p5pRT
Copy link
Author

p5pRT commented Feb 1, 2015

From @cpansprout

On Sun Feb 01 13​:11​:02 2015, crux wrote​:

Simple test case produced sigsegv​:

$ perl -e '$x|=*x=0'

*x=0 frees $x after $x is already on the stack. This is another one for #77706.

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Feb 1, 2015

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

@p5pRT
Copy link
Author

p5pRT commented Feb 12, 2015

From @hvds

Found by AFL (<http​://lcamtuf.coredump.cx/afl>)​:

% ./miniperl -e '$x.=*x=0'
Segmentation fault (core dumped)
%

4918 dptr[len] = '\0';
(gdb) where
#0 0x00000000005b5d76 in Perl_sv_setpvn (sv=0xad0498, ptr=0x7acea7 "", len=0)
  at sv.c​:4918
#1 0x0000000000575574 in Perl_pp_concat () at pp_hot.c​:292
#2 0x000000000052a15e in Perl_runops_debug () at dump.c​:2231
#3 0x00000000004098c7 in S_run_body (oldscope=1) at perl.c​:2423
#4 0x0000000000408f0b in perl_run (my_perl=0xaaf010) at perl.c​:2346
#5 0x00000000004508b7 in main (argc=3, argv=0x7fffdb70cbb8,
  env=0x7fffdb70cbd8) at miniperlmain.c​:122

If I read it right, the $x is stacked first; the assignment to *x then frees the already-stacked $x; by the time we get to sv_setpvn the destination is a freed SV (type = 0xff), so the SvGROW returns a null pointer that we then try to write to.

I guess in a sense this is just another example of the unrefcounted stacks issue; I'm not sure that's all that's missing here, though.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Feb 14, 2015

From @hvds

Ah, I see [perl #123804] is near-identical to [perl #123710], I'll merge.

@p5pRT
Copy link
Author

p5pRT commented Mar 6, 2015

From @geeknik

Built v5.21.10 (v5.21.9-43-g2c3f32a) with the following command line​:

/Configure -des -Dusedevel -DDEBUGGING -Dcc=afl-gcc -Doptimize=-O2\ -g && AFL_HARDEN=1 make -j12 test-prep

Bug found with AFL (http​://lcamtuf.coredump.cx/afl)

Valgrind​:
perl​: sv.c​:3977​: S_glob_assign_glob​: Assertion `((svtype)((_gvgp)->sv_flags & 0xff)) == SVt_PVGV || ((svtype)((_gvgp)->sv_flags & 0xff)) == SVt_PVLV' failed.
==57720==
==57720== Process terminating with default action of signal 6 (SIGABRT)
==57720== at 0x5B55165​: raise (raise.c​:64)
==57720== by 0x5B583DF​: abort (abort.c​:92)
==57720== by 0x5B4E310​: __assert_fail (assert.c​:81)
==57720== by 0x994558​: S_glob_assign_glob (sv.c​:3977)
==57720== by 0x959E91​: Perl_sv_setsv_flags (sv.c​:4426)
==57720== by 0x8B4E17​: Perl_pp_sassign (pp_hot.c​:231)
==57720== by 0x7CB49E​: Perl_runops_debug (dump.c​:2237)
==57720== by 0x53B4C8​: perl_run (perl.c​:2427)
==57720== by 0x42B167​: main (perlmain.c​:116)
==57720==

GDB​:
gdb-peda$ file ~/perl/perl
gdb-peda$ set args test26-min
gdb-peda$ r
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
perl​: sv.c​:3977​: S_glob_assign_glob​: Assertion `((svtype)((_gvgp)->sv_flags & 0xff)) == SVt_PVGV || ((svtype)((_gvgp)->sv_flags & 0xff)) == SVt_PVLV' failed.

Program received signal SIGABRT, Aborted.
[----------------------------------registers-----------------------------------]
RAX​: 0x0
RBX​: 0x7fffffffe63b --> 0x736574006c726570 ('perl')
RCX​: 0xffffffffffffffff
RDX​: 0x6
RSI​: 0xf5ac
RDI​: 0xf5ac
RBP​: 0x7ffff6ea9a07 --> 0x257325732500203a ('​: ')
RSP​: 0x7fffffffde98 --> 0x7ffff6d923e0 (<*__GI_abort+384>​: mov rdx,QWORD PTR fs​:0x10)
RIP​: 0x7ffff6d8f165 (<*__GI_raise+53>​: cmp rax,0xfffffffffffff000)
R8 : 0x7ffff7fdd700 (0x00007ffff7fdd700)
R9 : 0x733e2d2970677667 ('gvgp)->s')
R10​: 0x8
R11​: 0x206
R12​: 0xeb3590 ("((svtype)((_gvgp)->sv_flags & 0xff)) == SVt_PVGV || ((svtype)((_gvgp)->sv_flags & 0xff)) == SVt_PVLV")
R13​: 0xf4bd40 ("S_glob_assign_glob")
R14​: 0x7ffff6ea9a07 --> 0x257325732500203a ('​: ')
R15​: 0xf89
EFLAGS​: 0x206 (carry PARITY adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
  0x7ffff6d8f15b <*__GI_raise+43>​: movsxd rdi,eax
  0x7ffff6d8f15e <*__GI_raise+46>​: mov eax,0xea
  0x7ffff6d8f163 <*__GI_raise+51>​: syscall
=> 0x7ffff6d8f165 <*__GI_raise+53>​: cmp rax,0xfffffffffffff000
  0x7ffff6d8f16b <*__GI_raise+59>​: ja 0x7ffff6d8f182 <*__GI_raise+82>
  0x7ffff6d8f16d <*__GI_raise+61>​: repz ret
  0x7ffff6d8f16f <*__GI_raise+63>​: nop
  0x7ffff6d8f170 <*__GI_raise+64>​: test eax,eax
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffde98 --> 0x7ffff6d923e0 (<*__GI_abort+384>​: mov rdx,QWORD PTR fs​:0x10)
0008| 0x7fffffffdea0 --> 0xeb3590 ("((svtype)((_gvgp)->sv_flags & 0xff)) == SVt_PVGV || ((svtype)((_gvgp)->sv_flags & 0xff)) == SVt_PVLV")
0016| 0x7fffffffdea8 --> 0x7ffff6eab9c1 --> 0x706c6568007325 ('%s')
0024| 0x7fffffffdeb0 --> 0x7fffffffded0 --> 0x3000000018
0032| 0x7fffffffdeb8 --> 0xf89
0040| 0x7fffffffdec0 --> 0x7fffffffdfc0 --> 0x7fffffffe63b --> 0x736574006c726570 ('perl')
0048| 0x7fffffffdec8 --> 0x7ffff6dc3fe6 (<__fxprintf+310>​: lea rsp,[rbp-0x20])
0056| 0x7fffffffded0 --> 0x3000000018
[------------------------------------------------------------------------------]
Legend​: code, data, rodata, value
Stopped reason​: SIGABRT
0x00007ffff6d8f165 in *__GI_raise (sig=<optimized out>) at ../nptl/sysdeps/unix/sysv/linux/raise.c​:64
64 ../nptl/sysdeps/unix/sysv/linux/raise.c​: No such file or directory.

Hexdump of 11-byte test case​:
0000000 3024 2a3d 3d78 7824 2a3d 0030
000000b

System Info​: Debian 7, Kernel 3.2.65-1+deb7u1 x86_64, GCC 4.9.2, libc 2.13-38+deb7u7

@p5pRT
Copy link
Author

p5pRT commented Mar 6, 2015

From @geeknik

test26-min

@p5pRT
Copy link
Author

p5pRT commented Mar 7, 2015

From @hvds

This is the same as [perl #123710], cascading asssignment to a scalar and its glob.

I'll merge them.

Hugo

@p5pRT
Copy link
Author

p5pRT commented Mar 7, 2015

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

@p5pRT
Copy link
Author

p5pRT commented Aug 26, 2015

From @dcollinsn

[perl #125840] was fixed in blead, however is only a symptom of this larger bug. To aid anyone attempting to resolve this, an odd testcase, in that it actually throws an assert fail on perls built with -DDEBUGGING.

Testcase​:
$0*=$=*=*==$$=0

Perl 5.10 exits with an error message​:
Modification of a read-only value attempted at -e line 1.

Blead segfaults with no output

A -DDEBUGGING blead throws the following assert fail​:
miniperl​: sv.c​:1792​: Perl_sv_setnv​: Assertion `PL_valid_types_NV_set[((svtype)((sv)->sv_flags & 0xff)) & 0xf]' failed.

@p5pRT
Copy link
Author

p5pRT commented Sep 1, 2015

From @iabyn

On Wed, Aug 26, 2015 at 01​:17​:04PM -0700, Dan Collins via RT wrote​:

[perl #125840] was fixed in blead, however is only a symptom of this larger bug. To aid anyone attempting to resolve this, an odd testcase, in that it actually throws an assert fail on perls built with -DDEBUGGING.

Testcase​:
$0*=$=*=*==$$=0

Perl 5.10 exits with an error message​:
Modification of a read-only value attempted at -e line 1.

Blead segfaults with no output

A -DDEBUGGING blead throws the following assert fail​:
miniperl​: sv.c​:1792​: Perl_sv_setnv​: Assertion `PL_valid_types_NV_set[((svtype)((sv)->sv_flags & 0xff)) & 0xf]' failed.

Presumably my bigger fix for [perl #125840], 3c62f09, which was
applied on Aug 30, fixes that too? Certainly I don't see the assertion.

--
You're only as old as you look.

@p5pRT
Copy link
Author

p5pRT commented Nov 25, 2015

From @tonycoz

On Tue Sep 01 07​:14​:27 2015, davem wrote​:

On Wed, Aug 26, 2015 at 01​:17​:04PM -0700, Dan Collins via RT wrote​:

[perl #125840] was fixed in blead, however is only a symptom of this
larger bug. To aid anyone attempting to resolve this, an odd
testcase, in that it actually throws an assert fail on perls built
with -DDEBUGGING.

Testcase​:
$0*=$=*=*==$$=0

Perl 5.10 exits with an error message​:
Modification of a read-only value attempted at -e line 1.

Blead segfaults with no output

A -DDEBUGGING blead throws the following assert fail​:
miniperl​: sv.c​:1792​: Perl_sv_setnv​: Assertion
`PL_valid_types_NV_set[((svtype)((sv)->sv_flags & 0xff)) & 0xf]'
failed.

Presumably my bigger fix for [perl #125840], 3c62f09, which
was
applied on Aug 30, fixes that too? Certainly I don't see the
assertion.

Yes, your fix also fixed this. Closing.

Tony

@p5pRT
Copy link
Author

p5pRT commented Nov 25, 2015

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

@p5pRT
Copy link
Author

p5pRT commented May 13, 2016

From @khwilliamson

Thank you for submitting this report. You have helped make Perl better.
 
With the release of Perl 5.24.0 on May 9, 2016, this and 149 other issues have been resolved.

Perl 5.24.0 may be downloaded via https://metacpan.org/release/RJBS/perl-5.24.0

@p5pRT
Copy link
Author

p5pRT commented May 13, 2016

@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