Skip to content

release-44.0.0: Fix wasmtime-wasi path_open(TRUNCATE) bypass of FilePerms::WRITE check#13431

Merged
pchickey merged 5 commits into
bytecodealliance:release-44.0.0from
pchickey:fix_ghsa_2r75_release_44
May 21, 2026
Merged

release-44.0.0: Fix wasmtime-wasi path_open(TRUNCATE) bypass of FilePerms::WRITE check#13431
pchickey merged 5 commits into
bytecodealliance:release-44.0.0from
pchickey:fix_ghsa_2r75_release_44

Conversation

@pchickey
Copy link
Copy Markdown
Contributor

@pchickey pchickey commented May 21, 2026

This is a backport of #13429 to the 44.0.0 release branch.

Details

In wasmtime-wasi, when a filesystem preopen is given DirPerms::all() and FilePerms::READ without FilePerms::WRITE, this wasmtime-wasi enforced access control mechanism can be bypassed by using the wasip2 descriptor.open-at or wasip1 path_open interfaces by opening a file with OpenFlags::TRUNCATE oflag only, for example:

dir_descriptor.open_at(
   PathFlags::empty(),
   FILENAME,
   OpenFlags::TRUNCATE,
   DescriptorFlags::READ,
)
wasip1::path_open(
    dir_fd,
    0,
    FILENAME,
    wasip1::OFLAGS_TRUNC,
    wasip1::RIGHTS_FD_READ,
    0,
    0
)

The root cause is that the clause that considered OpenFlags::TRUNCATE did not set open_mode |= OpenMode::WRITE;, used later in that function for the access control check against FilePerms for whether opening that file is permitted. With the bug corrected, these calls to open-at and path_open fail with error-code.not-permitted and ERRNO_PERM respectively.

The bug in crates/wasi/src/filesystem.rs, Dir::open_at, lines 967–969:

if oflags.contains(OpenFlags::TRUNCATE) {
    opts.truncate(true).write(true);
}

and the single line fix is:

if oflags.contains(OpenFlags::TRUNCATE) {
    opts.truncate(true).write(true);
    open_mode |= OpenMode::WRITE;
}

Only wasmtime-wasi embeddings that use a combination of DirPerms::MUTATE with FilePerms::READ are affected by this bug, e.g. those that use in the WasiCtxBuilder:

builder.preopened_dir("readonly", "readonly", DirPerms::READ | DirPerms::MUTATE, FilePerms::READ);

In particular, the Wasmtime project's wasmtime-cli's use of wasmtime-wasi is not affected, because it always sets FilePerms::all() for all preopens.

pchickey added 3 commits May 20, 2026 15:08
In wasmtime-wasi, when a filesystem preopen is given DirPerms::all() and FilePerms::READ without FilePerms::WRITE, this wasmtime-wasi enforced access control mechanism can be bypassed by using the wasip2 descriptor.open-at or wasip1 path_open interfaces by opening a file with OpenFlags::TRUNCATE oflag only, for example:

```rust
dir_descriptor.open_at(
   PathFlags::empty(),
   FILENAME,
   OpenFlags::TRUNCATE,
   DescriptorFlags::READ,
)
```
or
```rust
wasip1::path_open(
    dir_fd,
    0,
    FILENAME,
    wasip1::OFLAGS_TRUNC,
    wasip1::RIGHTS_FD_READ,
    0,
    0
)
```
The root cause is that the clause that considered OpenFlags::TRUNCATE did not set open_mode |= OpenMode::WRITE;, used later in that function for the access control check against FilePerms for whether opening that file is permitted. With the bug corrected, these calls to open-at and path_open fail with error-code.not-permitted and ERRNO_PERM respectively.

This commit contains the fix for the above bug, and tests for the fix.
@pchickey pchickey requested review from a team as code owners May 21, 2026 16:34
@pchickey pchickey requested review from dicej and fitzgen and removed request for a team May 21, 2026 16:34
@pchickey
Copy link
Copy Markdown
Contributor Author

pchickey commented May 21, 2026

One of the macos ci runners has hung and the cancel button isnt working, closing and reopening to hopefully get a fresh run?

@pchickey pchickey closed this May 21, 2026
auto-merge was automatically disabled May 21, 2026 17:31

Pull request was closed

@pchickey pchickey reopened this May 21, 2026
@pchickey pchickey enabled auto-merge (squash) May 21, 2026 17:35
@pchickey pchickey merged commit 9f5d851 into bytecodealliance:release-44.0.0 May 21, 2026
350 of 354 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants