tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

signal-null-check.js (5576B)


      1 // Checks if null dereference works.
      2 
      3 for (let [fieldType, signedness, defaultValue] of [
      4  ['i8', '_u', 'i32.const 42'],
      5  ['i8', '_s', 'i32.const -42'],
      6  ['i16', '_u', 'i32.const 1'],
      7  ['i16', '_s', 'i32.const -1'],
      8  ['i32', '', 'i32.const 3'],
      9  ['i64', '', 'i64.const -77777777777'],
     10  ['f32', '', 'f32.const 1.4'],
     11  ['f64', '', 'f64.const 3.14'],
     12  ['externref', '', 'ref.null extern'],
     13 ].concat(
     14  wasmSimdEnabled() ? [['v128', '', 'v128.const i32x4 1 2 -3 4']] : []
     15 )) {
     16  // Check struct.get from null struct of a field of fieldType works
     17  // Check struct.set similarly
     18  testStructGetSet(fieldType, signedness, defaultValue, 4);
     19  //   - Also when the field is in the outline_ data area?
     20  testStructGetSet(fieldType, signedness, defaultValue, 1000);
     21  // Check array.get similarly
     22  // Check array.set from null array with element of type fieldType
     23  testArrayGetSet(fieldType, signedness, defaultValue, 100);
     24 }
     25 
     26 function testStructGetSet(fieldType, signedness, defaultValue, numFields) {
     27  const ins = wasmEvalText(`
     28 (module
     29  (type $t (struct ${
     30      Array(numFields).fill("(field (mut " + fieldType + "))").join(' ')
     31  }))
     32  (global $g (mut (ref null $t)) (ref.null $t))
     33  (func (export "init-null")
     34    ref.null $t
     35    global.set $g
     36  )
     37  (func (export "init-non-null")
     38    ${ Array(numFields).fill(defaultValue).join('\n    ') }
     39    struct.new $t
     40    global.set $g
     41  )
     42  (func (export "test_get_first")
     43    global.get $g
     44    struct.get${signedness} $t 0
     45    drop
     46  )
     47  (func (export "test_set_first")
     48    global.get $g
     49    ${defaultValue}
     50    struct.set $t 0
     51  )
     52  (func (export "test_get_mid")
     53    global.get $g
     54    struct.get${signedness} $t ${numFields >> 1}
     55    drop
     56  )
     57  (func (export "test_set_mid")
     58    global.get $g
     59    ${defaultValue}
     60    struct.set $t ${numFields >> 1}
     61  )
     62  (func (export "test_get_last")
     63    global.get $g
     64    struct.get${signedness} $t ${numFields - 1}
     65    drop
     66  )
     67  (func (export "test_set_last")
     68    global.get $g
     69    ${defaultValue}
     70    struct.set $t ${numFields - 1}
     71  )
     72 )`);
     73  ins.exports["init-non-null"]();
     74  ins.exports["test_get_first"]();
     75  ins.exports["test_get_mid"]();
     76  ins.exports["test_get_last"]();
     77  ins.exports["test_set_first"]();
     78  ins.exports["test_set_mid"]();
     79  ins.exports["test_set_last"]();
     80 
     81  ins.exports["init-null"]();
     82  assertDereferenceNull(() => ins.exports["test_get_first"]());
     83  assertDereferenceNull(() => ins.exports["test_get_mid"]());
     84  assertDereferenceNull(() => ins.exports["test_get_last"]());
     85  assertDereferenceNull(() => ins.exports["test_set_first"]());
     86  assertDereferenceNull(() => ins.exports["test_set_mid"]());
     87  assertDereferenceNull(() => ins.exports["test_set_last"]());
     88 
     89  ins.exports["init-non-null"]();
     90  ins.exports["test_set_last"]();
     91  ins.exports["test_get_first"]();
     92 }
     93 
     94 function testArrayGetSet(fieldType, signedness, defaultValue, numItems) {
     95  const ins = wasmEvalText(`
     96 (module
     97  (type $t (array (mut ${fieldType})))
     98  (global $g (mut (ref null $t)) (ref.null $t))
     99  (func (export "init-null")
    100    ref.null $t
    101    global.set $g
    102  )
    103  (func (export "init-non-null")
    104    ${defaultValue}
    105    i32.const ${numItems}
    106    array.new $t
    107    global.set $g
    108  )
    109  (func (export "test_get") (param i32)
    110    global.get $g
    111    local.get 0
    112    array.get${signedness} $t
    113    drop
    114  )
    115  (func (export "test_set") (param i32)
    116    global.get $g
    117    local.get 0
    118    ${defaultValue}
    119    array.set $t
    120  )
    121 )`);
    122  ins.exports["init-non-null"]();
    123  ins.exports["test_get"](0);
    124  ins.exports["test_get"](numItems >> 1);
    125  ins.exports["test_get"](numItems - 1);
    126  ins.exports["test_set"](0);
    127  ins.exports["test_set"](numItems >> 1);
    128  ins.exports["test_set"](numItems - 1);
    129 
    130  ins.exports["init-null"]();
    131  assertDereferenceNull(() => ins.exports["test_get"](0));
    132  assertDereferenceNull(() => ins.exports["test_get"](numItems >> 1));
    133  assertDereferenceNull(() => ins.exports["test_get"](numItems - 1));
    134  assertDereferenceNull(() => ins.exports["test_set"](0));
    135  assertDereferenceNull(() => ins.exports["test_set"](numItems >> 1));
    136  assertDereferenceNull(() => ins.exports["test_set"](numItems - 1));
    137 
    138  ins.exports["init-non-null"]();
    139  ins.exports["test_set"](3);
    140  ins.exports["test_get"](0);
    141 }
    142 
    143 
    144 function assertDereferenceNull(fun) {
    145  assertErrorMessage(fun, WebAssembly.RuntimeError, /dereferencing null pointer/);
    146 }
    147 
    148 // Linear memory loads/stores from small constant addresses also require
    149 // trapsites, it seems.  So check that the following is compilable -- in
    150 // particular, that it doesn't produce any TrapSite placement validation errors.
    151 
    152 const ins = wasmEvalText(`
    153  (module
    154    (memory 1)
    155    (func (result i32) (i32.load8_s (i32.const 17)))
    156    (func (result i32) (i32.load8_u (i32.const 17)))
    157    (func (result i32) (i32.load16_s (i32.const 17)))
    158    (func (result i32) (i32.load16_u (i32.const 17)))
    159 
    160    (func (result i64) (i64.load8_s (i32.const 17)))
    161    (func (result i64) (i64.load8_u (i32.const 17)))
    162    (func (result i64) (i64.load16_s (i32.const 17)))
    163    (func (result i64) (i64.load16_u (i32.const 17)))
    164 
    165    (func (result i64) (i64.load32_s (i32.const 17)))
    166    (func (result i64) (i64.load32_u (i32.const 17)))
    167 
    168    (func (param i32) (i32.store8  (i32.const 17) (local.get 0)))
    169    (func (param i32) (i32.store16 (i32.const 17) (local.get 0)))
    170 
    171    (func (param i64) (i64.store8  (i32.const 17) (local.get 0)))
    172    (func (param i64) (i64.store16 (i32.const 17) (local.get 0)))
    173    (func (param i64) (i64.store32 (i32.const 17) (local.get 0)))
    174 
    175    (func (export "leet") (result i32) (i32.const 1337))
    176  )`);
    177 
    178 assertEq(ins.exports["leet"](), 1337);