summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2019-01-31 18:23:27 +0000
committertedu <tedu@openbsd.org>2019-01-31 18:23:27 +0000
commit66562f017457c77fa2b00c6e29dc6030b0ae9a0d (patch)
tree6012bd244fb2c44606888c6939a7c80fa0cf5ea8
parentMake divert-packet port accept any port specification (diff)
downloadwireguard-openbsd-66562f017457c77fa2b00c6e29dc6030b0ae9a0d.tar.xz
wireguard-openbsd-66562f017457c77fa2b00c6e29dc6030b0ae9a0d.zip
matthew noticed that some clocks use tfind() which is not mpsafe.
add locking in clock_gettime where needed. ok cheloha matthew
-rw-r--r--sys/kern/kern_time.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c
index 8e00465657b..e6b0d817421 100644
--- a/sys/kern/kern_time.c
+++ b/sys/kern/kern_time.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_time.c,v 1.109 2019/01/23 21:53:42 cheloha Exp $ */
+/* $OpenBSD: kern_time.c,v 1.110 2019/01/31 18:23:27 tedu Exp $ */
/* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */
/*
@@ -112,6 +112,7 @@ clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp)
{
struct bintime bt;
struct proc *q;
+ int error = 0;
switch (clock_id) {
case CLOCK_REALTIME:
@@ -141,14 +142,18 @@ clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp)
default:
/* check for clock from pthread_getcpuclockid() */
if (__CLOCK_TYPE(clock_id) == CLOCK_THREAD_CPUTIME_ID) {
+ KERNEL_LOCK();
q = tfind(__CLOCK_PTID(clock_id) - THREAD_PID_OFFSET);
if (q == NULL || q->p_p != p->p_p)
- return (ESRCH);
- *tp = q->p_tu.tu_runtime;
+ error = ESRCH;
+ else
+ *tp = q->p_tu.tu_runtime;
+ KERNEL_UNLOCK();
} else
- return (EINVAL);
+ error = EINVAL;
+ break;
}
- return (0);
+ return (error);
}
int
@@ -232,16 +237,21 @@ sys_clock_getres(struct proc *p, void *v, register_t *retval)
default:
/* check for clock from pthread_getcpuclockid() */
if (__CLOCK_TYPE(clock_id) == CLOCK_THREAD_CPUTIME_ID) {
+ KERNEL_LOCK();
q = tfind(__CLOCK_PTID(clock_id) - THREAD_PID_OFFSET);
if (q == NULL || q->p_p != p->p_p)
- return (ESRCH);
- ts.tv_sec = 0;
- ts.tv_nsec = 1000000000 / hz;
+ error = ESRCH;
+ else {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1000000000 / hz;
+ }
+ KERNEL_UNLOCK();
} else
- return (EINVAL);
+ error = EINVAL;
+ break;
}
- if (SCARG(uap, tp)) {
+ if (error == 0 && SCARG(uap, tp)) {
error = copyout(&ts, SCARG(uap, tp), sizeof (ts));
#ifdef KTRACE
if (error == 0 && KTRPOINT(p, KTR_STRUCT))