From 15bd86c5808d7f5a3a02a8f54b769fa5962858b4 Mon Sep 17 00:00:00 2001 From: mohammadmseet-hue Date: Thu, 2 Apr 2026 07:59:02 +0200 Subject: [PATCH] fix: prevent integer overflow in CopyDataAsUint32 accessor count In CopyDataAsUint32 (gltf_decoder.cc), the computation accessor.count * num_components uses int arithmetic. When accessor.count is large and num_components > 1 (VEC2/VEC3/VEC4), the product overflows int32, causing output.resize() to receive a wrong (small or negative) value. The subsequent loop writes accessor.count * num_components entries into the undersized buffer, causing a heap buffer overflow. ASan confirms: WRITE of size 4 past buffer end when the overflowed resize allocates fewer elements than the loop writes. Fix: use int64_t for the multiplication and check for overflow before casting back to int. --- src/draco/io/gltf_decoder.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/draco/io/gltf_decoder.cc b/src/draco/io/gltf_decoder.cc index 2ea71ec8a..dd2fd33fd 100644 --- a/src/draco/io/gltf_decoder.cc +++ b/src/draco/io/gltf_decoder.cc @@ -167,7 +167,14 @@ StatusOr> CopyDataAsUint32( tinygltf::GetComponentSizeInBytes(accessor.componentType); const int num_components = TinyGltfUtils::GetNumComponentsForType(accessor.type); - const int num_elements = accessor.count * num_components; + // Check for integer overflow in accessor.count * num_components. + const int64_t num_elements_64 = + static_cast(accessor.count) * num_components; + if (num_elements_64 > std::numeric_limits::max()) { + return Status(Status::DRACO_ERROR, + "CopyDataAsUint32: accessor count overflow."); + } + const int num_elements = static_cast(num_elements_64); std::vector output; output.resize(num_elements);