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

Unreachable code reached when executing pipe_reverse.wasm and infinitely returning bytes from WasiPipe #3349

Closed
fschutt opened this issue Nov 21, 2022 · 2 comments
Assignees
Labels
bug Something isn't working priority-high High priority issue 🏚 stale Inactive issues or PR

Comments

@fschutt
Copy link
Contributor

fschutt commented Nov 21, 2022

In c80fc58 we discovered a bug in which the recv() behaviour of the WasiPipe somehow triggers a Trap(UnreachableCode) in the wasm file.

// features: cranelift,vfs,wasi
fn main() -> anyhow::Result<()> {
    
    use wasmer_wasi::{Pipe, WasiState};
    use wasmer::{Store, Module, Instance};
    use std::io::{Write, Read};

    let bytes = include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/pipe_reverse.wasm"));

    let args: Vec<String> = Vec::new();
    let env: Vec<(String, String)> = Vec::new();
    let preopens: Vec<(String, String)> = Vec::new();
    let fs = wasmer_vfs::mem_fs::FileSystem::default();
    let mut store = Store::default();

    let mut stdout = Pipe::default().with_blocking(false);
    let mut stdin = Pipe::default().with_blocking(false);
    let stderr = Pipe::default();

    let wasi_env = WasiState::new(&args.get(0).unwrap_or(&"".to_string()))
        .args(if args.len() > 0 { &args[1..] } else { &[] })
        .envs(env)
        .set_fs(Box::new(fs))
        .stdout(Box::new(stdout.clone()))
        .stdin(Box::new(stdin.clone()))
        .stderr(Box::new(stderr.clone()))
        .map_dirs(preopens)
        .map_err(|e| anyhow::anyhow!("Couldn't preopen the dir: {}`", e))?
        .finalize(&mut store)
        .map_err(|e| anyhow::anyhow!("Failed to create the WasiState: {}`", e))?;

    let module = Module::new(&store, &bytes)?;

    let import_object = wasi_env
    .import_object(&mut store, &module)
    .map_err(|e| anyhow::anyhow!("failed to create import object: {e}"))?;

    let instance = Instance::new(&mut store, &module, &import_object)?;

    let memory = instance.exports.get_memory("memory").unwrap();
    wasi_env.data_mut(&mut store).set_memory(memory.clone());

    stdin
    .write_all(b"Hello World!")
    .map_err(|e| anyhow::anyhow!("Error writing stdin: {}`", e))?;

    let start = instance.exports.get_function("_start")
    .map_err(|_e| anyhow::anyhow!("The _start function is not present"))?;
    let _ = start.call(&mut store, &[]).unwrap();

    let mut buf = Vec::new();
    stdout
        .read_to_end(&mut buf)
        .map_err(|e| anyhow::anyhow!("Could not get the stdout bytes: {}`", e))?;

    println!("buf as slice: {}", String::from_utf8_lossy(&buf));
    
    assert_eq!(buf.as_slice(), b"!dlroW olleH\n");
    Ok(())
}

This trap can be reached by editing:

