An integer overflow flaw, leading to a heap-based buffer overflow, was found in the way libzip, which is embedded in PHP, processed certain ZIP archives. If an attacker were able to supply a specially crafted ZIP archive to an application using libzip, it could cause the application to crash or, possibly, execute arbitrary code.
According to http://seclists.org/oss-sec/2015/q1/885 , libzip upstream has been notified of this issue.
Created libzip tracking bugs for this issue:
Affects: fedora-all [bug 1204677]
Created mingw-libzip tracking bugs for this issue:
Affects: fedora-all [bug 1204678]
libzip upstream commit:
mingw-libzip-0.11.2-3.fc22 has been pushed to the Fedora 22 stable repository. If problems still persist, please make note of it in this bug report.
mingw-libzip-0.11.2-3.fc21 has been pushed to the Fedora 21 stable repository. If problems still persist, please make note of it in this bug report.
mingw-libzip-0.11.2-3.fc20 has been pushed to the Fedora 20 stable repository. If problems still persist, please make note of it in this bug report.
While the patch that was applied to libzip (either upstream or bundled with PHP, see comment 4 and comment 0 respectively) is applicable to libzip versions prior to 0.11, it is only required in 0.11 and later. The 0.11 version introduced Zip64 support and made it possible to call the affected _zip_cdir_new() with large enough nentry argument to trigger overflow.
In versions before 0.11, the _zip_cdir_new() function was called from _zip_readcdir() function when reading Zip files. The nentry value is directly read from an input file as short / 2 byte value. Hence the maximum possible nentry value is 0xffff / 65535. This is insufficient to trigger integer overflow when multiplied by sizeof(struct zip_dirent).
The following libzip upstream commit adds support for reading Zip64 central directory.
In this format, number of entries in the directory is stored as 64 bit value, rather than 16 bit used in the original Zip format. There are now two code paths to call _zip_cdir_new() when reading Zip file - _zip_read_eocd() handling old central directory format and _zip_read_eocd64() handling Zip64 central directory. In the latter case, nentry value is 64 bit and hence can trigger integer overflow in _zip_cdir_new().
Note that only this upstream commit changed nentry type in _zip_cdir_new() from int to zip_uint64_t, so it seems integer overflow was only possible on 32 bit systems for versions between this and the above commit.
Note that there is similar problem in the _zip_cdir_grow() function, which was introduced via the following commit:
According to the NEWS file, it first appeared in version 0.9.1. It seems this change can make it possible for a malicious Zip file to cause nentry to be incremented to value that triggers integer overflow (only on 32 bit systems, as nentry continues to be int). However, as nentry is only incremented slowly (by 0xffff, which means less than 4mb increase on each re-allocation), it's not really possible to trigger this without causing memory allocation failure earlier. Note that upstream commit linked in comment 4 does not correct the _zip_cdir_grow() function, but that function is no longer called in current 0.11.2 version.
The libzip packages in Red Hat Enterprise Linux 6 and 7 are based on upstream versions 0.9 and 0.10.1, and hence are not affected by this issue.
The PHP packages in Red Hat products embed the following libzip versions:
- PHP 5.3.3 (in Red Hat Enterprise Linux 5 and 6) - libzip 0.9.3
- PHP 5.4 and 5.5 (in Red Hat Enterprise Linux 7 and Red Hat Software Collections) - libzip 0.10.1
- PHP 5.6 - libzip 0.11.2
Therefore no PHP packages in Red Hat products were affected. Neither upstream PHP 5.4 and 5.5 needed this handled as a security fix.
This issue did not affect the versions of PHP as shipped with Red Hat Enterprise Linux 5, 6 and 7, and the versions of libzip as shipped with Red Hat Enterprise Linux 6 and 7.
libzip-0.11.2-5.fc22 has been pushed to the Fedora 22 stable repository. If problems still persist, please make note of it in this bug report.
libzip-0.11.2-5.fc20 has been pushed to the Fedora 20 stable repository. If problems still persist, please make note of it in this bug report.
libzip-0.11.2-5.fc21 has been pushed to the Fedora 21 stable repository. If problems still persist, please make note of it in this bug report.
(In reply to Tomas Hoger from comment #20)
> Note that upstream commit linked in comment 4 does not correct the
> _zip_cdir_grow() function, but that function is no longer called in
> current 0.11.2 version.
Unused _zip_cdir_grow() was now removed upstream:
Additional related commits, which add checks to memory allocation where overflows are not practically possible because of slow increase in memory usage (similar to what's described for _zip_cdir_grow() in comment 20) or called after zip_open(), and hence constrained by zip_open() / _zip_cdir_new() limits or checks.