diff --git a/system/lib/wasmfs/syscalls.cpp b/system/lib/wasmfs/syscalls.cpp index 0b6acf681b16b..9100ac5d2dd00 100644 --- a/system/lib/wasmfs/syscalls.cpp +++ b/system/lib/wasmfs/syscalls.cpp @@ -112,6 +112,12 @@ static __wasi_errno_t writeAtOffset(OffsetHandling setOffset, return __WASI_ERRNO_ISDIR; } + // A file opened for reading only (O_RDONLY) cannot be written. POSIX write(2) + // returns EBADF when the file descriptor is not open for writing. + if ((lockedOpenFile.getFlags() & O_ACCMODE) == O_RDONLY) { + return __WASI_ERRNO_BADF; + } + auto lockedFile = file->locked(); if (setOffset == OffsetHandling::OpenFileState) { @@ -128,8 +134,6 @@ static __wasi_errno_t writeAtOffset(OffsetHandling setOffset, } } - // TODO: Check open file access mode for write permissions. - size_t bytesWritten = 0; for (size_t i = 0; i < iovs_len; i++) { const uint8_t* buf = iovs[i].buf; @@ -198,8 +202,6 @@ static __wasi_errno_t readAtOffset(OffsetHandling setOffset, return __WASI_ERRNO_INVAL; } - // TODO: Check open file access mode for read permissions. - auto file = lockedOpenFile.getFile()->dynCast(); // If file is nullptr, then the file was not a DataFile. @@ -207,6 +209,12 @@ static __wasi_errno_t readAtOffset(OffsetHandling setOffset, return __WASI_ERRNO_ISDIR; } + // A file opened for writing only (O_WRONLY) cannot be read. POSIX read(2) + // returns EBADF when the file descriptor is not open for reading. + if ((lockedOpenFile.getFlags() & O_ACCMODE) == O_WRONLY) { + return __WASI_ERRNO_BADF; + } + auto lockedFile = file->locked(); size_t bytesRead = 0; @@ -568,7 +576,7 @@ int wasmfs_create_file(char* pathname, mode_t mode, backend_t backend) { static_assert(std::is_same_v, "unexpected conversion from result of doOpen to int"); return doOpen( - path::parseParent((char*)pathname), O_CREAT | O_EXCL, mode, backend); + path::parseParent(pathname), O_CREAT | O_EXCL | O_RDWR, mode, backend); } // TODO: Test this with non-AT_FDCWD values.