Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Unified Diff: Source/modules/webgl/WebGL2RenderingContextBase.cpp

Issue 1315983010: WebGL: validations and fixes to avoid buffer/texture overflow (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: code rebase Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | Source/modules/webgl/WebGLRenderingContextBase.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/modules/webgl/WebGL2RenderingContextBase.cpp
diff --git a/Source/modules/webgl/WebGL2RenderingContextBase.cpp b/Source/modules/webgl/WebGL2RenderingContextBase.cpp
index 0e91d8c93c3c84922312232357578d8cf56e16be..695e09ad88afecff6cbfc5cef105436d19d8660e 100644
--- a/Source/modules/webgl/WebGL2RenderingContextBase.cpp
+++ b/Source/modules/webgl/WebGL2RenderingContextBase.cpp
@@ -118,6 +118,11 @@ void WebGL2RenderingContextBase::copyBufferSubData(GLenum readTarget, GLenum wri
if (!writeBuffer)
return;
+ if (readOffset + size > readBuffer->getSize() || writeOffset + size > writeBuffer->getSize()) {
+ synthesizeGLError(GL_INVALID_VALUE, "copyBufferSubData", "buffer overflow");
+ return;
+ }
+
if ((writeBuffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER && readBuffer->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER)
|| (writeBuffer->getInitialTarget() != GL_ELEMENT_ARRAY_BUFFER && readBuffer->getInitialTarget() == GL_ELEMENT_ARRAY_BUFFER)) {
synthesizeGLError(GL_INVALID_OPERATION, "copyBufferSubData", "Cannot copy into an element buffer destination from a non-element buffer source");
@@ -144,6 +149,14 @@ void WebGL2RenderingContextBase::getBufferSubData(GLenum target, long long offse
return;
}
+ WebGLBuffer* buffer = validateBufferDataTarget("getBufferSubData", target);
+ if (!buffer)
+ return;
+ if (offset + returnedData->byteLength() > buffer->getSize()) {
+ synthesizeGLError(GL_INVALID_VALUE, "getBufferSubData", "buffer overflow");
+ return;
+ }
+
void* mappedData = webContext()->mapBufferRange(target, static_cast<GLintptr>(offset), returnedData->byteLength(), GL_MAP_READ_BIT);
if (!mappedData)
@@ -509,10 +522,16 @@ bool WebGL2RenderingContextBase::validateTexSubImage3D(const char* functionName,
if (!validateTexFuncLevel(functionName, target, level))
return false;
- if (width - xoffset > tex->getWidth(target, level)
- || height - yoffset > tex->getHeight(target, level)
- || depth - zoffset > tex->getDepth(target, level)) {
- synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions out of range");
+ // Before checking if it is in the range, check if overflow happens first.
+ Checked<GLint, RecordOverflow> maxX = xoffset, maxY = yoffset, maxZ = zoffset;
+ maxX += width;
+ maxY += height;
+ maxZ += depth;
+ if (maxX.hasOverflowed() || maxY.hasOverflowed() || maxZ.hasOverflowed()
+ || maxX.unsafeGet() > tex->getWidth(target, level)
+ || maxY.unsafeGet() > tex->getHeight(target, level)
+ || maxZ.unsafeGet() > tex->getDepth(target, level)) {
+ synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of range");
return false;
}
@@ -609,10 +628,7 @@ void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint
void WebGL2RenderingContextBase::texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
{
- if (isContextLost() || !image || !validateTexSubImage3D("texSubImage3D", target, level, xoffset, yoffset, zoffset, format, type, image->width(), image->height(), 1))
- return;
-
- if (isContextLost() || !validateHTMLImageElement("texSubImage3D", image, exceptionState))
+ if (isContextLost() || !image || !validateHTMLImageElement("texSubImage3D", image, exceptionState))
return;
RefPtr<Image> imageForRender = image->cachedImage()->imageForLayoutObject(image->layoutObject());
@@ -1681,8 +1697,10 @@ void WebGL2RenderingContextBase::bindBufferRange(GLenum target, GLuint index, We
return;
}
- if (!validateAndUpdateBufferBindBaseTarget("bindBufferRange", target, index, buffer))
+ if (buffer && (offset + size > buffer->getSize())) {
+ synthesizeGLError(GL_INVALID_VALUE, "bindBufferRange", "buffer overflow");
return;
+ }
webContext()->bindBufferRange(target, index, objectOrZero(buffer), static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size));
}
« no previous file with comments | « no previous file | Source/modules/webgl/WebGLRenderingContextBase.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698