Closed Bug 1906451 Opened 2 years ago Closed 2 years ago

Table.set incorrectly set entries to null for not-nullable typed tables

Categories

(Core :: JavaScript: WebAssembly, defect)

Firefox 130
defect

Tracking

()

RESOLVED FIXED
130 Branch
Tracking Status
firefox130 --- fixed

People

(Reporter: alessandro, Assigned: rhunt)

Details

(Keywords: testcase)

Attachments

(2 files)

Attached file typedtable.wasm

User Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:127.0) Gecko/20100101 Firefox/127.0

Steps to reproduce:

  1. Create a WebAssembly module with a typed table using the typed funcrefs feature
  2. Initialize the table from the same module using the elements sections
  3. Export the table
  4. Read one of the previously initialized entries from the table, which is not-null as expected
  5. Store the entry back in the table using the Table.set method
  6. Extract the entry one more time

Attached is a minimal wasm file demonstrating the problem, it can be tested together with the following JS snippet designed to run on the Spidermonkey shell

{
        var buffer = await read('typedtable.wasm', 'binary');
        var ret = await WebAssembly.instantiate(buffer,{i:{m:new WebAssembly.Memory({initial:16384,maximum:16384,shared:true})}})
        var instance = ret.instance;
        var tbl = instance.exports.tbl;
        var oldFunc = tbl.get(0);
        if(oldFunc == null)
                console.log("Invalid test case: function is null");
        else
                console.log("Expected: Function is not null");
        tbl.set(0, oldFunc);
        var newFunc = tbl.get(0);
        if(oldFunc != newFunc)
                console.log("Failed: Table.set nullifies not-null table entry");
        else
                console.log("Success");
}
test();

Actual results:

Roundtripping the WebAssembly function via Table.get and Table.set introduces spurious null values in the table.

Expected results:

The function should correctly be stored in the table

Please note that a line got lost during copy-paste above. The script should start with:

async function test()
async function test()
{
        var buffer = await read('typedtable.wasm', 'binary');
        var ret = await WebAssembly.instantiate(buffer,{i:{m:new WebAssembly.Memory({initial:16384,maximum:16384,shared:true})}})
        var instance = ret.instance;
        var tbl = instance.exports.tbl;
        var oldFunc = tbl.get(0);
        if(oldFunc == null)
                print("Invalid test case: function is null");
        else
                print("Expected: Function is not null");
        tbl.set(0, oldFunc);
        var newFunc = tbl.get(0);
        if(oldFunc != newFunc)
                print("Failed: Table.set nullifies not-null table entry");
        else
                print("Success");
}
test();
changeset:   https://hg.mozilla.org/mozilla-central/rev/3e4e0fef13e0
user:        Yury Delendik
date:        Thu Sep 28 21:46:35 2023 +0000
summary:     Bug 1845373 - Enable Wasm GC proposal in release. r=rhunt

Prior to this changeset, the testcase shows a types not enabled error, but after this changeset landed (and till now), it has always showed:

Expected: Function is not null
Failed: Table.set nullifies not-null table entry

I cannot seem to find a changeset where the Success message was shown. In any case, perhaps Yury/Ryan might know more?

Flags: needinfo?(ydelendik)

This is a pre-existing bug in our wasm-GC implementation. CheckRefType returns the value through the funcref out-param, but the typed funcref case doesn't handle this right.

I don't know of any code in our system that would be exploitable by unexpectedly getting null for a non-nullable funcref, so I don't believe this is exploitable.

Assignee: nobody → rhunt
Flags: needinfo?(ydelendik)

CheckRefType used to return through one of two out-params depending
on what kind of reftype you asked for. This was not correctly handled
for typed references to functions. This is overall error prone for
little benefit, so this commit refactors this so that we always
return through an anyref out-param. Users who want a JSFunction*
can just grab that through that anyref easily.

Pushed by rhunt@eqrion.net: https://hg.mozilla.org/integration/autoland/rev/210ec778dbfc wasm: Always return an AnyRef from CheckRefType. r=bvisness
Status: UNCONFIRMED → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 130 Branch
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: