X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/316670eb35587141e969394ae8537d66b9211e80..e8c3f78193f1895ea514044358b93b1add9322f3:/bsd/kern/kern_subr.c diff --git a/bsd/kern/kern_subr.c b/bsd/kern/kern_subr.c index 9e9587bea..610c94936 100644 --- a/bsd/kern/kern_subr.c +++ b/bsd/kern/kern_subr.c @@ -126,11 +126,7 @@ int uiomove64(const addr64_t c_cp, int n, struct uio *uio) { addr64_t cp = c_cp; -#if LP64KERN uint64_t acnt; -#else - u_int acnt; -#endif int error = 0; #if DIAGNOSTIC @@ -911,15 +907,16 @@ int uio_getiov( uio_t a_uio, * uio_calculateresid - runs through all iovecs associated with this * uio_t and calculates (and sets) the residual IO count. */ -__private_extern__ void uio_calculateresid( uio_t a_uio ) +__private_extern__ int uio_calculateresid( uio_t a_uio ) { int i; + u_int64_t resid = 0; if (a_uio == NULL) { #if LP64_DEBUG panic("%s :%d - invalid uio_t\n", __FILE__, __LINE__); #endif /* LP64_DEBUG */ - return; + return EINVAL; } a_uio->uio_iovcnt = a_uio->uio_max_iovs; @@ -927,9 +924,14 @@ __private_extern__ void uio_calculateresid( uio_t a_uio ) a_uio->uio_resid_64 = 0; for ( i = 0; i < a_uio->uio_max_iovs; i++ ) { if (a_uio->uio_iovs.uiovp[i].iov_len != 0 && a_uio->uio_iovs.uiovp[i].iov_base != 0) { - a_uio->uio_resid_64 += a_uio->uio_iovs.uiovp[i].iov_len; + if (a_uio->uio_iovs.uiovp[i].iov_len > LONG_MAX) + return EINVAL; + resid += a_uio->uio_iovs.uiovp[i].iov_len; + if (resid > LONG_MAX) + return EINVAL; } } + a_uio->uio_resid_64 = resid; /* position to first non zero length iovec (4235922) */ while (a_uio->uio_iovcnt > 0 && a_uio->uio_iovs.uiovp->iov_len == 0) { @@ -943,9 +945,14 @@ __private_extern__ void uio_calculateresid( uio_t a_uio ) a_uio->uio_resid_64 = 0; for ( i = 0; i < a_uio->uio_max_iovs; i++ ) { if (a_uio->uio_iovs.kiovp[i].iov_len != 0 && a_uio->uio_iovs.kiovp[i].iov_base != 0) { - a_uio->uio_resid_64 += a_uio->uio_iovs.kiovp[i].iov_len; + if (a_uio->uio_iovs.kiovp[i].iov_len > LONG_MAX) + return EINVAL; + resid += a_uio->uio_iovs.kiovp[i].iov_len; + if (resid > LONG_MAX) + return EINVAL; } } + a_uio->uio_resid_64 = resid; /* position to first non zero length iovec (4235922) */ while (a_uio->uio_iovcnt > 0 && a_uio->uio_iovs.kiovp->iov_len == 0) { @@ -956,7 +963,7 @@ __private_extern__ void uio_calculateresid( uio_t a_uio ) } } - return; + return 0; } /* @@ -997,9 +1004,6 @@ void uio_update( uio_t a_uio, user_size_t a_count ) a_uio->uio_iovs.uiovp->iov_base += a_count; a_uio->uio_iovs.uiovp->iov_len -= a_count; } - if (a_uio->uio_resid_64 < 0) { - a_uio->uio_resid_64 = 0; - } if (a_count > (user_size_t)a_uio->uio_resid_64) { a_uio->uio_offset += a_uio->uio_resid_64; a_uio->uio_resid_64 = 0; @@ -1033,9 +1037,6 @@ void uio_update( uio_t a_uio, user_size_t a_count ) a_uio->uio_iovs.kiovp->iov_base += a_count; a_uio->uio_iovs.kiovp->iov_len -= a_count; } - if (a_uio->uio_resid_64 < 0) { - a_uio->uio_resid_64 = 0; - } if (a_count > (user_size_t)a_uio->uio_resid_64) { a_uio->uio_offset += a_uio->uio_resid_64; a_uio->uio_resid_64 = 0; @@ -1143,6 +1144,10 @@ uio_t uio_duplicate( uio_t a_uio ) } my_uio->uio_flags = UIO_FLAGS_WE_ALLOCED | UIO_FLAGS_INITED; +#if DEBUG + (void)hw_atomic_add(&uio_t_count, 1); +#endif + return(my_uio); }