Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dropping all references to a Global export leads to a use-after-free in returned NativeFuncs #2873

Closed
samdoiron opened this issue May 6, 2022 · 0 comments · Fixed by #2892
Labels
bug Something isn't working

Comments

@samdoiron
Copy link

samdoiron commented May 6, 2022

Describe the bug

When all references to a NativeFunc's Global externs are dropped and it is returned from a function then the extern takes a garbage value in the module.

wasmer 1.2.1 (crate) | rustc 1.60.0 (7737e0b5c 2022-04-04) | arm64

Steps to reproduce

This can be reproduce with a fresh Rust project and the following code.

use wasmer::{self, Store, imports, Instance, NativeFunc, Module, Global};

fn make_function() -> (Global, NativeFunc<(), i64>) {
    let store = Store::default();
    let wasm = wasmer::wat2wasm(r#"
    (module
        (import "global" "foo" (global $global_foo i64))
        (func $bar (result i64) (global.get $global_foo))
        (export "bar" (func $bar)))
    "#.as_bytes()).unwrap();

    let global = Global::new(&store, wasmer::Value::I64(123));
    let module = Module::new(&store, wasm).unwrap();
    let imports = imports! { "global" => { "foo" => global.clone() } };
    let instance = Instance::new(&module, &imports).unwrap();
    let func: NativeFunc<(), i64> = instance.exports.get_native_function("bar").unwrap();
    (global, func)
}

fn main() {
    let (global, func) = make_function();
    dbg!(func.call().unwrap());
    drop(global);
    dbg!(func.call().unwrap());
}

Expected behavior

The above code outputs

[src/main.rs:22] func.call().unwrap() = 123
[src/main.rs:24] func.call().unwrap() = 123

Actual behavior

The above code outputs

[src/main.rs:22] func.call().unwrap() = 123
[src/main.rs:24] func.call().unwrap() = 101649545396320

I feel like NativeFunc instances either shouldn't be able to outlive their instance's exports or should keep a reference to them internally.

Additional context

My actual use case doesn't require any of the allocation / reference counting performed by Global, and it would be nice if I could simply provide a value for immutable global exports.

@samdoiron samdoiron added the bug Something isn't working label May 6, 2022
@bors bors bot closed this as completed in #2892 Jul 19, 2022
@bors bors bot closed this as completed in 06474c1 Jul 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant