From c835f76b38c7e27c528f7ed3e0da9bc37460c933 Mon Sep 17 00:00:00 2001 From: guenther Date: Mon, 2 Jan 2023 23:09:48 +0000 Subject: [PATCH] Add tfind_user(), for getting a proc* given a user-space TID and the process* that it should be part of. Use that in clock_get{time,res}(), thrkill(), and ptrace(). ok jca@ miod@ mpi@ mvs@ --- sys/kern/kern_proc.c | 20 +++++++++++++++++++- sys/kern/kern_sig.c | 17 +++++------------ sys/kern/kern_time.c | 10 +++++----- sys/kern/sys_process.c | 6 ++---- sys/sys/proc.h | 4 +++- 5 files changed, 34 insertions(+), 23 deletions(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index e68ffad4126..0eb2df6583a 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_proc.c,v 1.93 2022/12/07 20:08:28 mvs Exp $ */ +/* $OpenBSD: kern_proc.c,v 1.94 2023/01/02 23:09:48 guenther Exp $ */ /* $NetBSD: kern_proc.c,v 1.14 1996/02/09 18:59:41 christos Exp $ */ /* @@ -199,6 +199,24 @@ tfind(pid_t tid) return (NULL); } +/* + * Locate a thread by userspace id, from a given process. + */ +struct proc * +tfind_user(pid_t tid, struct process *pr) +{ + struct proc *p; + + if (tid < THREAD_PID_OFFSET) + return NULL; + p = tfind(tid - THREAD_PID_OFFSET); + + /* verify we found a thread in the correct process */ + if (p != NULL && p->p_p != pr) + p = NULL; + return p; +} + /* * Locate a process by number */ diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index f3e2761a78d..38149c19cc8 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.302 2022/12/29 01:36:36 guenther Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.303 2023/01/02 23:09:48 guenther Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -640,17 +640,10 @@ sys_thrkill(struct proc *cp, void *v, register_t *retval) if (((u_int)signum) >= NSIG) return (EINVAL); - if (tid > THREAD_PID_OFFSET) { - if ((p = tfind(tid - THREAD_PID_OFFSET)) == NULL) - return (ESRCH); - - /* can only kill threads in the same process */ - if (p->p_p != cp->p_p) - return (ESRCH); - } else if (tid == 0) - p = cp; - else - return (EINVAL); + + p = tid ? tfind_user(tid, cp->p_p) : cp; + if (p == NULL) + return (ESRCH); /* optionally require the target thread to have the given tcb addr */ tcb = SCARG(uap, tcb); diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index a86e272a253..1dd0f3aef7f 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_time.c,v 1.160 2022/12/31 16:06:24 cheloha Exp $ */ +/* $OpenBSD: kern_time.c,v 1.161 2023/01/02 23:09:48 guenther Exp $ */ /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ /* @@ -139,8 +139,8 @@ clock_gettime(struct proc *p, clockid_t clock_id, struct timespec *tp) /* 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) + q = tfind_user(__CLOCK_PTID(clock_id), p->p_p); + if (q == NULL) error = ESRCH; else *tp = q->p_tu.tu_runtime; @@ -244,8 +244,8 @@ sys_clock_getres(struct proc *p, void *v, register_t *retval) /* 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) + q = tfind_user(__CLOCK_PTID(clock_id), p->p_p); + if (q == NULL) error = ESRCH; else ts.tv_nsec = 1000000000 / realstathz; diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index de054f0febc..5d0df0cda2e 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_process.c,v 1.91 2022/12/21 07:59:02 claudio Exp $ */ +/* $OpenBSD: sys_process.c,v 1.92 2023/01/02 23:09:48 guenther Exp $ */ /* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */ /*- @@ -556,11 +556,9 @@ ptrace_kstate(struct proc *p, int req, pid_t pid, void *addr) struct proc *t; if (req == PT_GET_THREAD_NEXT) { - t = tfind(pts->pts_tid - THREAD_PID_OFFSET); + t = tfind_user(pts->pts_tid, tr); if (t == NULL || ISSET(t->p_flag, P_WEXIT)) return ESRCH; - if (t->p_p != tr) - return EINVAL; t = TAILQ_NEXT(t, p_thr_link); } else { t = TAILQ_FIRST(&tr->ps_threads); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index a916b1d4566..545f20027da 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: proc.h,v 1.336 2022/12/07 20:08:29 mvs Exp $ */ +/* $OpenBSD: proc.h,v 1.337 2023/01/02 23:09:48 guenther Exp $ */ /* $NetBSD: proc.h,v 1.44 1996/04/22 01:23:21 christos Exp $ */ /*- @@ -524,6 +524,8 @@ struct process *prfind(pid_t); /* Find process by id. */ struct process *zombiefind(pid_t); /* Find zombie process by id. */ struct proc *tfind(pid_t); /* Find thread by id. */ struct pgrp *pgfind(pid_t); /* Find process group by id. */ +struct proc *tfind_user(pid_t, struct process *); + /* Find thread by userspace id. */ void proc_printit(struct proc *p, const char *modif, int (*pr)(const char *, ...)); -- 2.20.1