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

stack-overflow in __GI__IO_default_xsputn #16024

Open
p5pRT opened this issue Jun 18, 2017 · 5 comments
Open

stack-overflow in __GI__IO_default_xsputn #16024

p5pRT opened this issue Jun 18, 2017 · 5 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 18, 2017

Migrated from rt.perl.org#131596 (status was 'open')

Searchable as RT131596$

@p5pRT
Copy link
Author

p5pRT commented Jun 18, 2017

From @Mipu94

I have found a sample that triggered stack-overflow
in __GI__IO_default_xsputn.
Please find file attached bellow to check.

ASAN report​:

==16611==ERROR​: AddressSanitizer​: stack-overflow on address 0x7fffd9bd1eb8
(pc 0x0000004812b6 bp 0x7fffd9bd2730 sp 0x7fffd9bd1ec0 T0)
  #0 0x4812b5 (/home/mipu94/perlfuzz/perl-asan+0x4812b5)
.....
#244 0x532dff (/home/mipu94/perlfuzz/perl-asan+0x532dff)
  #245 0x57d799 (/home/mipu94/perlfuzz/perl-asan+0x57d799)
  #246 0x608b8f (/home/mipu94/perlfuzz/perl-asan+0x608b8f)
  #247 0x608506 (/home/mipu94/perlfuzz/perl-asan+0x608506)
  #248 0x5c8162 (/home/mipu94/perlfuzz/perl-asan+0x5c8162)
  #249 0x548d96 (/home/mipu94/perlfuzz/perl-asan+0x548d96)
  #250 0x545f69 (/home/mipu94/perlfuzz/perl-asan+0x545f69)

SUMMARY​: AddressSanitizer​: stack-overflow
(/home/mipu94/perlfuzz/perl-asan+0x4812b5)
==16611==ABORTING

This is perl 5, version 26, subversion 0 (v5.26.0) built for x86_64 debug
on gdb-peda​:

[----------------------------------registers-----------------------------------]
RAX​: 0x7ffff746e4a0 --> 0x0
RBX​: 0x7fffff7ff590 --> 0xfbad8001
RCX​: 0x8
RDX​: 0x8
RSI​: 0xc51cd7 ("_<(eval %lu)")
RDI​: 0x7fffff7ff590 --> 0xfbad8001
RBP​: 0x7fffff7ff580 --> 0x1f
RSP​: 0x7fffff7ff000 --> 0x0
RIP​: 0x7ffff712763b (<__GI__IO_default_xsputn+11>​: push r13)
R8 : 0x0
R9 : 0x7fffff7ff708 --> 0x3000000028 ('(')
R10​: 0x7ffff746fb98 --> 0x55be7f0 --> 0x0
R11​: 0x7ffff7241550 --> 0xfffcae20fffca79e
R12​: 0xc51cd7 ("_<(eval %lu)")
R13​: 0x7fffff7ff708 --> 0x3000000028 ('(')
R14​: 0x0
R15​: 0xc51cdf --> 0x6e61700029756c25 ('%lu)')
EFLAGS​: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction
overflow)
[-------------------------------------code-------------------------------------]
  0x7ffff7127630 <__GI__IO_default_xsputn>​: test rdx,rdx
  0x7ffff7127633 <__GI__IO_default_xsputn+3>​: je 0x7ffff71276f0
<__GI__IO_default_xsputn+192>
  0x7ffff7127639 <__GI__IO_default_xsputn+9>​: push r14
=> 0x7ffff712763b <__GI__IO_default_xsputn+11>​: push r13
  0x7ffff712763d <__GI__IO_default_xsputn+13>​: mov r14,rsi
  0x7ffff7127640 <__GI__IO_default_xsputn+16>​: push r12
  0x7ffff7127642 <__GI__IO_default_xsputn+18>​: push rbp
  0x7ffff7127643 <__GI__IO_default_xsputn+19>​: mov r12,rdi
[------------------------------------stack-------------------------------------]
0000| 0x7fffff7ff000 --> 0x0
0008| 0x7fffff7ff008 --> 0x7ffff70f9241 (<_IO_vfprintf_internal+209>​: mov
  rcx,QWORD PTR [rbp-0x4b0])
0016| 0x7fffff7ff010 --> 0x0
0024| 0x7fffff7ff018 --> 0x0
0032| 0x7fffff7ff020 --> 0x0
0040| 0x7fffff7ff028 --> 0x0
0048| 0x7fffff7ff030 --> 0x0
0056| 0x7fffff7ff038 --> 0x0
[------------------------------------------------------------------------------]
blue
Legend​: code, data, rodata, value
Stopped reason​: SIGSEGV
0x00007ffff712763b in __GI__IO_default_xsputn (f=0x7fffff7ff590,
data=0xc51cd7, n=0x8) at genops.c​:422
422 {

gdb-peda$ where
#0 0x00007ffff712763b in __GI__IO_default_xsputn (f=0x7fffff7ff590,
data=0xc51cd7, n=0x8) at genops.c​:422
#1 0x00007ffff70f9241 in _IO_vfprintf_internal (s=s@​entry=0x7fffff7ff590,
format=format@​entry=0xc51cd7 "_<(eval %lu)", ap=ap@​entry=0x7fffff7ff708) at
vfprintf.c​:1320
#2 0x00007ffff71c1ca6 in ___vsnprintf_chk (s=0x7fffff7ff830 "",
maxlen=<optimized out>, flags=0x1, slen=<optimized out>, format=0xc51cd7
"_<(eval %lu)", args=args@​entry=0x7fffff7ff708)
  at vsnprintf_chk.c​:63
