From 5bbbb282be638f2d12825ab6422e7c0b505e0001 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Sat, 11 Mar 2017 17:07:48 -0800 Subject: [PATCH] buffer: random-fill Buffer(num) and new Buffer(num) Selects a random byte and fills Buffer(num) and new Buffer(num) automatically using the randomly selected value. Why random-fill vs. zero-fill? Prior to this commit, the uninitialized Buffer allocation would be potentially filled with non-zeroed data. By filling with a randomly selected value, we eliminate the possibility of leaking uninitialized data but we preserve the need for users to completely over-write the Buffer contents in order for it to be useful. Zero-filling by default would *potentially* put users at risk if module developers assume that the Buffer instance will always be zero-filled (which will not be the case on older versions of Node.js). The cost, however, is that filling with a randomly selected value is a bit less performant than zero-filling on allocation. Note that Buffer.allocUnsafe() and Buffer.alloc() are *not* affected by this change. Buffer.allocUnsafe() will returns a Buffer with uninitialized data and Buffer.alloc() returns *zero-filled* data. --- lib/buffer.js | 5 ++++- src/node_config.cc | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/buffer.js b/lib/buffer.js index 415f37238db7cc..c2383b6d7a032c 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -22,11 +22,14 @@ 'use strict'; const binding = process.binding('buffer'); +const config = process.binding('config'); const { compare: compare_, compareOffset } = binding; const { isArrayBuffer, isSharedArrayBuffer, isUint8Array } = process.binding('util'); const bindingObj = {}; const internalUtil = require('internal/util'); +const zeroFillBuffers = !!config.zeroFillBuffers; +const randomFill = zeroFillBuffers ? 0 : Math.floor(Math.random() * 256); class FastBuffer extends Uint8Array { constructor(arg1, arg2, arg3) { @@ -102,7 +105,7 @@ function Buffer(arg, encodingOrOffset, length) { 'If encoding is specified then the first argument must be a string' ); } - return Buffer.allocUnsafe(arg); + return Buffer.allocUnsafe(arg).fill(randomFill); } return Buffer.from(arg, encodingOrOffset, length); } diff --git a/src/node_config.cc b/src/node_config.cc index 5c9c51585baf3a..8ad30afdae38db 100644 --- a/src/node_config.cc +++ b/src/node_config.cc @@ -1,4 +1,5 @@ #include "node.h" +#include "node_buffer.h" #include "node_i18n.h" #include "env.h" #include "env-inl.h" @@ -49,6 +50,9 @@ void InitConfig(Local target, if (config_preserve_symlinks) READONLY_BOOLEAN_PROPERTY("preserveSymlinks"); + if (zero_fill_all_buffers) + READONLY_BOOLEAN_PROPERTY("zeroFillBuffers"); + if (!config_warning_file.empty()) { Local name = OneByteString(env->isolate(), "warningFile"); Local value = String::NewFromUtf8(env->isolate(),