madler / unzip

Fork of InfoZIP UnZip 6.0 for new zip bomb detection patch
Other
33 stars 16 forks source link

Reset G.zip64 for empty extra filed #6

Closed janchochol closed 3 years ago

janchochol commented 4 years ago

When zip file contains a file with central directory header without an extra filed (and thus the data descriptor is not in ZIP64 format), G.zip64 flag is not reset.

It can cause problems for zip files with mix of files larger and smaller than 4GB, created by compressors, which add extra fields only for files larger than 4GB (like Java).

This change resets G.zip64 (by calling getZip64Data with empty buffer) in case of an empty extra field in central directory header.

Following sequence of commands reproduces the problem:

dd if=/dev/zero of=file_larger_than_4g bs=1024 count=4194305
dd if=/dev/zero of=file_smaller_than_4g bs=1024 count=1

cat > TestZip.java <<EOF
import java.util.zip.ZipOutputStream;
import java.util.zip.ZipEntry;
import java.io.FileInputStream;
import java.io.FileOutputStream;

class TestZip {
    private static void addFileToZip(ZipOutputStream zos, String name) throws Exception {
        byte[] buffer = new byte[2048];

        FileInputStream fis = new FileInputStream(name);
        zos.putNextEntry(new ZipEntry(name));
        int length;
        while ((length = fis.read(buffer)) > 0) {
            zos.write(buffer, 0, length);
        }
    }

    public static void main(String args[]) throws Exception {
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream("test_zip.zip"));
        addFileToZip(zos, "file_larger_than_4g");
        addFileToZip(zos, "file_smaller_than_4g");
        zos.close();
    }
}
EOF

javac TestZip.java
java TestZip

./unzip -t test_zip.zip file_smaller_than_4g

Without the fix:

[nix-shell:~/src/unzip]$ ./unzip -t test_zip.zip file_smaller_than_4g
Archive:  test_zip.zip
    testing: file_smaller_than_4g     OK
error: invalid zip file with overlapped components (possible zip bomb)

After the fix:

[nix-shell:~/src/unzip]$ ./unzip -t test_zip.zip file_smaller_than_4g
Archive:  test_zip.zip
    testing: file_smaller_than_4g     OK
No errors detected in test_zip.zip for the 1 file tested.
madler commented 3 years ago

Thank you for the excellent report with how to generate a zip file that manifests the issue. This is fixed in https://github.com/madler/unzip/commit/122050bac16fae82a460ff739fb1ca0f106e9d85 . (Your patch would not fix the issue in general.)

janchochol commented 3 years ago

Thanks for fix - your commit definitely makes more sense.