Stream: git-wasmtime

Topic: wasmtime / PR #13432 release-36.0.0: Fix wasmtime-wasi pa...


view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 16:34):

pchickey opened PR #13432 from pchickey:fix_ghsa_2r75_release_36 to bytecodealliance:release-36.0.0:

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.

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 16:34):

pchickey requested dicej for a review on PR #13432.

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 16:34):

pchickey requested wasmtime-wasi-reviewers for a review on PR #13432.

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 16:34):

pchickey requested wasmtime-core-reviewers for a review on PR #13432.

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 16:34):

pchickey requested fitzgen for a review on PR #13432.

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 16:34):

pchickey requested wasmtime-default-reviewers for a review on PR #13432.

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 16:39):

:thumbs_up: dicej submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 17:02):

pchickey updated PR #13432.

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 17:10):

pchickey edited PR #13432:

This is a backport of #13431 to the 36.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.

</details>

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 17:10):

pchickey has enabled auto merge for PR #13432.

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 17:26):

:check: pchickey merged PR #13432.

view this post on Zulip Wasmtime GitHub notifications bot (May 21 2026 at 19:54):

pchickey edited PR #13432:

This is a backport of #13429 to the 36.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.

</details>


Last updated: Jun 01 2026 at 09:49 UTC