Add tfind_user(), for getting a proc* given a user-space TID and
authorguenther <guenther@openbsd.org>
Mon, 2 Jan 2023 23:09:48 +0000 (23:09 +0000)
committerguenther <guenther@openbsd.org>
Mon, 2 Jan 2023 23:09:48 +0000 (23:09 +0000)
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
sys/kern/kern_sig.c
sys/kern/kern_time.c
sys/kern/sys_process.c
sys/sys/proc.h

index e68ffad..0eb2df6 100644 (file)
@@ -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
  */
index f3e2761..38149c1 100644 (file)
@@ -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);
index a86e272..1dd0f3a 100644 (file)
@@ -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;
index de054f0..5d0df0c 100644 (file)
@@ -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);
index a916b1d..545f200 100644 (file)
@@ -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 *, ...));