diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2013-01-10 00:39:44 +0100 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2013-01-10 00:55:27 +0100 |
commit | ed825f488867d7586bee6ca4feb5fe5b0461775e (patch) | |
tree | fef6394778e72538ea85bb9fa63d4bb1a9110e97 | |
parent | aa742ddf80f104bc4f13321668a4ede0c518cd4a (diff) | |
download | node-new-ed825f488867d7586bee6ca4feb5fe5b0461775e.tar.gz |
typed arrays: fix 32 bit size/index overflow
Fix an out-of-bound read/write bug due to integer wrapping. Reported by
Dean McNamee.
-rw-r--r-- | src/v8_typed_array.cc | 19 | ||||
-rw-r--r-- | test/simple/test-typed-arrays.js | 10 |
2 files changed, 23 insertions, 6 deletions
diff --git a/src/v8_typed_array.cc b/src/v8_typed_array.cc index d1437cdcdf..783ce3417b 100644 --- a/src/v8_typed_array.cc +++ b/src/v8_typed_array.cc @@ -21,6 +21,7 @@ #include <stdlib.h> // calloc, etc #include <string.h> // memmove +#include <stdint.h> #include "v8_typed_array.h" #include "node_buffer.h" @@ -722,11 +723,14 @@ class DataView { // TODO(deanm): All of these things should be cacheable. int element_size = SizeOfArrayElementForType( args.This()->GetIndexedPropertiesExternalArrayDataType()); - int size = args.This()->GetIndexedPropertiesExternalArrayDataLength() * - element_size; + assert(element_size > 0); + int size = args.This()->GetIndexedPropertiesExternalArrayDataLength(); + assert(size >= 0); - if (index + sizeof(T) > (unsigned)size) // TODO(deanm): integer overflow. + if (static_cast<uint64_t>(index) + sizeof(T) > + static_cast<uint64_t>(size) * element_size) { return ThrowError("Index out of range."); + } void* ptr = args.This()->GetIndexedPropertiesExternalArrayData(); return cTypeToValue<T>(getValue<T>(ptr, index, !little_endian)); @@ -742,11 +746,14 @@ class DataView { // TODO(deanm): All of these things should be cacheable. int element_size = SizeOfArrayElementForType( args.This()->GetIndexedPropertiesExternalArrayDataType()); - int size = args.This()->GetIndexedPropertiesExternalArrayDataLength() * - element_size; + assert(element_size > 0); + int size = args.This()->GetIndexedPropertiesExternalArrayDataLength(); + assert(size >= 0); - if (index + sizeof(T) > (unsigned)size) // TODO(deanm): integer overflow. + if (static_cast<uint64_t>(index) + sizeof(T) > + static_cast<uint64_t>(size) * element_size) { return ThrowError("Index out of range."); + } void* ptr = args.This()->GetIndexedPropertiesExternalArrayData(); setValue<T>(ptr, index, valueToCType<T>(args[1]), !little_endian); diff --git a/test/simple/test-typed-arrays.js b/test/simple/test-typed-arrays.js index 00bf613543..cf6b760075 100644 --- a/test/simple/test-typed-arrays.js +++ b/test/simple/test-typed-arrays.js @@ -182,3 +182,13 @@ assert.equal(uint8c[1], 255); var view = new DataView(array.buffer); for (var i = 128; i <= 255; ++i) assert.equal(view.getInt8(i - 128), i - 256); })(); + +assert.throws(function() { + var buf = new DataView(new ArrayBuffer(8)); + buf.getFloat64(0xffffffff, true); +}, /Index out of range/); + +assert.throws(function() { + var buf = new DataView(new ArrayBuffer(8)); + buf.setFloat64(0xffffffff, 0.0, true); +}, /Index out of range/); |