Skip to content

[WasmFS] Enforce open file access mode on read/write#27249

Merged
sbc100 merged 5 commits into
emscripten-core:mainfrom
pavelsavara:wasmfs-enforce-write-access
Jul 7, 2026
Merged

[WasmFS] Enforce open file access mode on read/write#27249
sbc100 merged 5 commits into
emscripten-core:mainfrom
pavelsavara:wasmfs-enforce-write-access

Conversation

@pavelsavara

@pavelsavara pavelsavara commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

writeAtOffset and readAtOffset in system/lib/wasmfs/syscalls.cpp each carried a
// TODO: Check open file access mode for ... permissions. and never actually checked it.
As a result, WasmFS let you:

  • write to a file descriptor opened O_RDONLY, and
  • read from a file descriptor opened O_WRONLY,

both of which silently succeeded instead of failing. POSIX write(2)/read(2) require
EBADF when the descriptor is not open for the requested operation.

The change mirrors the check WasmFS already performs in the mmap path
(__syscall_mmap2, which returns -EACCES when the mapping requires an access mode the
descriptor doesn't have).

Motivation

Higher-level runtimes rely on the kernel enforcing the descriptor's access mode. For example,
.NET's System.IO maps EBADF on a write to UnauthorizedAccessException, so tests such as
RandomAccess.Write to a read-only handle and FileStream flushing a buffer on a read-only
handle expect the native write to fail. Under WasmFS these currently pass silently, diverging
from the legacy (MEMFS) JS filesystem and from every other POSIX platform.

Related dotnet/runtime#130141

Behavior change / risk

  • Programs that (incorrectly) wrote to O_RDONLY descriptors or read from O_WRONLY
    descriptors and ignored the result will now observe EBADF.

writeAtOffset and readAtOffset had a TODO to check the open file access
mode but did not, so writing to an O_RDONLY fd (or reading from an
O_WRONLY fd) silently succeeded instead of failing with EBADF as POSIX
requires. Return __WASI_ERRNO_BADF in those cases, matching the existing
check in the mmap path.
@sbc100

sbc100 commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

It looks like the failure of the other.test_wasmfs_jsfile test is probably valid?

Are there any other tests that maybe now pass under wasmfs that did not before?

Comment thread system/lib/wasmfs/syscalls.cpp Outdated
Comment thread system/lib/wasmfs/syscalls.cpp Outdated
@pavelsavara

Copy link
Copy Markdown
Contributor Author

It looks like the failure of the other.test_wasmfs_jsfile test is probably valid?

Root cause: wasmfs_create_file opens with O_CREAT | O_EXCL, and since O_RDONLY == 0, flags & O_ACCMODE is O_RDONLY - so the returned fd was technically read-only. wasmfs_jsfile.c then writes to it, which the new enforcement (correctly) rejects with EBADF. This was a latent bug that only surfaced once we started enforcing the mode.

Fixed by having wasmfs_create_file open O_CREAT | O_EXCL | O_RDWR, so the returned handle is actually writable. That's also consistent with the legacy FS, which never hands back an implicitly read-only fd on creation.

Are there any other tests that maybe now pass under wasmfs that did not before?

no, nothing newly passes

@tlively tlively left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks good, but we need testing. If there are no existing tests that are now expected to pass, then we should write a new test.

@sbc100 sbc100 changed the title WasmFS: enforce open file access mode on read/write [WasmFS] Enforce open file access mode on read/write Jul 7, 2026
Comment thread test/fs/test_access_mode.c Outdated
@sbc100 sbc100 enabled auto-merge (squash) July 7, 2026 17:37
@sbc100 sbc100 merged commit 382503c into emscripten-core:main Jul 7, 2026
39 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.

3 participants