summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2013-01-17 01:10:15 +0100
committerBen Noordhuis <info@bnoordhuis.nl>2013-01-17 01:22:11 +0100
commit498200b87c186658c867772bd6cf0c8afcb2b56b (patch)
treeaa5c9c7af6719e5ce1e27cae2ad36b7251af6b8a
parent6b4a93577b5677f9738f6dd7d7acd71f86f46888 (diff)
downloadnode-498200b87c186658c867772bd6cf0c8afcb2b56b.tar.gz
buffer: reject negative SlowBuffer offsets
Reject negative offsets in SlowBuffer::MakeFastBuffer(), it allows the creation of buffers that point to arbitrary addresses. Reported by Trevor Norris.
-rw-r--r--lib/buffer.js2
-rw-r--r--src/node_buffer.cc13
-rw-r--r--test/simple/test-buffer.js45
3 files changed, 59 insertions, 1 deletions
diff --git a/lib/buffer.js b/lib/buffer.js
index ca53ab951..978a566bc 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -557,7 +557,7 @@ Buffer.prototype.slice = function(start, end) {
if (end === undefined) end = this.length;
if (end > this.length) throw new Error('oob');
if (start > end) throw new Error('oob');
-
+ if (start < 0) throw new Error('start out of bounds');
return new Buffer(this.parent, end - start, +start + this.offset);
};
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index 98dfa5e00..4a6e83665 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -708,6 +708,19 @@ Handle<Value> Buffer::MakeFastBuffer(const Arguments &args) {
uint32_t offset = args[2]->Uint32Value();
uint32_t length = args[3]->Uint32Value();
+ if (offset > buffer->length_) {
+ return ThrowRangeError("offset out of range");
+ }
+
+ if (offset + length > buffer->length_) {
+ return ThrowRangeError("length out of range");
+ }
+
+ // Check for wraparound. Safe because offset and length are unsigned.
+ if (offset + length < offset) {
+ return ThrowRangeError("offset or length out of range");
+ }
+
fast_buffer->SetIndexedPropertiesToExternalArrayData(buffer->data_ + offset,
kExternalUnsignedByteArray,
length);
diff --git a/test/simple/test-buffer.js b/test/simple/test-buffer.js
index 25688182b..c1f5dea8c 100644
--- a/test/simple/test-buffer.js
+++ b/test/simple/test-buffer.js
@@ -22,6 +22,7 @@
var common = require('../common');
var assert = require('assert');
+var SlowBuffer = require('buffer').SlowBuffer;
var Buffer = require('buffer').Buffer;
var b = Buffer(1024); // safe constructor
@@ -745,3 +746,47 @@ assert.throws(function() {
assert.throws(function() {
new Buffer(0xFFFFFFFFF);
}, TypeError);
+
+// SlowBuffer sanity checks.
+assert.throws(function() {
+ var len = 0xfffff;
+ var sbuf = new SlowBuffer(len);
+ var buf = new Buffer(sbuf, len, 0);
+ SlowBuffer.makeFastBuffer(sbuf, buf, -len, len); // Should throw.
+ for (var i = 0; i < len; ++i) buf[i] = 0x42; // Try to force segfault.
+}, RangeError);
+
+assert.throws(function() {
+ var len = 0xfffff;
+ var sbuf = new SlowBuffer(len);
+ var buf = new Buffer(sbuf, len, -len); // Should throw.
+ for (var i = 0; i < len; ++i) buf[i] = 0x42; // Try to force segfault.
+}, RangeError);
+
+assert.throws(function() {
+ var len = 0xfffff;
+ var sbuf = new SlowBuffer(len);
+ sbuf = sbuf.slice(-len); // Should throw.
+ for (var i = 0; i < len; ++i) sbuf[i] = 0x42; // Try to force segfault.
+}, RangeError);
+
+assert.throws(function() {
+ var sbuf = new SlowBuffer(1);
+ var buf = new Buffer(sbuf, 1, 0);
+ buf.length = 0xffffffff;
+ buf.slice(0xffffff0, 0xffffffe); // Should throw.
+}, Error);
+
+assert.throws(function() {
+ var sbuf = new SlowBuffer(8);
+ var buf = new Buffer(sbuf, 8, 0);
+ buf.slice(-8); // Should throw. Throws Error instead of RangeError
+ // for the sake of v0.8 compatibility.
+}, Error);
+
+assert.throws(function() {
+ var sbuf = new SlowBuffer(16);
+ var buf = new Buffer(sbuf, 8, 8);
+ buf.slice(-8); // Should throw. Throws Error instead of RangeError
+ // for the sake of v0.8 compatibility.
+}, Error);