Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern untangle the mess:



details:   https://anonhg.NetBSD.org/src/rev/625e56dd4617
branches:  trunk
changeset: 828507:625e56dd4617
user:      christos <christos%NetBSD.org@localhost>
date:      Sun Dec 17 04:35:21 2017 +0000

description:
untangle the mess:
- factor out common code
- break each ptrace subcall to its own sub-function
... more to come ...

diffstat:

 sys/kern/sys_ptrace_common.c |  959 +++++++++++++++++++++---------------------
 1 files changed, 487 insertions(+), 472 deletions(-)

diffs (truncated from 1127 to 300 lines):

diff -r 62f0a41cda61 -r 625e56dd4617 sys/kern/sys_ptrace_common.c
--- a/sys/kern/sys_ptrace_common.c      Sun Dec 17 04:06:03 2017 +0000
+++ b/sys/kern/sys_ptrace_common.c      Sun Dec 17 04:35:21 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sys_ptrace_common.c,v 1.26 2017/12/09 05:18:45 christos Exp $  */
+/*     $NetBSD: sys_ptrace_common.c,v 1.27 2017/12/17 04:35:21 christos Exp $  */
 
 /*-
  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -118,7 +118,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.26 2017/12/09 05:18:45 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.27 2017/12/17 04:35:21 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ptrace.h"
@@ -299,113 +299,80 @@
        return 0;
 }
 
-int
-do_ptrace(struct ptrace_methods *ptm, struct lwp *l, int req, pid_t pid,
-    void *addr, int data, register_t *retval)
+static struct proc *
+ptrace_find(struct lwp *l, int req, pid_t pid)
 {
-       struct proc *p = l->l_proc;
-       struct lwp *lt;
-       struct lwp *lt2;
-       struct proc *t;                         /* target process */
-       struct uio uio;
-       struct iovec iov;
-       struct ptrace_io_desc piod;
-       struct ptrace_event pe;
-       struct ptrace_state ps;
-       struct ptrace_lwpinfo pl;
-       struct ptrace_siginfo psi;
-       struct vmspace *vm;
-       int error, write, tmp, pheld;
-       int signo = 0;
-       int resume_all;
-       ksiginfo_t ksi;
-       char *path;
-       int len = 0;
-       error = 0;
-
-       /*
-        * If attaching or detaching, we need to get a write hold on the
-        * proclist lock so that we can re-parent the target process.
-        */
-       mutex_enter(proc_lock);
+       struct proc *t;
 
        /* "A foolish consistency..." XXX */
        if (req == PT_TRACE_ME) {
-               t = p;
+               t = l->l_proc;
                mutex_enter(t->p_lock);
-       } else {
-               /* Find the process we're supposed to be operating on. */
-               t = proc_find(pid);
-               if (t == NULL) {
-                       mutex_exit(proc_lock);
-                       return ESRCH;
-               }
-
-               /* XXX-elad */
-               mutex_enter(t->p_lock);
-               error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
-                   t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
-               if (error) {
-                       mutex_exit(proc_lock);
-                       mutex_exit(t->p_lock);
-                       return ESRCH;
-               }
+               return t;
        }
 