#3 0x00007ffff71c1c08 in ___snprintf_chk (s=s@​entry=0x7fffff7ff830 "",
maxlen=maxlen@​entry=0x20, flags=flags@​entry=0x1, slen=slen@​entry=0x20,
format=format@​entry=0xc51cd7 "_<(eval %lu)")
  at snprintf_chk.c​:34
#4 0x000000000093d8e6 in snprintf (__fmt=0xc51cd7 "_<(eval %lu)",
__n=0x20, __s=0x7fffff7ff830 "") at
/usr/include/x86_64-linux-gnu/bits/stdio2.h​:64
#5 Perl_pp_entereval () at pp_ctl.c​:4347
#6 0x0000000000792f1b in Perl_runops_standard () at run.c​:41
#7 0x00000000004c60ee in Perl_call_sv (sv=sv@​entry=0x55a4de8,
flags=flags@​entry=0xd) at perl.c​:2848
#8 0x00000000004cdbf4 in Perl_call_list (oldscope=oldscope@​entry=0x59f4,
paramList=0x55a4d88) at perl.c​:5016
#9 0x000000000042b7fd in S_process_special_blocks (floor=floor@​entry=0x9a9bf,
fullname=fullname@​entry=0xeb71e0 "BEGIN", cv=cv@​entry=0x55a4de8,
gv=0xeabc78) at op.c​:9055
#10 0x00000000004a79a7 in Perl_newATTRSUB_x (floor=floor@​entry=0x9a9bf,
o=<optimized out>, proto=proto@​entry=0x0, attrs=attrs@​entry=0x0,
block=0x55bee98, block@​entry=0x55bef18,
  o_is_gv=o_is_gv@​entry=0x0) at op.c​:8983
........

--
Ta Dinh Sung,

@p5pRT
Copy link
Author

p5pRT commented Jun 18, 2017

From @Mipu94

bug1.pl

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2017

From @tonycoz

On Sun, 18 Jun 2017 05​:36​:26 -0700, tadinhsung@​gmail.com wrote​:

I have found a sample that triggered stack-overflow
in __GI__IO_default_xsputn.
Please find file attached bellow to check.

This is simple deep recursion and isn't a bug in perl.

The # on line 4 comments out of rest of the line, so the code becomes​:

#!/usr/bin/perl -w
use Test​::More tests => 1;

BEGIN { *CORE​::GLOBAL​::require = sub {

  {
  {
  sub zzz {}
  }
  ok(eval <<'EOS', "handle require overrides")
use base 'RequireOverride';
EOS
  }
  }
  }

This simplifies down to​:

use Test​::More tests => 1;
BEGIN { *CORE​::GLOBAL​::require = sub {
  eval <<'EOS';
use base 'RequireOverride';
EOS
  }
  }

Test2​::API creates an END block​:

END {
  test2_set_is_end(); # See gh #16
  $INST->set_exit();
}

The set_exit() method attempts to load a module at runtime (well, destruct time), which sees the CORE​::GLOBAL​::require override​:

  $new_exit = 255 if $new_exit > 255;

  if ($new_exit && eval { require Test2​::API​::Breakage; 1 }) {
  my @​warn = Test2​::API​::Breakage->report();

causing deep recursion and a stack overflow, so this can be further simplified to​:

#!/usr/bin/perl -w
BEGIN { *CORE​::GLOBAL​::require = sub {
  eval <<'EOS';
use base 'RequireOverride';
EOS
  }
  }
require Foo;

Tony

@p5pRT
Copy link
Author

p5pRT commented Jun 19, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Jun 21, 2017

From @iabyn

On Sun, Jun 18, 2017 at 05​:36​:27AM -0700, sung wrote​:

I have found a sample that triggered stack-overflow

#!/usr/bin/perl -w
use Test​::More tests => 1;

BEGIN { *CORE​::GLOBAL​::require = sub {#?equire $_[0] }; }

{
{
sub zzz {}
}
ok(eval <<'EOS', "handle require overrides")
use base 'RequireOverride';
EOS
}
}
}

This is fairly standard example of certain types of recursive perl code
triggering recursive C code calls and an eventual SEGV.

I don't see any particular security issues with it.

I'll move the ticket to the public queue and attach it to the relevant
meta-ticket​:

  #111358​: [META] C stack recursion

--
In economics, the exam questions are the same every year.
They just change the answers.

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