From 1ac661515e3e86e46d1bf2086755ca1766f4ed4b Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Sat, 27 Mar 2021 21:32:15 +0300 Subject: [PATCH] LibArchive: Bounds check header offsets in Zip Parser Since the central directory offset in the end of central directory record and the local file offset in each central directory header are user-controlled arbitary data, we have to bounds check them before using them. --- Userland/Libraries/LibArchive/Zip.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Userland/Libraries/LibArchive/Zip.cpp b/Userland/Libraries/LibArchive/Zip.cpp index 69a70169f5a..72724053a24 100644 --- a/Userland/Libraries/LibArchive/Zip.cpp +++ b/Userland/Libraries/LibArchive/Zip.cpp @@ -60,6 +60,8 @@ Optional Zip::try_create(const ReadonlyBytes& buffer) size_t member_offset = end_of_central_directory.central_directory_offset; for (size_t i = 0; i < end_of_central_directory.total_records_count; i++) { CentralDirectoryRecord central_directory_record {}; + if (member_offset > buffer.size()) + return {}; if (!central_directory_record.read(buffer.slice(member_offset))) return {}; if (central_directory_record.general_purpose_flags & 1) @@ -75,6 +77,8 @@ Optional Zip::try_create(const ReadonlyBytes& buffer) if (memchr(central_directory_record.name, 0, central_directory_record.name_length) != nullptr) return {}; LocalFileHeader local_file_header {}; + if (central_directory_record.local_file_header_offset > buffer.size()) + return {}; if (!local_file_header.read(buffer.slice(central_directory_record.local_file_header_offset))) return {}; if (buffer.size() - (local_file_header.compressed_data - buffer.data()) < central_directory_record.compressed_size)