summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2013-01-10 00:39:44 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2013-01-10 00:55:27 +0100
commited825f488867d7586bee6ca4feb5fe5b0461775e (patch)
treefef6394778e72538ea85bb9fa63d4bb1a9110e97
parentaa742ddf80f104bc4f13321668a4ede0c518cd4a (diff)
downloadnode-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.cc19
-rw-r--r--test/simple/test-typed-arrays.js10
2 files changed, 23 insertions, 6 deletions
diff --git a/src/v8_typed_array.cc b/src/v8_typed_array.cc
index d1437cdcd..783ce3417 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 00bf61354..cf6b76007 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/);