From 67fa155878861699336380980c3601f733f56194 Mon Sep 17 00:00:00 2001 From: "liang.he" Date: Tue, 13 Aug 2024 10:10:22 +0800 Subject: [PATCH] libc-wasi: Make rights of STDIN/STDOUT/STDERR fixed and overlook their access modes (#3694) When determining the file descriptor rights in the function fd_determine_type_rights(), we assign fixed and unchangeable rights to STDIN, STDOUT and STDERR. ps. https://github.com/bytecodealliance/wasm-micro-runtime/issues/3686 --- .../sandboxed-system-primitives/src/posix.c | 21 +++++++++- .../sandboxed-system-primitives/src/rights.h | 13 +++++++ .../shared/platform/common/posix/posix_file.c | 39 ++++++++++++++----- core/shared/platform/esp-idf/espidf_file.c | 39 ++++++++++++++----- .../platform/include/platform_api_extension.h | 27 +++++++++++++ core/shared/platform/windows/win_file.c | 18 +++++++++ 6 files changed, 138 insertions(+), 19 deletions(-) diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c index 627bbbb3..a313b9be 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/posix.c @@ -459,8 +459,27 @@ fd_determine_type_rights(os_file_handle fd, __wasi_filetype_t *type, __wasi_rights_t *rights_inheriting) { struct __wasi_filestat_t buf; - __wasi_errno_t error = os_fstat(fd, &buf); + __wasi_errno_t error; + if (os_is_stdin_handle(fd)) { + *rights_base = RIGHTS_STDIN; + *rights_inheriting = RIGHTS_STDIN; + return __WASI_ESUCCESS; + } + + if (os_is_stdout_handle(fd)) { + *rights_base = RIGHTS_STDOUT; + *rights_inheriting = RIGHTS_STDOUT; + return __WASI_ESUCCESS; + } + + if (os_is_stderr_handle(fd)) { + *rights_base = RIGHTS_STDERR; + *rights_inheriting = RIGHTS_STDERR; + return __WASI_ESUCCESS; + } + + error = os_fstat(fd, &buf); if (error != __WASI_ESUCCESS) return error; diff --git a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/rights.h b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/rights.h index 4f583815..41ff56f2 100644 --- a/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/rights.h +++ b/core/iwasm/libraries/libc-wasi/sandboxed-system-primitives/src/rights.h @@ -47,6 +47,19 @@ #define RIGHTS_CHARACTER_DEVICE_BASE RIGHTS_ALL #define RIGHTS_CHARACTER_DEVICE_INHERITING RIGHTS_ALL +#define RIGHTS_STDIN \ + (__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_FD_FILESTAT_GET | \ + __WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_WRITE | \ + __WASI_RIGHT_POLL_FD_READWRITE) + +#define RIGHTS_STDOUT \ + (__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_FD_DATASYNC | \ + __WASI_RIGHT_FD_FILESTAT_GET | __WASI_RIGHT_FD_SYNC | \ + __WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_WRITE | \ + __WASI_RIGHT_POLL_FD_READWRITE) + +#define RIGHTS_STDERR RIGHTS_STDOUT + // Only allow directory operations on directories. Directories can only // yield file descriptors to other directories and files. #define RIGHTS_DIRECTORY_BASE \ diff --git a/core/shared/platform/common/posix/posix_file.c b/core/shared/platform/common/posix/posix_file.c index e3aec9f4..9ae0a03a 100644 --- a/core/shared/platform/common/posix/posix_file.c +++ b/core/shared/platform/common/posix/posix_file.c @@ -54,6 +54,18 @@ #define CONFIG_HAS_O_SYNC #endif +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif + +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif + +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif + // Converts a POSIX timespec to a WASI timestamp. static __wasi_timestamp_t convert_timespec(const struct timespec *ts) @@ -858,30 +870,39 @@ os_isatty(os_file_handle handle) #endif } +bool +os_is_stdin_handle(os_file_handle fd) +{ + return fd == STDIN_FILENO; +} + +bool +os_is_stdout_handle(os_file_handle fd) +{ + return fd == STDOUT_FILENO; +} + +bool +os_is_stderr_handle(os_file_handle fd) +{ + return fd == STDERR_FILENO; +} + os_file_handle os_convert_stdin_handle(os_raw_file_handle raw_stdin) { -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif return raw_stdin >= 0 ? raw_stdin : STDIN_FILENO; } os_file_handle os_convert_stdout_handle(os_raw_file_handle raw_stdout) { -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif return raw_stdout >= 0 ? raw_stdout : STDOUT_FILENO; } os_file_handle os_convert_stderr_handle(os_raw_file_handle raw_stderr) { -#ifndef STDERR_FILENO -#define STDERR_FILENO 2 -#endif return raw_stderr >= 0 ? raw_stderr : STDERR_FILENO; } diff --git a/core/shared/platform/esp-idf/espidf_file.c b/core/shared/platform/esp-idf/espidf_file.c index ac7e5853..be50a290 100644 --- a/core/shared/platform/esp-idf/espidf_file.c +++ b/core/shared/platform/esp-idf/espidf_file.c @@ -54,6 +54,18 @@ #define CONFIG_HAS_O_SYNC #endif +#ifndef STDIN_FILENO +#define STDIN_FILENO 0 +#endif + +#ifndef STDOUT_FILENO +#define STDOUT_FILENO 1 +#endif + +#ifndef STDERR_FILENO +#define STDERR_FILENO 2 +#endif + // Converts a POSIX timespec to a WASI timestamp. static __wasi_timestamp_t convert_timespec(const struct timespec *ts) @@ -858,30 +870,39 @@ os_isatty(os_file_handle handle) #endif } +bool +os_is_stdin_handle(os_file_handle fd) +{ + return fd == STDIN_FILENO; +} + +bool +os_is_stdout_handle(os_file_handle fd) +{ + return fd == STDOUT_FILENO; +} + +bool +os_is_stderr_handle(os_file_handle fd) +{ + return fd == STDERR_FILENO; +} + os_file_handle os_convert_stdin_handle(os_raw_file_handle raw_stdin) { -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif return raw_stdin >= 0 ? raw_stdin : STDIN_FILENO; } os_file_handle os_convert_stdout_handle(os_raw_file_handle raw_stdout) { -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif return raw_stdout >= 0 ? raw_stdout : STDOUT_FILENO; } os_file_handle os_convert_stderr_handle(os_raw_file_handle raw_stderr) { -#ifndef STDERR_FILENO -#define STDERR_FILENO 2 -#endif return raw_stderr >= 0 ? raw_stderr : STDERR_FILENO; } diff --git a/core/shared/platform/include/platform_api_extension.h b/core/shared/platform/include/platform_api_extension.h index 7c6120ba..e165e5ef 100644 --- a/core/shared/platform/include/platform_api_extension.h +++ b/core/shared/platform/include/platform_api_extension.h @@ -1502,6 +1502,33 @@ os_convert_stdout_handle(os_raw_file_handle raw_stdout); os_file_handle os_convert_stderr_handle(os_raw_file_handle raw_stderr); +/** + * + * @param fd a file handle + * + * @return true if it is stdin + */ +bool +os_is_stdin_handle(os_file_handle fd); + +/** + * + * @param fd a file handle + * + * @return true if it is stdout + */ +bool +os_is_stdout_handle(os_file_handle fd); + +/** + * + * @param fd a file handle + * + * @return true if it is stderr + */ +bool +os_is_stderr_handle(os_file_handle fd); + /** * Open a directory stream for the provided directory handle. The returned * directory stream will be positioned at the first entry in the directory. diff --git a/core/shared/platform/windows/win_file.c b/core/shared/platform/windows/win_file.c index 63dfb5b5..408d0d00 100644 --- a/core/shared/platform/windows/win_file.c +++ b/core/shared/platform/windows/win_file.c @@ -1540,6 +1540,24 @@ create_stdio_handle(HANDLE raw_stdio_handle, DWORD stdio) return stdio_handle; } +bool +os_is_stdin_handle(os_file_handle fd) +{ + return fd->raw.handle == GetStdHandle(STD_INPUT_HANDLE); +} + +bool +os_is_stdout_handle(os_file_handle fd) +{ + return fd->raw.handle == GetStdHandle(STD_OUTPUT_HANDLE); +} + +bool +os_is_stderr_handle(os_file_handle fd) +{ + return fd->raw.handle == GetStdHandle(STD_ERROR_HANDLE); +} + os_file_handle os_convert_stdin_handle(os_raw_file_handle raw_stdin) {