VYPR
Low severity2.9OSV Advisory· Published Jun 19, 2024· Updated Apr 15, 2026

CVE-2024-38358

CVE-2024-38358

Description

Wasmer is a web assembly (wasm) Runtime supporting WASIX, WASI and Emscripten. If the preopened directory has a symlink pointing outside, WASI programs can traverse the symlink and access host filesystem if the caller sets both oflags::creat and rights::fd_write. Programs can also crash the runtime by creating a symlink pointing outside with path_symlink and path_opening the link. This issue has been addressed in commit b9483d022 which has been included in release version 4.3.2. Users are advised to upgrade. There are no known workarounds for this vulnerability.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
wasmercrates.io
<= 4.3.1

Affected products

1

Patches

1
b9483d022c60

Merge pull request from GHSA-55f3-3qvg-8pv5

https://github.com/wasmerio/wasmerSyrus AkbaryJun 7, 2024via ghsa
4 files changed · +71 4
  • lib/wasix/src/syscalls/wasi/path_open.rs+16 4 modified
    @@ -330,11 +330,13 @@ pub(crate) fn path_open_internal(
                 // once we got the data we need from the parent, we lookup the host file
                 // todo: extra check that opening with write access is okay
                 let handle = {
    +                // We set create_new because the path already didn't resolve to an existing file,
    +                // so it must be created.
                     let open_options = open_options
                         .read(minimum_rights.read)
                         .append(minimum_rights.append)
                         .write(minimum_rights.write)
    -                    .create_new(minimum_rights.create_new);
    +                    .create_new(true);
     
                     if minimum_rights.read {
                         open_flags |= Fd::READ;
    @@ -349,9 +351,19 @@ pub(crate) fn path_open_internal(
                         open_flags |= Fd::TRUNCATE;
                     }
     
    -                Some(wasi_try_ok_ok!(open_options
    -                    .open(&new_file_host_path)
    -                    .map_err(|e| { fs_error_into_wasi_err(e) })))
    +                match open_options.open(&new_file_host_path) {
    +                    Ok(handle) => Some(handle),
    +                    Err(err) => {
    +                        // Even though the file does not exist, it still failed to create with
    +                        // `AlreadyExists` error.  This can happen if the path resolves to a
    +                        // symlink that points outside the FS sandbox.
    +                        if err == FsError::AlreadyExists {
    +                            return Ok(Err(Errno::Perm));
    +                        }
    +
    +                        return Ok(Err(fs_error_into_wasi_err(err)));
    +                    }
    +                }
                 };
     
                 let new_inode = {
    
  • tests/wasi-fyi/fs_sandbox_symlink.rs+53 0 added
    @@ -0,0 +1,53 @@
    +#[link(wasm_import_module = "wasi_snapshot_preview1")]
    +extern "C" {
    +    pub fn path_open(
    +        fd: i32,
    +        dirflags: i32,
    +        path: i32,
    +        path_len: i32,
    +        oflags: i32,
    +        fs_rights_base: i64,
    +        fs_rights_inheriting: i64,
    +        fdflags: i32,
    +        result_fd: i32,
    +    ) -> i32;
    +}
    +
    +const ERRNO_PERM: i32 = 63;
    +const LOOKUPFLAGS_SYMLINK_FOLLOW: i32 = 1;
    +const OFLAGS_CREAT: i32 = 1;
    +const RIGHTS_FD_WRITE: i64 = 64;
    +
    +fn main() {
    +    let link_path = "fyi/fs_sandbox_symlink.dir/link";
    +    let link_path_non_existant = "fyi/fs_sandbox_symlink.dir/link-non-existant";
    +    let mut fd: i32 = 0;
    +
    +    unsafe {
    +        let errno = path_open(
    +            5,
    +            LOOKUPFLAGS_SYMLINK_FOLLOW,
    +            link_path.as_ptr() as i32,
    +            link_path.len() as i32,
    +            OFLAGS_CREAT,
    +            RIGHTS_FD_WRITE,
    +            0,
    +            0,
    +            &mut fd as *mut i32 as i32,
    +        );
    +        assert_eq!(errno, ERRNO_PERM, "symlink cannot escape fs sandbox");
    +
    +        let errno = path_open(
    +            5,
    +            LOOKUPFLAGS_SYMLINK_FOLLOW,
    +            link_path_non_existant.as_ptr() as i32,
    +            link_path_non_existant.len() as i32,
    +            OFLAGS_CREAT,
    +            RIGHTS_FD_WRITE,
    +            0,
    +            0,
    +            &mut fd as *mut i32 as i32,
    +        );
    +        assert_eq!(errno, ERRNO_PERM, "symlink cannot escape fs sandbox");
    +    }
    +}
    
  • tests/wasi-fyi/test_fs/fyi/fs_sandbox_symlink.dir/link+1 0 added
    @@ -0,0 +1 @@
    +../../README.md
    \ No newline at end of file
    
  • tests/wasi-fyi/test_fs/fyi/fs_sandbox_symlink.dir/link-non-existant+1 0 added
    @@ -0,0 +1 @@
    +../../non-existant
    \ No newline at end of file
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.