summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 00:33:18 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-05 00:33:18 +0000
commita76b005bf78e63263abacfed35ad3e9ab3aef26a (patch)
tree25fe4a79a6ce254d1a331d0c533ddc79a0553d3f /gpu
parent0bc2448f867ad96f0cffe102cc4fc13aede5c891 (diff)
downloadchromium_src-a76b005bf78e63263abacfed35ad3e9ab3aef26a.zip
chromium_src-a76b005bf78e63263abacfed35ad3e9ab3aef26a.tar.gz
chromium_src-a76b005bf78e63263abacfed35ad3e9ab3aef26a.tar.bz2
Added SafeMultiply and SafeAdd to check for overflows
in math calculations related to memory access. Refactored code to use them where appropriate. One issue that has come up is we need to make sure that no GLES2 client call can crash the GPU process. In other words, the GLES2Implementation must never generate a command the service side will see as malicious. For example: glTexImage2d(..width = 0x7fffffff, height = 0x7fffffff) should return an gl error rather than pass it through to the service side which will currently return a parse error and stop the GPU process. It does make me wonder if the service side should return GL errors for more things rather than parse errors. TEST=none BUG=35942,35943,35941,35938 Review URL: http://codereview.chromium.org/669011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40696 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/command_buffer/client/gles2_implementation.cc59
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h54
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils.cc32
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils.h42
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc41
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h421
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h12
7 files changed, 497 insertions, 164 deletions
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index 0dacb54..8e212d6 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -362,6 +362,12 @@ void GLES2Implementation::TexImage2D(
SetGLError(GL_INVALID_VALUE);
return;
}
+ uint32 size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, height, format, type, unpack_alignment_, &size)) {
+ SetGLError(GL_INVALID_VALUE);
+ return;
+ }
helper_->TexImage2D(
target, level, internalformat, width, height, border, format, type, 0, 0);
if (pixels) {
@@ -378,10 +384,23 @@ void GLES2Implementation::TexSubImage2D(
}
const int8* source = static_cast<const int8*>(pixels);
GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize();
- GLsizeiptr unpadded_row_size = GLES2Util::ComputeImageDataSize(
- width, 1, format, type, unpack_alignment_);
- GLsizeiptr padded_row_size = GLES2Util::ComputeImageDataSize(
- width, 2, format, type, unpack_alignment_) - unpadded_row_size;
+ uint32 temp_size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, 1, format, type, unpack_alignment_, &temp_size)) {
+ SetGLError(GL_INVALID_VALUE);
+ return;
+ }
+ GLsizeiptr unpadded_row_size = temp_size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, 2, format, type, unpack_alignment_, &temp_size)) {
+ SetGLError(GL_INVALID_VALUE);
+ return;
+ }
+ GLsizeiptr padded_row_size = temp_size - unpadded_row_size;
+ if (padded_row_size < 0 || unpadded_row_size < 0) {
+ SetGLError(GL_INVALID_VALUE);
+ return;
+ }
if (padded_row_size <= max_size) {
// Transfer by rows.
@@ -401,8 +420,10 @@ void GLES2Implementation::TexSubImage2D(
}
} else {
// Transfer by sub rows. Beacuse GL has no maximum texture dimensions.
- GLsizeiptr element_size = GLES2Util::ComputeImageDataSize(
- 1, 1, format, type, unpack_alignment_);
+ uint32 temp;
+ GLES2Util::ComputeImageDataSize(
+ 1, 1, format, type, unpack_alignment_, &temp);
+ GLsizeiptr element_size = temp;
max_size -= max_size % element_size;
GLint max_sub_row_pixels = max_size / element_size;
for (; height; --height) {
@@ -606,10 +627,23 @@ void GLES2Implementation::ReadPixels(
Result* result = static_cast<Result*>(result_buffer_);
int8* dest = reinterpret_cast<int8*>(pixels);
GLsizeiptr max_size = transfer_buffer_.GetLargestFreeOrPendingSize();
- GLsizeiptr unpadded_row_size = GLES2Util::ComputeImageDataSize(
- width, 1, format, type, pack_alignment_);
- GLsizeiptr padded_row_size = GLES2Util::ComputeImageDataSize(
- width, 2, format, type, pack_alignment_) - unpadded_row_size;
+ uint32 temp_size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, 1, format, type, pack_alignment_, &temp_size)) {
+ SetGLError(GL_INVALID_VALUE);
+ return;
+ }
+ GLsizeiptr unpadded_row_size = temp_size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, 2, format, type, pack_alignment_, &temp_size)) {
+ SetGLError(GL_INVALID_VALUE);
+ return;
+ }
+ GLsizeiptr padded_row_size = temp_size - unpadded_row_size;
+ if (padded_row_size < 0 || unpadded_row_size < 0) {
+ SetGLError(GL_INVALID_VALUE);
+ return;
+ }
if (padded_row_size <= max_size) {
// Transfer by rows.
GLint max_rows = max_size / padded_row_size;
@@ -635,8 +669,9 @@ void GLES2Implementation::ReadPixels(
}
} else {
// Transfer by sub rows. Beacuse GL has no maximum texture dimensions.
- GLsizeiptr element_size = GLES2Util::ComputeImageDataSize(
- 1, 1, format, type, pack_alignment_);
+ GLES2Util::ComputeImageDataSize(
+ 1, 1, format, type, pack_alignment_, &temp_size);
+ GLsizeiptr element_size = temp_size;
max_size -= max_size % element_size;
GLint max_sub_row_pixels = max_size / element_size;
for (; height; --height) {
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index b758002..ef6803d 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -334,15 +334,17 @@ void GetProgramInfoLog(
GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) {
helper_->SetBucketSize(kResultBucketId, 0);
helper_->GetProgramInfoLog(program, kResultBucketId);
- std::string str;
- if (GetBucketAsString(kResultBucketId, &str)) {
- GLsizei max_size =
- std::min(static_cast<size_t>(bufsize) - 1, str.size());
- if (length != NULL) {
- *length = max_size;
+ if (bufsize > 0) {
+ std::string str;
+ if (GetBucketAsString(kResultBucketId, &str)) {
+ GLsizei max_size =
+ std::min(static_cast<size_t>(bufsize) - 1, str.size());
+ if (length != NULL) {
+ *length = max_size;
+ }
+ memcpy(infolog, str.c_str(), max_size);
+ infolog[max_size] = '\0';
}
- memcpy(infolog, str.c_str(), max_size);
- infolog[max_size] = '\0';
}
}
void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) {
@@ -366,15 +368,17 @@ void GetShaderInfoLog(
GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) {
helper_->SetBucketSize(kResultBucketId, 0);
helper_->GetShaderInfoLog(shader, kResultBucketId);
- std::string str;
- if (GetBucketAsString(kResultBucketId, &str)) {
- GLsizei max_size =
- std::min(static_cast<size_t>(bufsize) - 1, str.size());
- if (length != NULL) {
- *length = max_size;
+ if (bufsize > 0) {
+ std::string str;
+ if (GetBucketAsString(kResultBucketId, &str)) {
+ GLsizei max_size =
+ std::min(static_cast<size_t>(bufsize) - 1, str.size());
+ if (length != NULL) {
+ *length = max_size;
+ }
+ memcpy(infolog, str.c_str(), max_size);
+ infolog[max_size] = '\0';
}
- memcpy(infolog, str.c_str(), max_size);
- infolog[max_size] = '\0';
}
}
void GetShaderPrecisionFormat(
@@ -384,15 +388,17 @@ void GetShaderSource(
GLuint shader, GLsizei bufsize, GLsizei* length, char* source) {
helper_->SetBucketSize(kResultBucketId, 0);
helper_->GetShaderSource(shader, kResultBucketId);
- std::string str;
- if (GetBucketAsString(kResultBucketId, &str)) {
- GLsizei max_size =
- std::min(static_cast<size_t>(bufsize) - 1, str.size());
- if (length != NULL) {
- *length = max_size;
+ if (bufsize > 0) {
+ std::string str;
+ if (GetBucketAsString(kResultBucketId, &str)) {
+ GLsizei max_size =
+ std::min(static_cast<size_t>(bufsize) - 1, str.size());
+ if (length != NULL) {
+ *length = max_size;
+ }
+ memcpy(source, str.c_str(), max_size);
+ source[max_size] = '\0';
}
- memcpy(source, str.c_str(), max_size);
- source[max_size] = '\0';
}
}
const GLubyte* GetString(GLenum name);
diff --git a/gpu/command_buffer/common/gles2_cmd_utils.cc b/gpu/command_buffer/common/gles2_cmd_utils.cc
index e0fc8e6..7587dd8 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils.cc
+++ b/gpu/command_buffer/common/gles2_cmd_utils.cc
@@ -341,17 +341,35 @@ int BytesPerElement(int type) {
} // anonymous namespace
// Returns the amount of data glTexImage2D or glTexSubImage2D will access.
-uint32 GLES2Util::ComputeImageDataSize(
- int width, int height, int format, int type, int unpack_alignment) {
+bool GLES2Util::ComputeImageDataSize(
+ int width, int height, int format, int type, int unpack_alignment,
+ uint32* size) {
uint32 bytes_per_group =
BytesPerElement(type) * ElementsPerGroup(format, type);
- uint32 row_size = width * bytes_per_group;
+ uint32 row_size;
+ if (!SafeMultiplyUint32(width, bytes_per_group, &row_size)) {
+ return false;
+ }
if (height > 1) {
- uint32 padded_row_size = ((row_size + unpack_alignment - 1) /
- unpack_alignment) * unpack_alignment;
- return (height - 1) * padded_row_size + row_size;
+ uint32 temp;
+ if (!SafeAddUint32(row_size, unpack_alignment - 1, &temp)) {
+ return false;
+ }
+ uint32 padded_row_size = (temp / unpack_alignment) * unpack_alignment;
+ uint32 size_of_all_but_last_row;
+ if (!SafeMultiplyUint32((height - 1), padded_row_size,
+ &size_of_all_but_last_row)) {
+ return false;
+ }
+ if (!SafeAddUint32(size_of_all_but_last_row, row_size, size)) {
+ return false;
+ }
+ } else {
+ if (!SafeMultiplyUint32(height, row_size, size)) {
+ return false;
+ }
}
- return height * row_size;
+ return true;
}
uint32 GLES2Util::GetGLDataTypeSizeForUniforms(int type) {
diff --git a/gpu/command_buffer/common/gles2_cmd_utils.h b/gpu/command_buffer/common/gles2_cmd_utils.h
index 99b17e5..c5cd792 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils.h
@@ -14,6 +14,43 @@
namespace gpu {
namespace gles2 {
+// Does a multiply and checks for overflow. If the multiply did not overflow
+// returns true.
+template <typename T>
+inline bool SafeMultiply(T a, T b, T* dst) {
+ *dst = 0;
+ if (b == 0) {
+ return true;
+ }
+ T v = a * b;
+ if (v / b != a) {
+ return false;
+ }
+ *dst = v;
+ return true;
+}
+
+// A wrapper for SafeMultiply to remove the need to cast.
+inline bool SafeMultiplyUint32(uint32 a, uint32 b, uint32* dst) {
+ return SafeMultiply(a, b, dst);
+}
+
+// Does an add checking for overflow. If there was no overflow returns true.
+template <typename T>
+inline bool SafeAdd(T a, T b, T* dst) {
+ *dst = 0;
+ if (a + b < a) {
+ return false;
+ }
+ *dst = a + b;
+ return true;
+}
+
+// A wrapper for SafeAdd to remove the need to cast.
+inline bool SafeAddUint32(uint32 a, uint32 b, uint32* dst) {
+ return SafeAdd(a, b, dst);
+}
+
// Utilties for GLES2 support.
class GLES2Util {
public:
@@ -27,8 +64,9 @@ class GLES2Util {
int GLGetNumValuesReturned(int id) const;
// Computes the size of image data for TexImage2D and TexSubImage2D.
- static uint32 ComputeImageDataSize(
- int width, int height, int format, int type, int unpack_alignment);
+ static bool ComputeImageDataSize(
+ int width, int height, int format, int type, int unpack_alignment,
+ uint32* size);
static uint32 GetGLDataTypeSizeForUniforms(int type);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 52f59ce..54cef89 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -78,12 +78,20 @@ RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
}
// Computes the data size for certain gl commands like glUniform.
-uint32 ComputeImmediateDataSize(
- uint32 immediate_data_size,
+bool ComputeDataSize(
GLuint count,
size_t size,
- unsigned int elements_per_unit) {
- return count * size * elements_per_unit;
+ unsigned int elements_per_unit,
+ uint32* dst) {
+ uint32 value;
+ if (!SafeMultiplyUint32(count, size, &value)) {
+ return false;
+ }
+ if (!SafeMultiplyUint32(value, elements_per_unit, &value)) {
+ return false;
+ }
+ *dst = value;
+ return true;
}
// A struct to hold info about each command.
@@ -1905,7 +1913,7 @@ error::Error GLES2DecoderImpl::HandleDrawElements(
GLsizei count = c.count;
GLenum type = c.type;
int32 offset = c.index_offset;
- if (count < 0) {
+ if (count < 0 || offset < 0) {
SetGLError(GL_INVALID_VALUE);
} else if (!ValidateGLenumDrawMode(mode) ||
!ValidateGLenumIndexType(type)) {
@@ -2025,6 +2033,8 @@ void GLES2DecoderImpl::DoGetShaderSource(
SetGLError(GL_INVALID_OPERATION);
return;
}
+ // bufsize is set by the service side code and should always be positive.
+ DCHECK_GT(bufsize, 0);
const std::string& source = info->source();
GLsizei size = std::min(bufsize - 1, static_cast<GLsizei>(source.size()));
if (length) {
@@ -2085,8 +2095,11 @@ error::Error GLES2DecoderImpl::HandleReadPixels(
GLenum type = c.type;
// TODO(gman): Handle out of range rectangles.
typedef gles2::ReadPixels::Result Result;
- uint32 pixels_size = GLES2Util::ComputeImageDataSize(
- width, height, format, type, pack_alignment_);
+ uint32 pixels_size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, height, format, type, pack_alignment_, &pixels_size)) {
+ return error::kOutOfBounds;
+ }
void* pixels = GetSharedMemoryAs<void*>(
c.pixels_shm_id, c.pixels_shm_offset, pixels_size);
Result* result = GetSharedMemoryAs<Result*>(
@@ -2473,8 +2486,11 @@ error::Error GLES2DecoderImpl::HandleTexImage2D(
GLenum type = static_cast<GLenum>(c.type);
uint32 pixels_shm_id = static_cast<uint32>(c.pixels_shm_id);
uint32 pixels_shm_offset = static_cast<uint32>(c.pixels_shm_offset);
- uint32 pixels_size = GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_);
+ uint32 pixels_size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, height, format, type, unpack_alignment_, &pixels_size)) {
+ return error::kOutOfBounds;
+ }
const void* pixels = NULL;
if (pixels_shm_id != 0 || pixels_shm_offset != 0) {
pixels = GetSharedMemoryAs<const void*>(
@@ -2498,8 +2514,11 @@ error::Error GLES2DecoderImpl::HandleTexImage2DImmediate(
GLint border = static_cast<GLint>(c.border);
GLenum format = static_cast<GLenum>(c.format);
GLenum type = static_cast<GLenum>(c.type);
- uint32 size = GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_);
+ uint32 size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, height, format, type, unpack_alignment_, &size)) {
+ return error::kOutOfBounds;
+ }
const void* pixels = GetImmediateDataAs<const void*>(
c, size, immediate_data_size);
if (!pixels) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index c2620ac..025e0b3 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -481,7 +481,10 @@ error::Error GLES2DecoderImpl::HandleCullFace(
error::Error GLES2DecoderImpl::HandleDeleteBuffers(
uint32 immediate_data_size, const gles2::DeleteBuffers& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLuint* buffers = GetSharedMemoryAs<const GLuint*>(
c.buffers_shm_id, c.buffers_shm_offset, data_size);
if (n < 0) {
@@ -498,7 +501,10 @@ error::Error GLES2DecoderImpl::HandleDeleteBuffers(
error::Error GLES2DecoderImpl::HandleDeleteBuffersImmediate(
uint32 immediate_data_size, const gles2::DeleteBuffersImmediate& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLuint* buffers = GetImmediateDataAs<const GLuint*>(
c, data_size, immediate_data_size);
if (n < 0) {
@@ -515,7 +521,10 @@ error::Error GLES2DecoderImpl::HandleDeleteBuffersImmediate(
error::Error GLES2DecoderImpl::HandleDeleteFramebuffers(
uint32 immediate_data_size, const gles2::DeleteFramebuffers& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLuint* framebuffers = GetSharedMemoryAs<const GLuint*>(
c.framebuffers_shm_id, c.framebuffers_shm_offset, data_size);
if (n < 0) {
@@ -532,7 +541,10 @@ error::Error GLES2DecoderImpl::HandleDeleteFramebuffers(
error::Error GLES2DecoderImpl::HandleDeleteFramebuffersImmediate(
uint32 immediate_data_size, const gles2::DeleteFramebuffersImmediate& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLuint* framebuffers = GetImmediateDataAs<const GLuint*>(
c, data_size, immediate_data_size);
if (n < 0) {
@@ -549,7 +561,10 @@ error::Error GLES2DecoderImpl::HandleDeleteFramebuffersImmediate(
error::Error GLES2DecoderImpl::HandleDeleteRenderbuffers(
uint32 immediate_data_size, const gles2::DeleteRenderbuffers& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLuint* renderbuffers = GetSharedMemoryAs<const GLuint*>(
c.renderbuffers_shm_id, c.renderbuffers_shm_offset, data_size);
if (n < 0) {
@@ -566,7 +581,10 @@ error::Error GLES2DecoderImpl::HandleDeleteRenderbuffers(
error::Error GLES2DecoderImpl::HandleDeleteRenderbuffersImmediate(
uint32 immediate_data_size, const gles2::DeleteRenderbuffersImmediate& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLuint* renderbuffers = GetImmediateDataAs<const GLuint*>(
c, data_size, immediate_data_size);
if (n < 0) {
@@ -583,7 +601,10 @@ error::Error GLES2DecoderImpl::HandleDeleteRenderbuffersImmediate(
error::Error GLES2DecoderImpl::HandleDeleteTextures(
uint32 immediate_data_size, const gles2::DeleteTextures& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLuint* textures = GetSharedMemoryAs<const GLuint*>(
c.textures_shm_id, c.textures_shm_offset, data_size);
if (n < 0) {
@@ -600,7 +621,10 @@ error::Error GLES2DecoderImpl::HandleDeleteTextures(
error::Error GLES2DecoderImpl::HandleDeleteTexturesImmediate(
uint32 immediate_data_size, const gles2::DeleteTexturesImmediate& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLuint* textures = GetImmediateDataAs<const GLuint*>(
c, data_size, immediate_data_size);
if (n < 0) {
@@ -789,7 +813,10 @@ error::Error GLES2DecoderImpl::HandleFrontFace(
error::Error GLES2DecoderImpl::HandleGenBuffers(
uint32 immediate_data_size, const gles2::GenBuffers& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
GLuint* buffers = GetSharedMemoryAs<GLuint*>(
c.buffers_shm_id, c.buffers_shm_offset, data_size);
if (n < 0) {
@@ -808,7 +835,10 @@ error::Error GLES2DecoderImpl::HandleGenBuffers(
error::Error GLES2DecoderImpl::HandleGenBuffersImmediate(
uint32 immediate_data_size, const gles2::GenBuffersImmediate& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
GLuint* buffers = GetImmediateDataAs<GLuint*>(
c, data_size, immediate_data_size);
if (n < 0) {
@@ -838,7 +868,10 @@ error::Error GLES2DecoderImpl::HandleGenerateMipmap(
error::Error GLES2DecoderImpl::HandleGenFramebuffers(
uint32 immediate_data_size, const gles2::GenFramebuffers& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
GLuint* framebuffers = GetSharedMemoryAs<GLuint*>(
c.framebuffers_shm_id, c.framebuffers_shm_offset, data_size);
if (n < 0) {
@@ -857,7 +890,10 @@ error::Error GLES2DecoderImpl::HandleGenFramebuffers(
error::Error GLES2DecoderImpl::HandleGenFramebuffersImmediate(
uint32 immediate_data_size, const gles2::GenFramebuffersImmediate& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
GLuint* framebuffers = GetImmediateDataAs<GLuint*>(
c, data_size, immediate_data_size);
if (n < 0) {
@@ -876,7 +912,10 @@ error::Error GLES2DecoderImpl::HandleGenFramebuffersImmediate(
error::Error GLES2DecoderImpl::HandleGenRenderbuffers(
uint32 immediate_data_size, const gles2::GenRenderbuffers& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
GLuint* renderbuffers = GetSharedMemoryAs<GLuint*>(
c.renderbuffers_shm_id, c.renderbuffers_shm_offset, data_size);
if (n < 0) {
@@ -895,7 +934,10 @@ error::Error GLES2DecoderImpl::HandleGenRenderbuffers(
error::Error GLES2DecoderImpl::HandleGenRenderbuffersImmediate(
uint32 immediate_data_size, const gles2::GenRenderbuffersImmediate& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
GLuint* renderbuffers = GetImmediateDataAs<GLuint*>(
c, data_size, immediate_data_size);
if (n < 0) {
@@ -914,7 +956,10 @@ error::Error GLES2DecoderImpl::HandleGenRenderbuffersImmediate(
error::Error GLES2DecoderImpl::HandleGenTextures(
uint32 immediate_data_size, const gles2::GenTextures& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
GLuint* textures = GetSharedMemoryAs<GLuint*>(
c.textures_shm_id, c.textures_shm_offset, data_size);
if (n < 0) {
@@ -933,7 +978,10 @@ error::Error GLES2DecoderImpl::HandleGenTextures(
error::Error GLES2DecoderImpl::HandleGenTexturesImmediate(
uint32 immediate_data_size, const gles2::GenTexturesImmediate& c) {
GLsizei n = static_cast<GLsizei>(c.n);
- uint32 data_size = n * sizeof(GLuint);
+ uint32 data_size;
+ if (!SafeMultiplyUint32(n, sizeof(GLuint), &data_size)) {
+ return error::kOutOfBounds;
+ }
GLuint* textures = GetImmediateDataAs<GLuint*>(
c, data_size, immediate_data_size);
if (n < 0) {
@@ -952,9 +1000,13 @@ error::Error GLES2DecoderImpl::HandleGenTexturesImmediate(
error::Error GLES2DecoderImpl::HandleGetBooleanv(
uint32 immediate_data_size, const gles2::GetBooleanv& c) {
GLenum pname = static_cast<GLenum>(c.pname);
+
GLboolean* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLboolean*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (params == NULL) {
@@ -968,9 +1020,13 @@ error::Error GLES2DecoderImpl::HandleGetBufferParameteriv(
uint32 immediate_data_size, const gles2::GetBufferParameteriv& c) {
GLenum target = static_cast<GLenum>(c.target);
GLenum pname = static_cast<GLenum>(c.pname);
+
GLint* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLint*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (!ValidateGLenumBufferTarget(target)) {
@@ -999,9 +1055,13 @@ error::Error GLES2DecoderImpl::HandleGetError(
error::Error GLES2DecoderImpl::HandleGetFloatv(
uint32 immediate_data_size, const gles2::GetFloatv& c) {
GLenum pname = static_cast<GLenum>(c.pname);
+
GLfloat* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLfloat*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (params == NULL) {
@@ -1017,9 +1077,13 @@ error::Error GLES2DecoderImpl::HandleGetFramebufferAttachmentParameteriv(
GLenum target = static_cast<GLenum>(c.target);
GLenum attachment = static_cast<GLenum>(c.attachment);
GLenum pname = static_cast<GLenum>(c.pname);
+
GLint* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLint*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (!ValidateGLenumFrameBufferTarget(target)) {
@@ -1044,9 +1108,13 @@ error::Error GLES2DecoderImpl::HandleGetFramebufferAttachmentParameteriv(
error::Error GLES2DecoderImpl::HandleGetIntegerv(
uint32 immediate_data_size, const gles2::GetIntegerv& c) {
GLenum pname = static_cast<GLenum>(c.pname);
+
GLint* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLint*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (params == NULL) {
@@ -1064,9 +1132,13 @@ error::Error GLES2DecoderImpl::HandleGetProgramiv(
return error::kNoError;
}
GLenum pname = static_cast<GLenum>(c.pname);
+
GLint* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLint*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (!ValidateGLenumProgramParameter(pname)) {
@@ -1101,9 +1173,13 @@ error::Error GLES2DecoderImpl::HandleGetRenderbufferParameteriv(
uint32 immediate_data_size, const gles2::GetRenderbufferParameteriv& c) {
GLenum target = static_cast<GLenum>(c.target);
GLenum pname = static_cast<GLenum>(c.pname);
+
GLint* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLint*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (!ValidateGLenumRenderBufferTarget(target)) {
@@ -1129,9 +1205,13 @@ error::Error GLES2DecoderImpl::HandleGetShaderiv(
return error::kNoError;
}
GLenum pname = static_cast<GLenum>(c.pname);
+
GLint* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLint*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (!ValidateGLenumShaderParameter(pname)) {
@@ -1183,9 +1263,13 @@ error::Error GLES2DecoderImpl::HandleGetTexParameterfv(
uint32 immediate_data_size, const gles2::GetTexParameterfv& c) {
GLenum target = static_cast<GLenum>(c.target);
GLenum pname = static_cast<GLenum>(c.pname);
+
GLfloat* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLfloat*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (!ValidateGLenumTextureTarget(target)) {
@@ -1207,9 +1291,13 @@ error::Error GLES2DecoderImpl::HandleGetTexParameteriv(
uint32 immediate_data_size, const gles2::GetTexParameteriv& c) {
GLenum target = static_cast<GLenum>(c.target);
GLenum pname = static_cast<GLenum>(c.pname);
+
GLint* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLint*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (!ValidateGLenumTextureTarget(target)) {
@@ -1231,9 +1319,13 @@ error::Error GLES2DecoderImpl::HandleGetVertexAttribfv(
uint32 immediate_data_size, const gles2::GetVertexAttribfv& c) {
GLuint index = static_cast<GLuint>(c.index);
GLenum pname = static_cast<GLenum>(c.pname);
+
GLfloat* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLfloat*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (!ValidateGLenumVertexAttribute(pname)) {
@@ -1251,9 +1343,13 @@ error::Error GLES2DecoderImpl::HandleGetVertexAttribiv(
uint32 immediate_data_size, const gles2::GetVertexAttribiv& c) {
GLuint index = static_cast<GLuint>(c.index);
GLenum pname = static_cast<GLenum>(c.pname);
+
GLint* params;
GLsizei num_values = util_.GLGetNumValuesReturned(pname);
- uint32 params_size = num_values * sizeof(*params);
+ uint32 params_size;
+ if (!SafeMultiplyUint32(num_values, sizeof(*params), &params_size)) {
+ return error::kOutOfBounds;
+ }
params = GetSharedMemoryAs<GLint*>(
c.params_shm_id, c.params_shm_offset, params_size);
if (!ValidateGLenumVertexAttribute(pname)) {
@@ -1570,8 +1666,10 @@ error::Error GLES2DecoderImpl::HandleTexParameterfv(
uint32 immediate_data_size, const gles2::TexParameterfv& c) {
GLenum target = static_cast<GLenum>(c.target);
GLenum pname = static_cast<GLenum>(c.pname);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* params = GetSharedMemoryAs<const GLfloat*>(
c.params_shm_id, c.params_shm_offset, data_size);
if (!ValidateGLenumTextureBindTarget(target)) {
@@ -1593,8 +1691,13 @@ error::Error GLES2DecoderImpl::HandleTexParameterfvImmediate(
uint32 immediate_data_size, const gles2::TexParameterfvImmediate& c) {
GLenum target = static_cast<GLenum>(c.target);
GLenum pname = static_cast<GLenum>(c.pname);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* params = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (!ValidateGLenumTextureBindTarget(target)) {
@@ -1633,8 +1736,10 @@ error::Error GLES2DecoderImpl::HandleTexParameteriv(
uint32 immediate_data_size, const gles2::TexParameteriv& c) {
GLenum target = static_cast<GLenum>(c.target);
GLenum pname = static_cast<GLenum>(c.pname);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 1);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLint* params = GetSharedMemoryAs<const GLint*>(
c.params_shm_id, c.params_shm_offset, data_size);
if (!ValidateGLenumTextureBindTarget(target)) {
@@ -1656,8 +1761,13 @@ error::Error GLES2DecoderImpl::HandleTexParameterivImmediate(
uint32 immediate_data_size, const gles2::TexParameterivImmediate& c) {
GLenum target = static_cast<GLenum>(c.target);
GLenum pname = static_cast<GLenum>(c.pname);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 1);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLint* params = GetImmediateDataAs<const GLint*>(
c, data_size, immediate_data_size);
if (!ValidateGLenumTextureBindTarget(target)) {
@@ -1685,8 +1795,11 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2D(
GLsizei height = static_cast<GLsizei>(c.height);
GLenum format = static_cast<GLenum>(c.format);
GLenum type = static_cast<GLenum>(c.type);
- uint32 data_size = GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_);
+ uint32 data_size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, height, format, type, unpack_alignment_, &data_size)) {
+ return error::kOutOfBounds;
+ }
const void* pixels = GetSharedMemoryAs<const void*>(
c.pixels_shm_id, c.pixels_shm_offset, data_size);
if (!ValidateGLenumTextureTarget(target)) {
@@ -1727,8 +1840,11 @@ error::Error GLES2DecoderImpl::HandleTexSubImage2DImmediate(
GLsizei height = static_cast<GLsizei>(c.height);
GLenum format = static_cast<GLenum>(c.format);
GLenum type = static_cast<GLenum>(c.type);
- uint32 data_size = GLES2Util::ComputeImageDataSize(
- width, height, format, type, unpack_alignment_);
+ uint32 data_size;
+ if (!GLES2Util::ComputeImageDataSize(
+ width, height, format, type, unpack_alignment_, &data_size)) {
+ return error::kOutOfBounds;
+ }
const void* pixels = GetImmediateDataAs<const void*>(
c, data_size, immediate_data_size);
if (!ValidateGLenumTextureTarget(target)) {
@@ -1771,8 +1887,10 @@ error::Error GLES2DecoderImpl::HandleUniform1fv(
uint32 immediate_data_size, const gles2::Uniform1fv& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
c.v_shm_id, c.v_shm_offset, data_size);
if (count < 0) {
@@ -1790,8 +1908,13 @@ error::Error GLES2DecoderImpl::HandleUniform1fvImmediate(
uint32 immediate_data_size, const gles2::Uniform1fvImmediate& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -1817,8 +1940,10 @@ error::Error GLES2DecoderImpl::HandleUniform1iv(
uint32 immediate_data_size, const gles2::Uniform1iv& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 1);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLint* v = GetSharedMemoryAs<const GLint*>(
c.v_shm_id, c.v_shm_offset, data_size);
if (count < 0) {
@@ -1836,8 +1961,13 @@ error::Error GLES2DecoderImpl::HandleUniform1ivImmediate(
uint32 immediate_data_size, const gles2::Uniform1ivImmediate& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 1);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLint* v = GetImmediateDataAs<const GLint*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -1864,8 +1994,10 @@ error::Error GLES2DecoderImpl::HandleUniform2fv(
uint32 immediate_data_size, const gles2::Uniform2fv& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 2);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
c.v_shm_id, c.v_shm_offset, data_size);
if (count < 0) {
@@ -1883,8 +2015,13 @@ error::Error GLES2DecoderImpl::HandleUniform2fvImmediate(
uint32 immediate_data_size, const gles2::Uniform2fvImmediate& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 2);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -1911,8 +2048,10 @@ error::Error GLES2DecoderImpl::HandleUniform2iv(
uint32 immediate_data_size, const gles2::Uniform2iv& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 2);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLint* v = GetSharedMemoryAs<const GLint*>(
c.v_shm_id, c.v_shm_offset, data_size);
if (count < 0) {
@@ -1930,8 +2069,13 @@ error::Error GLES2DecoderImpl::HandleUniform2ivImmediate(
uint32 immediate_data_size, const gles2::Uniform2ivImmediate& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 2);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLint* v = GetImmediateDataAs<const GLint*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -1959,8 +2103,10 @@ error::Error GLES2DecoderImpl::HandleUniform3fv(
uint32 immediate_data_size, const gles2::Uniform3fv& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 3);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
c.v_shm_id, c.v_shm_offset, data_size);
if (count < 0) {
@@ -1978,8 +2124,13 @@ error::Error GLES2DecoderImpl::HandleUniform3fvImmediate(
uint32 immediate_data_size, const gles2::Uniform3fvImmediate& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 3);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -2007,8 +2158,10 @@ error::Error GLES2DecoderImpl::HandleUniform3iv(
uint32 immediate_data_size, const gles2::Uniform3iv& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 3);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLint* v = GetSharedMemoryAs<const GLint*>(
c.v_shm_id, c.v_shm_offset, data_size);
if (count < 0) {
@@ -2026,8 +2179,13 @@ error::Error GLES2DecoderImpl::HandleUniform3ivImmediate(
uint32 immediate_data_size, const gles2::Uniform3ivImmediate& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 3);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLint* v = GetImmediateDataAs<const GLint*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -2056,8 +2214,10 @@ error::Error GLES2DecoderImpl::HandleUniform4fv(
uint32 immediate_data_size, const gles2::Uniform4fv& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* v = GetSharedMemoryAs<const GLfloat*>(
c.v_shm_id, c.v_shm_offset, data_size);
if (count < 0) {
@@ -2075,8 +2235,13 @@ error::Error GLES2DecoderImpl::HandleUniform4fvImmediate(
uint32 immediate_data_size, const gles2::Uniform4fvImmediate& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* v = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -2105,8 +2270,10 @@ error::Error GLES2DecoderImpl::HandleUniform4iv(
uint32 immediate_data_size, const gles2::Uniform4iv& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 4);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLint* v = GetSharedMemoryAs<const GLint*>(
c.v_shm_id, c.v_shm_offset, data_size);
if (count < 0) {
@@ -2124,8 +2291,13 @@ error::Error GLES2DecoderImpl::HandleUniform4ivImmediate(
uint32 immediate_data_size, const gles2::Uniform4ivImmediate& c) {
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLint), 4);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLint), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLint* v = GetImmediateDataAs<const GLint*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -2144,8 +2316,10 @@ error::Error GLES2DecoderImpl::HandleUniformMatrix2fv(
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
GLboolean transpose = static_cast<GLboolean>(c.transpose);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* value = GetSharedMemoryAs<const GLfloat*>(
c.value_shm_id, c.value_shm_offset, data_size);
if (count < 0) {
@@ -2168,8 +2342,13 @@ error::Error GLES2DecoderImpl::HandleUniformMatrix2fvImmediate(
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
GLboolean transpose = static_cast<GLboolean>(c.transpose);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* value = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -2192,8 +2371,10 @@ error::Error GLES2DecoderImpl::HandleUniformMatrix3fv(
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
GLboolean transpose = static_cast<GLboolean>(c.transpose);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 9);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 9, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* value = GetSharedMemoryAs<const GLfloat*>(
c.value_shm_id, c.value_shm_offset, data_size);
if (count < 0) {
@@ -2216,8 +2397,13 @@ error::Error GLES2DecoderImpl::HandleUniformMatrix3fvImmediate(
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
GLboolean transpose = static_cast<GLboolean>(c.transpose);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 9);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 9, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* value = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -2240,8 +2426,10 @@ error::Error GLES2DecoderImpl::HandleUniformMatrix4fv(
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
GLboolean transpose = static_cast<GLboolean>(c.transpose);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 16);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 16, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* value = GetSharedMemoryAs<const GLfloat*>(
c.value_shm_id, c.value_shm_offset, data_size);
if (count < 0) {
@@ -2264,8 +2452,13 @@ error::Error GLES2DecoderImpl::HandleUniformMatrix4fvImmediate(
GLint location = static_cast<GLint>(c.location);
GLsizei count = static_cast<GLsizei>(c.count);
GLboolean transpose = static_cast<GLboolean>(c.transpose);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 16);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 16, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* value = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (count < 0) {
@@ -2316,8 +2509,10 @@ error::Error GLES2DecoderImpl::HandleVertexAttrib1f(
error::Error GLES2DecoderImpl::HandleVertexAttrib1fv(
uint32 immediate_data_size, const gles2::VertexAttrib1fv& c) {
GLuint indx = static_cast<GLuint>(c.indx);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
c.values_shm_id, c.values_shm_offset, data_size);
if (values == NULL) {
@@ -2330,8 +2525,13 @@ error::Error GLES2DecoderImpl::HandleVertexAttrib1fv(
error::Error GLES2DecoderImpl::HandleVertexAttrib1fvImmediate(
uint32 immediate_data_size, const gles2::VertexAttrib1fvImmediate& c) {
GLuint indx = static_cast<GLuint>(c.indx);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 1);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 1, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (values == NULL) {
@@ -2353,8 +2553,10 @@ error::Error GLES2DecoderImpl::HandleVertexAttrib2f(
error::Error GLES2DecoderImpl::HandleVertexAttrib2fv(
uint32 immediate_data_size, const gles2::VertexAttrib2fv& c) {
GLuint indx = static_cast<GLuint>(c.indx);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 2);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
c.values_shm_id, c.values_shm_offset, data_size);
if (values == NULL) {
@@ -2367,8 +2569,13 @@ error::Error GLES2DecoderImpl::HandleVertexAttrib2fv(
error::Error GLES2DecoderImpl::HandleVertexAttrib2fvImmediate(
uint32 immediate_data_size, const gles2::VertexAttrib2fvImmediate& c) {
GLuint indx = static_cast<GLuint>(c.indx);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 2);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 2, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (values == NULL) {
@@ -2391,8 +2598,10 @@ error::Error GLES2DecoderImpl::HandleVertexAttrib3f(
error::Error GLES2DecoderImpl::HandleVertexAttrib3fv(
uint32 immediate_data_size, const gles2::VertexAttrib3fv& c) {
GLuint indx = static_cast<GLuint>(c.indx);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 3);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
c.values_shm_id, c.values_shm_offset, data_size);
if (values == NULL) {
@@ -2405,8 +2614,13 @@ error::Error GLES2DecoderImpl::HandleVertexAttrib3fv(
error::Error GLES2DecoderImpl::HandleVertexAttrib3fvImmediate(
uint32 immediate_data_size, const gles2::VertexAttrib3fvImmediate& c) {
GLuint indx = static_cast<GLuint>(c.indx);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 3);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 3, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (values == NULL) {
@@ -2430,8 +2644,10 @@ error::Error GLES2DecoderImpl::HandleVertexAttrib4f(
error::Error GLES2DecoderImpl::HandleVertexAttrib4fv(
uint32 immediate_data_size, const gles2::VertexAttrib4fv& c) {
GLuint indx = static_cast<GLuint>(c.indx);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
const GLfloat* values = GetSharedMemoryAs<const GLfloat*>(
c.values_shm_id, c.values_shm_offset, data_size);
if (values == NULL) {
@@ -2444,8 +2660,13 @@ error::Error GLES2DecoderImpl::HandleVertexAttrib4fv(
error::Error GLES2DecoderImpl::HandleVertexAttrib4fvImmediate(
uint32 immediate_data_size, const gles2::VertexAttrib4fvImmediate& c) {
GLuint indx = static_cast<GLuint>(c.indx);
- uint32 data_size =
- ComputeImmediateDataSize(immediate_data_size, 1, sizeof(GLfloat), 4);
+ uint32 data_size;
+ if (!ComputeDataSize(1, sizeof(GLfloat), 4, &data_size)) {
+ return error::kOutOfBounds;
+ }
+ if (data_size > immediate_data_size) {
+ return error::kOutOfBounds;
+ }
const GLfloat* values = GetImmediateDataAs<const GLfloat*>(
c, data_size, immediate_data_size);
if (values == NULL) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
index f8dc38b..767505a 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
@@ -1117,10 +1117,8 @@ TEST_F(GLES2DecoderTest1, GetProgramInfoLogValidArgs) {
const char* kInfo = "hello";
const uint32 kBucketId = 123;
SpecializedSetup<GetProgramInfoLog, 0>();
- EXPECT_CALL(
- *gl_, GetProgramiv(
- kServiceProgramId, GL_INFO_LOG_LENGTH, _)) .WillOnce(
- SetArgumentPointee<2>(strlen(kInfo)));
+ EXPECT_CALL(*gl_, GetProgramiv(kServiceProgramId, GL_INFO_LOG_LENGTH, _))
+ .WillOnce(SetArgumentPointee<2>(strlen(kInfo)));
EXPECT_CALL(
*gl_, GetProgramInfoLog(kServiceProgramId, strlen(kInfo) + 1, _, _))
.WillOnce(DoAll(SetArgumentPointee<2>(strlen(kInfo)),
@@ -1211,10 +1209,8 @@ TEST_F(GLES2DecoderTest1, GetShaderInfoLogValidArgs) {
const char* kInfo = "hello";
const uint32 kBucketId = 123;
SpecializedSetup<GetShaderInfoLog, 0>();
- EXPECT_CALL(
- *gl_, GetShaderiv(
- kServiceShaderId, GL_INFO_LOG_LENGTH, _)) .WillOnce(
- SetArgumentPointee<2>(strlen(kInfo)));
+ EXPECT_CALL(*gl_, GetShaderiv(kServiceShaderId, GL_INFO_LOG_LENGTH, _))
+ .WillOnce(SetArgumentPointee<2>(strlen(kInfo)));
EXPECT_CALL(
*gl_, GetShaderInfoLog(kServiceShaderId, strlen(kInfo) + 1, _, _))
.WillOnce(DoAll(SetArgumentPointee<2>(strlen(kInfo)),