Fix heap-buffer-overflow in vendored assimp Quick3D importer (CVE-2025-11277)

Engine/lib/assimp/code/AssetLib/Q3D/Q3DLoader.cpp:
Q3DImporter::InternReadFile reads attacker-controlled 32-bit texture
mWidth and mHeight, then computes `unsigned int mul = mWidth * mHeight`
and allocates `new aiTexel[mul]`. The pre-existing check only rejects
zero dimensions, so a crafted .q3o/.q3s file can make the product
overflow 32 bits and wrap to a small value, yielding an undersized
allocation. The subsequent fill loop bounded by
`end = &begin[mul - 1] + 1` then writes far past the buffer
(mul-1 underflows when mul wraps to 0), an out-of-bounds heap write.

Add the integer-overflow guard from upstream assimp (the fix that
closed assimp/assimp#6358 / CVE-2025-11277) verbatim: after the
zero check, reject dimensions whose product would overflow before
the multiplication, throwing DeadlyImportError instead.

Refs #1765
This commit is contained in:
dkgkdfg65 2026-06-10 01:25:46 +08:00
parent 2d2eb57e2e
commit fa8dd7decc

View file

@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/IOSystem.hpp>
#include <limits>
namespace Assimp {
@ -309,6 +310,11 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
throw DeadlyImportError("Quick3D: Invalid texture. Width or height is zero");
}
const unsigned int uint_max = std::numeric_limits<unsigned int>::max();
if (tex->mWidth > (uint_max / tex->mHeight)) {
throw DeadlyImportError("Quick3D: Texture dimensions are too large, resulting in overflow.");
}
unsigned int mul = tex->mWidth * tex->mHeight;
aiTexel *begin = tex->pcData = new aiTexel[mul];
aiTexel *const end = &begin[mul - 1] + 1;