Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.91k stars 542 forks source link

Segmentation fault in Perl_sv_setpvn() #14460

Closed p5pRT closed 8 years ago

p5pRT commented 9 years ago

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

Searchable as RT123710$

p5pRT commented 9 years ago

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=\) 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 \

\, argc=3\, argv=0x7fffffffe488\,   init=\\, fini=\\, rtld_fini=\\, 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 commented 9 years ago

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 commented 9 years ago

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

p5pRT commented 9 years ago

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 commented 9 years ago

From @hvds

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

p5pRT commented 9 years ago

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=\) 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 commented 9 years ago

From @geeknik

test26-min

p5pRT commented 9 years ago

From @hvds

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

I'll merge them.

Hugo

p5pRT commented 9 years ago

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

p5pRT commented 9 years ago

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 commented 9 years ago

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]\, 3c62f09f418b63bd\, 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 commented 8 years ago

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]\, 3c62f09f418b63bd\, 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 commented 8 years ago

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

p5pRT commented 8 years ago

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 commented 8 years ago

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