commit 410a23e8a442e3de4f8df29339946a7d826120d0 Author: Joshua Pawlicki Date: Wed May 14 10:58:18 2025 -0700 [zip]: Allow zip64 files to have prepended content. This was already supported for non-zip64 files. Fixed: 414848094 Change-Id: I3bd79f4b5175d8abca8d8e81f26373037868dcf8 Cq-Include-Trybots: luci.chromium.try:ios-blink-dbg-fyi Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6533087 Commit-Queue: Joshua Pawlicki Auto-Submit: Joshua Pawlicki Reviewed-by: Hans Wennborg Cr-Commit-Position: refs/heads/main@{#1460236} commit 3daf10f4a4cd6dbfaaaef6a90091f7c6c3148a24 Author: Hans Wennborg Date: Fri May 16 15:35:36 2025 +0200 [minizip] Fix possible infinite loop in unz64local_SearchCentralDir64 This is a follow-up to crrev.com/1460236, where `uPosFound - 48` could overflow, resulting in a possible readSize of 3, which meant the loop did not make progress. Bug: 414848094 Change-Id: Icda653b2c9ac59161fb2aba9ac287fe510ee8653 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6554217 diff --git a/third_party/zlib/contrib/minizip/unzip.c b/third_party/zlib/contrib/minizip/unzip.c index a39e1752f6d2e..2c8a73e87e011 100644 --- a/third_party/zlib/contrib/minizip/unzip.c +++ b/third_party/zlib/contrib/minizip/unzip.c @@ -482,6 +482,44 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib if (uL != 1) return CENTRALDIRINVALID; + /* If bytes are pre-pended to the archive, relativeOffset must be advanced + by that many bytes. The central dir must exist between the specified + relativeOffset and uPosFound. */ + if (relativeOffset > uPosFound) + return CENTRALDIRINVALID; + const int BUFSIZE = 1024 * 4; + buf = (unsigned char*)ALLOC(BUFSIZE); + if (buf==NULL) + return CENTRALDIRINVALID; + // Zip64 EOCDR is at least 48 bytes long. + while (uPosFound - relativeOffset >= 48) { + int found = 0; + uLong uReadSize = uPosFound - relativeOffset; + if (uReadSize > BUFSIZE) { + uReadSize = BUFSIZE; + } + if (ZSEEK64(*pzlib_filefunc_def, filestream, relativeOffset, ZLIB_FILEFUNC_SEEK_SET) != 0) { + break; + } + if (ZREAD64(*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize) { + break; + } + for (int i = 0; i < uReadSize - 3; ++i) { + // Looking for 0x06064b50, the Zip64 EOCDR signature. + if (buf[i] == 0x50 && buf[i + 1] == 0x4b && + buf[i + 2] == 0x06 && buf[i + 3] == 0x06) + { + relativeOffset += i; + found = 1; + break; + } + } + if (found) { + break; + } + // Re-read the last 3 bytes, in case they're the front of the signature. + relativeOffset += uReadSize - 3; + } + free(buf); + /* Goto end of central directory record */ if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) return CENTRALDIRINVALID;