]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_subr.c
xnu-4903.231.4.tar.gz
[apple/xnu.git] / bsd / kern / kern_subr.c
index cc05a7db7309e0b2d24063e9b2a187ca6dc6d7a9..610c94936b9efb8ffdf3b1301cd3adbecdac8e18 100644 (file)
@@ -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
@@ -153,7 +149,7 @@ uiomove64(const addr64_t c_cp, int n, struct uio *uio)
                if (n > 0 && acnt > (uint64_t)n)
                        acnt = n;
 
-               switch (uio->uio_segflg) {
+               switch ((int) uio->uio_segflg) {
 
                case UIO_USERSPACE64:
                case UIO_USERISPACE64:
@@ -280,7 +276,7 @@ ureadc(int c, struct uio *uio)
        if (uio_curriovlen(uio) <= 0)
                panic("ureadc: non-positive iovlen");
 
-       switch (uio->uio_segflg) {
+       switch ((int) uio->uio_segflg) {
 
        case UIO_USERSPACE32:
        case UIO_USERSPACE:
@@ -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);
 }