From 8441c82c4a98f554b12971450220b580c3c2b6df Mon Sep 17 00:00:00 2001 From: ha1vk <2801045898@qq.com> Date: Thu, 14 Apr 2022 01:48:13 +0800 Subject: [PATCH] fix WASI API read/write pread/pwrite buffer overflow (#324) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 赵海 --- source/m3_api_meta_wasi.c | 26 ++++++++++++++++++++------ source/m3_api_uvwasi.c | 6 ++++-- source/m3_api_wasi.c | 18 +++++++++++++----- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/source/m3_api_meta_wasi.c b/source/m3_api_meta_wasi.c index 611f035..3f1ac54 100644 --- a/source/m3_api_meta_wasi.c +++ b/source/m3_api_meta_wasi.c @@ -37,13 +37,15 @@ static m3_wasi_context_t* wasi_context; typedef size_t __wasi_size_t; static inline -void copy_iov_to_host(void* _mem, __wasi_iovec_t* host_iov, __wasi_iovec_t* wasi_iov, int32_t iovs_len) +const void* copy_iov_to_host(IM3Runtime runtime, void* _mem, __wasi_iovec_t* host_iov, __wasi_iovec_t* wasi_iov, int32_t iovs_len) { // Convert wasi memory offsets to host addresses for (int i = 0; i < iovs_len; i++) { host_iov[i].buf = m3ApiOffsetToPtr(wasi_iov[i].buf); host_iov[i].buf_len = wasi_iov[i].buf_len; + m3ApiCheckMem(host_iov[i].buf, host_iov[i].buf_len); } + m3ApiSuccess(); } #if d_m3EnableWasiTracing @@ -665,7 +667,10 @@ m3ApiRawFunction(m3_wasi_generic_fd_pread) m3ApiCheckMem(nread, sizeof(__wasi_size_t)); __wasi_iovec_t iovs[iovs_len]; - copy_iov_to_host(_mem, iovs, wasi_iovs, iovs_len); + const void* mem_check = copy_iov_to_host(runtime, _mem, iovs, wasi_iovs, iovs_len); + if (mem_check != m3Err_none) { + return mem_check; + } __wasi_errno_t ret = __wasi_fd_pread(fd, iovs, iovs_len, offset, nread); @@ -686,7 +691,10 @@ m3ApiRawFunction(m3_wasi_generic_fd_read) m3ApiCheckMem(nread, sizeof(__wasi_size_t)); __wasi_iovec_t iovs[iovs_len]; - copy_iov_to_host(_mem, iovs, wasi_iovs, iovs_len); + const void* mem_check = copy_iov_to_host(runtime, _mem, iovs, wasi_iovs, iovs_len); + if (mem_check != m3Err_none) { + return mem_check; + } __wasi_errno_t ret = __wasi_fd_read(fd, iovs, iovs_len, nread); @@ -707,7 +715,10 @@ m3ApiRawFunction(m3_wasi_generic_fd_write) m3ApiCheckMem(nwritten, sizeof(__wasi_size_t)); __wasi_iovec_t iovs[iovs_len]; - copy_iov_to_host(_mem, iovs, wasi_iovs, iovs_len); + const void* mem_check = copy_iov_to_host(runtime, _mem, iovs, wasi_iovs, iovs_len); + if (mem_check != m3Err_none) { + return mem_check; + } __wasi_errno_t ret = __wasi_fd_write(fd, (__wasi_ciovec_t*)iovs, iovs_len, nwritten); @@ -729,8 +740,11 @@ m3ApiRawFunction(m3_wasi_generic_fd_pwrite) m3ApiCheckMem(nwritten, sizeof(__wasi_size_t)); __wasi_iovec_t iovs[iovs_len]; - copy_iov_to_host(_mem, iovs, wasi_iovs, iovs_len); - + const void* mem_check = copy_iov_to_host(runtime, _mem, iovs, wasi_iovs, iovs_len); + if (mem_check != m3Err_none) { + return mem_check; + } + __wasi_errno_t ret = __wasi_fd_pwrite(fd, (__wasi_ciovec_t*)iovs, iovs_len, offset, nwritten); WASI_TRACE("fd:%d | nwritten:%d", fd, *nwritten); diff --git a/source/m3_api_uvwasi.c b/source/m3_api_uvwasi.c index 423ec1b..9e6ccb0 100644 --- a/source/m3_api_uvwasi.c +++ b/source/m3_api_uvwasi.c @@ -729,7 +729,7 @@ m3ApiRawFunction(m3_wasi_generic_fd_pread) for (uvwasi_size_t i = 0; i < iovs_len; ++i) { iovs[i].buf = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf)); iovs[i].buf_len = m3ApiReadMem32(&wasi_iovs[i].buf_len); - + m3ApiCheckMem(iovs[i].buf, iovs[i].buf_len); //fprintf(stderr, "> fd_pread fd:%d iov%d.len:%d\n", fd, i, iovs[i].buf_len); } @@ -767,7 +767,7 @@ m3ApiRawFunction(m3_wasi_generic_fd_read) for (uvwasi_size_t i = 0; i < iovs_len; ++i) { iovs[i].buf = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf)); iovs[i].buf_len = m3ApiReadMem32(&wasi_iovs[i].buf_len); - + m3ApiCheckMem(iovs[i].buf, iovs[i].buf_len); //fprintf(stderr, "> fd_read fd:%d iov%d.len:%d\n", fd, i, iovs[i].buf_len); } @@ -803,6 +803,7 @@ m3ApiRawFunction(m3_wasi_generic_fd_write) for (uvwasi_size_t i = 0; i < iovs_len; ++i) { iovs[i].buf = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf)); iovs[i].buf_len = m3ApiReadMem32(&wasi_iovs[i].buf_len); + m3ApiCheckMem(iovs[i].buf, iovs[i].buf_len); } ret = uvwasi_fd_write(&uvwasi, fd, iovs, iovs_len, &num_written); @@ -838,6 +839,7 @@ m3ApiRawFunction(m3_wasi_generic_fd_pwrite) for (uvwasi_size_t i = 0; i < iovs_len; ++i) { iovs[i].buf = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf)); iovs[i].buf_len = m3ApiReadMem32(&wasi_iovs[i].buf_len); + m3ApiCheckMem(iovs[i].buf, iovs[i].buf_len); } ret = uvwasi_fd_pwrite(&uvwasi, fd, iovs, iovs_len, offset, &num_written); diff --git a/source/m3_api_wasi.c b/source/m3_api_wasi.c index 8b6f2e3..836d6f4 100644 --- a/source/m3_api_wasi.c +++ b/source/m3_api_wasi.c @@ -189,13 +189,15 @@ __wasi_timestamp_t convert_timespec(const struct timespec *ts) { #if defined(HAS_IOVEC) static inline -void copy_iov_to_host(void* _mem, struct iovec* host_iov, wasi_iovec_t* wasi_iov, int32_t iovs_len) +const void* copy_iov_to_host(IM3Runtime runtime, void* _mem, struct iovec* host_iov, wasi_iovec_t* wasi_iov, int32_t iovs_len) { // Convert wasi memory offsets to host addresses for (int i = 0; i < iovs_len; i++) { host_iov[i].iov_base = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iov[i].buf)); host_iov[i].iov_len = m3ApiReadMem32(&wasi_iov[i].buf_len); + m3ApiCheckMem(host_iov[i].iov_base, host_iov[i].iov_len); } + m3ApiSuccess(); } #endif @@ -576,7 +578,10 @@ m3ApiRawFunction(m3_wasi_generic_fd_read) #if defined(HAS_IOVEC) struct iovec iovs[iovs_len]; - copy_iov_to_host(_mem, iovs, wasi_iovs, iovs_len); + const void* mem_check = copy_iov_to_host(runtime, _mem, iovs, wasi_iovs, iovs_len); + if (mem_check != m3Err_none) { + return mem_check; + } ssize_t ret = readv(fd, iovs, iovs_len); if (ret < 0) { m3ApiReturn(errno_to_wasi(errno)); } @@ -588,7 +593,7 @@ m3ApiRawFunction(m3_wasi_generic_fd_read) void* addr = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf)); size_t len = m3ApiReadMem32(&wasi_iovs[i].buf_len); if (len == 0) continue; - + m3ApiCheckMem(addr, len); int ret = read (fd, addr, len); if (ret < 0) m3ApiReturn(errno_to_wasi(errno)); res += ret; @@ -612,7 +617,10 @@ m3ApiRawFunction(m3_wasi_generic_fd_write) #if defined(HAS_IOVEC) struct iovec iovs[iovs_len]; - copy_iov_to_host(_mem, iovs, wasi_iovs, iovs_len); + const void* mem_check = copy_iov_to_host(runtime, _mem, iovs, wasi_iovs, iovs_len); + if (mem_check != m3Err_none) { + return mem_check; + } ssize_t ret = writev(fd, iovs, iovs_len); if (ret < 0) { m3ApiReturn(errno_to_wasi(errno)); } @@ -624,7 +632,7 @@ m3ApiRawFunction(m3_wasi_generic_fd_write) void* addr = m3ApiOffsetToPtr(m3ApiReadMem32(&wasi_iovs[i].buf)); size_t len = m3ApiReadMem32(&wasi_iovs[i].buf_len); if (len == 0) continue; - + m3ApiCheckMem(addr, len); int ret = write (fd, addr, len); if (ret < 0) m3ApiReturn(errno_to_wasi(errno)); res += ret;