diff --git a/.circleci/config.yml b/.circleci/config.yml index 4c139e23b3abd..0159ba1da508b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -590,6 +590,7 @@ jobs: wasmfs.test_readdir_rawfs wasmfs.test_utime wasmfs.test_unistd_unlink + wasmfs.test_unistd_dup wasmfs.test_unistd_access wasmfs.test_unistd_close wasmfs.test_unistd_truncate diff --git a/system/lib/wasmfs/file_table.cpp b/system/lib/wasmfs/file_table.cpp index ef11597dc2ac9..13b8429f40386 100644 --- a/system/lib/wasmfs/file_table.cpp +++ b/system/lib/wasmfs/file_table.cpp @@ -33,6 +33,7 @@ std::shared_ptr FileTable::Handle::setEntry(__wasi_fd_t fd, std::shared_ptr openFile) { assert(fd >= 0); + assert(fd < WASMFS_FD_MAX); if (fd >= fileTable.entries.size()) { fileTable.entries.resize(fd + 1); } @@ -50,7 +51,7 @@ FileTable::Handle::setEntry(__wasi_fd_t fd, __wasi_fd_t FileTable::Handle::addEntry(std::shared_ptr openFileState) { // TODO: add freelist to avoid linear lookup time. - for (__wasi_fd_t i = 0;; i++) { + for (__wasi_fd_t i = 0; i < WASMFS_FD_MAX; i++) { if (!getEntry(i)) { (void)setEntry(i, openFileState); return i; diff --git a/system/lib/wasmfs/file_table.h b/system/lib/wasmfs/file_table.h index 75eca96328a9c..e85d9b38e07f2 100644 --- a/system/lib/wasmfs/file_table.h +++ b/system/lib/wasmfs/file_table.h @@ -15,6 +15,9 @@ #include #include +// Copied from legacy FS (FS.MAX_OPEN_FDS) +#define WASMFS_FD_MAX 4096 + namespace wasmfs { static_assert(std::is_same::value, "size_t should be the same as __wasi_size_t"); diff --git a/system/lib/wasmfs/syscalls.cpp b/system/lib/wasmfs/syscalls.cpp index f52eb65ad9ec2..48dd311c33c93 100644 --- a/system/lib/wasmfs/syscalls.cpp +++ b/system/lib/wasmfs/syscalls.cpp @@ -60,7 +60,7 @@ int __syscall_dup3(int oldfd, int newfd, int flags) { if (!oldOpenFile) { return -EBADF; } - if (newfd < 0) { + if (newfd < 0 || newfd >= WASMFS_FD_MAX) { return -EBADF; } if (oldfd == newfd) { diff --git a/test/other/codesize/test_codesize_files_wasmfs.size b/test/other/codesize/test_codesize_files_wasmfs.size index 16548dcf103a6..61a9d15a5ddbe 100644 --- a/test/other/codesize/test_codesize_files_wasmfs.size +++ b/test/other/codesize/test_codesize_files_wasmfs.size @@ -1 +1 @@ -49979 +49968 diff --git a/test/unistd/dup.c b/test/unistd/dup.c index dcc737c3b819c..b276f608605ee 100644 --- a/test/unistd/dup.c +++ b/test/unistd/dup.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -21,7 +20,7 @@ int main() { f = open("/", O_RDONLY); f2 = open("/", O_RDONLY); f3 = dup(f); - printf("errno: %d\n", errno); + printf("errno: %s\n", strerror(errno)); assert(f != -1); assert(f2 != -1); assert(f3 != -1); @@ -40,7 +39,7 @@ int main() { assert(f != -1); assert(f2 != -1); assert(f3 != -1); - printf("errno: %d\n", errno); + printf("errno: %s\n", strerror(errno)); printf("f: %d\n", f != f2 && f != f3); printf("f2,f3: %d\n", f2 == f3); printf("close(f1): %d\n", close(f)); @@ -53,7 +52,7 @@ int main() { f = dup2(-2, -2); printf("f: %d\n", f); assert(f == -1); - printf("errno: %d\n", errno); + printf("errno: %s\n", strerror(errno)); printf("close(f): %d\n", close(f)); printf("\n"); errno = 0; @@ -64,11 +63,11 @@ int main() { f3 = dup2(f, -1); printf("f3: %d\n", f3); assert(f3 == -1); - printf("errno: %d\n", errno); + printf("errno: %s\n", strerror(errno)); f3 = dup2(f, 256000); printf("f3: %d\n", f3); assert(f3 == -1); - printf("errno: %d\n", errno); + printf("errno: %s\n", strerror(errno)); printf("close(f1): %d\n", close(f)); printf("\n"); errno = 0; diff --git a/test/unistd/dup.out b/test/unistd/dup.out index ed3f03e4d48d6..22ed73631cc11 100644 --- a/test/unistd/dup.out +++ b/test/unistd/dup.out @@ -1,5 +1,5 @@ DUP -errno: 0 +errno: No error information f: 1 f2,f3: 1 close(f1): 0 @@ -7,7 +7,7 @@ close(f2): 0 close(f3): 0 DUP2 -errno: 0 +errno: No error information f: 1 f2,f3: 1 close(f1): 0 @@ -16,14 +16,14 @@ close(f3): -1 DUP2 bad fds f: -1 -errno: 8 +errno: Bad file descriptor close(f): -1 DUP2 bad newfd f3: -1 -errno: 8 +errno: Bad file descriptor f3: -1 -errno: 8 +errno: Bad file descriptor close(f1): 0 DUP2 pipe