D3D11: Fix out-of-range access with robust access.
When using a vertex buffer with DYNAMIC usage, with robust buffer
access enabled, we would sometimes read out-of-bounds when using very
large values for the index range. An unchecked signed addition would
overflow and lead to reading a negative offset.
Fix this problem by keeping the value size_t whenever possible. Also do
clamped casts when converting to a smaller values.
Also adds a regression test.
Bug: chromium:842028
Change-Id: Ie630ac857c6acfc0bace849a03eebfbaa2fbe89a
Reviewed-on: https://chromium-review.googlesource.com/1055928
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
index 5972339..16af443 100644
--- a/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
+++ b/src/libANGLE/renderer/vulkan/VertexArrayVk.cpp
@@ -357,14 +357,17 @@
ANGLE_TRY(onDraw(context, renderer, drawCallParams, drawNode, newCommandBuffer));
+ // Note: Vertex indexes can be arbitrarily large.
+ uint32_t clampedVertexCount = drawCallParams.getClampedVertexCount<uint32_t>();
+
if (drawCallParams.mode() != GL_LINE_LOOP)
{
- commandBuffer->draw(drawCallParams.vertexCount(), 1, drawCallParams.firstVertex(), 0);
+ commandBuffer->draw(clampedVertexCount, 1, drawCallParams.firstVertex(), 0);
return gl::NoError();
}
// Handle GL_LINE_LOOP drawArrays.
- int lastVertex = drawCallParams.firstVertex() + drawCallParams.vertexCount();
+ size_t lastVertex = static_cast<size_t>(drawCallParams.firstVertex() + clampedVertexCount);
if (!mLineLoopBufferFirstIndex.valid() || !mLineLoopBufferLastIndex.valid() ||
mLineLoopBufferFirstIndex != drawCallParams.firstVertex() ||
mLineLoopBufferLastIndex != lastVertex)
@@ -380,7 +383,7 @@
commandBuffer->bindIndexBuffer(mCurrentElementArrayBufferHandle,
mCurrentElementArrayBufferOffset, VK_INDEX_TYPE_UINT32);
- vk::LineLoopHelper::Draw(drawCallParams.vertexCount(), commandBuffer);
+ vk::LineLoopHelper::Draw(clampedVertexCount, commandBuffer);
return gl::NoError();
}