Author: pho
Date: Mon Dec 12 17:33:38 2011
New Revision: 228439
URL: http://svn.freebsd.org/changeset/base/228439

Log:
  MFC: r228218, r228219, 228220, 228221
  
  Rename copyin_timeout32 to umtx_copyin_timeout32 and move parameter
  check here. Include check for negative seconds value.
  Add umtx_copyin_timeout() and move parameter checks here.
  Add declaration of umtx_copyin_timeout()
  Use umtx_copyin_timeout() to copy and check timeout parameteri in
  kern_thr_suspend().

Modified:
  stable/8/sys/kern/kern_thr.c
  stable/8/sys/kern/kern_umtx.c
  stable/8/sys/sys/umtx.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/conf/ldscript.mips.octeon1.32   (props changed)
  stable/8/sys/conf/ldscript.mips.octeon1.64   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/kern/kern_thr.c
==============================================================================
--- stable/8/sys/kern/kern_thr.c        Mon Dec 12 13:12:55 2011        
(r228438)
+++ stable/8/sys/kern/kern_thr.c        Mon Dec 12 17:33:38 2011        
(r228439)
@@ -428,8 +428,7 @@ thr_suspend(struct thread *td, struct th
 
        tsp = NULL;
        if (uap->timeout != NULL) {
-               error = copyin((const void *)uap->timeout, (void *)&ts,
-                   sizeof(struct timespec));
+               error = umtx_copyin_timeout(uap->timeout, &ts);
                if (error != 0)
                        return (error);
                tsp = &ts;
@@ -445,9 +444,6 @@ kern_thr_suspend(struct thread *td, stru
        int error = 0, hz = 0;
 
        if (tsp != NULL) {
-               if (tsp->tv_sec < 0 || tsp->tv_nsec < 0 ||
-                   tsp->tv_nsec > 1000000000)
-                       return (EINVAL);
                if (tsp->tv_sec == 0 && tsp->tv_nsec == 0)
                        return (ETIMEDOUT);
                TIMESPEC_TO_TIMEVAL(&tv, tsp);

Modified: stable/8/sys/kern/kern_umtx.c
==============================================================================
--- stable/8/sys/kern/kern_umtx.c       Mon Dec 12 13:12:55 2011        
(r228438)
+++ stable/8/sys/kern/kern_umtx.c       Mon Dec 12 17:33:38 2011        
(r228439)
@@ -2740,6 +2740,21 @@ _umtx_unlock(struct thread *td, struct _
        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)
 {
@@ -2750,13 +2765,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));
@@ -2777,12 +2788,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);
@@ -2797,12 +2805,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);
@@ -2817,12 +2822,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);
@@ -2850,14 +2852,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);
@@ -2879,14 +2876,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);
@@ -2920,14 +2912,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));
@@ -2955,14 +2942,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);
@@ -2978,14 +2960,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);
        }
@@ -3051,15 +3028,21 @@ struct timespec32 {
 };
 
 static inline int
-copyin_timeout32(void *addr, struct timespec *tsp)
+umtx_copyin_timeout32(void *addr, struct timespec *tsp)
 {
        struct timespec32 ts32;
        int error;
 
        error = copyin(addr, &ts32, sizeof(struct timespec32));
        if (error == 0) {
-               tsp->tv_sec = ts32.tv_sec;
-               tsp->tv_nsec = ts32.tv_nsec;
+               if (ts32.tv_sec < 0 ||
+                   ts32.tv_nsec >= 1000000000 ||
+                   ts32.tv_nsec < 0)
+                       error = EINVAL;
+               else {
+                       tsp->tv_sec = ts32.tv_sec;
+                       tsp->tv_nsec = ts32.tv_nsec;
+               }
        }
        return (error);
 }
@@ -3074,13 +3057,9 @@ __umtx_op_lock_umtx_compat32(struct thre
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin_timeout32(uap->uaddr2, &timeout);
+               error = umtx_copyin_timeout32(uap->uaddr2, &timeout);
                if (error != 0)
                        return (error);
-               if (timeout.tv_nsec >= 1000000000 ||
-                   timeout.tv_nsec < 0) {
-                       return (EINVAL);
-               }
                ts = &timeout;
        }
        return (do_lock_umtx32(td, uap->obj, uap->val, ts));
@@ -3101,12 +3080,9 @@ __umtx_op_wait_compat32(struct thread *t
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin_timeout32(uap->uaddr2, &timeout);
+               error = umtx_copyin_timeout32(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);
@@ -3122,12 +3098,9 @@ __umtx_op_lock_umutex_compat32(struct th
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin_timeout32(uap->uaddr2, &timeout);
+               error = umtx_copyin_timeout32(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);
@@ -3143,12 +3116,9 @@ __umtx_op_wait_umutex_compat32(struct th
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin_timeout32(uap->uaddr2, &timeout);
+               error = umtx_copyin_timeout32(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);
@@ -3164,12 +3134,9 @@ __umtx_op_cv_wait_compat32(struct thread
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin_timeout32(uap->uaddr2, &timeout);
+               error = umtx_copyin_timeout32(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));
@@ -3185,13 +3152,9 @@ __umtx_op_rw_rdlock_compat32(struct thre
        if (uap->uaddr2 == NULL) {
                error = do_rw_rdlock(td, uap->obj, uap->val, 0);
        } else {
-               error = copyin_timeout32(uap->uaddr2, &timeout);
+               error = umtx_copyin_timeout32(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);
@@ -3207,13 +3170,9 @@ __umtx_op_rw_wrlock_compat32(struct thre
        if (uap->uaddr2 == NULL) {
                error = do_rw_wrlock(td, uap->obj, 0);
        } else {
-               error = copyin_timeout32(uap->uaddr2, &timeout);
+               error = umtx_copyin_timeout32(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);
        }
@@ -3229,12 +3188,9 @@ __umtx_op_wait_uint_private_compat32(str
        if (uap->uaddr2 == NULL)
                ts = NULL;
        else {
-               error = copyin_timeout32(uap->uaddr2, &timeout);
+               error = umtx_copyin_timeout32(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);

Modified: stable/8/sys/sys/umtx.h
==============================================================================
--- stable/8/sys/sys/umtx.h     Mon Dec 12 13:12:55 2011        (r228438)
+++ stable/8/sys/sys/umtx.h     Mon Dec 12 17:33:38 2011        (r228439)
@@ -241,6 +241,7 @@ umtx_key_match(const struct umtx_key *k1
                k1->info.both.b == k2->info.both.b);
 }
 
+int umtx_copyin_timeout(const void *, struct timespec *);
 int umtx_key_get(void *, int, int, struct umtx_key *);
 void umtx_key_release(struct umtx_key *);
 struct umtx_q *umtxq_alloc(void);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to