From owner-svn-src-stable@FreeBSD.ORG Tue Jan 17 11:04:59 2012 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9226D106564A; Tue, 17 Jan 2012 11:04:59 +0000 (UTC) (envelope-from pho@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7F16A8FC08; Tue, 17 Jan 2012 11:04:59 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q0HB4xR9087736; Tue, 17 Jan 2012 11:04:59 GMT (envelope-from pho@svn.freebsd.org) Received: (from pho@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q0HB4xjn087732; Tue, 17 Jan 2012 11:04:59 GMT (envelope-from pho@svn.freebsd.org) Message-Id: <201201171104.q0HB4xjn087732@svn.freebsd.org> From: Peter Holm Date: Tue, 17 Jan 2012 11:04:59 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r230263 - in stable/9/sys: kern sys X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 17 Jan 2012 11:04:59 -0000 Author: pho Date: Tue Jan 17 11:04:58 2012 New Revision: 230263 URL: http://svn.freebsd.org/changeset/base/230263 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 parameter. Modified: stable/9/sys/kern/kern_thr.c stable/9/sys/kern/kern_umtx.c stable/9/sys/sys/umtx.h Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/kern/kern_thr.c ============================================================================== --- stable/9/sys/kern/kern_thr.c Tue Jan 17 07:30:36 2012 (r230262) +++ stable/9/sys/kern/kern_thr.c Tue Jan 17 11:04:58 2012 (r230263) @@ -449,8 +449,7 @@ sys_thr_suspend(struct thread *td, struc 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; @@ -473,9 +472,6 @@ kern_thr_suspend(struct thread *td, stru } 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) error = EWOULDBLOCK; else { Modified: stable/9/sys/kern/kern_umtx.c ============================================================================== --- stable/9/sys/kern/kern_umtx.c Tue Jan 17 07:30:36 2012 (r230262) +++ stable/9/sys/kern/kern_umtx.c Tue Jan 17 11:04:58 2012 (r230263) @@ -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)); @@ -3267,15 +3239,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); } @@ -3290,13 +3268,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)); @@ -3317,12 +3291,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); @@ -3338,12 +3309,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); @@ -3359,12 +3327,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); @@ -3380,12 +3345,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)); @@ -3401,13 +3363,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); @@ -3423,13 +3381,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); } @@ -3445,12 +3399,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); @@ -3466,12 +3417,9 @@ __umtx_op_sem_wait_compat32(struct threa 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_sem_wait(td, uap->obj, ts)); Modified: stable/9/sys/sys/umtx.h ============================================================================== --- stable/9/sys/sys/umtx.h Tue Jan 17 07:30:36 2012 (r230262) +++ stable/9/sys/sys/umtx.h Tue Jan 17 11:04:58 2012 (r230263) @@ -223,6 +223,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);