Skip to content

Commit 26cad3f

Browse files
committed
fix(ses): plug implicit NaN side-channel
1 parent 83c0b06 commit 26cad3f

File tree

8 files changed

+83
-7
lines changed

8 files changed

+83
-7
lines changed

packages/eslint-plugin/lib/configs/recommended.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ module.exports = {
1717
URL: 'readonly',
1818
URLSearchParams: 'readonly',
1919

20+
// These have been moved out of the list below because they open
21+
// the NaN side channel on some platforms, and so are not considered
22+
// powerless.
23+
//
24+
// https://github.com/tc39/proposal-float16array
25+
Float16Array: 'readonly',
26+
Float32Array: 'readonly',
27+
Float64Array: 'readonly',
28+
2029
// Allow what SES makes powerless, copied from its whitelist
2130
// *** Constructor Properties of the Global Object
2231
Array: 'readonly',
@@ -27,8 +36,6 @@ module.exports = {
2736
Boolean: 'readonly',
2837
DataView: 'readonly',
2938
EvalError: 'readonly',
30-
Float32Array: 'readonly',
31-
Float64Array: 'readonly',
3239
Int8Array: 'readonly',
3340
Int16Array: 'readonly',
3441
Int32Array: 'readonly',

packages/eslint-plugin/lib/configs/ses.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module.exports = {
1313
extends: ['plugin:@endo/internal'],
1414
rules: {
1515
'no-restricted-globals': [
16-
'error',
16+
'error', // TODO why is this here?
1717
'AggregateError',
1818
'Array',
1919
'ArrayBuffer',
@@ -27,6 +27,8 @@ module.exports = {
2727
'Date',
2828
'Error',
2929
'EvalError',
30+
// https://github.com/tc39/proposal-float16array
31+
'Float16Array',
3032
'Float32Array',
3133
'Float64Array',
3234
'Function',

packages/harden/test/make-hardener-shallow.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ test('harden typed arrays', t => {
7676
Uint8Array,
7777
Uint8ClampedArray,
7878
];
79+
if (typeof Float16Array !== 'undefined') {
80+
// https://github.com/tc39/proposal-float16array
81+
typedArrayConstructors.push(Float16Array);
82+
}
7983

8084
for (const TypedArray of typedArrayConstructors) {
8185
const h = makeHardener({ traversePrototypes: false });

packages/harden/test/make-hardener.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,10 @@ test('harden typed arrays', t => {
7676
Uint8Array,
7777
Uint8ClampedArray,
7878
];
79+
if (typeof Float16Array !== 'undefined') {
80+
// https://github.com/tc39/proposal-float16array
81+
typedArrayConstructors.push(Float16Array);
82+
}
7983

8084
for (const TypedArray of typedArrayConstructors) {
8185
const h = makeHardener({ traversePrototypes: true });

packages/ses/src/permits.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,7 @@ export const universalPropertyNames = {
5959
Boolean: 'Boolean',
6060
DataView: 'DataView',
6161
EvalError: 'EvalError',
62-
// https://github.com/tc39/proposal-float16array
63-
Float16Array: 'Float16Array',
64-
Float32Array: 'Float32Array',
65-
Float64Array: 'Float64Array',
62+
6663
Int8Array: 'Int8Array',
6764
Int16Array: 'Int16Array',
6865
Int32Array: 'Int32Array',
@@ -144,6 +141,18 @@ export const initialGlobalPropertyNames = {
144141

145142
Math: '%InitialMath%',
146143

144+
// We move these from universalPropertyNames because the NaN side channel
145+
// means that they are not quite harmless.
146+
// We move them to initialGlobalPropertyNames so that they'll still be
147+
// included in the primordials, repaired, and hardened. Thus, they
148+
// can be endowed into compartments without hazard beyond the
149+
// NaN side channel.
150+
//
151+
// // https://github.com/tc39/proposal-float16array
152+
Float16Array: 'Float16Array',
153+
Float32Array: 'Float32Array',
154+
Float64Array: 'Float64Array',
155+
147156
// ESNext
148157

149158
// From Error-stack proposal
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import test from 'ava';
2+
import '../index.js';
3+
4+
// The Float*Arrays are not fully harmless because they open a NaN side-channel
5+
// on some implementations like v8. However, they are still in the
6+
// start compartment, the intrinsics, and therefore repaired and frozen. They
7+
// are not endowed to constructed compartments by default, but can be
8+
// explicitly endowed.
9+
// The Int*Arrays remain fully harmless and universal.
10+
//
11+
test('float arrays in compartments', t => {
12+
t.false(Object.isFrozen(Float64Array));
13+
t.false(Object.isFrozen(Int32Array));
14+
lockdown();
15+
t.true(Object.isFrozen(Float64Array));
16+
t.true(Object.isFrozen(Int32Array));
17+
18+
const c1 = new Compartment();
19+
const c2 = new Compartment({
20+
__options__: true,
21+
globals: { Float64Array },
22+
});
23+
24+
t.false('Float64Array' in c1.globalThis);
25+
t.true('Int32Array' in c1.globalThis);
26+
t.true('Float64Array' in c2.globalThis);
27+
28+
t.is(c1.evaluate('Float64Array'), undefined);
29+
t.is(c1.evaluate('Int32Array'), Int32Array);
30+
t.is(c2.evaluate('Float64Array'), Float64Array);
31+
32+
t.throws(
33+
() => {
34+
c1.evaluate(`new Float64Array()`);
35+
},
36+
{
37+
message: 'Float64Array is not a constructor',
38+
},
39+
);
40+
t.true(c1.evaluate('new Int32Array()') instanceof Int32Array);
41+
t.true(c2.evaluate('new Float64Array()') instanceof Float64Array);
42+
});

packages/ses/test/is-typed-array.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ test('isTypedArray positive cases', t => {
1717
t.assert(isTypedArray(new Uint16Array()));
1818
t.assert(isTypedArray(new Int32Array()));
1919
t.assert(isTypedArray(new Uint32Array()));
20+
if (typeof Float16Array !== 'undefined') {
21+
// https://github.com/tc39/proposal-float16array
22+
t.assert(isTypedArray(new Float16Array()));
23+
}
2024
t.assert(isTypedArray(new Float32Array()));
2125
t.assert(isTypedArray(new Float64Array()));
2226
t.assert(isTypedArray(new BigInt64Array()));

packages/ses/test/make-hardener.test.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ test('harden typed arrays', t => {
7777
Uint8Array,
7878
Uint8ClampedArray,
7979
];
80+
if (typeof Float16Array !== 'undefined') {
81+
// https://github.com/tc39/proposal-float16array
82+
typedArrayConstructors.push(Float16Array);
83+
}
8084

8185
for (const TypedArray of typedArrayConstructors) {
8286
const h = makeHardener();

0 commit comments

Comments
 (0)