Author: pho
Date: Sat Dec  3 12:30:58 2011
New Revision: 228219
URL: http://svn.freebsd.org/changeset/base/228219

Log:
  Add umtx_copyin_timeout() and move parameter checks here.
  
  In collaboration with:        kib
  MFC after:    1 week

Modified:
  head/sys/kern/kern_umtx.c

Modified: head/sys/kern/kern_umtx.c
==============================================================================
--- head/sys/kern/kern_umtx.c   Sat Dec  3 12:28:33 2011        (r228218)
+++ head/sys/kern/kern_umtx.c   Sat Dec  3 12:30:58 2011        (r228219)
@@ -2898,6 +2898,21 @@ sys__umtx_unlock(struct thread *td, stru
        return do_unlock_umtx(td, uap->umtx, td->td_tid);
 }
 
+inline int
+umtx_copyin_timeout(const void *addr, struct timespec *tsp)
+{
+       int error;
+
+       error = copyin(addr, tsp, sizeof(struct timespec));
+       if (error == 0) {
+               if (tsp->tv_sec < 0 ||
+                   tsp->tv_nsec >= 1000000000 ||
+                   tsp->tv_nsec < 0)
+                       error = EINVAL;
+       }
+       return (error);
+}
+
 static int
 __umtx_op_lock_umtx(struct thread *td, struct _umtx_op_args *uap)
 {
@@ -2908,13 +2923,9 @@ __umtx_op_lock_umtx(struct thread *td, s
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin(uap->uaddr2, &timeout, sizeof(timeout));
+               error = umtx_copyin_timeout(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0) {
-                       return (EINVAL);
-               }
                ts = &timeout;
        }
        return (do_lock_umtx(td, uap->obj, uap->val, ts));
@@ -2935,12 +2946,9 @@ __umtx_op_wait(struct thread *td, struct
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin(uap->uaddr2, &timeout, sizeof(timeout));
+               error = umtx_copyin_timeout(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0)
-                       return (EINVAL);
                ts = &timeout;
        }
        return do_wait(td, uap->obj, uap->val, ts, 0, 0);
@@ -2955,12 +2963,9 @@ __umtx_op_wait_uint(struct thread *td, s
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin(uap->uaddr2, &timeout, sizeof(timeout));
+               error = umtx_copyin_timeout(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0)
-                       return (EINVAL);
                ts = &timeout;
        }
        return do_wait(td, uap->obj, uap->val, ts, 1, 0);
@@ -2975,12 +2980,9 @@ __umtx_op_wait_uint_private(struct threa
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin(uap->uaddr2, &timeout, sizeof(timeout));
+               error = umtx_copyin_timeout(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0)
-                       return (EINVAL);
                ts = &timeout;
        }
        return do_wait(td, uap->obj, uap->val, ts, 1, 1);
@@ -3034,14 +3036,9 @@ __umtx_op_lock_umutex(struct thread *td,
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin(uap->uaddr2, &timeout,
-                   sizeof(timeout));
+               error = umtx_copyin_timeout(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0) {
-                       return (EINVAL);
-               }
                ts = &timeout;
        }
        return do_lock_umutex(td, uap->obj, ts, 0);
@@ -3063,14 +3060,9 @@ __umtx_op_wait_umutex(struct thread *td,
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin(uap->uaddr2, &timeout,
-                   sizeof(timeout));
+               error = umtx_copyin_timeout(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0) {
-                       return (EINVAL);
-               }
                ts = &timeout;
        }
        return do_lock_umutex(td, uap->obj, ts, _UMUTEX_WAIT);
@@ -3104,14 +3096,9 @@ __umtx_op_cv_wait(struct thread *td, str
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin(uap->uaddr2, &timeout,
-                   sizeof(timeout));
+               error = umtx_copyin_timeout(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0) {
-                       return (EINVAL);
-               }
                ts = &timeout;
        }
        return (do_cv_wait(td, uap->obj, uap->uaddr1, ts, uap->val));
@@ -3139,14 +3126,9 @@ __umtx_op_rw_rdlock(struct thread *td, s
        if (uap->uaddr2 == NULL) {
                error = do_rw_rdlock(td, uap->obj, uap->val, 0);
        } else {
-               error = copyin(uap->uaddr2, &timeout,
-                   sizeof(timeout));
+               error = umtx_copyin_timeout(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0) {
-                       return (EINVAL);
-               }
                error = do_rw_rdlock2(td, uap->obj, uap->val, &timeout);
        }
        return (error);
@@ -3162,14 +3144,9 @@ __umtx_op_rw_wrlock(struct thread *td, s
        if (uap->uaddr2 == NULL) {
                error = do_rw_wrlock(td, uap->obj, 0);
        } else {
-               error = copyin(uap->uaddr2, &timeout,
-                   sizeof(timeout));
+               error = umtx_copyin_timeout(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0) {
-                       return (EINVAL);
-               }
 
                error = do_rw_wrlock2(td, uap->obj, &timeout);
        }
@@ -3192,14 +3169,9 @@ __umtx_op_sem_wait(struct thread *td, st
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin(uap->uaddr2, &timeout,
-                   sizeof(timeout));
+               error = umtx_copyin_timeout(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0) {
-                       return (EINVAL);
-               }
                ts = &timeout;
        }
        return (do_sem_wait(td, uap->obj, ts));
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to