Perl 5 Memory Corruption Vulnerability

2012-10-27T00:00:00
ID 1337DAY-ID-19634
Type zdt
Reporter Tim Brown
Modified 2012-10-27T00:00:00

Description

The Perl 5 interpreter is vulnerable to a memory corruption vulnerability which results in memory disclosure and potentially arbitrary code execution when large values are supplied to the x operator.

                                        
                                            Author: Tim Brown <mailto:[email protected]>
URL: <http://www.nth-dimension.org.uk/> / <http://www.machine.org.uk/>
Product: Perl 5 prior to 5.15.5 <http://dev.perl.org/perl5/>
Vendor: Perl <http://www.perl.org/>
Risk: Medium

Summary

The Perl 5 interpreter is vulnerable to a memory corruption
vulnerability which results in memory disclosure and potentially
arbitrary code execution when large values are supplied to the
x operator.

After discussions with the vendor, CVE-2012-5195 was assigned to this 
vulnerability.

Solutions

Nth Dimension recommends that the vendor supplied patches should be
applied.  These are:

* b675304e3fdbcce3ef853b06b6ebe870d99faa7e

Technical Details

Whilst working on a fuzzer for entirely different application, it
was identifed that Perl 5 could be made to crash by supplying large
values to the x operator as follows:

(gdb) run -e 'print "A"x4294967296'
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /usr/bin/perl -e 'print "A"x4294967296'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff70b650f in __memset_sse2 () at 
../sysdeps/x86_64/multiarch/../memset.S:64
64      ../sysdeps/x86_64/multiarch/../memset.S: No such file or directory.
(gdb) bt
#0  0x00007ffff70b650f in __memset_sse2 () at 
../sysdeps/x86_64/multiarch/../memset.S:64
#1  0x00007ffff7b3396e in Perl_pp_repeat () from /usr/lib/libperl.so.5.14
#2  0x00007ffff7b0c996 in Perl_runops_standard () from /usr/lib/libperl.so.5.14
#3  0x00007ffff7aae5a5 in perl_run () from /usr/lib/libperl.so.5.14
#4  0x0000000000400f89 in main ()
(gdb) x/1i $pc
=> 0x7ffff70b650f <__memset_sse2+63>:   add    %cl,0xf(%rdx)
(gdb) i r cl rdx
cl             0xf3     -13
rdx            0x4141414141414141       4702111234474983745

Further more by reducing the value supplied to the x operator by
one, perl could be made to disclosue memory.

(gdb) run -e 'print "B"x4294967295'
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /usr/bin/perl -e 'print "B"x4294967295'
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Bbl<hangs here>

The initial analysis shows that the issues appeared to exist on
both i386 and x86_64 architectures although the certain aspects
(such as the values required to trigger the crashes as well as
the resultant stack traces) were different between the two
architectures.

For reference, the full test results were as follows:

| Arch   | RAM     | Value      | Result
| x86_64 | 8Gb RAM | 4294967296 | Segmentation fault in __memset_sse2
| x86_64 | 8Gb RAM | 4294967295 | Memory disclosure & hang
| i386   | 2Gb RAM | 4294967296 | Perl error: Out of memory during
|        |         |            | string extend at -e line 1.
| i386   | 2Gb RAM | 4294967295 | Segmentation fault

Both systems were running Debian GNU/Linux unstable.

Having reported this to the Perl security team, further analysis
was performed which yielded the following conclusions:

In the case where the string to be repeated is a single character
and where the value supplied to the x operator is greater than 2Gb,
the value is first truncated and then sign-extended causing the loop
intended to populate the buffer to write to out-of-bounds locations
which will likely result in a crash but could potentially lead to
arbitrary code execution.  This is because versions of glibc's
memset() function prior to 2.16 did not check for a negative count
and could therefore access a negative offset.

Current

As of the 25th October 2012, the state of the vulnerabilities
is believed to be as follows.  Patches have been applied to
5.12 and 5.14 which resolve this issue.  Nth Dimension believe
that new packages have been release by both Red Hat and Debian
which incorporate these patches.

History

Nth Dimension contacted the Perl security team on 18th September
2012 to report the vulnerability and David Mitchell responded the
same day requesting further details of the architectures on which
testing had been performed.  Leon Timmermans also responded to
confirm that he could reproduce the reported issue but queried
whether it was security relevant since in his view simply being
able to request such memory allocations was a security flaw in
it's own right.

Further discussions took a similar course until on the 20th, David
Mitchell sent an update noting that he had reread Nth Dimension's
initial email and now believed (based on the provided stack traces)
that either "the stack's got corrupted (or gdb's got confused)".  He
also asked for further information about the Debian systems on which
testing had been performed, notably what libc was installed.  This
yielded a further thread about libc versions since the behaviour
was not consistant across the entire Perl security teams own test
systems.

On 21st September, Andy Dougherty provided a provisional patch
which he believed resolved the reported issue along with a more
complete trace from gdb in which he had stepped through the
affected code at the instruction level.  Nth Dimension responded on
the 26th to agree with Andy that we were observing similar
behaviour.

It should be noted that between 19th and 21st there was a
secondary thread reevaluating whether such memory allocations
was a security flaw in it's own right.  Nth Dimension pointed
to http://archives.neohapsis.com/archives/bugtraq/2003-04/0028.html
as a language level precedence and on 20th, Dave Mitchell noted
that he did not believe that there was consesus regarding "given
low risk and low severity" stating "I thought I understood what
was happening, but some of the data shown by the OP is
challenging my assumptions - like possible stack corruption, and
the fact that print is outputting garbage rather than just
segfaulting.  Until I understand more clearly what is happening,
I don't want to pass a verdict either way."

Meanwhile on the 24th, David Mitchell confirmed that the stack
trace provided by Andy was enough for him to be sure that there
was an issue to resolve.  At this point the discussion turned
to how to handle the resolution and David stated he was satisfied
that Andy's patch would resolve the issue.

Nth Dimension re-contacted the Perl security team on 5th October
and were informed by Ricardo Signes that the patch had been
accepted and was making it's way into the various Perl 5 maint
branches and that various vendors had been notified.  Ricardo
further confirmed on the 25th that the patch had been applied to
5.12 and 5.14.  It is worth noting that in this intervening
period, the Perl security team had CVE-2012-5195 assigned and
had been working with the vendors, particularly Red Hat and
Debian to get new packages containing the required patches
released.

Thanks

Nth Dimension would like to thank David Mitchell, Leon Timmermans,
David Golden, Andy Dougherty, Ricardo Signes and Nicholas Clark
of the Perl security team for the way they worked to resolve the
issue.

#  0day.today [2018-02-19]  #