Bug 1358395 (CVE-2016-5399) - CVE-2016-5399 php: Improper error handling in bzread()
Summary: CVE-2016-5399 php: Improper error handling in bzread()
Keywords:
Status: CLOSED ERRATA
Alias: CVE-2016-5399
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Red Hat Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 1358401 1358402 1358403 1358404 1363588 1525805 1525806
Blocks: 1323912 1352627
TreeView+ depends on / blocked
 
Reported: 2016-07-20 15:25 UTC by Adam Mariš
Modified: 2021-02-17 03:33 UTC (History)
22 users (show)

Fixed In Version:
Doc Type: If docs needed, set a value
Doc Text:
A flaw was found in the way certain error conditions were handled by bzread() function in PHP. An attacker could use this flaw to upload a specially crafted bz2 archive which, when parsed via the vulnerable function, could cause the application to crash or execute arbitrary code with the permissions of the user running the PHP application.
Clone Of:
Environment:
Last Closed: 2016-11-15 15:10:00 UTC
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHSA-2016:2598 0 normal SHIPPED_LIVE Moderate: php security and bug fix update 2016-11-03 12:12:00 UTC
Red Hat Product Errata RHSA-2016:2750 0 normal SHIPPED_LIVE Moderate: rh-php56 security, bug fix, and enhancement update 2016-11-15 16:40:02 UTC

Description Adam Mariš 2016-07-20 15:25:42 UTC
Wrong error handling in bzread() function that possibly leads to code execution was reported.

PHP bug:

https://bugs.php.net/bug.php?id=72613

Comment 1 Adam Mariš 2016-07-20 15:25:59 UTC
Acknowledgments:

Name: Hans Jerry Illikainen

Comment 2 Adam Mariš 2016-07-20 15:35:10 UTC
Created bzip2 tracking bugs for this issue:

Affects: fedora-all [bug 1358401]

Comment 3 Adam Mariš 2016-07-20 15:35:21 UTC
Created php tracking bugs for this issue:

Affects: fedora-all [bug 1358404]

Comment 4 Adam Mariš 2016-07-20 15:35:30 UTC
Created mingw-bzip2 tracking bugs for this issue:

Affects: fedora-all [bug 1358402]
Affects: epel-7 [bug 1358403]

Comment 5 Andrej Nemec 2016-07-21 08:17:39 UTC
References:

http://seclists.org/bugtraq/2016/Jul/96

Comment 6 Huzaifa S. Sidhpurwala 2016-08-02 10:05:16 UTC
I dont think this is a flaw with bzip2, the documentation (http://www.bzip.org/1.0.5/bzip2-manual-1.0.5.html#bzread) clearly states the following:

"BZ2_bzRead will supply len bytes, unless the logical stream end is detected or an error occurs. Because of this, it is possible to detect the stream end by observing when the number of bytes returned is less than the number requested. Nevertheless, this is regarded as inadvisable; you should instead check bzerror after every call and watch out for BZ_STREAM_END."

php_bz2iop_read does not do this, rather it exits only when the return from BZ2_bzRead < 1, which seems to be not what the bzip API states.

Comment 7 Huzaifa S. Sidhpurwala 2016-08-02 10:19:33 UTC
Upstream patch:

http://git.php.net/?p=php-src.git;a=commit;h=f3feddb5b45b5abd93abb1a95044b7e099d51c84

Also notice https://secure.php.net/manual/en/function.bzread.php (comment #2) gives a work around to this, ie check output of bzerrno() after every bzread invocation, and quit if its non-zero.

Comment 8 Remi Collet 2016-08-02 10:49:39 UTC
At first read it seems "return 0;" in case of error (read < 0) could be better, but this is handled in stream wrapper (justread && justread != (size_t)-1).

Unbuffered:
https://github.com/php/php-src/blob/master/ext/zlib/zlib_fopen_wrapper.c#L47

Buffered: 
https://github.com/php/php-src/blob/master/main/streams/streams.c#L580

Comment 9 Remi Collet 2016-08-02 11:00:39 UTC
Bad links, I mean for unbuffered: https://github.com/php/php-src/blob/master/main/streams/streams.c#L716

Comment 10 Huzaifa S. Sidhpurwala 2016-08-03 06:27:48 UTC
Exploitation Notes:
==================

When an attacker uploads a specially-crafted .bz2 archive to a php application, which attempts to extract files from the uploaded archive, it could result in arbitrary code execution.

This is because when the bz2 library reports a decompression error code, back to PHP, it does not stop the reading process, which can result in further calls to the decompression code of bz2, this may cause OOB writes which may under certain circumstances result in code execution.

However the above can easily be mitigated, by making sure that the PHP code calls bzerrno() after every call to bzread() something like:

$fh = bzopen('file.bz2','r');
while(!feof($fh)) {
  $buffer = bzread($fh);
  if($buffer === FALSE) die('Read problem');
  if(bzerrno($fh) !== 0) die('Compression Problem');
}
bzclose($fh);

Reference:
https://secure.php.net/manual/en/function.bzread.php

Comment 12 errata-xmlrpc 2016-11-03 21:05:59 UTC
This issue has been addressed in the following products:

  Red Hat Enterprise Linux 7

Via RHSA-2016:2598 https://rhn.redhat.com/errata/RHSA-2016-2598.html

Comment 14 errata-xmlrpc 2016-11-15 11:42:48 UTC
This issue has been addressed in the following products:

  Red Hat Software Collections for Red Hat Enterprise Linux 6
  Red Hat Software Collections for Red Hat Enterprise Linux 6.7 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 7
  Red Hat Software Collections for Red Hat Enterprise Linux 7.2 EUS
  Red Hat Software Collections for Red Hat Enterprise Linux 7.3 EUS

Via RHSA-2016:2750 https://rhn.redhat.com/errata/RHSA-2016-2750.html


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