From 2be019f8f8a1ecf6f8575233f1c918f76bc31997 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 2 May 2020 03:38:57 +0200 Subject: [PATCH] Fix integer overflow when reading ZIP central directory Our code didn't convert 32-bit offset to (possibly 64-bit) m_Offset correctly in the first place, and didn't check if the offset remained valid after adjustment. Fix both problems by using explicit cast and checking for the latter explicitly. Credit to OSS-Fuzz: this solves its issue 20527. --- src/common/zipstrm.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/common/zipstrm.cpp b/src/common/zipstrm.cpp index ff39cba742..93072fa40a 100644 --- a/src/common/zipstrm.cpp +++ b/src/common/zipstrm.cpp @@ -1852,8 +1852,20 @@ wxStreamError wxZipInputStream::ReadCentral() m_position += size; m_signature = ReadSignature(); - if (m_offsetAdjustment) - m_entry.SetOffset(m_entry.GetOffset() + m_offsetAdjustment); + if (m_offsetAdjustment) { + // Offset read from the stream is 4 bytes independently of the + // platform, but it's not clear if it can become greater than max + // 32-bit value after adjustment. For now consider that it can't. + wxFileOffset ofs = wxUint32(m_entry.GetOffset()); + ofs += m_offsetAdjustment; + if (ofs > wxUINT32_MAX) { + m_signature = 0; + return wxSTREAM_READ_ERROR; + } + + m_entry.SetOffset(ofs); + } + m_entry.SetKey(m_entry.GetOffset()); return wxSTREAM_NO_ERROR;