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 in Perl_sv_setpv_bufsize (sv.c:4956) #15740

Open
p5pRT opened this issue Nov 30, 2016 · 4 comments
Open

null ptr deref + segfault in Perl_sv_setpv_bufsize (sv.c:4956) #15740

p5pRT opened this issue Nov 30, 2016 · 4 comments

Comments

@p5pRT
Copy link

p5pRT commented Nov 30, 2016

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

Searchable as RT130224$

@p5pRT
Copy link
Author

p5pRT commented Nov 30, 2016

From @geeknik

Triggered while fuzzing Perl v5.25.7-26-g7332835.

./perl -e '$$.=$A=*$=0'
ASAN​:SIGSEGV

==8166==ERROR​: AddressSanitizer​: SEGV on unknown address 0x000000000000 (pc
0x0000009394e3 bp 0x0c4200002236 sp 0x7ffc09d74b20 T0)
  #0 0x9394e2 in Perl_sv_setpv_bufsize /root/perl/sv.c​:4956​:5
  #1 0x8a6ab0 in Perl_pp_concat /root/perl/pp_hot.c​:292​:13
  #2 0x7f63bb in Perl_runops_debug /root/perl/dump.c​:2260​:23
  #3 0x5a06c3 in S_run_body /root/perl/perl.c​:2526​:2
  #4 0x5a06c3 in perl_run /root/perl/perl.c​:2449
  #5 0x4de6cd in main /root/perl/perlmain.c​:123​:9
  #6 0x7f592806bb44 in __libc_start_main
/build/glibc-daoqzt/glibc-2.19/csu/libc-start.c​:287
  #7 0x4de33c in _start (/root/perl/perl+0x4de33c)

AddressSanitizer can not provide additional info.
SUMMARY​: AddressSanitizer​: SEGV /root/perl/sv.c​:4956 Perl_sv_setpv_bufsize
==8166==ABORTING

@p5pRT
Copy link
Author

p5pRT commented Jan 2, 2017

From @arc

Brian Carpenter <perlbug-followup@​perl.org> wrote​:

Triggered while fuzzing Perl v5.25.7-26-g7332835.

./perl -e '$$.=$A=*$=0'

This can be reduced to​: $x .= *x = 0

The segfault comes from the SvPVCLEAR() in this block of pp_concat()​:

  else { /* $l .= $r and left == TARG */
  if (!SvOK(left)) {
  if ((left == right /* $l .= $l */
  || (PL_op->op_private & OPpTARGET_MY)) /* $l = $l . $r */
  && ckWARN(WARN_UNINITIALIZED)
  )
  report_uninit(left);
  SvPVCLEAR(left);
  }
  else {
  SvPV_force_nomg_nolen(left);
  }
  lbyte = !DO_UTF8(left);
  if (IN_BYTES)
  SvUTF8_off(left);
  }

As far as I can tell, TARG has already been freed here (by the *x = 0)
assignment, but I'm afraid I'm a bit out of my depth on working out
how to fix that. Should this be marked as a stack-not-refcounted
issue?

--
Aaron Crane ** http​://aaroncrane.co.uk/

@p5pRT
Copy link
Author

p5pRT commented Jan 2, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Jan 3, 2017

From @iabyn

On Mon, Jan 02, 2017 at 07​:17​:59PM +0000, Aaron Crane wrote​:

Brian Carpenter <perlbug-followup@​perl.org> wrote​:

Triggered while fuzzing Perl v5.25.7-26-g7332835.

./perl -e '$$.=$A=*$=0'

This can be reduced to​: $x .= *x = 0

The segfault comes from the SvPVCLEAR() in this block of pp_concat()​:

else { /* $l .= $r and left == TARG */
if (!SvOK(left)) {
if ((left == right /* $l .= $l */
|| (PL_op->op_private & OPpTARGET_MY)) /* $l = $l . $r */
&& ckWARN(WARN_UNINITIALIZED)
)
report_uninit(left);
SvPVCLEAR(left);
}
else {
SvPV_force_nomg_nolen(left);
}
lbyte = !DO_UTF8(left);
if (IN_BYTES)
SvUTF8_off(left);
}

As far as I can tell, TARG has already been freed here (by the *x = 0)
assignment, but I'm afraid I'm a bit out of my depth on working out
how to fix that.

Should this be marked as a stack-not-refcounted issue?

Yes. If the stack were refcounted, $x wouldn't be freed by *x = 0.

--
Justice is when you get what you deserve.
Law is when you get what you pay for.

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

2 participants