fix WASI API read/write pread/pwrite buffer overflow (#324)

Co-authored-by: 赵海 <zhaohai@cyberpeace.cn>
opam-2.0.0
ha1vk 2 years ago committed by GitHub
parent 839e57a220
commit 8441c82c4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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);

@ -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);

@ -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;

Loading…
Cancel
Save