svn commit: r230263 - in stable/9/sys: kern sys
Peter Holm
pho at FreeBSD.org
Tue Jan 17 11:04:59 UTC 2012
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);
More information about the svn-src-stable-9
mailing list