wasmerio / wasmer

🚀 The leading Wasm Runtime supporting WASIX and WASI
https://wasmer.io
MIT License
19.05k stars 815 forks source link

Failed to open the file ? #4259

Open orangeC23 opened 1 year ago

orangeC23 commented 1 year ago

Steps to reproduce

(1)The c file is :

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>

int main() {
    const char* file_name = "Data/hello.txt";
    int open_style= O_CREAT | O_RDWR;
    int fd = get_fd(file_name, open_style);
    fd_allocatejVivk62KJm(fd, file_name);
    snapshot(fd);
    return 0;
}

int fd_allocatejVivk62KJm (int fd, const char* file_name){
    off_t start_value = 13;
    off_t len_value = 83;
    return fd_allocate(fd, file_name, start_value, len_value);
}

int get_fd(const char* file_name, int open_style){
    // Open a file for reading
    int fd = open(file_name, open_style);
    if (fd == -1) {
        perror("Failed to open the file");
        return 1;
    }

    return fd;
}

int fd_allocate (int fd, const char* filename, off_t start_value, off_t len_value){
    printf("Enter fd_allocate\n");

    if (posix_fallocate(fd, start_value, len_value) != 0) {
        perror("Error allocating file space");
        close(fd);
        return 1;
    }

    printf("File '%s' created and allocated with %lld bytes of space.\n", filename, (long long)len_value);
    printf("Leave fd_allocate\n");
    return fd;
}

int snapshot(int myfd){   
    printf("Enter snapshot\n");

    struct stat file_info;
    if (fstat(myfd, &file_info) == -1) {
        perror("Error getting file attributes");
        close(myfd);
        return 1;
    }

    printf("File Size: %lld bytes \n", (long long)file_info.st_size);
    printf("File Permissions: %o \n", file_info.st_mode & ~S_IFMT); 
    printf("File Owner UID: %d \n", file_info.st_uid);
    printf("File Group GID: %d \n", file_info.st_gid); 

    off_t cur_offset = lseek(myfd, 0, SEEK_CUR);
    if (cur_offset == -1) {
        perror("Error getting current offset");
    }
    printf("Current offset: %lld \n", (long long)cur_offset);

    if (close(myfd) == -1) {
        perror("Error closing file");
        return 1;
    }

    printf("Leave snapshot\n");
}

(2) compile the c file into wasm: ./wasi-sdk-16.0/bin/clang --target=wasm32-unkown-wasi --sysroot=./wasi-sdk-16.0/share/wasi-sysroot test.c -o test.wasm (3)exeute open.wasm wasmer run --dir=./Data test.wasm The permission of Data/hello.txt is 0700 or 0600 or 0300, user1 create the Data/hello.txt file and user1 execute the Wasm file.

Expected behavior

wasmtime, wazero, wamr, and ubuntu(compile the cfile directly into native code through gcc) print:

Enter fd_datasync
Current offset: 3
File data in 'Data/hello.txt' synchronized to disk successfully.
Leave fd_datasync
Enter snapshot
File Size: 131 bytes 
File Permissions: 0 
File Owner UID: 0 
File Group GID: 0 
Current offset: 131 
Leave snapshot

And the file size is 131, and the file content are the same.

Actual behavior

wavm prints:

Failed to open the file: Capabilities insufficient
Enter fd_datasync
Error setting new offset: Invalid seek
Error getting file attributes: Bad file descriptor

And the file size is still 30.

version

wasmer 4.2.2

ubuntu 20.04

Arshia001 commented 1 year ago

Probably related to #4257 and #4270

orangeC23 commented 11 months ago

There may be some mistakes when reporting the bug. I updated this as following:

Test case

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>

int get_fd(const char* file_name, int open_style){
    int fd = open(file_name, open_style);
    if (fd == -1) {
        printf("Failed to open the file.\n");
    } else{
        printf("Successfully get the file fd.\n");
    }

    return fd;
}

int fd_datasync(int fd, const char* filename, const char* data_to_write, off_t new_offset) {
    printf("Enter fd_datasync.\n");

    if (fd == -1) {
        printf("Failed to get the file fd, cannot fd_datasync.\n");
        return 1;
    }

    if (lseek(fd, new_offset, SEEK_SET) == -1) {
        printf("Error setting new offset");
        close(fd);
        return 1;
    }

    off_t current_offset = lseek(fd, 0, SEEK_CUR);
    if (current_offset == -1) {
        printf("Error getting current offset.\n");
    }
    printf("Current offset: %lld\n", (long long)current_offset);

    ssize_t bytes_written = write(fd, data_to_write, strlen(data_to_write));
    if (bytes_written == -1) {
        printf("Error writing to file.\n");
        close(fd);
        return 1;
    }

    if (fdatasync(fd) == -1) {
        printf("Error synchronizing file data to disk.\n");
        close(fd);
        return 1;
    }

    printf("File data in '%s' synchronized to disk successfully.\n", filename);
    printf("Leave fd_datasync\n");
    return fd;
}

int snapshot(int myfd){   
    printf("Enter snapshot.\n");

    struct stat file_info;
    if (fstat(myfd, &file_info) == -1) {
        printf("Error getting file attributes.\n");
        close(myfd);
        return 1;
    }

    printf("File Size: %lld bytes \n", (long long)file_info.st_size);

    if (close(myfd) == -1) {
        printf("Error closing file.\n");
        return 1;
    }

    printf("Leave snapshot.\n");
    return 0;
}

int main() {
    const char* file_name = "Data/hello.txt";
    int open_style= O_WRONLY | O_CREAT | O_TRUNC;
    int fd = get_fd(file_name, open_style);

    const char* data_to_write = "QubHqpplBCF8OwTyrQedwl79y2kE3NbWTK1dMTHZns3AaRWCuxQQJJ89f2id56ZkWrTIrH6QsJlrZ2PrLVVqkSDyv";
    off_t new_offset = 13; 
    fd_datasync(fd, file_name, data_to_write, new_offset);

    snapshot(fd);
    return 0;
}

Expected result

Successfully get the file fd.
Enter fd_datasync.
Current offset: 13
File data in 'Data/hello.txt' synchronized to disk successfully.
Leave fd_datasync
Enter snapshot.
File Size: 102 bytes 
Leave snapshot.

Actual result

Successfully get the file fd.
Enter fd_datasync.
Current offset: 13
Error synchronizing file data to disk.
Enter snapshot.
Error getting file attributes.

Although wasmer prints error, the content has already been synced. And the file content and size are the same with other runtimes, maybe the printing message is wrong.