@@ -205,12 +205,30 @@ static ssize_t _consolefs_read(oe_fd_t* file_, void* buf, size_t count)
205205 ssize_t ret = -1 ;
206206 file_t * file = _cast_file (file_ );
207207
208- if (!file )
208+ /*
209+ * According to the POSIX specification, when the count is greater
210+ * than SSIZE_MAX, the result is implementation-defined. OE raises an
211+ * error in this case.
212+ * Refer to
213+ * https://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html for
214+ * for more detail.
215+ */
216+ if (!file || count > OE_SSIZE_MAX )
209217 OE_RAISE_ERRNO (OE_EINVAL );
210218
211219 if (oe_syscall_read_ocall (& ret , file -> host_fd , buf , count ) != OE_OK )
212220 OE_RAISE_ERRNO (OE_EINVAL );
213221
222+ /*
223+ * Guard the special case that a host sets an arbitrarily large value.
224+ * The returned value should not exceed count.
225+ */
226+ if (ret > (ssize_t )count )
227+ {
228+ ret = -1 ;
229+ OE_RAISE_ERRNO (OE_EINVAL );
230+ }
231+
214232done :
215233 return ret ;
216234}
@@ -220,12 +238,30 @@ static ssize_t _consolefs_write(oe_fd_t* file_, const void* buf, size_t count)
220238 ssize_t ret = -1 ;
221239 file_t * file = _cast_file (file_ );
222240
223- if (!file )
241+ /*
242+ * According to the POSIX specification, when the count is greater
243+ * than SSIZE_MAX, the result is implementation-defined. OE raises an
244+ * error in this case.
245+ * Refer to
246+ * https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html for
247+ * for more detail.
248+ */
249+ if (!file || count > OE_SSIZE_MAX )
224250 OE_RAISE_ERRNO (OE_EINVAL );
225251
226252 if (oe_syscall_write_ocall (& ret , file -> host_fd , buf , count ) != OE_OK )
227253 OE_RAISE_ERRNO (OE_EINVAL );
228254
255+ /*
256+ * Guard the special case that a host sets an arbitrarily large value.
257+ * The returned value should not exceed count.
258+ */
259+ if (ret > (ssize_t )count )
260+ {
261+ ret = -1 ;
262+ OE_RAISE_ERRNO (OE_EINVAL );
263+ }
264+
229265done :
230266 return ret ;
231267}
@@ -239,21 +275,43 @@ static ssize_t _consolefs_readv(
239275 file_t * file = _cast_file (desc );
240276 void * buf = NULL ;
241277 size_t buf_size = 0 ;
278+ size_t data_size = 0 ;
242279
243280 if (!file || !iov || iovcnt < 0 || iovcnt > OE_IOV_MAX )
244281 OE_RAISE_ERRNO (OE_EINVAL );
245282
246283 /* Flatten the IO vector into contiguous heap memory. */
247- if (oe_iov_pack (iov , iovcnt , & buf , & buf_size ) != 0 )
284+ if (oe_iov_pack (iov , iovcnt , & buf , & buf_size , & data_size ) != 0 )
248285 OE_RAISE_ERRNO (OE_ENOMEM );
249286
287+ /*
288+ * According to the POSIX specification, when the data_size is greater
289+ * than SSIZE_MAX, the result is implementation-defined. OE raises an
290+ * error in this case.
291+ * Refer to
292+ * https://pubs.opengroup.org/onlinepubs/9699919799/functions/readv.html for
293+ * for more detail.
294+ */
295+ if (data_size > OE_SSIZE_MAX )
296+ OE_RAISE_ERRNO (OE_EINVAL );
297+
250298 /* Call the host. */
251299 if (oe_syscall_readv_ocall (& ret , file -> host_fd , buf , iovcnt , buf_size ) !=
252300 OE_OK )
253301 {
254302 OE_RAISE_ERRNO (OE_EINVAL );
255303 }
256304
305+ /*
306+ * Guard the special case that a host sets an arbitrarily large value.
307+ * The returned value should not exceed data_size.
308+ */
309+ if (ret > (ssize_t )data_size )
310+ {
311+ ret = -1 ;
312+ OE_RAISE_ERRNO (OE_EINVAL );
313+ }
314+
257315 /* Synchronize data read with IO vector. */
258316 if (oe_iov_sync (iov , iovcnt , buf , buf_size ) != 0 )
259317 OE_RAISE_ERRNO (OE_EINVAL );
@@ -275,21 +333,43 @@ static ssize_t _consolefs_writev(
275333 file_t * file = _cast_file (desc );
276334 void * buf = NULL ;
277335 size_t buf_size = 0 ;
336+ size_t data_size = 0 ;
278337
279338 if (!file || (!iov && iovcnt ) || iovcnt < 0 || iovcnt > OE_IOV_MAX )
280339 OE_RAISE_ERRNO (OE_EINVAL );
281340
282341 /* Flatten the IO vector into contiguous heap memory. */
283- if (oe_iov_pack (iov , iovcnt , & buf , & buf_size ) != 0 )
342+ if (oe_iov_pack (iov , iovcnt , & buf , & buf_size , & data_size ) != 0 )
284343 OE_RAISE_ERRNO (OE_ENOMEM );
285344
345+ /*
346+ * According to the POSIX specification, when the data_size is greater
347+ * than SSIZE_MAX, the result is implementation-defined. OE raises an
348+ * error in this case.
349+ * Refer to
350+ * https://pubs.opengroup.org/onlinepubs/9699919799/functions/writev.html
351+ * for more detail.
352+ */
353+ if (data_size > OE_SSIZE_MAX )
354+ OE_RAISE_ERRNO (OE_EINVAL );
355+
286356 /* Call the host. */
287357 if (oe_syscall_writev_ocall (& ret , file -> host_fd , buf , iovcnt , buf_size ) !=
288358 OE_OK )
289359 {
290360 OE_RAISE_ERRNO (OE_EINVAL );
291361 }
292362
363+ /*
364+ * Guard the special case that a host sets an arbitrarily large value.
365+ * The returned value should not exceed data_size.
366+ */
367+ if (ret > (ssize_t )data_size )
368+ {
369+ ret = -1 ;
370+ OE_RAISE_ERRNO (OE_EINVAL );
371+ }
372+
293373done :
294374
295375 if (buf )
0 commit comments