@@ -26,6 +26,18 @@ inline void Debug(const WASI& wasi, Args&&... args) {
2626 } \
2727 } while (0 )
2828
29+ // elem_size * count is computed in size_t. A uint32_t product wraps
30+ // (for example 0x20000000 * 8 == 0) and then skips the bounds check.
31+ #define CHECK_ARRAY_BOUNDS_OR_RETURN (mem_size, offset, elem_size, count ) \
32+ do { \
33+ if (!uvwasi_serdes_check_array_bounds ((offset), \
34+ (mem_size), \
35+ (elem_size), \
36+ (count))) { \
37+ return UVWASI_EOVERFLOW ; \
38+ } \
39+ } while (0 )
40+
2941using v8::Array;
3042using v8::ArrayBuffer;
3143using v8::BigInt;
@@ -664,8 +676,8 @@ uint32_t WASI::FdPread(WASI& wasi,
664676 iovs_len,
665677 offset,
666678 nread_ptr);
667- CHECK_BOUNDS_OR_RETURN (
668- memory.size , iovs_ptr, iovs_len * UVWASI_SERDES_SIZE_iovec_t);
679+ CHECK_ARRAY_BOUNDS_OR_RETURN (
680+ memory.size , iovs_ptr, UVWASI_SERDES_SIZE_iovec_t, iovs_len );
669681 CHECK_BOUNDS_OR_RETURN (memory.size , nread_ptr, UVWASI_SERDES_SIZE_size_t);
670682 std::vector<uvwasi_iovec_t > iovs (iovs_len);
671683 uvwasi_errno_t err;
@@ -724,8 +736,8 @@ uint32_t WASI::FdPwrite(WASI& wasi,
724736 iovs_len,
725737 offset,
726738 nwritten_ptr);
727- CHECK_BOUNDS_OR_RETURN (
728- memory.size , iovs_ptr, iovs_len * UVWASI_SERDES_SIZE_ciovec_t);
739+ CHECK_ARRAY_BOUNDS_OR_RETURN (
740+ memory.size , iovs_ptr, UVWASI_SERDES_SIZE_ciovec_t, iovs_len );
729741 CHECK_BOUNDS_OR_RETURN (memory.size , nwritten_ptr, UVWASI_SERDES_SIZE_size_t);
730742 std::vector<uvwasi_ciovec_t > iovs (iovs_len);
731743 uvwasi_errno_t err;
@@ -752,8 +764,8 @@ uint32_t WASI::FdRead(WASI& wasi,
752764 uint32_t iovs_len,
753765 uint32_t nread_ptr) {
754766 Debug (wasi, " fd_read(%d, %d, %d, %d)\n " , fd, iovs_ptr, iovs_len, nread_ptr);
755- CHECK_BOUNDS_OR_RETURN (
756- memory.size , iovs_ptr, iovs_len * UVWASI_SERDES_SIZE_iovec_t);
767+ CHECK_ARRAY_BOUNDS_OR_RETURN (
768+ memory.size , iovs_ptr, UVWASI_SERDES_SIZE_iovec_t, iovs_len );
757769 CHECK_BOUNDS_OR_RETURN (memory.size , nread_ptr, UVWASI_SERDES_SIZE_size_t);
758770 std::vector<uvwasi_iovec_t > iovs (iovs_len);
759771 uvwasi_errno_t err;
@@ -853,8 +865,8 @@ uint32_t WASI::FdWrite(WASI& wasi,
853865 iovs_ptr,
854866 iovs_len,
855867 nwritten_ptr);
856- CHECK_BOUNDS_OR_RETURN (
857- memory.size , iovs_ptr, iovs_len * UVWASI_SERDES_SIZE_ciovec_t);
868+ CHECK_ARRAY_BOUNDS_OR_RETURN (
869+ memory.size , iovs_ptr, UVWASI_SERDES_SIZE_ciovec_t, iovs_len );
858870 CHECK_BOUNDS_OR_RETURN (memory.size , nwritten_ptr, UVWASI_SERDES_SIZE_size_t);
859871 std::vector<uvwasi_ciovec_t > iovs (iovs_len);
860872 uvwasi_errno_t err;
@@ -1126,10 +1138,12 @@ uint32_t WASI::PollOneoff(WASI& wasi,
11261138 out_ptr,
11271139 nsubscriptions,
11281140 nevents_ptr);
1129- CHECK_BOUNDS_OR_RETURN (
1130- memory.size , in_ptr, nsubscriptions * UVWASI_SERDES_SIZE_subscription_t);
1131- CHECK_BOUNDS_OR_RETURN (
1132- memory.size , out_ptr, nsubscriptions * UVWASI_SERDES_SIZE_event_t);
1141+ CHECK_ARRAY_BOUNDS_OR_RETURN (memory.size ,
1142+ in_ptr,
1143+ UVWASI_SERDES_SIZE_subscription_t,
1144+ nsubscriptions);
1145+ CHECK_ARRAY_BOUNDS_OR_RETURN (
1146+ memory.size , out_ptr, UVWASI_SERDES_SIZE_event_t, nsubscriptions);
11331147 CHECK_BOUNDS_OR_RETURN (memory.size , nevents_ptr, UVWASI_SERDES_SIZE_size_t);
11341148 std::vector<uvwasi_subscription_t > in (nsubscriptions);
11351149 std::vector<uvwasi_event_t > out (nsubscriptions);
@@ -1209,8 +1223,8 @@ uint32_t WASI::SockRecv(WASI& wasi,
12091223 ri_flags,
12101224 ro_datalen_ptr,
12111225 ro_flags_ptr);
1212- CHECK_BOUNDS_OR_RETURN (
1213- memory.size , ri_data_ptr, ri_data_len * UVWASI_SERDES_SIZE_iovec_t);
1226+ CHECK_ARRAY_BOUNDS_OR_RETURN (
1227+ memory.size , ri_data_ptr, UVWASI_SERDES_SIZE_iovec_t, ri_data_len );
12141228 CHECK_BOUNDS_OR_RETURN (memory.size , ro_datalen_ptr, 4 );
12151229 CHECK_BOUNDS_OR_RETURN (memory.size , ro_flags_ptr, 4 );
12161230 std::vector<uvwasi_iovec_t > ri_data (ri_data_len);
@@ -1251,8 +1265,8 @@ uint32_t WASI::SockSend(WASI& wasi,
12511265 si_data_len,
12521266 si_flags,
12531267 so_datalen_ptr);
1254- CHECK_BOUNDS_OR_RETURN (
1255- memory.size , si_data_ptr, si_data_len * UVWASI_SERDES_SIZE_ciovec_t);
1268+ CHECK_ARRAY_BOUNDS_OR_RETURN (
1269+ memory.size , si_data_ptr, UVWASI_SERDES_SIZE_ciovec_t, si_data_len );
12561270 CHECK_BOUNDS_OR_RETURN (
12571271 memory.size , so_datalen_ptr, UVWASI_SERDES_SIZE_size_t);
12581272 std::vector<uvwasi_ciovec_t > si_data (si_data_len);
0 commit comments