Skip Menu |
Report information
Id: 129130
Status: resolved
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: brian.carpenter [at] gmail.com
Cc:
AdminCc:

Operating System: (no value)
PatchStatus: (no value)
Severity: (no value)
Type: (no value)
Perl Version: (no value)
Fixed In: (no value)



From: "Brian 'geeknik' Carpenter" <brian.carpenter [...] gmail.com>
Date: Mon, 29 Aug 2016 15:53:14 -0500
Subject: heap-buffer-overflow Perl_pp_chdir (pp_sys.c:3685)
To: perl5-security-report [...] perl.org
Download (untitled) / with headers
text/plain 2.3k
Found with AFL and Perl v5.25.4-20-gc2f7c0b*. I've attached the non-minimized script because afl-tmin minimizes the crash away (again).

==26581==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x619000009a80 at pc 0x000000ae54f7 bp 0x7ffc33c56be0 sp 0x7ffc33c56bd8
WRITE of size 8 at 0x619000009a80 thread T0
    #0 0xae54f6 in Perl_pp_chdir /root/perl/pp_sys.c:3685:9
    #1 0x7f1c63 in Perl_runops_debug /root/perl/dump.c:2234:23
    #2 0x5a10a6 in S_run_body /root/perl/perl.c:2525:2
    #3 0x5a10a6 in perl_run /root/perl/perl.c:2448
    #4 0x4de6cd in main /root/perl/perlmain.c:123:9
    #5 0x7f32be284b44 in __libc_start_main /build/glibc-uPj9cH/glibc-2.19/csu/libc-start.c:287
    #6 0x4de33c in _start (/root/perl/perl+0x4de33c)

0x619000009a80 is located 0 bytes to the right of 1024-byte region [0x619000009680,0x619000009a80)
allocated by thread T0 here:
    #0 0x4c0cbb in malloc (/root/perl/perl+0x4c0cbb)
    #1 0x7f5aa7 in Perl_safesysmalloc /root/perl/util.c:153:21

SUMMARY: AddressSanitizer: heap-buffer-overflow /root/perl/pp_sys.c:3685 Perl_pp_chdir
Shadow bytes around the buggy address:
  0x0c327fff9300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff9310: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff9320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff9330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff9340: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c327fff9350:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c327fff9360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c327fff9370: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff9380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff9390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c327fff93a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  ASan internal:           fe
==26581==ABORTING
Download crash330.gz
application/x-gzip 1k

Message body not shown because it is not plain text.

RT-Send-CC: rt-deliver-to-perl5-security-report [...] rt.perl.org
Download (untitled) / with headers
text/plain 1.1k
On Mon Aug 29 13:54:26 2016, brian.carpenter@gmail.com wrote: Show quoted text
> Found with AFL and Perl v5.25.4-20-gc2f7c0b*. I've attached the > non-minimized script because afl-tmin minimizes the crash away (again).
chdir() isn't allocating stack for its result when called with no argument. Most other ops default to $_ and are compiled that way, for example: tony@mars:.../git/perl$ ./perl -Ilib -MO=Concise -e sin 5 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 4 <1> sin[t2] vK/1 ->5 - <1> ex-rv2sv sK/1 ->4 3 <$> gvsv(*_) s ->4 chdir() doesn't get that faked argument: tony@mars:.../git/perl$ ./perl -Ilib -MO=Concise -e chdir 4 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter ->2 2 <;> nextstate(main 1 -e:1) v:{ ->3 3 <0> chdir[t1] v ->4 since chdir() with no argument has it's own special behaviour. A simpler reproducer: for $x (map $_+1, 1 .. 100) { map chdir, 1 .. $x; } Fix attached. I don't think this would be exploitable beyond a denial of service if it crashes perl - it only writes one pointersize beyond the end of the allocated block, and is always the address of a new SV (should this use PL_sv_yes and PL_sv_no?) Tony
Subject: 0001-perl-129130-make-chdir-allocate-the-stack-it-needs.patch
From d6151b2a56d80af849778fda3364f392ea9032b1 Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Mon, 5 Sep 2016 15:40:11 +1000 Subject: (perl #129130) make chdir allocate the stack it needs chdir with no argument didn't ensure there was stack space available for its result. --- pp_sys.c | 1 + t/op/chdir.t | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pp_sys.c b/pp_sys.c index a198d4e..7d74ea6 100644 --- a/pp_sys.c +++ b/pp_sys.c @@ -3639,6 +3639,7 @@ PP(pp_chdir) HV * const table = GvHVn(PL_envgv); SV **svp; + EXTEND(SP, 1); if ( (svp = hv_fetchs(table, "HOME", FALSE)) || (svp = hv_fetchs(table, "LOGDIR", FALSE)) #ifdef VMS diff --git a/t/op/chdir.t b/t/op/chdir.t index 9967707..38cbbe9 100644 --- a/t/op/chdir.t +++ b/t/op/chdir.t @@ -12,7 +12,7 @@ BEGIN { set_up_inc(qw(t . lib ../lib)); } -plan(tests => 47); +plan(tests => 48); use Config; use Errno qw(ENOENT EBADF EINVAL); @@ -162,6 +162,12 @@ sub check_env { } } +fresh_perl_is(<<'EOP', '', { stderr => 1 }, "check stack handling"); +for $x (map $_+1, 1 .. 100) { + map chdir, 1 .. $x; +} +EOP + my %Saved_Env = (); sub clean_env { foreach my $env (@magic_envs) { -- 2.1.4
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 391b
On Sun Sep 04 22:50:16 2016, tonyc wrote: Show quoted text
> Fix attached.
Applied as 92c843fb4b4e1a1e0ac7ec0fe198dc77266838da. Show quoted text
> > I don't think this would be exploitable beyond a denial of service if it > crashes perl - it only writes one pointersize beyond the end of the > allocated block, and is always the address of a new SV (should this use > PL_sv_yes and PL_sv_no?)
And made this public. Tony
Subject: Re: [perl #129130] heap-buffer-overflow Perl_pp_chdir (pp_sys.c:3685)
From: Zefram <zefram [...] fysh.org>
Date: Wed, 6 Dec 2017 22:26:51 +0000
To: perl5-porters [...] perl.org
This bug was fixed by Tony's patch. This ticket should be closed. -zefram


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org