From 6fc7fe10ec345d871006e5c9ed7a920945ad9f5a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 2 Jun 2024 19:37:24 +0200 Subject: [PATCH] VICAR: avoid harmless unsigned integer overflow Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=69389 --- frmts/pds/vicardataset.cpp | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/frmts/pds/vicardataset.cpp b/frmts/pds/vicardataset.cpp index 62dc0cbffa29..77d11af8b636 100644 --- a/frmts/pds/vicardataset.cpp +++ b/frmts/pds/vicardataset.cpp @@ -945,27 +945,38 @@ CPLErr VICARBASICRasterBand::IReadBlock(int /*nXBlock*/, int nYBlock, CPLAssert(poGDS->m_anRecordOffsets[poGDS->m_nLastRecordOffset + 1] == 0); + int nRet; if (poGDS->m_eCompress == VICARDataset::COMPRESS_BASIC) { - VSIFSeekL(poGDS->fpImage, - poGDS->m_anRecordOffsets[poGDS->m_nLastRecordOffset] - - sizeof(GUInt32), - SEEK_SET); + nRet = + VSIFSeekL(poGDS->fpImage, + poGDS->m_anRecordOffsets[poGDS->m_nLastRecordOffset] - + sizeof(GUInt32), + SEEK_SET); } else { - VSIFSeekL(poGDS->fpImage, - poGDS->m_nImageOffsetWithoutNBB + - static_cast(sizeof(GUInt32)) * - poGDS->m_nLastRecordOffset, - SEEK_SET); + nRet = VSIFSeekL(poGDS->fpImage, + poGDS->m_nImageOffsetWithoutNBB + + static_cast(sizeof(GUInt32)) * + poGDS->m_nLastRecordOffset, + SEEK_SET); } GUInt32 nSize; - VSIFReadL(&nSize, 1, sizeof(nSize), poGDS->fpImage); + if (nRet != 0 || + VSIFReadL(&nSize, sizeof(nSize), 1, poGDS->fpImage) != 1) + { + CPLError(CE_Failure, CPLE_AppDefined, "Cannot read record %d size", + poGDS->m_nLastRecordOffset); + return CE_Failure; + } CPL_LSBPTR32(&nSize); if ((poGDS->m_eCompress == VICARDataset::COMPRESS_BASIC && nSize <= sizeof(GUInt32)) || - (poGDS->m_eCompress == VICARDataset::COMPRESS_BASIC2 && nSize == 0)) + (poGDS->m_eCompress == VICARDataset::COMPRESS_BASIC2 && + nSize == 0) || + poGDS->m_anRecordOffsets[poGDS->m_nLastRecordOffset] > + std::numeric_limits::max() - nSize) { CPLError(CE_Failure, CPLE_AppDefined, "Wrong size at record %d", poGDS->m_nLastRecordOffset);