From 3bd98611d70e973b4f62cccc8e17519984d07588 Mon Sep 17 00:00:00 2001 From: dataisland Date: Tue, 10 Sep 2024 15:10:36 -0500 Subject: [PATCH 1/2] Fix buffer overflow in MD3Loader (#5763) Co-authored-by: Kim Kulling --- code/AssetLib/MD3/MD3Loader.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/code/AssetLib/MD3/MD3Loader.cpp b/code/AssetLib/MD3/MD3Loader.cpp index 3dd8d9c66..7a34ae1ad 100644 --- a/code/AssetLib/MD3/MD3Loader.cpp +++ b/code/AssetLib/MD3/MD3Loader.cpp @@ -724,6 +724,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy std::vector mBuffer2(fileSize); file->Read(&mBuffer2[0], 1, fileSize); mBuffer = &mBuffer2[0]; + const unsigned char* bufferEnd = mBuffer + fileSize; pcHeader = (BE_NCONST MD3::Header *)mBuffer; @@ -749,9 +750,15 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy // Navigate to the list of surfaces BE_NCONST MD3::Surface *pcSurfaces = (BE_NCONST MD3::Surface *)(mBuffer + pcHeader->OFS_SURFACES); + if ((const unsigned char*)pcSurfaces + sizeof(MD3::Surface) * pcHeader->NUM_SURFACES > bufferEnd) { + throw DeadlyImportError("MD3 surface headers are outside the file"); + } // Navigate to the list of tags BE_NCONST MD3::Tag *pcTags = (BE_NCONST MD3::Tag *)(mBuffer + pcHeader->OFS_TAGS); + if ((const unsigned char*)pcTags + sizeof(MD3::Tag) * pcHeader->NUM_TAGS > bufferEnd) { + throw DeadlyImportError("MD3 tags are outside the file"); + } // Allocate output storage pScene->mNumMeshes = pcHeader->NUM_SURFACES; @@ -1026,6 +1033,10 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy for (unsigned int i = 0; i < pcHeader->NUM_TAGS; ++i, ++pcTags) { aiNode *nd = pScene->mRootNode->mChildren[i] = new aiNode(); + if ((const unsigned char*)pcTags + sizeof(MD3::Tag) > bufferEnd) { + throw DeadlyImportError("MD3 tag is outside the file"); + } + nd->mName.Set((const char *)pcTags->NAME); nd->mParent = pScene->mRootNode; From ab12e8d8baecac95daa23ebb5528fe3d90e3c71e Mon Sep 17 00:00:00 2001 From: dataisland Date: Tue, 10 Sep 2024 16:15:31 -0500 Subject: [PATCH 2/2] Fix stack overflow (#5764) Co-authored-by: Kim Kulling --- code/AssetLib/LWS/LWSLoader.cpp | 12 ++++++++++-- code/AssetLib/LWS/LWSLoader.h | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/code/AssetLib/LWS/LWSLoader.cpp b/code/AssetLib/LWS/LWSLoader.cpp index 047ab0cc9..226615a4a 100644 --- a/code/AssetLib/LWS/LWSLoader.cpp +++ b/code/AssetLib/LWS/LWSLoader.cpp @@ -78,7 +78,15 @@ static constexpr aiImporterDesc desc = { // ------------------------------------------------------------------------------------------------ // Recursive parsing of LWS files -void LWS::Element::Parse(const char *&buffer, const char *end) { +namespace { + constexpr int MAX_DEPTH = 1000; // Define the maximum depth allowed +} + +void LWS::Element::Parse(const char *&buffer, const char *end, int depth) { + if (depth > MAX_DEPTH) { + throw std::runtime_error("Maximum recursion depth exceeded in LWS::Element::Parse"); + } + for (; SkipSpacesAndLineEnd(&buffer, end); SkipLine(&buffer, end)) { // begin of a new element with children @@ -121,7 +129,7 @@ void LWS::Element::Parse(const char *&buffer, const char *end) { // parse more elements recursively if (sub) { - children.back().Parse(buffer, end); + children.back().Parse(buffer, end, depth + 1); } } } diff --git a/code/AssetLib/LWS/LWSLoader.h b/code/AssetLib/LWS/LWSLoader.h index f66688249..d8b718655 100644 --- a/code/AssetLib/LWS/LWSLoader.h +++ b/code/AssetLib/LWS/LWSLoader.h @@ -76,7 +76,7 @@ public: std::list children; //! Recursive parsing function - void Parse(const char *&buffer, const char *end); + void Parse(const char *&buffer, const char *end, int depth = 0); }; #define AI_LWS_MASK (0xffffffff >> 4u)