Skip to content

Commit 9fd594a

Browse files
authored
filesystem: ErrorCode::IsDirectory when opening directory with WRITE (#12136)
* filesystem: ErrorCode::IsDirectory when opening director w/o READ On Windows, it was possible to return a directory descriptor if READ wasn't in the permissions. Fixes wasmtime for WebAssembly/wasi-testsuite#176. * Fix unused-variable error * Fix the sense of the EISDIR compatibility hack I had misremembered the nature of this incompatibility. Fixed (hopefully) with a reference to POSIX. prtest:full * Update test expectations prtest:full * Update expectations for wasi-testsuite tests path_open_preopen is now working on Windows. * Possible fix for wasip1 file_open test prtest:full
1 parent 85eed83 commit 9fd594a

File tree

4 files changed

+32
-33
lines changed

4 files changed

+32
-33
lines changed

crates/test-programs/src/bin/p1_path_open_preopen.rs

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -66,37 +66,23 @@ unsafe fn path_open_preopen() {
6666
)
6767
.expect("open with O_DIRECTORY and read right");
6868

69-
if !test_programs::preview1::config().errno_expect_windows() {
70-
// Open OFLAGS_DIRECTORY and read/write rights should fail with isdir:
71-
let err = wasip1::path_open(
72-
FIRST_PREOPEN,
73-
0,
74-
".",
75-
wasip1::OFLAGS_DIRECTORY,
76-
wasip1::RIGHTS_FD_READ | wasip1::RIGHTS_FD_WRITE,
77-
0,
78-
0,
79-
)
80-
.err()
81-
.expect("open with O_DIRECTORY and read/write should fail");
82-
assert_eq!(
83-
err,
84-
wasip1::ERRNO_ISDIR,
85-
"opening directory read/write should fail with ISDIR"
86-
);
87-
} else {
88-
// Open OFLAGS_DIRECTORY and read/write rights will succeed, only on windows:
89-
let _ = wasip1::path_open(
90-
FIRST_PREOPEN,
91-
0,
92-
".",
93-
wasip1::OFLAGS_DIRECTORY,
94-
wasip1::RIGHTS_FD_READ | wasip1::RIGHTS_FD_WRITE,
95-
0,
96-
0,
97-
)
98-
.expect("open with O_DIRECTORY and read/write should succeed on windows");
99-
}
69+
// Open OFLAGS_DIRECTORY and read/write rights should fail with isdir:
70+
let err = wasip1::path_open(
71+
FIRST_PREOPEN,
72+
0,
73+
".",
74+
wasip1::OFLAGS_DIRECTORY,
75+
wasip1::RIGHTS_FD_READ | wasip1::RIGHTS_FD_WRITE,
76+
0,
77+
0,
78+
)
79+
.err()
80+
.expect("open with O_DIRECTORY and read/write should fail");
81+
assert_eq!(
82+
err,
83+
wasip1::ERRNO_ISDIR,
84+
"opening directory read/write should fail with ISDIR"
85+
);
10086
}
10187

10288
fn main() {

crates/wasi-common/src/snapshots/preview_1.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,13 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
814814
drop(dir_entry);
815815

816816
let fd = match file {
817+
// Paper over a divergence between Windows and POSIX, where
818+
// POSIX returns EISDIR if you open a directory with the
819+
// WRITE flag: https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html#:~:text=EISDIR
820+
#[cfg(windows)]
821+
OpenResult::Dir(_) if write => {
822+
return Err(types::Errno::Isdir.into());
823+
}
817824
OpenResult::File(file) => table.push(Arc::new(FileEntry::new(file, access_mode)))?,
818825
OpenResult::Dir(child_dir) => table.push(Arc::new(DirEntry::new(None, child_dir)))?,
819826
};

crates/wasi/src/filesystem.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,6 +1045,14 @@ impl Dir {
10451045
.await?;
10461046

10471047
match opened {
1048+
// Paper over a divergence between Windows and POSIX, where
1049+
// POSIX returns EISDIR if you open a directory with the
1050+
// WRITE flag: https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html#:~:text=EISDIR
1051+
#[cfg(windows)]
1052+
OpenResult::Dir(_) if flags.contains(DescriptorFlags::WRITE) => {
1053+
Err(ErrorCode::IsDirectory)
1054+
}
1055+
10481056
OpenResult::Dir(dir) => Ok(Descriptor::Dir(Dir::new(
10491057
dir,
10501058
self.perms,

tests/wasi.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ const KNOWN_FAILURES: &[&str] = &[
6464
#[cfg(windows)]
6565
"path_open_missing",
6666
#[cfg(windows)]
67-
"path_open_preopen",
68-
#[cfg(windows)]
6967
"path_open_read_write",
7068
#[cfg(windows)]
7169
"path_rename",

0 commit comments

Comments
 (0)