impl Read for WasiPipe {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
loop {

to:

impl Read for WasiPipe { 
     fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> { 
         buf.fill('A' as u8);
         return Ok(buf.len());
         loop { 
         // ...

The code runs for a while and then panics with:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: RuntimeError { source: Trap(UnreachableCodeReached), wasm_trace: [], native_trace:    0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: <unknown>
   7: <unknown>
   8: <unknown>
 }', examples/failing.rs:48:41
stack backtrace:
   0:        0x103f8fd10 - std::backtrace_rs::backtrace::libunwind::trace::hd589abd6c35ac4ad
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:        0x103f8fd10 - std::backtrace_rs::backtrace::trace_unsynchronized::h98ffcaaa5ca3fa1b
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:        0x103f8fd10 - std::sys_common::backtrace::_print_fmt::h6d737d3ee2f9b02c
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/sys_common/backtrace.rs:66:5
   3:        0x103f8fd10 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h188b7ef1c7993e78
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/sys_common/backtrace.rs:45:22
   4:        0x103facacc - core::fmt::write::he84a3004e7af3f34
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/fmt/mod.rs:1197:17
   5:        0x103f89bcc - std::io::Write::write_fmt::h9370b50affaab0be
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/io/mod.rs:1672:15
   6:        0x103f91508 - std::sys_common::backtrace::_print::h6a312acaf6239500
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/sys_common/backtrace.rs:48:5
   7:        0x103f91508 - std::sys_common::backtrace::print::h8d70f4e1fc358fa6
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/sys_common/backtrace.rs:35:9
   8:        0x103f91508 - std::panicking::default_hook::{{closure}}::hc074f8023cce83ca
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:295:22
   9:        0x103f91270 - std::panicking::default_hook::hef854b51b9b79ff2
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:314:9
  10:        0x103f919a0 - std::panicking::rust_panic_with_hook::h1e59e224d558a492
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:698:17
  11:        0x103f918d4 - std::panicking::begin_panic_handler::{{closure}}::he1a9d6ab32bfd8c6
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:588:13
  12:        0x103f901ec - std::sys_common::backtrace::__rust_end_short_backtrace::he9b94791b02f48cd
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/sys_common/backtrace.rs:138:18
  13:        0x103f9162c - rust_begin_unwind
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:584:5
  14:        0x103fe32dc - core::panicking::panic_fmt::h9fec86f6a9c4146e
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/panicking.rs:142:14
  15:        0x103fe3380 - core::result::unwrap_failed::h04f08301b97a771c
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/result.rs:1805:5
  16:        0x102d74df8 - core::result::Result<T,E>::unwrap::h1aec55df6c3bb3bd
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/result.rs:1098:23
  17:        0x102d8cd6c - failing::main::h5e85f16747449119
                               at /Users/fs/Development/wasmer/examples/failing.rs:48:13
  18:        0x102d9f09c - core::ops::function::FnOnce::call_once::h41719138c74700f3
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/ops/function.rs:248:5
  19:        0x102f4cd0c - std::sys_common::backtrace::__rust_begin_short_backtrace::hb380c64b3732aede
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/sys_common/backtrace.rs:122:18
  20:        0x102eb9a9c - std::rt::lang_start::{{closure}}::h8eca097130b9b4b5
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/rt.rs:145:18
  21:        0x103f8372c - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h6091bdce585e0c9c
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/ops/function.rs:280:13
  22:        0x103f8372c - std::panicking::try::do_call::h2dde559bd47c537c
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:492:40
  23:        0x103f8372c - std::panicking::try::h0be0a0414f498150
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:456:19
  24:        0x103f8372c - std::panic::catch_unwind::h0dbebda9c8fcb6e3
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panic.rs:137:14
  25:        0x103f8372c - std::rt::lang_start_internal::{{closure}}::h70683b79d9154b98
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/rt.rs:128:48
  26:        0x103f8372c - std::panicking::try::do_call::h60888734191539e8
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:492:40
  27:        0x103f8372c - std::panicking::try::h212200e2cf152f8d
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:456:19
  28:        0x103f8372c - std::panic::catch_unwind::hf4ae91ebdc2dedaf
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panic.rs:137:14
  29:        0x103f8372c - std::rt::lang_start_internal::h92a00ef694077615
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/rt.rs:128:20
  30:        0x102eb9a64 - std::rt::lang_start::hf47a86f40d0eb8cb
                               at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/rt.rs:144:17
  31:        0x102d8d0c0 - _main

This does not happen when reverting to before #3145 and editing the same lines again, meaning that something in the PR broke the logic in a way to trigger the exception in the wasm file.

Wasm file for reference:

pipe_reverse.wasm.zip

@fschutt fschutt added the bug Something isn't working label Nov 21, 2022
@fschutt fschutt self-assigned this Nov 22, 2022
@fschutt fschutt added the priority-high High priority issue label Nov 22, 2022
Copy link

stale bot commented Nov 22, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the 🏚 stale Inactive issues or PR label Nov 22, 2023
Copy link

stale bot commented Dec 23, 2023

Feel free to reopen the issue if it has been closed by mistake.

@stale stale bot closed this as completed Dec 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working priority-high High priority issue 🏚 stale Inactive issues or PR
Projects
None yet
Development

No branches or pull requests

1 participant