Skip to content

Commit ed825f4

Browse files
committed
typed arrays: fix 32 bit size/index overflow
Fix an out-of-bound read/write bug due to integer wrapping. Reported by Dean McNamee.
1 parent aa742dd commit ed825f4

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

src/v8_typed_array.cc

+13-6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <stdlib.h> // calloc, etc
2323
#include <string.h> // memmove
24+
#include <stdint.h>
2425

2526
#include "v8_typed_array.h"
2627
#include "node_buffer.h"
@@ -722,11 +723,14 @@ class DataView {
722723
// TODO(deanm): All of these things should be cacheable.
723724
int element_size = SizeOfArrayElementForType(
724725
args.This()->GetIndexedPropertiesExternalArrayDataType());
725-
int size = args.This()->GetIndexedPropertiesExternalArrayDataLength() *
726-
element_size;
726+
assert(element_size > 0);
727+
int size = args.This()->GetIndexedPropertiesExternalArrayDataLength();
728+
assert(size >= 0);
727729

728-
if (index + sizeof(T) > (unsigned)size) // TODO(deanm): integer overflow.
730+
if (static_cast<uint64_t>(index) + sizeof(T) >
731+
static_cast<uint64_t>(size) * element_size) {
729732
return ThrowError("Index out of range.");
733+
}
730734

731735
void* ptr = args.This()->GetIndexedPropertiesExternalArrayData();
732736
return cTypeToValue<T>(getValue<T>(ptr, index, !little_endian));
@@ -742,11 +746,14 @@ class DataView {
742746
// TODO(deanm): All of these things should be cacheable.
743747
int element_size = SizeOfArrayElementForType(
744748
args.This()->GetIndexedPropertiesExternalArrayDataType());
745-
int size = args.This()->GetIndexedPropertiesExternalArrayDataLength() *
746-
element_size;
749+
assert(element_size > 0);
750+
int size = args.This()->GetIndexedPropertiesExternalArrayDataLength();
751+
assert(size >= 0);
747752

748-
if (index + sizeof(T) > (unsigned)size) // TODO(deanm): integer overflow.
753+
if (static_cast<uint64_t>(index) + sizeof(T) >
754+
static_cast<uint64_t>(size) * element_size) {
749755
return ThrowError("Index out of range.");
756+
}
750757

751758
void* ptr = args.This()->GetIndexedPropertiesExternalArrayData();
752759
setValue<T>(ptr, index, valueToCType<T>(args[1]), !little_endian);

test/simple/test-typed-arrays.js

+10
Original file line numberDiff line numberDiff line change
@@ -182,3 +182,13 @@ assert.equal(uint8c[1], 255);
182182
var view = new DataView(array.buffer);
183183
for (var i = 128; i <= 255; ++i) assert.equal(view.getInt8(i - 128), i - 256);
184184
})();
185+
186+
assert.throws(function() {
187+
var buf = new DataView(new ArrayBuffer(8));
188+
buf.getFloat64(0xffffffff, true);
189+
}, /Index out of range/);
190+
191+
assert.throws(function() {
192+
var buf = new DataView(new ArrayBuffer(8));
193+
buf.setFloat64(0xffffffff, 0.0, true);
194+
}, /Index out of range/);

0 commit comments

Comments
 (0)