From 0fbaab2d356cc24d16c750435ad5880786a43fc6 Mon Sep 17 00:00:00 2001 From: niklas Date: Fri, 15 Jul 2022 20:25:57 +0200 Subject: [PATCH] Added a maxSize of the EOCD constructor to detect corruption in the EOCD and to avoid reading over end of file --- src/XrdCl/XrdClZipArchive.cc | 12 ++++++++++-- src/XrdZip/XrdZipEOCD.hh | 4 +++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/XrdCl/XrdClZipArchive.cc b/src/XrdCl/XrdClZipArchive.cc index a0a8ba6e866..adf54ae7d1a 100644 --- a/src/XrdCl/XrdClZipArchive.cc +++ b/src/XrdCl/XrdClZipArchive.cc @@ -321,10 +321,18 @@ namespace XrdCl "End-of-central-directory signature not found." ); Pipeline::Stop( error ); } - eocd.reset( new EOCD( eocdBlock ) ); + try{ + eocd.reset( new EOCD( eocdBlock, chunk.length - uint32_t(eocdBlock - buff) ) ); log->Dump( ZipMsg, "[0x%x] EOCD record parsed: %s", this, eocd->ToString().c_str() ); - + if(eocd->cdOffset > archsize || eocd->cdOffset + eocd->cdSize > archsize) + throw bad_data(); + } + catch(const bad_data &ex){ + XRootDStatus error( stError, errDataError, 0, + "End-of-central-directory signature corrupted." ); + Pipeline::Stop( error ); + } // Do we have the whole archive? if( chunk.length == archsize ) { diff --git a/src/XrdZip/XrdZipEOCD.hh b/src/XrdZip/XrdZipEOCD.hh index 2388f8853bd..d38a6a1c865 100644 --- a/src/XrdZip/XrdZipEOCD.hh +++ b/src/XrdZip/XrdZipEOCD.hh @@ -51,7 +51,7 @@ namespace XrdZip //------------------------------------------------------------------------- //! Constructor from buffer //------------------------------------------------------------------------- - EOCD( const char *buffer ) + EOCD( const char *buffer, uint32_t maxSize = 0 ) { nbDisk = *reinterpret_cast( buffer + 4 ); nbDiskCd = *reinterpret_cast( buffer + 6 ); @@ -60,6 +60,8 @@ namespace XrdZip cdSize = *reinterpret_cast( buffer + 12 ); cdOffset = *reinterpret_cast( buffer + 16 ); commentLength = *reinterpret_cast( buffer + 20 ); + if(maxSize > 0 && (uint32_t)(eocdBaseSize + commentLength) > maxSize) + throw bad_data(); comment = std::string( buffer + 22, commentLength ); eocdSize = eocdBaseSize + commentLength;