Skip to content

Commit d937874

Browse files
addaleaxBridgeAR
authored andcommitted
buffer: mark pool ArrayBuffer as untransferable
This removes a footgun in which users could attempt to transfer the pooled ArrayBuffer underlying a regular `Buffer`, which would lead to all `Buffer`s that share the same pool being rendered unusable as well, and potentially break creation of new pooled `Buffer`s. This disables this kind of transfer. Refs: #32752 PR-URL: #32759 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Richard Lau <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent c0e4ac4 commit d937874

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

lib/buffer.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,13 @@ const {
5959
zeroFill: bindingZeroFill
6060
} = internalBinding('buffer');
6161
const {
62+
arraybuffer_untransferable_private_symbol,
6263
getOwnNonIndexProperties,
6364
propertyFilter: {
6465
ALL_PROPERTIES,
6566
ONLY_ENUMERABLE
66-
}
67+
},
68+
setHiddenValue,
6769
} = internalBinding('util');
6870
const {
6971
customInspectSymbol,
@@ -153,6 +155,7 @@ function createUnsafeBuffer(size) {
153155
function createPool() {
154156
poolSize = Buffer.poolSize;
155157
allocPool = createUnsafeBuffer(poolSize).buffer;
158+
setHiddenValue(allocPool, arraybuffer_untransferable_private_symbol, true);
156159
poolOffset = 0;
157160
}
158161
createPool();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
'use strict';
2+
require('../common');
3+
const assert = require('assert');
4+
const { MessageChannel } = require('worker_threads');
5+
6+
// Make sure that the pools used by the Buffer implementation are not
7+
// transferable.
8+
// Refs: https://github.com/nodejs/node/issues/32752
9+
10+
const a = Buffer.from('hello world');
11+
const b = Buffer.from('hello world');
12+
assert.strictEqual(a.buffer, b.buffer);
13+
const length = a.length;
14+
15+
const { port1 } = new MessageChannel();
16+
port1.postMessage(a, [ a.buffer ]);
17+
18+
// Verify that the pool ArrayBuffer has not actually been transfered:
19+
assert.strictEqual(a.buffer, b.buffer);
20+
assert.strictEqual(a.length, length);

0 commit comments

Comments
 (0)