Skip to content

Memory corruption in WASI build #774

@Hakkin

Description

@Hakkin

Hi, I seem to have come across some kind of memory-corruption(?) bug while trying to use the WASI build.
This is the script I was running, it is an obfuscated function extracted from the YouTube player JS.
I added a bit of debug code to the middle of the function here:

    let getHandler = function(target, property, receiver) {
        console.log(typeof property);
        return Reflect.get(target, property, receiver);
    }
    let p = new Proxy(N,{get:getHandler});
    N = p;

I originally was trying to run this using wazero, but got the following output:

$ wazero run --mount .:/:ro qjs-wasi.wasm youtube.js
string
string
(...)
string
symbol
string
string
string
string
string
string
string
string
string
stri¡�
stri¡�
stri¡�
stri¡�
error instantiating wasm binary: module[] function[_start] failed: wasm error: out of bounds memory access
wasm stack trace:
        .JS_ToCStringLen2(i32,i32,i64,i32) i32
        .js_print(i32,i64,i32,i32) i64
        .js_call_c_function(i32,i64,i64,i32,i32,i32) i64
        .JS_CallInternal(i32,i64,i64,i64,i32,i32,i32) i64
        .JS_CallInternal(i32,i64,i64,i64,i32,i32,i32) i64
        .js_proxy_get(i32,i64,i32,i64) i64
        .JS_GetPropertyInternal2(i32,i64,i32,i64,i32,i32) i64
        .JS_ToPrimitiveFree(i32,i64,i32) i64
        .JS_ToStringInternal(i32,i64,i32) i64
        .JS_ToStringFree(i32,i64) i64
        .string_buffer_concat_value_free(i32,i64) i32
        .js_array_join(i32,i64,i32,i32,i32) i64
        .js_call_c_function(i32,i64,i64,i32,i32,i32) i64
        .JS_CallInternal(i32,i64,i64,i64,i32,i32,i32) i64
        .js_array_toString(i32,i64,i32,i32) i64
        .js_call_c_function(i32,i64,i64,i32,i32,i32) i64
        .JS_CallInternal(i32,i64,i64,i64,i32,i32,i32) i64
        .JS_ToPrimitiveFree(i32,i64,i32) i64
        .JS_ToStringInternal(i32,i64,i32) i64
        .JS_ToStringFree(i32,i64) i64
        .string_buffer_concat_value_free(i32,i64) i32
        .js_array_join(i32,i64,i32,i32,i32) i64
        .js_call_c_function(i32,i64,i64,i32,i32,i32) i64
        .JS_CallInternal(i32,i64,i64,i64,i32,i32,i32) i64
        .js_array_toString(i32,i64,i32,i32) i64
        .js_call_c_function(i32,i64,i64,i32,i32,i32) i64
        .JS_CallInternal(i32,i64,i64,i64,i32,i32,i32) i64
        .JS_ToPrimitiveFree(i32,i64,i32) i64
        .JS_ToStringInternal(i32,i64,i32) i64
        .JS_ToStringFree(i32,i64) i64
        ... maybe followed by omitted frames

I thought this might be a bug with wazero, so I attempted using wasmer, but got the same results:

$ wasmer run --mapdir /:. qjs-wasi.wasm youtube.js
string
string
(...)
string
symbol
string
string
string
string
string
string
string
string
string
stri¡�
stri¡�
stri¡�
stri¡�
[05:14:49:627 - 0]: wasm_runtime_malloc failed: memory hasn't been initialize.

[05:14:49:628 - 0]: Init vector failed: alloc memory failed.

The couple stri¡� before it crashes leads me to believe the script is causing some kind of memory corruption in the WASM runtime.

Running this script using the native version (seemingly?) works correctly, though I can't guarantee there isn't some kind of subtle memory corruption going on:

$ qjs youtube.js
string
string
(...)
string
string
B08_QXeAL9aa3Q

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions