Bug 504386 (CVE-2009-1391) - CVE-2009-1391 Buffer overflow in Compress::Raw::Zlib
Summary: CVE-2009-1391 Buffer overflow in Compress::Raw::Zlib
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2009-1391
Product: Fedora
Classification: Fedora
Component: perl
Version: 10
Hardware: All
OS: Linux
low
urgent
Target Milestone: ---
Assignee: Marcela Mašláňová
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2009-06-05 23:14 UTC by Leo Bergolth
Modified: 2009-07-16 07:32 UTC (History)
2 users (show)

Fixed In Version: 5.10.0-69.fc11
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2009-06-11 08:42:09 UTC
Type: ---
Embargoed:
kevin: fedora-cvs+


Attachments (Terms of Use)
Test case that triggers the buffer overflow (82.00 KB, application/octet-stream)
2009-06-05 23:14 UTC, Leo Bergolth
no flags Details


Links
System ID Private Priority Status Summary Last Updated
Gentoo 273141 0 None None None Never

Description Leo Bergolth 2009-06-05 23:14:12 UTC
Created attachment 346729 [details]
Test case that triggers the buffer overflow

Description of problem:

Compress::Raw::Zlib versions before 2.017 contain a buffer overflow in inflate().
A badly formed zlib-stream can trigger this buffer overflow and cause the perl process at least to hang or to crash.

There is an e-mail virus in circulation that contains a zip file that causes such a memory corruption when being uncompressed using perl-applications that depend on Compress::Raw::Zlib. (E.g. spamassassin and amavisd-new.)
(See http://thread.gmane.org/gmane.mail.virus.amavis.user/33635.)


Version-Release number of selected component (if applicable):
perl-5.10.0-68.fc10.i386 for Fedora 10
perl-5.8.8-18.el5_3.1 for RHEL5


How reproducible:
Use the attached tarball that contains a testcase.


Steps to Reproduce:
1. tar -xzvf compress-raw-zlib-buffer-overflow.tar.gz
2. cd compress-raw-zlib-buffer-overflow
3. valgrind perl compress-raw-zlib.pl


Actual results:

[...]
inflating...
==6322== Invalid write of size 1
==6322==    at 0x46DB113: XS_Compress__Raw__Zlib__inflateStream_inflate (in /usr/lib/perl5/5.10.0/i386-linux-thread-multi/auto/Compress/Raw/Zlib/Zlib.so)                                                                 
==6322==    by 0x3E256F8: Perl_pp_entersub (in /usr/lib/perl5/5.10.0/i386-linux-thread-multi/CORE/libperl.so)
==6322==    by 0x3DE6F02: Perl_runops_debug (in /usr/lib/perl5/5.10.0/i386-linux-thread-multi/CORE/libperl.so)
==6322==    by 0x3E1FA88: perl_run (in /usr/lib/perl5/5.10.0/i386-linux-thread-multi/CORE/libperl.so)
==6322==    by 0x8048A2D: main (in /usr/bin/perl)
==6322==  Address 0x423f554 is 0 bytes after a block of size 32,780 alloc'd
==6322==    at 0x4006AEE: malloc (vg_replace_malloc.c:207)
==6322==    by 0x3DF1EC2: Perl_safesysmalloc (in /usr/lib/perl5/5.10.0/i386-linux-thread-multi/CORE/libperl.so)
==6322==    by 0x3E5187F: Perl_sv_grow (in /usr/lib/perl5/5.10.0/i386-linux-thread-multi/CORE/libperl.so)
==6322==    by 0x46DAF83: XS_Compress__Raw__Zlib__inflateStream_inflate (in /usr/lib/perl5/5.10.0/i386-linux-thread-multi/auto/Compress/Raw/Zlib/Zlib.so)
==6322==    by 0x3E256F8: Perl_pp_entersub (in /usr/lib/perl5/5.10.0/i386-linux-thread-multi/CORE/libperl.so)
==6322==    by 0x3DE6F02: Perl_runops_debug (in /usr/lib/perl5/5.10.0/i386-linux-thread-multi/CORE/libperl.so)
==6322==    by 0x3E1FA88: perl_run (in /usr/lib/perl5/5.10.0/i386-linux-thread-multi/CORE/libperl.so)
==6322==    by 0x8048A2D: main (in /usr/bin/perl)
done: status: stream end
[...]


Expected results:
No valgrind error.


Additional info:

Note that this bug also applies to F9 and RHEL5.

The following changes between 2.015 and 2.017 fix the problem. Note the "+ 1" on buffer allocation...

--- Compress-Raw-Zlib-2.015/Zlib.xs	2008-09-02 23:02:41.000000000 +0200
+++ Compress-Raw-Zlib-2.017/Zlib.xs	2009-03-26 10:40:57.000000000 +0100
@@ -1306,23 +1310,39 @@
     if((s->flags & FLAG_APPEND) != FLAG_APPEND) {
         SvCUR_set(output, 0);
     }
+   
+    /* Assume no output buffer - the code below will update if there is any available */
+    s->stream.avail_out = 0;
+
+
     if (SvLEN(output)) {
         prefix_length = cur_length =  SvCUR(output) ;
-        s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
-        increment = SvLEN(output) -  cur_length - 1;
-        s->stream.avail_out = increment;
-    }
-    else {
-        s->stream.avail_out = 0;
+    
+        if (s->flags & FLAG_LIMIT_OUTPUT && SvLEN(output) - cur_length - 1 < bufinc)
+        {
+            Sv_Grow(output, bufinc + cur_length + 1) ;
+        }
+    
+        /* Only setup the stream output pointers if there is spare 
+           capacity in the outout SV
+        */
+        if (SvLEN(output) > cur_length + 1)
+        {
+            s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length;
+            increment = SvLEN(output) -  cur_length - 1;
+            s->stream.avail_out = increment;
+        }
     }
+    
+
     s->bytesInflated = 0;
     
     RETVAL = Z_OK;
 
     while (RETVAL == Z_OK) {
-        if (s->stream.avail_out == 0 ) {
+        if (s->stream.avail_out == 0) {
 	    /* out of space in the output buffer so make it bigger */
-            Sv_Grow(output, SvLEN(output) + bufinc) ;
+            Sv_Grow(output, SvLEN(output) + bufinc +1) ;
             cur_length += increment ;
             s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ;
             increment = bufinc ;

Comment 1 Marcela Mašláňová 2009-06-08 10:43:42 UTC
Thank you for your investigation. In Fedora will be updated version of Compress::Raw::Zlib.

Comment 2 Marcela Mašláňová 2009-06-08 12:25:56 UTC
I suppose you have perl-Compress-Raw-Zlib from different source than RHEL or EPEL. I see it in EPEL-4 as a package and then as a part of perl-5.10 in Fedora.

Comment 3 Leo Bergolth 2009-06-08 13:14:13 UTC
OK, sorry, the package on my RHEL5 box is from rpmfusion.
So RHEL5 doesn't seem to provide perl-Compress-Raw-Zlib at all...

Comment 4 Marcela Mašláňová 2009-06-08 13:19:33 UTC
Updates will be done for F-10, F-11 and rawhide perl. For the EPEL will be updated EPEL-4 and 5 for package perl-Compress-Raw-Zlib.

Comment 5 Tomas Hoger 2009-06-08 13:32:26 UTC
Even though there seem to be a directory in CVS for the package in EPEL-4, it does not seem to be included in either EPEL-4 or EPEL-5 on download FTPs.  Module seems to be part of perl SRPM as of F-9.

Comment 6 Stepan Kasal 2009-06-08 13:52:14 UTC
Package Change Request
======================
Package Name: perl-Compress-Raw-Zlib
New Branches: EL-5
Owners: kasal mmaslano

Please branch from devel -D 2008-02-25 .
(Or from F-8 branch if that's easier.)

Comment 7 Tomas Hoger 2009-06-08 14:57:16 UTC
Just a sanity self-check - this should only be an issue when inflated output size is exactly the same size as the output buffer (initial size is -Bufsize or 4096 by default, doubles in size on each buffer grow).  This problem exists because Compress::Raw::Zlib's inflate NUL-terminates the output buffer (*SvEND(output) = '\0';), even it may not have enough space.  So this should be heap off-by-one, unless I'm missing something.  Do I have it right?

Comment 8 Leo Bergolth 2009-06-08 15:39:48 UTC
This corresponds to my interpretation of the source code.

Archive::Zip which is used by amavisd-new uses a default ChunkSize of 32768. That's why it hangs when processing the zip file contained in my test-case.

Comment 9 Tomas Hoger 2009-06-09 06:59:16 UTC
Ok, thanks for confirmation.  Leo, this bug will be made public sooner or later.  Can we keep your test cases public, or would you prefer if we restrict access to your attachment?  Can we share tests with other vendors?  Thanks!

Comment 10 Tomas Hoger 2009-06-09 15:50:59 UTC
Opening bug to add it to bodhi update requests.  Attachment marked as private for now.  Test case can be re-created by deflating input of Bufsize and re-inflating it again.

Comment 11 Leo Bergolth 2009-06-09 16:18:15 UTC
I don't mind if you make the attachment available to the public. (I couldn't figure out how to do it myself... :-))

Comment 12 Tomas Hoger 2009-06-09 16:37:35 UTC
Thanks, done.

Comment 13 Kevin Fenzi 2009-06-10 04:49:07 UTC
cvs done.

Comment 15 Stepan Kasal 2009-06-11 08:42:09 UTC
perl-Compress-Raw-Zlib-2.020-1 has been built for EPEL 4 and EPEL 5.

Comment 16 Fedora Update System 2009-06-16 01:28:54 UTC
perl-5.10.0-69.fc11 has been pushed to the Fedora 11 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 17 Fedora Update System 2009-07-08 08:23:48 UTC
perl-5.10.0-73.fc10 has been submitted as an update for Fedora 10.
http://admin.fedoraproject.org/updates/perl-5.10.0-73.fc10

Comment 18 Fedora Update System 2009-07-08 08:23:58 UTC
perl-5.10.0-73.fc9 has been submitted as an update for Fedora 9.
http://admin.fedoraproject.org/updates/perl-5.10.0-73.fc9

Comment 19 Fedora Update System 2009-07-08 08:24:08 UTC
perl-5.10.0-73.fc11 has been submitted as an update for Fedora 11.
http://admin.fedoraproject.org/updates/perl-5.10.0-73.fc11

Comment 20 Fedora Update System 2009-07-16 07:32:55 UTC
perl-5.10.0-73.fc10 has been pushed to the Fedora 10 stable repository.  If problems still persist, please make note of it in this bug report.


Note You need to log in before you can comment on or make changes to this bug.