diff --git a/lib/wasix/src/syscalls/wasi/path_open.rs b/lib/wasix/src/syscalls/wasi/path_open.rs index 833dc3a3df7..2607d371aef 100644 --- a/lib/wasix/src/syscalls/wasi/path_open.rs +++ b/lib/wasix/src/syscalls/wasi/path_open.rs @@ -273,8 +273,12 @@ pub(crate) fn path_open_internal( return Ok(Err(Errno::Notcapable)); } } - Kind::Dir { .. } - | Kind::Socket { .. } + Kind::Dir { .. } => { + if fs_rights_base.contains(Rights::FD_WRITE) { + return Ok(Err(Errno::Isdir)); + } + } + Kind::Socket { .. } | Kind::Pipe { .. } | Kind::EventNotifications { .. } | Kind::Epoll { .. } => {} diff --git a/tests/wasi-fyi/fs_open_dir_write.rs b/tests/wasi-fyi/fs_open_dir_write.rs new file mode 100644 index 00000000000..7c6bb97e8ec --- /dev/null +++ b/tests/wasi-fyi/fs_open_dir_write.rs @@ -0,0 +1,39 @@ +#[link(wasm_import_module = "wasi_snapshot_preview1")] +extern "C" { + pub fn path_open( + fd: i32, + dirflags: i32, + path: i32, + path_len: i32, + oflags: i32, + fs_rights_base: i64, + fs_rights_inheriting: i64, + fdflags: i32, + result_fd: i32, + ) -> i32; +} + +const ERRNO_ISDIR: i32 = 31; +const RIGHTS_FD_WRITE: i64 = 64; + +fn main() { + unsafe { + let base_fd = 5; + let path = "fyi/fs_open_dir_write.dir"; + let errno = path_open( + base_fd, + 0, + path.as_ptr() as i32, + path.as_bytes().len() as i32, + 0, + RIGHTS_FD_WRITE, + 0, + 0, + 1024, + ); + assert_eq!( + errno, ERRNO_ISDIR, + "opening a dir with rights::fd_write should fail" + ); + } +} diff --git a/tests/wasi-fyi/test_fs/fyi/fs_open_dir_write.dir/.ignore b/tests/wasi-fyi/test_fs/fyi/fs_open_dir_write.dir/.ignore new file mode 100644 index 00000000000..e69de29bb2d