diff --git a/CHANGELOG.md b/CHANGELOG.md index 144292117fa..d0da24a7afc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## **[Unreleased]** +- [#936](https://github.com/wasmerio/wasmer/pull/939) Fix bug causing attempts to append to files with WASI to delete the contents of the file - [#940](https://github.com/wasmerio/wasmer/pull/940) Update supported Rust version to 1.38+ - [#921](https://github.com/wasmerio/wasmer/pull/921) In LLVM backend, annotate all memory accesses with TBAA metadata. - [#883](https://github.com/wasmerio/wasmer/pull/883) Allow floating point operations to have arbitrary inputs, even including SNaNs. diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index 71344335595..8d6a38140ea 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -12,6 +12,8 @@ cargo-fuzz = true wasmer-runtime = { path = "../lib/runtime" } wasmer-runtime-core = { path = "../lib/runtime-core" } wasmer = { path = "../" } +wasmer-llvm-backend = { path = "../lib/llvm-backend" } +wasmer-singlepass-backend = { path = "../lib/singlepass-backend" } libfuzzer-sys = { git = "https://github.com/rust-fuzz/libfuzzer-sys.git" } # Prevent this from interfering with workspaces diff --git a/fuzz/fuzz_targets/compile_wasm.rs b/fuzz/fuzz_targets/compile_wasm.rs index 4abe062f510..e36d8c39630 100644 --- a/fuzz/fuzz_targets/compile_wasm.rs +++ b/fuzz/fuzz_targets/compile_wasm.rs @@ -2,9 +2,24 @@ #[macro_use] extern crate libfuzzer_sys; extern crate wasmer_runtime; +extern crate wasmer_runtime_core; +extern crate wasmer_llvm_backend; +extern crate wasmer_singlepass_backend; -use wasmer_runtime::compile; +use wasmer_runtime::{compile, compile_with}; +use wasmer_runtime_core::backend::Compiler; + +fn get_llvm_compiler() -> impl Compiler { + use wasmer_llvm_backend::LLVMCompiler; + LLVMCompiler::new() +} +fn get_singlepass_compiler() -> impl Compiler { + use wasmer_singlepass_backend::SinglePassCompiler; + SinglePassCompiler::new() +} fuzz_target!(|data: &[u8]| { + let _ = compile_with(data, &get_llvm_compiler()); let _ = compile(data); + let _ = compile_with(data, &get_singlepass_compiler()); }); diff --git a/lib/wasi-tests/build/wasitests.rs b/lib/wasi-tests/build/wasitests.rs index 0144da92056..5ccda63c9fe 100644 --- a/lib/wasi-tests/build/wasitests.rs +++ b/lib/wasi-tests/build/wasitests.rs @@ -83,7 +83,7 @@ pub fn compile(file: &str, ignores: &HashSet) -> Option { .arg("+nightly") .arg("--target=wasm32-wasi") .arg("-C") - .arg("opt-level=s") + .arg("opt-level=z") .arg(file) .arg("-o") .arg(&wasm_out_name) diff --git a/lib/wasi-tests/tests/wasitests/fd_append.rs b/lib/wasi-tests/tests/wasitests/fd_append.rs new file mode 100644 index 00000000000..0ac3ea6ebf8 --- /dev/null +++ b/lib/wasi-tests/tests/wasitests/fd_append.rs @@ -0,0 +1,18 @@ +// !!! THIS IS A GENERATED FILE !!! +// ANY MANUAL EDITS MAY BE OVERWRITTEN AT ANY TIME +// Files autogenerated with cargo build (build/wasitests.rs). + +#[test] +fn test_fd_append() { + assert_wasi_output!( + "../../wasitests/fd_append.wasm", + "fd_append", + vec![], + vec![( + ".".to_string(), + ::std::path::PathBuf::from("wasitests/test_fs/temp") + ),], + vec![], + "../../wasitests/fd_append.out" + ); +} diff --git a/lib/wasi-tests/tests/wasitests/mod.rs b/lib/wasi-tests/tests/wasitests/mod.rs index 75a91d6f003..d226dc0ee0d 100644 --- a/lib/wasi-tests/tests/wasitests/mod.rs +++ b/lib/wasi-tests/tests/wasitests/mod.rs @@ -9,6 +9,7 @@ mod close_preopen_fd; mod create_dir; mod envvar; mod fd_allocate; +mod fd_append; mod fd_close; mod fd_pread; mod fd_read; diff --git a/lib/wasi-tests/wasitests/close_preopen_fd.wasm b/lib/wasi-tests/wasitests/close_preopen_fd.wasm index 56d37f64630..5badfb755e5 100755 Binary files a/lib/wasi-tests/wasitests/close_preopen_fd.wasm and b/lib/wasi-tests/wasitests/close_preopen_fd.wasm differ diff --git a/lib/wasi-tests/wasitests/create_dir.wasm b/lib/wasi-tests/wasitests/create_dir.wasm index f4a9898f0c7..0c2fb0bbf08 100755 Binary files a/lib/wasi-tests/wasitests/create_dir.wasm and b/lib/wasi-tests/wasitests/create_dir.wasm differ diff --git a/lib/wasi-tests/wasitests/envvar.wasm b/lib/wasi-tests/wasitests/envvar.wasm index 1e394c49f97..b05151905a2 100755 Binary files a/lib/wasi-tests/wasitests/envvar.wasm and b/lib/wasi-tests/wasitests/envvar.wasm differ diff --git a/lib/wasi-tests/wasitests/fd_allocate.wasm b/lib/wasi-tests/wasitests/fd_allocate.wasm index ee688bf93ad..e604f6e407d 100755 Binary files a/lib/wasi-tests/wasitests/fd_allocate.wasm and b/lib/wasi-tests/wasitests/fd_allocate.wasm differ diff --git a/lib/wasi-tests/wasitests/fd_append.out b/lib/wasi-tests/wasitests/fd_append.out new file mode 100644 index 00000000000..e9d92ef26a6 --- /dev/null +++ b/lib/wasi-tests/wasitests/fd_append.out @@ -0,0 +1 @@ +"Hello, world!\nGoodbye, world!\n" diff --git a/lib/wasi-tests/wasitests/fd_append.rs b/lib/wasi-tests/wasitests/fd_append.rs new file mode 100644 index 00000000000..f1e55c5ed9a --- /dev/null +++ b/lib/wasi-tests/wasitests/fd_append.rs @@ -0,0 +1,48 @@ +// Args: +// mapdir: .:wasitests/test_fs/temp + +use std::fs::OpenOptions; +use std::io::{Read, Write}; +use std::path::PathBuf; + +static STR1: &str = "Hello, world!\n"; +static STR2: &str = "Goodbye, world!\n"; + +fn main() { + let file = { + #[cfg(not(target_os = "wasi"))] + let mut base = PathBuf::from("wasitests/test_fs/temp"); + #[cfg(target_os = "wasi")] + let mut base = PathBuf::from("."); + + base.push("fd_append_test"); + base + }; + + { + let mut file_handle = OpenOptions::new() + .create_new(true) + .append(true) + .open(&file) + .expect("Couldn't create file"); + file_handle.write(STR1.as_bytes()).unwrap(); + } + { + let mut file_handle = OpenOptions::new() + .append(true) + .open(&file) + .expect("Couldn't reopen file to append"); + file_handle.write(STR2.as_bytes()).unwrap(); + } + + let mut file_handle = OpenOptions::new() + .read(true) + .open(&file) + .expect("Couldn't reopen file to read"); + + let mut test = String::new(); + file_handle.read_to_string(&mut test); + + assert_eq!(&test, &format!("{}{}", STR1, STR2)); + println!("{:?}", &test); +} diff --git a/lib/wasi-tests/wasitests/fd_append.wasm b/lib/wasi-tests/wasitests/fd_append.wasm new file mode 100755 index 00000000000..b1c73d14fab Binary files /dev/null and b/lib/wasi-tests/wasitests/fd_append.wasm differ diff --git a/lib/wasi-tests/wasitests/fd_close.wasm b/lib/wasi-tests/wasitests/fd_close.wasm index 5ace5206203..162e968755a 100755 Binary files a/lib/wasi-tests/wasitests/fd_close.wasm and b/lib/wasi-tests/wasitests/fd_close.wasm differ diff --git a/lib/wasi-tests/wasitests/fd_pread.wasm b/lib/wasi-tests/wasitests/fd_pread.wasm index 11031b32ef0..7b48e4959fc 100755 Binary files a/lib/wasi-tests/wasitests/fd_pread.wasm and b/lib/wasi-tests/wasitests/fd_pread.wasm differ diff --git a/lib/wasi-tests/wasitests/fd_read.wasm b/lib/wasi-tests/wasitests/fd_read.wasm index 227157f989d..799ca164514 100755 Binary files a/lib/wasi-tests/wasitests/fd_read.wasm and b/lib/wasi-tests/wasitests/fd_read.wasm differ diff --git a/lib/wasi-tests/wasitests/fd_sync.wasm b/lib/wasi-tests/wasitests/fd_sync.wasm index 497b63c9bc8..5fde9b62744 100755 Binary files a/lib/wasi-tests/wasitests/fd_sync.wasm and b/lib/wasi-tests/wasitests/fd_sync.wasm differ diff --git a/lib/wasi-tests/wasitests/file_metadata.wasm b/lib/wasi-tests/wasitests/file_metadata.wasm index 938fdc1f256..68c59917238 100755 Binary files a/lib/wasi-tests/wasitests/file_metadata.wasm and b/lib/wasi-tests/wasitests/file_metadata.wasm differ diff --git a/lib/wasi-tests/wasitests/fs_sandbox_test.wasm b/lib/wasi-tests/wasitests/fs_sandbox_test.wasm index 3f088985069..8a8c6349451 100755 Binary files a/lib/wasi-tests/wasitests/fs_sandbox_test.wasm and b/lib/wasi-tests/wasitests/fs_sandbox_test.wasm differ diff --git a/lib/wasi-tests/wasitests/fseek.wasm b/lib/wasi-tests/wasitests/fseek.wasm index ce68b75f05a..d3a7c8f8494 100755 Binary files a/lib/wasi-tests/wasitests/fseek.wasm and b/lib/wasi-tests/wasitests/fseek.wasm differ diff --git a/lib/wasi-tests/wasitests/hello.wasm b/lib/wasi-tests/wasitests/hello.wasm index 1175a7f7236..a2625868b71 100755 Binary files a/lib/wasi-tests/wasitests/hello.wasm and b/lib/wasi-tests/wasitests/hello.wasm differ diff --git a/lib/wasi-tests/wasitests/mapdir.wasm b/lib/wasi-tests/wasitests/mapdir.wasm index 849a3a6ae2f..5675534ef0b 100755 Binary files a/lib/wasi-tests/wasitests/mapdir.wasm and b/lib/wasi-tests/wasitests/mapdir.wasm differ diff --git a/lib/wasi-tests/wasitests/path_link.wasm b/lib/wasi-tests/wasitests/path_link.wasm index 306a911e651..eae511069d0 100755 Binary files a/lib/wasi-tests/wasitests/path_link.wasm and b/lib/wasi-tests/wasitests/path_link.wasm differ diff --git a/lib/wasi-tests/wasitests/path_rename.wasm b/lib/wasi-tests/wasitests/path_rename.wasm index f76120ab85a..7e613b96011 100755 Binary files a/lib/wasi-tests/wasitests/path_rename.wasm and b/lib/wasi-tests/wasitests/path_rename.wasm differ diff --git a/lib/wasi-tests/wasitests/path_symlink.wasm b/lib/wasi-tests/wasitests/path_symlink.wasm index 61bb0a0224b..c30b1637864 100755 Binary files a/lib/wasi-tests/wasitests/path_symlink.wasm and b/lib/wasi-tests/wasitests/path_symlink.wasm differ diff --git a/lib/wasi-tests/wasitests/poll_oneoff.wasm b/lib/wasi-tests/wasitests/poll_oneoff.wasm index 9510f5b83ee..009a57e8061 100755 Binary files a/lib/wasi-tests/wasitests/poll_oneoff.wasm and b/lib/wasi-tests/wasitests/poll_oneoff.wasm differ diff --git a/lib/wasi-tests/wasitests/quine.wasm b/lib/wasi-tests/wasitests/quine.wasm index 8cf55c4aca2..21fb813a378 100755 Binary files a/lib/wasi-tests/wasitests/quine.wasm and b/lib/wasi-tests/wasitests/quine.wasm differ diff --git a/lib/wasi-tests/wasitests/readlink.wasm b/lib/wasi-tests/wasitests/readlink.wasm index 26480cf84aa..d8ef0c74fee 100755 Binary files a/lib/wasi-tests/wasitests/readlink.wasm and b/lib/wasi-tests/wasitests/readlink.wasm differ diff --git a/lib/wasi-tests/wasitests/wasi_sees_virtual_root.wasm b/lib/wasi-tests/wasitests/wasi_sees_virtual_root.wasm index 7f6d3125374..0abf7729494 100755 Binary files a/lib/wasi-tests/wasitests/wasi_sees_virtual_root.wasm and b/lib/wasi-tests/wasitests/wasi_sees_virtual_root.wasm differ diff --git a/lib/wasi-tests/wasitests/writing.wasm b/lib/wasi-tests/wasitests/writing.wasm index ce7e0180a7d..0b8b96abcdf 100755 Binary files a/lib/wasi-tests/wasitests/writing.wasm and b/lib/wasi-tests/wasitests/writing.wasm differ diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 5854690352d..3db7323e7c9 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -1724,12 +1724,25 @@ pub fn path_open( } } let mut open_options = std::fs::OpenOptions::new(); + let write_permission = adjusted_rights & __WASI_RIGHT_FD_WRITE != 0; + // append, truncate, and create all require the permission to write + let (append_permission, truncate_permission, create_permission) = + if write_permission { + ( + fs_flags & __WASI_FDFLAG_APPEND != 0, + o_flags & __WASI_O_TRUNC != 0, + o_flags & __WASI_O_CREAT != 0, + ) + } else { + (false, false, false) + }; let open_options = open_options .read(true) // TODO: ensure these rights are actually valid given parent, etc. - .write(adjusted_rights & __WASI_RIGHT_FD_WRITE != 0) - .create(o_flags & __WASI_O_CREAT != 0) - .truncate(o_flags & __WASI_O_TRUNC != 0); + .write(write_permission) + .create(create_permission) + .append(append_permission) + .truncate(truncate_permission); open_flags |= Fd::READ; if adjusted_rights & __WASI_RIGHT_FD_WRITE != 0 { open_flags |= Fd::WRITE; @@ -1798,6 +1811,7 @@ pub fn path_open( let mut open_options = std::fs::OpenOptions::new(); let open_options = open_options .read(true) + .append(fs_flags & __WASI_FDFLAG_APPEND != 0) // TODO: ensure these rights are actually valid given parent, etc. // write access is required for creating a file .write(true)