+       /* Find the process we're supposed to be operating on. */
+       t = proc_find(pid);
+       if (t == NULL)
+               return NULL;
+
+       /* XXX-elad */
+       mutex_enter(t->p_lock);
+       int error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
+           t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
+       if (error) {
+               mutex_exit(t->p_lock);
+               return NULL;
+       }
+       return t;
+}
+
+static int
+ptrace_allowed(struct lwp *l, int req, struct proc *t, struct proc *p)
+{
        /*
         * Grab a reference on the process to prevent it from execing or
         * exiting.
         */
-       if (!rw_tryenter(&t->p_reflock, RW_READER)) {
-               mutex_exit(proc_lock);
-               mutex_exit(t->p_lock);
+       if (!rw_tryenter(&t->p_reflock, RW_READER))
                return EBUSY;
-       }
 
        /* Make sure we can operate on it. */
        switch (req) {
        case  PT_TRACE_ME:
                /* Saying that you're being traced is always legal. */
-               break;
+               return 0;
 
        case  PT_ATTACH:
                /*
                 * You can't attach to a process if:
                 *      (1) it's the process that's doing the attaching,
                 */
-               if (t->p_pid == p->p_pid) {
-                       error = EINVAL;
-                       break;
-               }
+               if (t->p_pid == p->p_pid)
+                       return EINVAL;
 
                /*
                 *  (2) it's a system process
                 */
-               if (t->p_flag & PK_SYSTEM) {
-                       error = EPERM;
-                       break;
-               }
+               if (t->p_flag & PK_SYSTEM)
+                       return EPERM;
 
                /*
                 *      (3) it's already being traced, or
                 */
-               if (ISSET(t->p_slflag, PSL_TRACED)) {
-                       error = EBUSY;
-                       break;
-               }
+               if (ISSET(t->p_slflag, PSL_TRACED))
+                       return EBUSY;
 
                /*
                 *      (4) the tracer is chrooted, and its root directory is
                 *          not at or above the root directory of the tracee
                 */
                mutex_exit(t->p_lock);  /* XXXSMP */
-               tmp = proc_isunder(t, l);
+               int tmp = proc_isunder(t, l);
                mutex_enter(t->p_lock); /* XXXSMP */
-               if (!tmp) {
-                       error = EPERM;
-                       break;
-               }
-               break;
+               if (!tmp)
+                       return EPERM;
+               return 0;
 
        case  PT_READ_I:
        case  PT_READ_D:
@@ -445,10 +412,8 @@
                mutex_exit(t->p_lock);  /* XXXSMP */
                tmp = proc_isunder(t, l);
                mutex_enter(t->p_lock); /* XXXSMP */
-               if (!tmp) {
-                       error = EPERM;
-                       break;
-               }
+               if (!tmp)
+                       return EPERM;
                /*FALLTHROUGH*/
 
        case  PT_CONTINUE:
@@ -472,10 +437,8 @@
                 * You can't do what you want to the process if:
                 *      (1) It's not being traced at all,
                 */
-               if (!ISSET(t->p_slflag, PSL_TRACED)) {
-                       error = EPERM;
-                       break;
-               }
+               if (!ISSET(t->p_slflag, PSL_TRACED))
+                       return EPERM;
 
                /*
                 *      (2) it's not being traced by _you_, or
@@ -483,8 +446,7 @@
                if (t->p_pptr != p) {
                        DPRINTF(("parent %d != %d\n", t->p_pptr->p_pid,
                            p->p_pid));
-                       error = EBUSY;
-                       break;
+                       return EBUSY;
                }
 
                /*
@@ -493,42 +455,18 @@
                if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) {
                        DPRINTF(("stat %d flag %d\n", t->p_stat,
                            !t->p_waited));
-                       error = EBUSY;
-                       break;
+                       return EBUSY;
                }
-               break;
+               return 0;
 
        default:                        /* It was not a legal request. */
-               error = EINVAL;
-               break;
+               return EINVAL;
        }
-
-       if (error == 0) {
-               error = kauth_authorize_process(l->l_cred,
-                   KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req),
-                   NULL, NULL);
-       }
-       if (error == 0) {
-               lt = lwp_find_first(t);
-               if (lt == NULL)
-                       error = ESRCH;
-       }
+}
 
-       if (error != 0) {
-               mutex_exit(proc_lock);
-               mutex_exit(t->p_lock);
-               rw_exit(&t->p_reflock);
-               return error;
-       }
-
-       /* Do single-step fixup if needed. */
-       FIX_SSTEP(t);
-       KASSERT(lt != NULL);
-       lwp_addref(lt);
-
-       /*
-        * Which locks do we need held? XXX Ugly.
-        */
+static int
+ptrace_needs_hold(int req)
+{
        switch (req) {
 #ifdef PT_STEP
        case PT_STEP:
@@ -540,13 +478,431 @@
        case PT_SYSCALLEMU:
        case PT_ATTACH:
        case PT_TRACE_ME:
-               pheld = 1;
+       case PT_GET_SIGINFO:
+       case PT_SET_SIGINFO:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
+static int
+ptrace_update_lwp(struct proc *t, struct lwp **lt, lwpid_t lid)
+{
+       if (lid == 0 || lid == (*lt)->l_lid || t->p_nlwps == 1)
+               return 0;
+
+       lwp_delref(*lt);
+
+       mutex_enter(t->p_lock);
+       *lt = lwp_find(t, lid);
+       if (*lt == NULL) {
+               mutex_exit(t->p_lock);
+               return ESRCH;
+       }
+
+       if ((*lt)->l_flag & LW_SYSTEM) {
+               *lt = NULL;
+               return EINVAL;
+       }
+
+       lwp_addref(*lt);
+       mutex_exit(t->p_lock);
+
+       return 0;
+}
+
+static int
+ptrace_get_siginfo(struct proc *t, void *addr, size_t data)
+{
+       struct ptrace_siginfo psi;
+
+       if (data != sizeof(psi)) {
+               DPRINTF(("%s: %zu != %zu\n", __func__, data, sizeof(psi)));



Home | Main Index | Thread Index | Old Index