Revision control
Copy as Markdown
From 9044a9d888c94a2bcae442dfdc4fe8d2c3e814da Mon Sep 17 00:00:00 2001
From: Jonas Karlsson <jonas.karlsson@qt.io>
Date: Thu, 13 Aug 2026 17:26:54 +0200
Subject: [PATCH] Fix stack-buffer-overflow in PhysX BucketPruner raycasts
precomputeRayData() in SqBucketPruner.cpp read 16 bytes via an SSE load
(_mm_loadu_ps) from the address of a PxVec3, which is only 12 bytes.
Callers that pass a bare stack PxVec3 with nothing guaranteed to follow
it -- such as CharacterController's internal ground-detection raycast,
Cct::Controller::findTouchedObject() -- trigger a 4-byte out-of-bounds
read past the object. This is caught as a stack-buffer-overflow under
AddressSanitizer and is undefined behavior in any build.
Fix by building the SSE vector from the 3 known components instead of
loading a phantom 4th float.
Pick-to: 6.12 6.11 6.8
Change-Id: I09b7c09bc83650ccf2c64ebe0f7a1b45f1978275
---
src/3rdparty/PhysX/source/scenequery/src/SqBucketPruner.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/3rdparty/PhysX/source/scenequery/src/SqBucketPruner.cpp b/src/3rdparty/PhysX/source/scenequery/src/SqBucketPruner.cpp
index 04bfa245..5404ae02 100644
--- a/src/3rdparty/PhysX/source/scenequery/src/SqBucketPruner.cpp
+++ b/src/3rdparty/PhysX/source/scenequery/src/SqBucketPruner.cpp
@@ -1216,8 +1216,10 @@ namespace {
#ifdef USE_SIMD
const float Half = 0.5f * maxDist;
const __m128 HalfV = _mm_load1_ps(&Half);
- const __m128 DataV = _mm_mul_ps(_mm_loadu_ps(&rayDir.x), HalfV);
- const __m128 Data2V = _mm_add_ps(_mm_loadu_ps(&rayOrig.x), DataV);
+ const __m128 rayDirV = _mm_set_ps(0.0f, rayDir.z, rayDir.y, rayDir.x);
+ const __m128 rayOrigV = _mm_set_ps(0.0f, rayOrig.z, rayOrig.y, rayOrig.x);
+ const __m128 DataV = _mm_mul_ps(rayDirV, HalfV);
+ const __m128 Data2V = _mm_add_ps(rayOrigV, DataV);
const PxU32 MaskI = 0x7fffffff;
const __m128 FDirV = _mm_and_ps(_mm_load1_ps(reinterpret_cast<const float*>(&MaskI)), DataV);
_mm_store_ps(&rayParams->mData.x, DataV);
--
2.55.0