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

(WASI) Wrong file offset after file write in append mode #4469

Closed
ethanstanley3 opened this issue Feb 27, 2024 · 1 comment · Fixed by #4685
Closed

(WASI) Wrong file offset after file write in append mode #4469

ethanstanley3 opened this issue Feb 27, 2024 · 1 comment · Fixed by #4685
Assignees
Labels
bug Something isn't working 📦 lib-vfs About wasmer-vfs priority-medium Medium priority issue
Milestone

Comments

@ethanstanley3
Copy link

ethanstanley3 commented Feb 27, 2024

Describe the bug

echo "`wasmer -V` | `rustc -V` | `uname -m`"
wasmer 4.2.5 | rustc 1.76.0 (07dca489a 2024-02-04) | x86_64

Compiling a Rust test case to Wasm and running it with Wasmer gives a different result than when compiling to native code (x86 assembly). Other Wasm runtimes (Wasmtime, WasmEdge, WAMR, and Wasmi) are consistent with x86.

The test case (shown below) creates a file in append mode, writes an arbitrary string, seeks to the beginning of the file, writes another string, and then outputs the file offset. Wasmer outputs a different file offset than the other targets/runtimes.

use std::fs::OpenOptions;
use std::io::prelude::*;
use std::io::SeekFrom;

fn main() {
    let mut fp = OpenOptions::new()
        .append(true)
        .read(true)
        .create(true)
        .open("file")
        .unwrap();

    write!(fp, "{}", "a").unwrap();
    let _ = fp.rewind(); // seek to start of the file
    write!(fp, "{}", "b").unwrap();
    println!("{}", fp.seek(SeekFrom::Current(0)).unwrap()); // output file offset
}

Steps to reproduce

Here is a zipped Rust project that reproduces the bug:
wasmer-seek-append-bug.zip

  1. Unzip wasmer-seek-append-bug.zip
  2. Go to wasmer-seek-append-bug
  3. Compile with cargo build ; cargo build --target wasm32-wasi
  4. Run the test case with ./verify.sh
  5. Observe that Wasmer and the default target yield different outputs

My default target is x86_64-unknown-linux-gnu, and I get the following output:

Wasmer ==> 1
Default ==> 2

Expected behavior

The outputs should be the same.

Actual behavior

The outputs differ.

Note that running the test case with other Wasm runtimes yields 2.

The targets have the same behavior after the first file write and file seek i.e. both successfully write the string a to file and then set the file offset to 0.

The targets diverge after the second file write. They both write b to file, but the file offsets are updated differently. Wasmer updates the file offset to 1, which points to the b character that was just written. The other targets update the file offset to 2, or the end of the file.

The 2018 edition of POSIX states the following about file writes in append mode: "If the O_APPEND flag of the file status flags is set, the file offset shall be set to the end of the file prior to each write and no intervening file modification operation shall occur between changing the file offset and the write operation."

It also states that "Before successful return from write(), the file offset is incremented by the number of bytes actually written."

Before the second file write, the file offset should be set to the end of the file (offset 1, since the file only contains a at this point). Before the file write returns, the file offset must be incremented by one because one byte (b) was written. Therefore, the expected output is 2.

Additional context

This test case is derived from a program created by Wasimilar, an Xsmith-based random program generator.

Copy link

linear bot commented Feb 27, 2024

@Arshia001 Arshia001 added bug Something isn't working 📦 lib-vfs About wasmer-vfs priority-medium Medium priority issue labels Feb 27, 2024
@Arshia001 Arshia001 added this to the v4.3 milestone Feb 27, 2024
@Arshia001 Arshia001 self-assigned this Feb 27, 2024
@maminrayej maminrayej assigned maminrayej and unassigned Arshia001 May 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working 📦 lib-vfs About wasmer-vfs priority-medium Medium priority issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants