Skip to content

Commit ab628ed

Browse files
authored
[WasmFS] Move O_TRUNC handling to avoid crash (#17192)
WasmFS backends like OPFS may reasonably expect that files will only be modified while open and may be unprepared to modify unopened files. However, when handling O_TRUNC, we truncated files before opening them in the backend. For the OPFS backend in particular, this caused a crash because the backend did not yet have an AccessHandle for the file. Fix the problem by deferring O_TRUNC handling until after we have asked the backend to open the file.
1 parent 51281a3 commit ab628ed

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

system/lib/wasmfs/syscalls.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,10 @@ static __wasi_fd_t doOpen(path::ParsedParent parsed,
465465
return -EEXIST;
466466
}
467467

468+
// Note that we open the file before truncating it because some backends may
469+
// depend on that (e.g. OPFS).
470+
auto openFile = std::make_shared<OpenFileState>(0, flags, child);
471+
468472
// If O_TRUNC, truncate the file if possible.
469473
if ((flags & O_TRUNC) && child->is<DataFile>()) {
470474
if (fileMode & WASMFS_PERM_WRITE) {
@@ -474,7 +478,6 @@ static __wasi_fd_t doOpen(path::ParsedParent parsed,
474478
}
475479
}
476480

477-
auto openFile = std::make_shared<OpenFileState>(0, flags, child);
478481
return wasmFS.getFileTable().locked().addEntry(openFile);
479482
}
480483

tests/wasmfs/wasmfs_opfs.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,17 @@ int main(int argc, char* argv[]) {
121121
err = stat("/opfs/working/foo.txt", &stat_buf);
122122
assert(err == 0);
123123
assert(stat_buf.st_size == 1);
124-
emscripten_console_log("statted");
124+
emscripten_console_log("statted while closed");
125+
126+
fd = open("/opfs/working/foo.txt", O_RDONLY | O_TRUNC);
127+
assert(fd > 0);
128+
emscripten_console_log("truncated while opening");
129+
close(fd);
130+
131+
err = stat("/opfs/working/foo.txt", &stat_buf);
132+
assert(err == 0);
133+
assert(stat_buf.st_size == 0);
134+
emscripten_console_log("statted after truncation");
125135

126136
err = rename("/opfs/working/foo.txt", "/opfs/foo.txt");
127137
assert(err == 0);

0 commit comments

Comments
 (0)