Node: Inexplicable "RangeError: Attempt to write outside buffer bounds"

Created on 29 May 2016  Â·  4Comments  Â·  Source: nodejs/node

  • Version: v6.2.0
  • Platform: Windows 10, possibly others
  • Subsystem: buffer

I've had multiple users report a RangeError: Attempt to write outside buffer bounds error that originates inside the Buffer constructor.

Here's some code that triggers it, according to the bug reports that I've received.

var buf = new Buffer(infoHash, 'hex')

Example stack traces:

Uncaught RangeError: Attempt to write outside buffer bounds
Buffer.write @ buffer.js:772
fromString @ buffer.js:238
Buffer.from @ buffer.js:131
Buffer @ buffer.js:112
Wire.handshake @ .../node_modules/bittorrent-protocol/index.js:192
RangeError: Attempt to write outside buffer bounds
    at Buffer.write (buffer.js:772:11)
    at fromString (buffer.js:238:26)
    at Function.Buffer.from (buffer.js:131:12)
    at new Buffer (buffer.js:112:17)
    at Function.encode.buffer (../webtorrent-cli/node_modules/bencode/lib/encode.js:61:17)

The call to buf.write that's crashing is in core, and it's here. Is the buffer pool offset incorrect somehow?

I don't understand how this could happen. Apologies for not having a reproducible test case. I haven't been able to reproduce it yet and I'm out of ideas.

buffer

Most helpful comment

In future, if you think there are security implications to a bug you're seeing then it's best to use [email protected] so we can handle it in a more controlled manner. In this case it's not clear that we would handle it differently to what's being done in public because it falls in the same category as what .from and .alloc* were introduced to deal with but it might have been best for us to have this conversation in private anyway.

All 4 comments

I think I have narrowed this down a bit… is there a chance that something tried to allocate a buffer of negative size using allocUnsafe()/new Buffer(n)? That would make poolSize negative and thereby out of bounds.

PR for that: #7051

@addaleax That must be what was happening. There must be someplace where I'm passing a negative number received from a remote peer into the Buffer constructor.

This is actually a potential security issue because:

// Make buffer, fill it with a's
var buf1 = Buffer(10).fill('a')

// Reset the pool offset back to where it was before. No exception thrown!
// This happens if the programmer passes in unvalidated user data into the Buffer constructor
// (same as the previous Buffer issue, fixed with Buffer.from, etc.)
Buffer(-20)

// Makes a buffer that OVERLAPS with buf1! Write b's into it.
var buf2 = Buffer(10).fill('b')

console.log(buf1.toString()) // prints out 'bbbbbbbbbb'

Even if the user uses Buffer.from, etc. throughout most of their code, if there's just one place where they do Buffer(userJson.prop) and a negative number gets passed in from user input, then future Buffer.from calls could overlap a previous buffer without warning.

In future, if you think there are security implications to a bug you're seeing then it's best to use [email protected] so we can handle it in a more controlled manner. In this case it's not clear that we would handle it differently to what's being done in public because it falls in the same category as what .from and .alloc* were introduced to deal with but it might have been best for us to have this conversation in private anyway.

Was this page helpful?
0 / 5 - 0 ratings