The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/kern_ktrace.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-3-Clause
    3  *
    4  * Copyright (c) 1989, 1993
    5  *      The Regents of the University of California.
    6  * Copyright (c) 2005 Robert N. M. Watson
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 3. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  *
   33  *      @(#)kern_ktrace.c       8.2 (Berkeley) 9/23/93
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD$");
   38 
   39 #include "opt_ktrace.h"
   40 
   41 #include <sys/param.h>
   42 #include <sys/capsicum.h>
   43 #include <sys/systm.h>
   44 #include <sys/fcntl.h>
   45 #include <sys/kernel.h>
   46 #include <sys/kthread.h>
   47 #include <sys/lock.h>
   48 #include <sys/mutex.h>
   49 #include <sys/malloc.h>
   50 #include <sys/mount.h>
   51 #include <sys/namei.h>
   52 #include <sys/priv.h>
   53 #include <sys/proc.h>
   54 #include <sys/resourcevar.h>
   55 #include <sys/unistd.h>
   56 #include <sys/vnode.h>
   57 #include <sys/socket.h>
   58 #include <sys/stat.h>
   59 #include <sys/ktrace.h>
   60 #include <sys/sx.h>
   61 #include <sys/sysctl.h>
   62 #include <sys/sysent.h>
   63 #include <sys/syslog.h>
   64 #include <sys/sysproto.h>
   65 
   66 #include <security/mac/mac_framework.h>
   67 
   68 /*
   69  * The ktrace facility allows the tracing of certain key events in user space
   70  * processes, such as system calls, signal delivery, context switches, and
   71  * user generated events using utrace(2).  It works by streaming event
   72  * records and data to a vnode associated with the process using the
   73  * ktrace(2) system call.  In general, records can be written directly from
   74  * the context that generates the event.  One important exception to this is
   75  * during a context switch, where sleeping is not permitted.  To handle this
   76  * case, trace events are generated using in-kernel ktr_request records, and
   77  * then delivered to disk at a convenient moment -- either immediately, the
   78  * next traceable event, at system call return, or at process exit.
   79  *
   80  * When dealing with multiple threads or processes writing to the same event
   81  * log, ordering guarantees are weak: specifically, if an event has multiple
   82  * records (i.e., system call enter and return), they may be interlaced with
   83  * records from another event.  Process and thread ID information is provided
   84  * in the record, and user applications can de-interlace events if required.
   85  */
   86 
   87 static MALLOC_DEFINE(M_KTRACE, "KTRACE", "KTRACE");
   88 
   89 #ifdef KTRACE
   90 
   91 FEATURE(ktrace, "Kernel support for system-call tracing");
   92 
   93 #ifndef KTRACE_REQUEST_POOL
   94 #define KTRACE_REQUEST_POOL     100
   95 #endif
   96 
   97 struct ktr_request {
   98         struct  ktr_header ktr_header;
   99         void    *ktr_buffer;
  100         union {
  101                 struct  ktr_proc_ctor ktr_proc_ctor;
  102                 struct  ktr_cap_fail ktr_cap_fail;
  103                 struct  ktr_syscall ktr_syscall;
  104                 struct  ktr_sysret ktr_sysret;
  105                 struct  ktr_genio ktr_genio;
  106                 struct  ktr_psig ktr_psig;
  107                 struct  ktr_csw ktr_csw;
  108                 struct  ktr_fault ktr_fault;
  109                 struct  ktr_faultend ktr_faultend;
  110                 struct  ktr_struct_array ktr_struct_array;
  111         } ktr_data;
  112         STAILQ_ENTRY(ktr_request) ktr_list;
  113 };
  114 
  115 static int data_lengths[] = {
  116         [KTR_SYSCALL] = offsetof(struct ktr_syscall, ktr_args),
  117         [KTR_SYSRET] = sizeof(struct ktr_sysret),
  118         [KTR_NAMEI] = 0,
  119         [KTR_GENIO] = sizeof(struct ktr_genio),
  120         [KTR_PSIG] = sizeof(struct ktr_psig),
  121         [KTR_CSW] = sizeof(struct ktr_csw),
  122         [KTR_USER] = 0,
  123         [KTR_STRUCT] = 0,
  124         [KTR_SYSCTL] = 0,
  125         [KTR_PROCCTOR] = sizeof(struct ktr_proc_ctor),
  126         [KTR_PROCDTOR] = 0,
  127         [KTR_CAPFAIL] = sizeof(struct ktr_cap_fail),
  128         [KTR_FAULT] = sizeof(struct ktr_fault),
  129         [KTR_FAULTEND] = sizeof(struct ktr_faultend),
  130         [KTR_STRUCT_ARRAY] = sizeof(struct ktr_struct_array),
  131 };
  132 
  133 static STAILQ_HEAD(, ktr_request) ktr_free;
  134 
  135 static SYSCTL_NODE(_kern, OID_AUTO, ktrace, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
  136     "KTRACE options");
  137 
  138 static u_int ktr_requestpool = KTRACE_REQUEST_POOL;
  139 TUNABLE_INT("kern.ktrace.request_pool", &ktr_requestpool);
  140 
  141 u_int ktr_geniosize = PAGE_SIZE;
  142 SYSCTL_UINT(_kern_ktrace, OID_AUTO, genio_size, CTLFLAG_RWTUN, &ktr_geniosize,
  143     0, "Maximum size of genio event payload");
  144 
  145 /*
  146  * Allow to not to send signal to traced process, in which context the
  147  * ktr record is written.  The limit is applied from the process that
  148  * set up ktrace, so killing the traced process is not completely fair.
  149  */
  150 int ktr_filesize_limit_signal = 0;
  151 SYSCTL_INT(_kern_ktrace, OID_AUTO, filesize_limit_signal, CTLFLAG_RWTUN,
  152     &ktr_filesize_limit_signal, 0,
  153     "Send SIGXFSZ to the traced process when the log size limit is exceeded");
  154 
  155 static int print_message = 1;
  156 static struct mtx ktrace_mtx;
  157 static struct sx ktrace_sx;
  158 
  159 struct ktr_io_params {
  160         struct vnode    *vp;
  161         struct ucred    *cr;
  162         off_t           lim;
  163         u_int           refs;
  164 };
  165 
  166 static void ktrace_init(void *dummy);
  167 static int sysctl_kern_ktrace_request_pool(SYSCTL_HANDLER_ARGS);
  168 static u_int ktrace_resize_pool(u_int oldsize, u_int newsize);
  169 static struct ktr_request *ktr_getrequest_entered(struct thread *td, int type);
  170 static struct ktr_request *ktr_getrequest(int type);
  171 static void ktr_submitrequest(struct thread *td, struct ktr_request *req);
  172 static struct ktr_io_params *ktr_freeproc(struct proc *p);
  173 static void ktr_freerequest(struct ktr_request *req);
  174 static void ktr_freerequest_locked(struct ktr_request *req);
  175 static void ktr_writerequest(struct thread *td, struct ktr_request *req);
  176 static int ktrcanset(struct thread *,struct proc *);
  177 static int ktrsetchildren(struct thread *, struct proc *, int, int,
  178     struct ktr_io_params *);
  179 static int ktrops(struct thread *, struct proc *, int, int,
  180     struct ktr_io_params *);
  181 static void ktrprocctor_entered(struct thread *, struct proc *);
  182 
  183 /*
  184  * ktrace itself generates events, such as context switches, which we do not
  185  * wish to trace.  Maintain a flag, TDP_INKTRACE, on each thread to determine
  186  * whether or not it is in a region where tracing of events should be
  187  * suppressed.
  188  */
  189 static void
  190 ktrace_enter(struct thread *td)
  191 {
  192 
  193         KASSERT(!(td->td_pflags & TDP_INKTRACE), ("ktrace_enter: flag set"));
  194         td->td_pflags |= TDP_INKTRACE;
  195 }
  196 
  197 static void
  198 ktrace_exit(struct thread *td)
  199 {
  200 
  201         KASSERT(td->td_pflags & TDP_INKTRACE, ("ktrace_exit: flag not set"));
  202         td->td_pflags &= ~TDP_INKTRACE;
  203 }
  204 
  205 static void
  206 ktrace_assert(struct thread *td)
  207 {
  208 
  209         KASSERT(td->td_pflags & TDP_INKTRACE, ("ktrace_assert: flag not set"));
  210 }
  211 
  212 static void
  213 ast_ktrace(struct thread *td, int tda __unused)
  214 {
  215         KTRUSERRET(td);
  216 }
  217 
  218 static void
  219 ktrace_init(void *dummy)
  220 {
  221         struct ktr_request *req;
  222         int i;
  223 
  224         mtx_init(&ktrace_mtx, "ktrace", NULL, MTX_DEF | MTX_QUIET);
  225         sx_init(&ktrace_sx, "ktrace_sx");
  226         STAILQ_INIT(&ktr_free);
  227         for (i = 0; i < ktr_requestpool; i++) {
  228                 req = malloc(sizeof(struct ktr_request), M_KTRACE, M_WAITOK |
  229                     M_ZERO);
  230                 STAILQ_INSERT_HEAD(&ktr_free, req, ktr_list);
  231         }
  232         ast_register(TDA_KTRACE, ASTR_ASTF_REQUIRED, 0, ast_ktrace);
  233 }
  234 SYSINIT(ktrace_init, SI_SUB_KTRACE, SI_ORDER_ANY, ktrace_init, NULL);
  235 
  236 static int
  237 sysctl_kern_ktrace_request_pool(SYSCTL_HANDLER_ARGS)
  238 {
  239         struct thread *td;
  240         u_int newsize, oldsize, wantsize;
  241         int error;
  242 
  243         /* Handle easy read-only case first to avoid warnings from GCC. */
  244         if (!req->newptr) {
  245                 oldsize = ktr_requestpool;
  246                 return (SYSCTL_OUT(req, &oldsize, sizeof(u_int)));
  247         }
  248 
  249         error = SYSCTL_IN(req, &wantsize, sizeof(u_int));
  250         if (error)
  251                 return (error);
  252         td = curthread;
  253         ktrace_enter(td);
  254         oldsize = ktr_requestpool;
  255         newsize = ktrace_resize_pool(oldsize, wantsize);
  256         ktrace_exit(td);
  257         error = SYSCTL_OUT(req, &oldsize, sizeof(u_int));
  258         if (error)
  259                 return (error);
  260         if (wantsize > oldsize && newsize < wantsize)
  261                 return (ENOSPC);
  262         return (0);
  263 }
  264 SYSCTL_PROC(_kern_ktrace, OID_AUTO, request_pool,
  265     CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, &ktr_requestpool, 0,
  266     sysctl_kern_ktrace_request_pool, "IU",
  267     "Pool buffer size for ktrace(1)");
  268 
  269 static u_int
  270 ktrace_resize_pool(u_int oldsize, u_int newsize)
  271 {
  272         STAILQ_HEAD(, ktr_request) ktr_new;
  273         struct ktr_request *req;
  274         int bound;
  275 
  276         print_message = 1;
  277         bound = newsize - oldsize;
  278         if (bound == 0)
  279                 return (ktr_requestpool);
  280         if (bound < 0) {
  281                 mtx_lock(&ktrace_mtx);
  282                 /* Shrink pool down to newsize if possible. */
  283                 while (bound++ < 0) {
  284                         req = STAILQ_FIRST(&ktr_free);
  285                         if (req == NULL)
  286                                 break;
  287                         STAILQ_REMOVE_HEAD(&ktr_free, ktr_list);
  288                         ktr_requestpool--;
  289                         free(req, M_KTRACE);
  290                 }
  291         } else {
  292                 /* Grow pool up to newsize. */
  293                 STAILQ_INIT(&ktr_new);
  294                 while (bound-- > 0) {
  295                         req = malloc(sizeof(struct ktr_request), M_KTRACE,
  296                             M_WAITOK | M_ZERO);
  297                         STAILQ_INSERT_HEAD(&ktr_new, req, ktr_list);
  298                 }
  299                 mtx_lock(&ktrace_mtx);
  300                 STAILQ_CONCAT(&ktr_free, &ktr_new);
  301                 ktr_requestpool += (newsize - oldsize);
  302         }
  303         mtx_unlock(&ktrace_mtx);
  304         return (ktr_requestpool);
  305 }
  306 
  307 /* ktr_getrequest() assumes that ktr_comm[] is the same size as td_name[]. */
  308 CTASSERT(sizeof(((struct ktr_header *)NULL)->ktr_comm) ==
  309     (sizeof((struct thread *)NULL)->td_name));
  310 
  311 static struct ktr_request *
  312 ktr_getrequest_entered(struct thread *td, int type)
  313 {
  314         struct ktr_request *req;
  315         struct proc *p = td->td_proc;
  316         int pm;
  317 
  318         mtx_lock(&ktrace_mtx);
  319         if (!KTRCHECK(td, type)) {
  320                 mtx_unlock(&ktrace_mtx);
  321                 return (NULL);
  322         }
  323         req = STAILQ_FIRST(&ktr_free);
  324         if (req != NULL) {
  325                 STAILQ_REMOVE_HEAD(&ktr_free, ktr_list);
  326                 req->ktr_header.ktr_type = type;
  327                 if (p->p_traceflag & KTRFAC_DROP) {
  328                         req->ktr_header.ktr_type |= KTR_DROP;
  329                         p->p_traceflag &= ~KTRFAC_DROP;
  330                 }
  331                 mtx_unlock(&ktrace_mtx);
  332                 nanotime(&req->ktr_header.ktr_time);
  333                 req->ktr_header.ktr_type |= KTR_VERSIONED;
  334                 req->ktr_header.ktr_pid = p->p_pid;
  335                 req->ktr_header.ktr_tid = td->td_tid;
  336                 req->ktr_header.ktr_cpu = PCPU_GET(cpuid);
  337                 req->ktr_header.ktr_version = KTR_VERSION1;
  338                 bcopy(td->td_name, req->ktr_header.ktr_comm,
  339                     sizeof(req->ktr_header.ktr_comm));
  340                 req->ktr_buffer = NULL;
  341                 req->ktr_header.ktr_len = 0;
  342         } else {
  343                 p->p_traceflag |= KTRFAC_DROP;
  344                 pm = print_message;
  345                 print_message = 0;
  346                 mtx_unlock(&ktrace_mtx);
  347                 if (pm)
  348                         printf("Out of ktrace request objects.\n");
  349         }
  350         return (req);
  351 }
  352 
  353 static struct ktr_request *
  354 ktr_getrequest(int type)
  355 {
  356         struct thread *td = curthread;
  357         struct ktr_request *req;
  358 
  359         ktrace_enter(td);
  360         req = ktr_getrequest_entered(td, type);
  361         if (req == NULL)
  362                 ktrace_exit(td);
  363 
  364         return (req);
  365 }
  366 
  367 /*
  368  * Some trace generation environments don't permit direct access to VFS,
  369  * such as during a context switch where sleeping is not allowed.  Under these
  370  * circumstances, queue a request to the thread to be written asynchronously
  371  * later.
  372  */
  373 static void
  374 ktr_enqueuerequest(struct thread *td, struct ktr_request *req)
  375 {
  376 
  377         mtx_lock(&ktrace_mtx);
  378         STAILQ_INSERT_TAIL(&td->td_proc->p_ktr, req, ktr_list);
  379         mtx_unlock(&ktrace_mtx);
  380         ast_sched(td, TDA_KTRACE);
  381 }
  382 
  383 /*
  384  * Drain any pending ktrace records from the per-thread queue to disk.  This
  385  * is used both internally before committing other records, and also on
  386  * system call return.  We drain all the ones we can find at the time when
  387  * drain is requested, but don't keep draining after that as those events
  388  * may be approximately "after" the current event.
  389  */
  390 static void
  391 ktr_drain(struct thread *td)
  392 {
  393         struct ktr_request *queued_req;
  394         STAILQ_HEAD(, ktr_request) local_queue;
  395 
  396         ktrace_assert(td);
  397         sx_assert(&ktrace_sx, SX_XLOCKED);
  398 
  399         STAILQ_INIT(&local_queue);
  400 
  401         if (!STAILQ_EMPTY(&td->td_proc->p_ktr)) {
  402                 mtx_lock(&ktrace_mtx);
  403                 STAILQ_CONCAT(&local_queue, &td->td_proc->p_ktr);
  404                 mtx_unlock(&ktrace_mtx);
  405 
  406                 while ((queued_req = STAILQ_FIRST(&local_queue))) {
  407                         STAILQ_REMOVE_HEAD(&local_queue, ktr_list);
  408                         ktr_writerequest(td, queued_req);
  409                         ktr_freerequest(queued_req);
  410                 }
  411         }
  412 }
  413 
  414 /*
  415  * Submit a trace record for immediate commit to disk -- to be used only
  416  * where entering VFS is OK.  First drain any pending records that may have
  417  * been cached in the thread.
  418  */
  419 static void
  420 ktr_submitrequest(struct thread *td, struct ktr_request *req)
  421 {
  422 
  423         ktrace_assert(td);
  424 
  425         sx_xlock(&ktrace_sx);
  426         ktr_drain(td);
  427         ktr_writerequest(td, req);
  428         ktr_freerequest(req);
  429         sx_xunlock(&ktrace_sx);
  430         ktrace_exit(td);
  431 }
  432 
  433 static void
  434 ktr_freerequest(struct ktr_request *req)
  435 {
  436 
  437         mtx_lock(&ktrace_mtx);
  438         ktr_freerequest_locked(req);
  439         mtx_unlock(&ktrace_mtx);
  440 }
  441 
  442 static void
  443 ktr_freerequest_locked(struct ktr_request *req)
  444 {
  445 
  446         mtx_assert(&ktrace_mtx, MA_OWNED);
  447         if (req->ktr_buffer != NULL)
  448                 free(req->ktr_buffer, M_KTRACE);
  449         STAILQ_INSERT_HEAD(&ktr_free, req, ktr_list);
  450 }
  451 
  452 static void
  453 ktr_io_params_ref(struct ktr_io_params *kiop)
  454 {
  455         mtx_assert(&ktrace_mtx, MA_OWNED);
  456         kiop->refs++;
  457 }
  458 
  459 static struct ktr_io_params *
  460 ktr_io_params_rele(struct ktr_io_params *kiop)
  461 {
  462         mtx_assert(&ktrace_mtx, MA_OWNED);
  463         if (kiop == NULL)
  464                 return (NULL);
  465         KASSERT(kiop->refs > 0, ("kiop ref == 0 %p", kiop));
  466         return (--(kiop->refs) == 0 ? kiop : NULL);
  467 }
  468 
  469 void
  470 ktr_io_params_free(struct ktr_io_params *kiop)
  471 {
  472         if (kiop == NULL)
  473                 return;
  474 
  475         MPASS(kiop->refs == 0);
  476         vn_close(kiop->vp, FWRITE, kiop->cr, curthread);
  477         crfree(kiop->cr);
  478         free(kiop, M_KTRACE);
  479 }
  480 
  481 static struct ktr_io_params *
  482 ktr_io_params_alloc(struct thread *td, struct vnode *vp)
  483 {
  484         struct ktr_io_params *res;
  485 
  486         res = malloc(sizeof(struct ktr_io_params), M_KTRACE, M_WAITOK);
  487         res->vp = vp;
  488         res->cr = crhold(td->td_ucred);
  489         res->lim = lim_cur(td, RLIMIT_FSIZE);
  490         res->refs = 1;
  491         return (res);
  492 }
  493 
  494 /*
  495  * Disable tracing for a process and release all associated resources.
  496  * The caller is responsible for releasing a reference on the returned
  497  * vnode and credentials.
  498  */
  499 static struct ktr_io_params *
  500 ktr_freeproc(struct proc *p)
  501 {
  502         struct ktr_io_params *kiop;
  503         struct ktr_request *req;
  504 
  505         PROC_LOCK_ASSERT(p, MA_OWNED);
  506         mtx_assert(&ktrace_mtx, MA_OWNED);
  507         kiop = ktr_io_params_rele(p->p_ktrioparms);
  508         p->p_ktrioparms = NULL;
  509         p->p_traceflag = 0;
  510         while ((req = STAILQ_FIRST(&p->p_ktr)) != NULL) {
  511                 STAILQ_REMOVE_HEAD(&p->p_ktr, ktr_list);
  512                 ktr_freerequest_locked(req);
  513         }
  514         return (kiop);
  515 }
  516 
  517 struct vnode *
  518 ktr_get_tracevp(struct proc *p, bool ref)
  519 {
  520         struct vnode *vp;
  521 
  522         PROC_LOCK_ASSERT(p, MA_OWNED);
  523 
  524         if (p->p_ktrioparms != NULL) {
  525                 vp = p->p_ktrioparms->vp;
  526                 if (ref)
  527                         vrefact(vp);
  528         } else {
  529                 vp = NULL;
  530         }
  531         return (vp);
  532 }
  533 
  534 void
  535 ktrsyscall(int code, int narg, syscallarg_t args[])
  536 {
  537         struct ktr_request *req;
  538         struct ktr_syscall *ktp;
  539         size_t buflen;
  540         char *buf = NULL;
  541 
  542         if (__predict_false(curthread->td_pflags & TDP_INKTRACE))
  543                 return;
  544 
  545         buflen = sizeof(register_t) * narg;
  546         if (buflen > 0) {
  547                 buf = malloc(buflen, M_KTRACE, M_WAITOK);
  548                 bcopy(args, buf, buflen);
  549         }
  550         req = ktr_getrequest(KTR_SYSCALL);
  551         if (req == NULL) {
  552                 if (buf != NULL)
  553                         free(buf, M_KTRACE);
  554                 return;
  555         }
  556         ktp = &req->ktr_data.ktr_syscall;
  557         ktp->ktr_code = code;
  558         ktp->ktr_narg = narg;
  559         if (buflen > 0) {
  560                 req->ktr_header.ktr_len = buflen;
  561                 req->ktr_buffer = buf;
  562         }
  563         ktr_submitrequest(curthread, req);
  564 }
  565 
  566 void
  567 ktrsysret(int code, int error, register_t retval)
  568 {
  569         struct ktr_request *req;
  570         struct ktr_sysret *ktp;
  571 
  572         if (__predict_false(curthread->td_pflags & TDP_INKTRACE))
  573                 return;
  574 
  575         req = ktr_getrequest(KTR_SYSRET);
  576         if (req == NULL)
  577                 return;
  578         ktp = &req->ktr_data.ktr_sysret;
  579         ktp->ktr_code = code;
  580         ktp->ktr_error = error;
  581         ktp->ktr_retval = ((error == 0) ? retval: 0);           /* what about val2 ? */
  582         ktr_submitrequest(curthread, req);
  583 }
  584 
  585 /*
  586  * When a setuid process execs, disable tracing.
  587  *
  588  * XXX: We toss any pending asynchronous records.
  589  */
  590 struct ktr_io_params *
  591 ktrprocexec(struct proc *p)
  592 {
  593         struct ktr_io_params *kiop;
  594 
  595         PROC_LOCK_ASSERT(p, MA_OWNED);
  596 
  597         kiop = p->p_ktrioparms;
  598         if (kiop == NULL || priv_check_cred(kiop->cr, PRIV_DEBUG_DIFFCRED))
  599                 return (NULL);
  600 
  601         mtx_lock(&ktrace_mtx);
  602         kiop = ktr_freeproc(p);
  603         mtx_unlock(&ktrace_mtx);
  604         return (kiop);
  605 }
  606 
  607 /*
  608  * When a process exits, drain per-process asynchronous trace records
  609  * and disable tracing.
  610  */
  611 void
  612 ktrprocexit(struct thread *td)
  613 {
  614         struct ktr_request *req;
  615         struct proc *p;
  616         struct ktr_io_params *kiop;
  617 
  618         p = td->td_proc;
  619         if (p->p_traceflag == 0)
  620                 return;
  621 
  622         ktrace_enter(td);
  623         req = ktr_getrequest_entered(td, KTR_PROCDTOR);
  624         if (req != NULL)
  625                 ktr_enqueuerequest(td, req);
  626         sx_xlock(&ktrace_sx);
  627         ktr_drain(td);
  628         sx_xunlock(&ktrace_sx);
  629         PROC_LOCK(p);
  630         mtx_lock(&ktrace_mtx);
  631         kiop = ktr_freeproc(p);
  632         mtx_unlock(&ktrace_mtx);
  633         PROC_UNLOCK(p);
  634         ktr_io_params_free(kiop);
  635         ktrace_exit(td);
  636 }
  637 
  638 static void
  639 ktrprocctor_entered(struct thread *td, struct proc *p)
  640 {
  641         struct ktr_proc_ctor *ktp;
  642         struct ktr_request *req;
  643         struct thread *td2;
  644 
  645         ktrace_assert(td);
  646         td2 = FIRST_THREAD_IN_PROC(p);
  647         req = ktr_getrequest_entered(td2, KTR_PROCCTOR);
  648         if (req == NULL)
  649                 return;
  650         ktp = &req->ktr_data.ktr_proc_ctor;
  651         ktp->sv_flags = p->p_sysent->sv_flags;
  652         ktr_enqueuerequest(td2, req);
  653 }
  654 
  655 void
  656 ktrprocctor(struct proc *p)
  657 {
  658         struct thread *td = curthread;
  659 
  660         if ((p->p_traceflag & KTRFAC_MASK) == 0)
  661                 return;
  662 
  663         ktrace_enter(td);
  664         ktrprocctor_entered(td, p);
  665         ktrace_exit(td);
  666 }
  667 
  668 /*
  669  * When a process forks, enable tracing in the new process if needed.
  670  */
  671 void
  672 ktrprocfork(struct proc *p1, struct proc *p2)
  673 {
  674 
  675         MPASS(p2->p_ktrioparms == NULL);
  676         MPASS(p2->p_traceflag == 0);
  677 
  678         if (p1->p_traceflag == 0)
  679                 return;
  680 
  681         PROC_LOCK(p1);
  682         mtx_lock(&ktrace_mtx);
  683         if (p1->p_traceflag & KTRFAC_INHERIT) {
  684                 p2->p_traceflag = p1->p_traceflag;
  685                 if ((p2->p_ktrioparms = p1->p_ktrioparms) != NULL)
  686                         p1->p_ktrioparms->refs++;
  687         }
  688         mtx_unlock(&ktrace_mtx);
  689         PROC_UNLOCK(p1);
  690 
  691         ktrprocctor(p2);
  692 }
  693 
  694 /*
  695  * When a thread returns, drain any asynchronous records generated by the
  696  * system call.
  697  */
  698 void
  699 ktruserret(struct thread *td)
  700 {
  701 
  702         ktrace_enter(td);
  703         sx_xlock(&ktrace_sx);
  704         ktr_drain(td);
  705         sx_xunlock(&ktrace_sx);
  706         ktrace_exit(td);
  707 }
  708 
  709 void
  710 ktrnamei(const char *path)
  711 {
  712         struct ktr_request *req;
  713         int namelen;
  714         char *buf = NULL;
  715 
  716         namelen = strlen(path);
  717         if (namelen > 0) {
  718                 buf = malloc(namelen, M_KTRACE, M_WAITOK);
  719                 bcopy(path, buf, namelen);
  720         }
  721         req = ktr_getrequest(KTR_NAMEI);
  722         if (req == NULL) {
  723                 if (buf != NULL)
  724                         free(buf, M_KTRACE);
  725                 return;
  726         }
  727         if (namelen > 0) {
  728                 req->ktr_header.ktr_len = namelen;
  729                 req->ktr_buffer = buf;
  730         }
  731         ktr_submitrequest(curthread, req);
  732 }
  733 
  734 void
  735 ktrsysctl(int *name, u_int namelen)
  736 {
  737         struct ktr_request *req;
  738         u_int mib[CTL_MAXNAME + 2];
  739         char *mibname;
  740         size_t mibnamelen;
  741         int error;
  742 
  743         /* Lookup name of mib. */    
  744         KASSERT(namelen <= CTL_MAXNAME, ("sysctl MIB too long"));
  745         mib[0] = 0;
  746         mib[1] = 1;
  747         bcopy(name, mib + 2, namelen * sizeof(*name));
  748         mibnamelen = 128;
  749         mibname = malloc(mibnamelen, M_KTRACE, M_WAITOK);
  750         error = kernel_sysctl(curthread, mib, namelen + 2, mibname, &mibnamelen,
  751             NULL, 0, &mibnamelen, 0);
  752         if (error) {
  753                 free(mibname, M_KTRACE);
  754                 return;
  755         }
  756         req = ktr_getrequest(KTR_SYSCTL);
  757         if (req == NULL) {
  758                 free(mibname, M_KTRACE);
  759                 return;
  760         }
  761         req->ktr_header.ktr_len = mibnamelen;
  762         req->ktr_buffer = mibname;
  763         ktr_submitrequest(curthread, req);
  764 }
  765 
  766 void
  767 ktrgenio(int fd, enum uio_rw rw, struct uio *uio, int error)
  768 {
  769         struct ktr_request *req;
  770         struct ktr_genio *ktg;
  771         int datalen;
  772         char *buf;
  773 
  774         if (error) {
  775                 free(uio, M_IOV);
  776                 return;
  777         }
  778         uio->uio_offset = 0;
  779         uio->uio_rw = UIO_WRITE;
  780         datalen = MIN(uio->uio_resid, ktr_geniosize);
  781         buf = malloc(datalen, M_KTRACE, M_WAITOK);
  782         error = uiomove(buf, datalen, uio);
  783         free(uio, M_IOV);
  784         if (error) {
  785                 free(buf, M_KTRACE);
  786                 return;
  787         }
  788         req = ktr_getrequest(KTR_GENIO);
  789         if (req == NULL) {
  790                 free(buf, M_KTRACE);
  791                 return;
  792         }
  793         ktg = &req->ktr_data.ktr_genio;
  794         ktg->ktr_fd = fd;
  795         ktg->ktr_rw = rw;
  796         req->ktr_header.ktr_len = datalen;
  797         req->ktr_buffer = buf;
  798         ktr_submitrequest(curthread, req);
  799 }
  800 
  801 void
  802 ktrpsig(int sig, sig_t action, sigset_t *mask, int code)
  803 {
  804         struct thread *td = curthread;
  805         struct ktr_request *req;
  806         struct ktr_psig *kp;
  807 
  808         req = ktr_getrequest(KTR_PSIG);
  809         if (req == NULL)
  810                 return;
  811         kp = &req->ktr_data.ktr_psig;
  812         kp->signo = (char)sig;
  813         kp->action = action;
  814         kp->mask = *mask;
  815         kp->code = code;
  816         ktr_enqueuerequest(td, req);
  817         ktrace_exit(td);
  818 }
  819 
  820 void
  821 ktrcsw(int out, int user, const char *wmesg)
  822 {
  823         struct thread *td = curthread;
  824         struct ktr_request *req;
  825         struct ktr_csw *kc;
  826 
  827         if (__predict_false(curthread->td_pflags & TDP_INKTRACE))
  828                 return;
  829 
  830         req = ktr_getrequest(KTR_CSW);
  831         if (req == NULL)
  832                 return;
  833         kc = &req->ktr_data.ktr_csw;
  834         kc->out = out;
  835         kc->user = user;
  836         if (wmesg != NULL)
  837                 strlcpy(kc->wmesg, wmesg, sizeof(kc->wmesg));
  838         else
  839                 bzero(kc->wmesg, sizeof(kc->wmesg));
  840         ktr_enqueuerequest(td, req);
  841         ktrace_exit(td);
  842 }
  843 
  844 void
  845 ktrstruct(const char *name, const void *data, size_t datalen)
  846 {
  847         struct ktr_request *req;
  848         char *buf;
  849         size_t buflen, namelen;
  850 
  851         if (__predict_false(curthread->td_pflags & TDP_INKTRACE))
  852                 return;
  853 
  854         if (data == NULL)
  855                 datalen = 0;
  856         namelen = strlen(name) + 1;
  857         buflen = namelen + datalen;
  858         buf = malloc(buflen, M_KTRACE, M_WAITOK);
  859         strcpy(buf, name);
  860         bcopy(data, buf + namelen, datalen);
  861         if ((req = ktr_getrequest(KTR_STRUCT)) == NULL) {
  862                 free(buf, M_KTRACE);
  863                 return;
  864         }
  865         req->ktr_buffer = buf;
  866         req->ktr_header.ktr_len = buflen;
  867         ktr_submitrequest(curthread, req);
  868 }
  869 
  870 void
  871 ktrstruct_error(const char *name, const void *data, size_t datalen, int error)
  872 {
  873 
  874         if (error == 0)
  875                 ktrstruct(name, data, datalen);
  876 }
  877 
  878 void
  879 ktrstructarray(const char *name, enum uio_seg seg, const void *data,
  880     int num_items, size_t struct_size)
  881 {
  882         struct ktr_request *req;
  883         struct ktr_struct_array *ksa;
  884         char *buf;
  885         size_t buflen, datalen, namelen;
  886         int max_items;
  887 
  888         if (__predict_false(curthread->td_pflags & TDP_INKTRACE))
  889                 return;
  890         if (num_items < 0)
  891                 return;
  892 
  893         /* Trim array length to genio size. */
  894         max_items = ktr_geniosize / struct_size;
  895         if (num_items > max_items) {
  896                 if (max_items == 0)
  897                         num_items = 1;
  898                 else
  899                         num_items = max_items;
  900         }
  901         datalen = num_items * struct_size;
  902 
  903         if (data == NULL)
  904                 datalen = 0;
  905 
  906         namelen = strlen(name) + 1;
  907         buflen = namelen + datalen;
  908         buf = malloc(buflen, M_KTRACE, M_WAITOK);
  909         strcpy(buf, name);
  910         if (seg == UIO_SYSSPACE)
  911                 bcopy(data, buf + namelen, datalen);
  912         else {
  913                 if (copyin(data, buf + namelen, datalen) != 0) {
  914                         free(buf, M_KTRACE);
  915                         return;
  916                 }
  917         }
  918         if ((req = ktr_getrequest(KTR_STRUCT_ARRAY)) == NULL) {
  919                 free(buf, M_KTRACE);
  920                 return;
  921         }
  922         ksa = &req->ktr_data.ktr_struct_array;
  923         ksa->struct_size = struct_size;
  924         req->ktr_buffer = buf;
  925         req->ktr_header.ktr_len = buflen;
  926         ktr_submitrequest(curthread, req);
  927 }
  928 
  929 void
  930 ktrcapfail(enum ktr_cap_fail_type type, const cap_rights_t *needed,
  931     const cap_rights_t *held)
  932 {
  933         struct thread *td = curthread;
  934         struct ktr_request *req;
  935         struct ktr_cap_fail *kcf;
  936 
  937         if (__predict_false(curthread->td_pflags & TDP_INKTRACE))
  938                 return;
  939 
  940         req = ktr_getrequest(KTR_CAPFAIL);
  941         if (req == NULL)
  942                 return;
  943         kcf = &req->ktr_data.ktr_cap_fail;
  944         kcf->cap_type = type;
  945         if (needed != NULL)
  946                 kcf->cap_needed = *needed;
  947         else
  948                 cap_rights_init(&kcf->cap_needed);
  949         if (held != NULL)
  950                 kcf->cap_held = *held;
  951         else
  952                 cap_rights_init(&kcf->cap_held);
  953         ktr_enqueuerequest(td, req);
  954         ktrace_exit(td);
  955 }
  956 
  957 void
  958 ktrfault(vm_offset_t vaddr, int type)
  959 {
  960         struct thread *td = curthread;
  961         struct ktr_request *req;
  962         struct ktr_fault *kf;
  963 
  964         if (__predict_false(curthread->td_pflags & TDP_INKTRACE))
  965                 return;
  966 
  967         req = ktr_getrequest(KTR_FAULT);
  968         if (req == NULL)
  969                 return;
  970         kf = &req->ktr_data.ktr_fault;
  971         kf->vaddr = vaddr;
  972         kf->type = type;
  973         ktr_enqueuerequest(td, req);
  974         ktrace_exit(td);
  975 }
  976 
  977 void
  978 ktrfaultend(int result)
  979 {
  980         struct thread *td = curthread;
  981         struct ktr_request *req;
  982         struct ktr_faultend *kf;
  983 
  984         if (__predict_false(curthread->td_pflags & TDP_INKTRACE))
  985                 return;
  986 
  987         req = ktr_getrequest(KTR_FAULTEND);
  988         if (req == NULL)
  989                 return;
  990         kf = &req->ktr_data.ktr_faultend;
  991         kf->result = result;
  992         ktr_enqueuerequest(td, req);
  993         ktrace_exit(td);
  994 }
  995 #endif /* KTRACE */
  996 
  997 /* Interface and common routines */
  998 
  999 #ifndef _SYS_SYSPROTO_H_
 1000 struct ktrace_args {
 1001         char    *fname;
 1002         int     ops;
 1003         int     facs;
 1004         int     pid;
 1005 };
 1006 #endif
 1007 /* ARGSUSED */
 1008 int
 1009 sys_ktrace(struct thread *td, struct ktrace_args *uap)
 1010 {
 1011 #ifdef KTRACE
 1012         struct vnode *vp = NULL;
 1013         struct proc *p;
 1014         struct pgrp *pg;
 1015         int facs = uap->facs & ~KTRFAC_ROOT;
 1016         int ops = KTROP(uap->ops);
 1017         int descend = uap->ops & KTRFLAG_DESCEND;
 1018         int ret = 0;
 1019         int flags, error = 0;
 1020         struct nameidata nd;
 1021         struct ktr_io_params *kiop, *old_kiop;
 1022 
 1023         /*
 1024          * Need something to (un)trace.
 1025          */
 1026         if (ops != KTROP_CLEARFILE && facs == 0)
 1027                 return (EINVAL);
 1028 
 1029         kiop = NULL;
 1030         if (ops != KTROP_CLEAR) {
 1031                 /*
 1032                  * an operation which requires a file argument.
 1033                  */
 1034                 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->fname);
 1035                 flags = FREAD | FWRITE | O_NOFOLLOW;
 1036                 error = vn_open(&nd, &flags, 0, NULL);
 1037                 if (error)
 1038                         return (error);
 1039                 NDFREE_PNBUF(&nd);
 1040                 vp = nd.ni_vp;
 1041                 VOP_UNLOCK(vp);
 1042                 if (vp->v_type != VREG) {
 1043                         (void)vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
 1044                         return (EACCES);
 1045                 }
 1046                 kiop = ktr_io_params_alloc(td, vp);
 1047         }
 1048 
 1049         /*
 1050          * Clear all uses of the tracefile.
 1051          */
 1052         ktrace_enter(td);
 1053         if (ops == KTROP_CLEARFILE) {
 1054 restart:
 1055                 sx_slock(&allproc_lock);
 1056                 FOREACH_PROC_IN_SYSTEM(p) {
 1057                         old_kiop = NULL;
 1058                         PROC_LOCK(p);
 1059                         if (p->p_ktrioparms != NULL &&
 1060                             p->p_ktrioparms->vp == vp) {
 1061                                 if (ktrcanset(td, p)) {
 1062                                         mtx_lock(&ktrace_mtx);
 1063                                         old_kiop = ktr_freeproc(p);
 1064                                         mtx_unlock(&ktrace_mtx);
 1065                                 } else
 1066                                         error = EPERM;
 1067                         }
 1068                         PROC_UNLOCK(p);
 1069                         if (old_kiop != NULL) {
 1070                                 sx_sunlock(&allproc_lock);
 1071                                 ktr_io_params_free(old_kiop);
 1072                                 goto restart;
 1073                         }
 1074                 }
 1075                 sx_sunlock(&allproc_lock);
 1076                 goto done;
 1077         }
 1078         /*
 1079          * do it
 1080          */
 1081         sx_slock(&proctree_lock);
 1082         if (uap->pid < 0) {
 1083                 /*
 1084                  * by process group
 1085                  */
 1086                 pg = pgfind(-uap->pid);
 1087                 if (pg == NULL) {
 1088                         sx_sunlock(&proctree_lock);
 1089                         error = ESRCH;
 1090                         goto done;
 1091                 }
 1092 
 1093                 /*
 1094                  * ktrops() may call vrele(). Lock pg_members
 1095                  * by the proctree_lock rather than pg_mtx.
 1096                  */
 1097                 PGRP_UNLOCK(pg);
 1098                 if (LIST_EMPTY(&pg->pg_members)) {
 1099                         sx_sunlock(&proctree_lock);
 1100                         error = ESRCH;
 1101                         goto done;
 1102                 }
 1103                 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
 1104                         PROC_LOCK(p);
 1105                         if (descend)
 1106                                 ret |= ktrsetchildren(td, p, ops, facs, kiop);
 1107                         else
 1108                                 ret |= ktrops(td, p, ops, facs, kiop);
 1109                 }
 1110         } else {
 1111                 /*
 1112                  * by pid
 1113                  */
 1114                 p = pfind(uap->pid);
 1115                 if (p == NULL) {
 1116                         error = ESRCH;
 1117                         sx_sunlock(&proctree_lock);
 1118                         goto done;
 1119                 }
 1120                 if (descend)
 1121                         ret |= ktrsetchildren(td, p, ops, facs, kiop);
 1122                 else
 1123                         ret |= ktrops(td, p, ops, facs, kiop);
 1124         }
 1125         sx_sunlock(&proctree_lock);
 1126         if (!ret)
 1127                 error = EPERM;
 1128 done:
 1129         if (kiop != NULL) {
 1130                 mtx_lock(&ktrace_mtx);
 1131                 kiop = ktr_io_params_rele(kiop);
 1132                 mtx_unlock(&ktrace_mtx);
 1133                 ktr_io_params_free(kiop);
 1134         }
 1135         ktrace_exit(td);
 1136         return (error);
 1137 #else /* !KTRACE */
 1138         return (ENOSYS);
 1139 #endif /* KTRACE */
 1140 }
 1141 
 1142 /* ARGSUSED */
 1143 int
 1144 sys_utrace(struct thread *td, struct utrace_args *uap)
 1145 {
 1146 
 1147 #ifdef KTRACE
 1148         struct ktr_request *req;
 1149         void *cp;
 1150         int error;
 1151 
 1152         if (!KTRPOINT(td, KTR_USER))
 1153                 return (0);
 1154         if (uap->len > KTR_USER_MAXLEN)
 1155                 return (EINVAL);
 1156         cp = malloc(uap->len, M_KTRACE, M_WAITOK);
 1157         error = copyin(uap->addr, cp, uap->len);
 1158         if (error) {
 1159                 free(cp, M_KTRACE);
 1160                 return (error);
 1161         }
 1162         req = ktr_getrequest(KTR_USER);
 1163         if (req == NULL) {
 1164                 free(cp, M_KTRACE);
 1165                 return (ENOMEM);
 1166         }
 1167         req->ktr_buffer = cp;
 1168         req->ktr_header.ktr_len = uap->len;
 1169         ktr_submitrequest(td, req);
 1170         return (0);
 1171 #else /* !KTRACE */
 1172         return (ENOSYS);
 1173 #endif /* KTRACE */
 1174 }
 1175 
 1176 #ifdef KTRACE
 1177 static int
 1178 ktrops(struct thread *td, struct proc *p, int ops, int facs,
 1179     struct ktr_io_params *new_kiop)
 1180 {
 1181         struct ktr_io_params *old_kiop;
 1182 
 1183         PROC_LOCK_ASSERT(p, MA_OWNED);
 1184         if (!ktrcanset(td, p)) {
 1185                 PROC_UNLOCK(p);
 1186                 return (0);
 1187         }
 1188         if ((ops == KTROP_SET && p->p_state == PRS_NEW) ||
 1189             p_cansee(td, p) != 0) {
 1190                 /*
 1191                  * Disallow setting trace points if the process is being born.
 1192                  * This avoids races with trace point inheritance in
 1193                  * ktrprocfork().
 1194                  */
 1195                 PROC_UNLOCK(p);
 1196                 return (0);
 1197         }
 1198         if ((p->p_flag & P_WEXIT) != 0) {
 1199                 /*
 1200                  * There's nothing to do if the process is exiting, but avoid
 1201                  * signaling an error.
 1202                  */
 1203                 PROC_UNLOCK(p);
 1204                 return (1);
 1205         }
 1206         old_kiop = NULL;
 1207         mtx_lock(&ktrace_mtx);
 1208         if (ops == KTROP_SET) {
 1209                 if (p->p_ktrioparms != NULL &&
 1210                     p->p_ktrioparms->vp != new_kiop->vp) {
 1211                         /* if trace file already in use, relinquish below */
 1212                         old_kiop = ktr_io_params_rele(p->p_ktrioparms);
 1213                         p->p_ktrioparms = NULL;
 1214                 }
 1215                 if (p->p_ktrioparms == NULL) {
 1216                         p->p_ktrioparms = new_kiop;
 1217                         ktr_io_params_ref(new_kiop);
 1218                 }
 1219                 p->p_traceflag |= facs;
 1220                 if (priv_check(td, PRIV_KTRACE) == 0)
 1221                         p->p_traceflag |= KTRFAC_ROOT;
 1222         } else {
 1223                 /* KTROP_CLEAR */
 1224                 if (((p->p_traceflag &= ~facs) & KTRFAC_MASK) == 0)
 1225                         /* no more tracing */
 1226                         old_kiop = ktr_freeproc(p);
 1227         }
 1228         mtx_unlock(&ktrace_mtx);
 1229         if ((p->p_traceflag & KTRFAC_MASK) != 0)
 1230                 ktrprocctor_entered(td, p);
 1231         PROC_UNLOCK(p);
 1232         ktr_io_params_free(old_kiop);
 1233 
 1234         return (1);
 1235 }
 1236 
 1237 static int
 1238 ktrsetchildren(struct thread *td, struct proc *top, int ops, int facs,
 1239     struct ktr_io_params *new_kiop)
 1240 {
 1241         struct proc *p;
 1242         int ret = 0;
 1243 
 1244         p = top;
 1245         PROC_LOCK_ASSERT(p, MA_OWNED);
 1246         sx_assert(&proctree_lock, SX_LOCKED);
 1247         for (;;) {
 1248                 ret |= ktrops(td, p, ops, facs, new_kiop);
 1249                 /*
 1250                  * If this process has children, descend to them next,
 1251                  * otherwise do any siblings, and if done with this level,
 1252                  * follow back up the tree (but not past top).
 1253                  */
 1254                 if (!LIST_EMPTY(&p->p_children))
 1255                         p = LIST_FIRST(&p->p_children);
 1256                 else for (;;) {
 1257                         if (p == top)
 1258                                 return (ret);
 1259                         if (LIST_NEXT(p, p_sibling)) {
 1260                                 p = LIST_NEXT(p, p_sibling);
 1261                                 break;
 1262                         }
 1263                         p = p->p_pptr;
 1264                 }
 1265                 PROC_LOCK(p);
 1266         }
 1267         /*NOTREACHED*/
 1268 }
 1269 
 1270 static void
 1271 ktr_writerequest(struct thread *td, struct ktr_request *req)
 1272 {
 1273         struct ktr_io_params *kiop, *kiop1;
 1274         struct ktr_header *kth;
 1275         struct vnode *vp;
 1276         struct proc *p;
 1277         struct ucred *cred;
 1278         struct uio auio;
 1279         struct iovec aiov[3];
 1280         struct mount *mp;
 1281         off_t lim;
 1282         int datalen, buflen;
 1283         int error;
 1284 
 1285         p = td->td_proc;
 1286 
 1287         /*
 1288          * We reference the kiop for use in I/O in case ktrace is
 1289          * disabled on the process as we write out the request.
 1290          */
 1291         mtx_lock(&ktrace_mtx);
 1292         kiop = p->p_ktrioparms;
 1293 
 1294         /*
 1295          * If kiop is NULL, it has been cleared out from under this
 1296          * request, so just drop it.
 1297          */
 1298         if (kiop == NULL) {
 1299                 mtx_unlock(&ktrace_mtx);
 1300                 return;
 1301         }
 1302 
 1303         ktr_io_params_ref(kiop);
 1304         vp = kiop->vp;
 1305         cred = kiop->cr;
 1306         lim = kiop->lim;
 1307 
 1308         KASSERT(cred != NULL, ("ktr_writerequest: cred == NULL"));
 1309         mtx_unlock(&ktrace_mtx);
 1310 
 1311         kth = &req->ktr_header;
 1312         KASSERT(((u_short)kth->ktr_type & ~KTR_TYPE) < nitems(data_lengths),
 1313             ("data_lengths array overflow"));
 1314         datalen = data_lengths[(u_short)kth->ktr_type & ~KTR_TYPE];
 1315         buflen = kth->ktr_len;
 1316         auio.uio_iov = &aiov[0];
 1317         auio.uio_offset = 0;
 1318         auio.uio_segflg = UIO_SYSSPACE;
 1319         auio.uio_rw = UIO_WRITE;
 1320         aiov[0].iov_base = (caddr_t)kth;
 1321         aiov[0].iov_len = sizeof(struct ktr_header);
 1322         auio.uio_resid = sizeof(struct ktr_header);
 1323         auio.uio_iovcnt = 1;
 1324         auio.uio_td = td;
 1325         if (datalen != 0) {
 1326                 aiov[1].iov_base = (caddr_t)&req->ktr_data;
 1327                 aiov[1].iov_len = datalen;
 1328                 auio.uio_resid += datalen;
 1329                 auio.uio_iovcnt++;
 1330                 kth->ktr_len += datalen;
 1331         }
 1332         if (buflen != 0) {
 1333                 KASSERT(req->ktr_buffer != NULL, ("ktrace: nothing to write"));
 1334                 aiov[auio.uio_iovcnt].iov_base = req->ktr_buffer;
 1335                 aiov[auio.uio_iovcnt].iov_len = buflen;
 1336                 auio.uio_resid += buflen;
 1337                 auio.uio_iovcnt++;
 1338         }
 1339 
 1340         vn_start_write(vp, &mp, V_WAIT);
 1341         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 1342         td->td_ktr_io_lim = lim;
 1343 #ifdef MAC
 1344         error = mac_vnode_check_write(cred, NOCRED, vp);
 1345         if (error == 0)
 1346 #endif
 1347                 error = VOP_WRITE(vp, &auio, IO_UNIT | IO_APPEND, cred);
 1348         VOP_UNLOCK(vp);
 1349         vn_finished_write(mp);
 1350         if (error == 0) {
 1351                 mtx_lock(&ktrace_mtx);
 1352                 kiop = ktr_io_params_rele(kiop);
 1353                 mtx_unlock(&ktrace_mtx);
 1354                 ktr_io_params_free(kiop);
 1355                 return;
 1356         }
 1357 
 1358         /*
 1359          * If error encountered, give up tracing on this vnode on this
 1360          * process.  Other processes might still be suitable for
 1361          * writes to this vnode.
 1362          */
 1363         log(LOG_NOTICE,
 1364             "ktrace write failed, errno %d, tracing stopped for pid %d\n",
 1365             error, p->p_pid);
 1366 
 1367         kiop1 = NULL;
 1368         PROC_LOCK(p);
 1369         mtx_lock(&ktrace_mtx);
 1370         if (p->p_ktrioparms != NULL && p->p_ktrioparms->vp == vp)
 1371                 kiop1 = ktr_freeproc(p);
 1372         kiop = ktr_io_params_rele(kiop);
 1373         mtx_unlock(&ktrace_mtx);
 1374         PROC_UNLOCK(p);
 1375         ktr_io_params_free(kiop1);
 1376         ktr_io_params_free(kiop);
 1377 }
 1378 
 1379 /*
 1380  * Return true if caller has permission to set the ktracing state
 1381  * of target.  Essentially, the target can't possess any
 1382  * more permissions than the caller.  KTRFAC_ROOT signifies that
 1383  * root previously set the tracing status on the target process, and
 1384  * so, only root may further change it.
 1385  */
 1386 static int
 1387 ktrcanset(struct thread *td, struct proc *targetp)
 1388 {
 1389 
 1390         PROC_LOCK_ASSERT(targetp, MA_OWNED);
 1391         if (targetp->p_traceflag & KTRFAC_ROOT &&
 1392             priv_check(td, PRIV_KTRACE))
 1393                 return (0);
 1394 
 1395         if (p_candebug(td, targetp) != 0)
 1396                 return (0);
 1397 
 1398         return (1);
 1399 }
 1400 
 1401 #endif /* KTRACE */

Cache object: ddb303a459d209d98da0feae3479a123


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.