summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_umtx.c
diff options
context:
space:
mode:
authorpho <pho@FreeBSD.org>2011-12-03 12:30:58 +0000
committerpho <pho@FreeBSD.org>2011-12-03 12:30:58 +0000
commit7195560d6673b32ede9f118a3cbc7e9fe4491f65 (patch)
tree6f2eba52421c9cd4f689c55320b98a765f93496c /sys/kern/kern_umtx.c
parent4a62c2f04c6d8a89dec539419d449986590fe3b0 (diff)
downloadFreeBSD-src-7195560d6673b32ede9f118a3cbc7e9fe4491f65.zip
FreeBSD-src-7195560d6673b32ede9f118a3cbc7e9fe4491f65.tar.gz
Add umtx_copyin_timeout() and move parameter checks here.
In collaboration with: kib MFC after: 1 week
Diffstat (limited to 'sys/kern/kern_umtx.c')
-rw-r--r--sys/kern/kern_umtx.c78
1 files changed, 25 insertions, 53 deletions
diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index 0247063..7d8a781 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -2898,6 +2898,21 @@ sys__umtx_unlock(struct thread *td, struct _umtx_unlock_args *uap)
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, struct _umtx_op_args *uap)
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 _umtx_op_args *uap)
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, struct _umtx_op_args *uap)
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 thread *td, struct _umtx_op_args *uap)
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, struct _umtx_op_args *uap)
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, struct _umtx_op_args *uap)
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, struct _umtx_op_args *uap)
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, struct _umtx_op_args *uap)
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, struct _umtx_op_args *uap)
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, struct _umtx_op_args *uap)
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));
OpenPOWER on IntegriCloud