[PRE-SA-2012-01] Denial-of-service vulnerability in java.util.zip

From: Timo Warns <warns@pre-sense.de>
To: bugtraq@securityfocus.com,full-disclosure@lists.grok.org.uk
Subject: [PRE-SA-2012-01] Denial-of-service vulnerability in java.util.zip

PRE-CERT Security Advisory

* Advisory: PRE-SA-2012-01
* Released on: 16th February 2012
* Affected products: Oracle Java SE 7 below Update 3
                     Oracle Java SE 6 below Update 31
                     IcedTea6 1.8.x below 1.8.13
                     IcedTea6 1.9.x below 1.9.13
                     IcedTea6 1.10.x below 1.10.6
                     IcedTea6 1.11.x below 1.11.1
                     IcedTea 2.x below 2.0.1
                     Older versions may also be affected.
* Impact: denial-of-service
* Origin: java.util.zip
* Credit: Timo Warns (PRESENSE Technologies GmbH)
* CVE Identifier: CVE-2012-0501


The function countCENHeaders() in zip_util.c of the java.util.zip
implementation contains an off-by-one bug. The bug can be exploited via
corrupted ZIP files to cause an endless recursion. The endless recursion
results in a segmentation fault of the JVM.

The following assessment is based on the JDK sources available from
Oracle's website (jdk-6u23-fcs-src-b05-jrl-12_nov_2010.jar).

readCEN() in zip_util.c is used by java.util.zip to read the central
directory of ZIP files.

It reads the total number of entries from the ZIP file via the
ENDTOT field:

    (543) total = (knownTotal != -1) ? knownTotal : ENDTOT(endbuf);

A corrupted ZIP file may have set the total number of entries to 0.
Alternatively, knownTotal may have been passed as a parameter with
value 0.

readCEN() iterates over all directory entries

    (552) for (i = 0, cp = cenbuf; cp <= cenend - CENHDR; i++, cp +=
CENSIZE(cp)) {

and recognizes an incorrect total field

    (557) if (i >= total) {

In this case, readCEN() counts the total number of fields via
countCENHeaders() before calling itself recursively

    (561) cenpos = readCEN(zip, countCENHeaders(cenbuf, cenend));

However, countCENHeaders() has an off-by-one bug. It fails to count
an entry that is precisely CENHDR bytes long

    (431) for (i = 0; i + CENHDR < end - beg; i += CENSIZE(beg + i))

and returns 0 in this case.

Hence, readCEN() is called recursively with knownTotal = 0 resulting
in an endless recursion.


The issue was fixed in the following versions:
    Oracle Java SE 7 Update 3
    Oracle Java SE 6 Update 31
    IcedTea6 1.8.13
    IcedTea6 1.9.13
    IcedTea6 1.10.6
    IcedTea6 1.11.1
    IcedTea 2.0.1
    IcedTea 2.1



When further information becomes available, this advisory will be
updated. The most recent version of this advisory is available at:



PRE-CERT can be reached under precert@pre-secure.de. For PGP key
information, refer to http://www.pre-cert.de/.

Copyright © 1995-2020 LinuxRocket.net. All rights reserved.