From 8ba666f0a9a165230c5e191e66d1719accb33e80 Mon Sep 17 00:00:00 2001 From: Jake Turner Date: Thu, 2 Jan 2025 12:27:45 +0000 Subject: [PATCH] Improve DXIL BufferStore/TextureStore out of bounds handling For texture data the maximum number of components to store comes from the format For non-texture data the maximum number of components is four which is then clamped to stop buffer overrun (by data size or offset) --- renderdoc/driver/shaders/dxil/dxil_debug.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/renderdoc/driver/shaders/dxil/dxil_debug.cpp b/renderdoc/driver/shaders/dxil/dxil_debug.cpp index 2f0fc3577a..a09f48efff 100644 --- a/renderdoc/driver/shaders/dxil/dxil_debug.cpp +++ b/renderdoc/driver/shaders/dxil/dxil_debug.cpp @@ -2160,14 +2160,15 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, { data += dataOffset; int numComps = fmt.numComps; + int maxNumComps = fmt.numComps; // Clamp the number of components to read based on the amount of data in the buffer if(!texData) { RDCASSERTNOTEQUAL(numElems, 0); - int maxNumComps = (int)((dataSize - dataOffset) / fmt.byteWidth); - fmt.numComps = RDCMIN(fmt.numComps, maxNumComps); + const int maxNumCompsData = (int)((dataSize - dataOffset) / fmt.byteWidth); size_t maxOffset = (firstElem + numElems) * stride + structOffset; - maxNumComps = (int)((maxOffset - dataOffset) / fmt.byteWidth); + const int maxNumCompsOffset = (int)((maxOffset - dataOffset) / fmt.byteWidth); + maxNumComps = RDCMIN(maxNumCompsData, maxNumCompsOffset); fmt.numComps = RDCMIN(fmt.numComps, maxNumComps); } @@ -2186,7 +2187,8 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, numComps = 0; // Modify the correct components const uint32_t valueStart = (dxOpCode == DXOp::TextureStore) ? 5 : 4; - for(uint32_t c = 0; c < (uint32_t)fmt.numComps; ++c) + const uint32_t numArgs = RDCMIN(4, maxNumComps); + for(uint32_t c = 0; c < numArgs; ++c) { if(GetShaderVariable(inst.args[c + valueStart], opCode, dxOpCode, arg)) { @@ -2196,7 +2198,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper, ++numComps; } } - fmt.numComps = numComps; + fmt.numComps = RDCMIN(numComps, maxNumComps); TypedUAVStore(fmt, (byte *)data, result.value); } }