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 /*      $NetBSD: kern_ktrace.c,v 1.147.4.1 2009/09/05 11:37:21 bouyer Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Andrew Doran.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*
   33  * Copyright (c) 1989, 1993
   34  *      The Regents of the University of California.  All rights reserved.
   35  *
   36  * Redistribution and use in source and binary forms, with or without
   37  * modification, are permitted provided that the following conditions
   38  * are met:
   39  * 1. Redistributions of source code must retain the above copyright
   40  *    notice, this list of conditions and the following disclaimer.
   41  * 2. Redistributions in binary form must reproduce the above copyright
   42  *    notice, this list of conditions and the following disclaimer in the
   43  *    documentation and/or other materials provided with the distribution.
   44  * 3. Neither the name of the University nor the names of its contributors
   45  *    may be used to endorse or promote products derived from this software
   46  *    without specific prior written permission.
   47  *
   48  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   49  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   50  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   51  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   52  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   55  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   56  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   57  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   58  * SUCH DAMAGE.
   59  *
   60  *      @(#)kern_ktrace.c       8.5 (Berkeley) 5/14/95
   61  */
   62 
   63 #include <sys/cdefs.h>
   64 __KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.147.4.1 2009/09/05 11:37:21 bouyer Exp $");
   65 
   66 #include <sys/param.h>
   67 #include <sys/systm.h>
   68 #include <sys/proc.h>
   69 #include <sys/file.h>
   70 #include <sys/namei.h>
   71 #include <sys/vnode.h>
   72 #include <sys/kernel.h>
   73 #include <sys/kthread.h>
   74 #include <sys/ktrace.h>
   75 #include <sys/kmem.h>
   76 #include <sys/syslog.h>
   77 #include <sys/filedesc.h>
   78 #include <sys/ioctl.h>
   79 #include <sys/callout.h>
   80 #include <sys/kauth.h>
   81 
   82 #include <sys/mount.h>
   83 #include <sys/sa.h>
   84 #include <sys/syscallargs.h>
   85 
   86 /*
   87  * TODO:
   88  *      - need better error reporting?
   89  *      - userland utility to sort ktrace.out by timestamp.
   90  *      - keep minimum information in ktrace_entry when rest of alloc failed.
   91  *      - per trace control of configurable parameters.
   92  */
   93 
   94 struct ktrace_entry {
   95         TAILQ_ENTRY(ktrace_entry) kte_list;
   96         struct  ktr_header kte_kth;
   97         void    *kte_buf;
   98         size_t  kte_bufsz;      
   99 #define KTE_SPACE               32
  100         uint8_t kte_space[KTE_SPACE];
  101 };
  102 
  103 struct ktr_desc {
  104         TAILQ_ENTRY(ktr_desc) ktd_list;
  105         int ktd_flags;
  106 #define KTDF_WAIT               0x0001
  107 #define KTDF_DONE               0x0002
  108 #define KTDF_BLOCKING           0x0004
  109 #define KTDF_INTERACTIVE        0x0008
  110         int ktd_error;
  111 #define KTDE_ENOMEM             0x0001
  112 #define KTDE_ENOSPC             0x0002
  113         int ktd_errcnt;
  114         int ktd_ref;                    /* # of reference */
  115         int ktd_qcount;                 /* # of entry in the queue */
  116 
  117         /*
  118          * Params to control behaviour.
  119          */
  120         int ktd_delayqcnt;              /* # of entry allowed to delay */
  121         int ktd_wakedelay;              /* delay of wakeup in *tick* */
  122         int ktd_intrwakdl;              /* ditto, but when interactive */
  123 
  124         file_t *ktd_fp;                 /* trace output file */
  125         lwp_t *ktd_lwp;                 /* our kernel thread */
  126         TAILQ_HEAD(, ktrace_entry) ktd_queue;
  127         callout_t ktd_wakch;            /* delayed wakeup */
  128         kcondvar_t ktd_sync_cv;
  129         kcondvar_t ktd_cv;
  130 };
  131 
  132 static int      ktealloc(struct ktrace_entry **, void **, lwp_t *, int,
  133                          size_t);
  134 static void     ktrwrite(struct ktr_desc *, struct ktrace_entry *);
  135 static int      ktrace_common(lwp_t *, int, int, int, file_t *);
  136 static int      ktrops(lwp_t *, struct proc *, int, int,
  137                     struct ktr_desc *);
  138 static int      ktrsetchildren(lwp_t *, struct proc *, int, int,
  139                     struct ktr_desc *);
  140 static int      ktrcanset(lwp_t *, struct proc *);
  141 static int      ktrsamefile(file_t *, file_t *);
  142 static void     ktr_kmem(lwp_t *, int, const void *, size_t);
  143 static void     ktr_io(lwp_t *, int, enum uio_rw, struct iovec *, size_t);
  144 
  145 static struct ktr_desc *
  146                 ktd_lookup(file_t *);
  147 static void     ktdrel(struct ktr_desc *);
  148 static void     ktdref(struct ktr_desc *);
  149 static void     ktraddentry(lwp_t *, struct ktrace_entry *, int);
  150 /* Flags for ktraddentry (3rd arg) */
  151 #define KTA_NOWAIT              0x0000
  152 #define KTA_WAITOK              0x0001
  153 #define KTA_LARGE               0x0002
  154 static void     ktefree(struct ktrace_entry *);
  155 static void     ktd_logerrl(struct ktr_desc *, int);
  156 static void     ktrace_thread(void *);
  157 static int      ktrderefall(struct ktr_desc *, int);
  158 
  159 /*
  160  * Default vaules.
  161  */
  162 #define KTD_MAXENTRY            1000    /* XXX: tune */
  163 #define KTD_TIMEOUT             5       /* XXX: tune */
  164 #define KTD_DELAYQCNT           100     /* XXX: tune */
  165 #define KTD_WAKEDELAY           5000    /* XXX: tune */
  166 #define KTD_INTRWAKDL           100     /* XXX: tune */
  167 
  168 /*
  169  * Patchable variables.
  170  */
  171 int ktd_maxentry = KTD_MAXENTRY;        /* max # of entry in the queue */
  172 int ktd_timeout = KTD_TIMEOUT;          /* timeout in seconds */
  173 int ktd_delayqcnt = KTD_DELAYQCNT;      /* # of entry allowed to delay */
  174 int ktd_wakedelay = KTD_WAKEDELAY;      /* delay of wakeup in *ms* */
  175 int ktd_intrwakdl = KTD_INTRWAKDL;      /* ditto, but when interactive */
  176 
  177 kmutex_t ktrace_lock;
  178 int ktrace_on;
  179 static TAILQ_HEAD(, ktr_desc) ktdq = TAILQ_HEAD_INITIALIZER(ktdq);
  180 static pool_cache_t kte_cache;
  181 
  182 static void
  183 ktd_wakeup(struct ktr_desc *ktd)
  184 {
  185 
  186         callout_stop(&ktd->ktd_wakch);
  187         cv_signal(&ktd->ktd_cv);
  188 }
  189 
  190 static void
  191 ktd_callout(void *arg)
  192 {
  193 
  194         mutex_enter(&ktrace_lock);
  195         ktd_wakeup(arg);
  196         mutex_exit(&ktrace_lock);
  197 }
  198 
  199 static void
  200 ktd_logerrl(struct ktr_desc *ktd, int error)
  201 {
  202 
  203         ktd->ktd_error |= error;
  204         ktd->ktd_errcnt++;
  205 }
  206 
  207 #if 0
  208 static void
  209 ktd_logerr(struct proc *p, int error)
  210 {
  211         struct ktr_desc *ktd;
  212 
  213         KASSERT(mutex_owned(&ktrace_lock));
  214 
  215         ktd = p->p_tracep;
  216         if (ktd == NULL)
  217                 return;
  218 
  219         ktd_logerrl(ktd, error);
  220 }
  221 #endif
  222 
  223 static inline int
  224 ktrenter(lwp_t *l)
  225 {
  226 
  227         if ((l->l_pflag & LP_KTRACTIVE) != 0)
  228                 return 1;
  229         l->l_pflag |= LP_KTRACTIVE;
  230         return 0;
  231 }
  232 
  233 static inline void
  234 ktrexit(lwp_t *l)
  235 {
  236 
  237         l->l_pflag &= ~LP_KTRACTIVE;
  238 }
  239 
  240 /*
  241  * Initialise the ktrace system.
  242  */
  243 void
  244 ktrinit(void)
  245 {
  246 
  247         mutex_init(&ktrace_lock, MUTEX_DEFAULT, IPL_NONE);
  248         kte_cache = pool_cache_init(sizeof(struct ktrace_entry), 0, 0, 0,
  249             "ktrace", &pool_allocator_nointr, IPL_NONE, NULL, NULL, NULL);
  250 }
  251 
  252 /*
  253  * Release a reference.  Called with ktrace_lock held.
  254  */
  255 void
  256 ktdrel(struct ktr_desc *ktd)
  257 {
  258 
  259         KASSERT(mutex_owned(&ktrace_lock));
  260 
  261         KDASSERT(ktd->ktd_ref != 0);
  262         KASSERT(ktd->ktd_ref > 0);
  263         KASSERT(ktrace_on > 0);
  264         ktrace_on--;
  265         if (--ktd->ktd_ref <= 0) {
  266                 ktd->ktd_flags |= KTDF_DONE;
  267                 cv_signal(&ktd->ktd_cv);
  268         }
  269 }
  270 
  271 void
  272 ktdref(struct ktr_desc *ktd)
  273 {
  274 
  275         KASSERT(mutex_owned(&ktrace_lock));
  276 
  277         ktd->ktd_ref++;
  278         ktrace_on++;
  279 }
  280 
  281 struct ktr_desc *
  282 ktd_lookup(file_t *fp)
  283 {
  284         struct ktr_desc *ktd;
  285 
  286         KASSERT(mutex_owned(&ktrace_lock));
  287 
  288         for (ktd = TAILQ_FIRST(&ktdq); ktd != NULL;
  289             ktd = TAILQ_NEXT(ktd, ktd_list)) {
  290                 if (ktrsamefile(ktd->ktd_fp, fp)) {
  291                         ktdref(ktd);
  292                         break;
  293                 }
  294         }
  295 
  296         return (ktd);
  297 }
  298 
  299 void
  300 ktraddentry(lwp_t *l, struct ktrace_entry *kte, int flags)
  301 {
  302         struct proc *p = l->l_proc;
  303         struct ktr_desc *ktd;
  304 #ifdef DEBUG
  305         struct timeval t1, t2;
  306 #endif
  307 
  308         mutex_enter(&ktrace_lock);
  309 
  310         if (p->p_traceflag & KTRFAC_TRC_EMUL) {
  311                 /* Add emulation trace before first entry for this process */
  312                 p->p_traceflag &= ~KTRFAC_TRC_EMUL;
  313                 mutex_exit(&ktrace_lock);
  314                 ktrexit(l);
  315                 ktremul();
  316                 (void)ktrenter(l);
  317                 mutex_enter(&ktrace_lock);
  318         }
  319 
  320         /* Tracing may have been cancelled. */
  321         ktd = p->p_tracep;
  322         if (ktd == NULL)
  323                 goto freekte;
  324 
  325         /*
  326          * Bump reference count so that the object will remain while
  327          * we are here.  Note that the trace is controlled by other
  328          * process.
  329          */
  330         ktdref(ktd);
  331 
  332         if (ktd->ktd_flags & KTDF_DONE)
  333                 goto relktd;
  334 
  335         if (ktd->ktd_qcount > ktd_maxentry) {
  336                 ktd_logerrl(ktd, KTDE_ENOSPC);
  337                 goto relktd;
  338         }
  339         TAILQ_INSERT_TAIL(&ktd->ktd_queue, kte, kte_list);
  340         ktd->ktd_qcount++;
  341         if (ktd->ktd_flags & KTDF_BLOCKING)
  342                 goto skip_sync;
  343 
  344         if (flags & KTA_WAITOK &&
  345             (/* flags & KTA_LARGE */0 || ktd->ktd_flags & KTDF_WAIT ||
  346             ktd->ktd_qcount > ktd_maxentry >> 1))
  347                 /*
  348                  * Sync with writer thread since we're requesting rather
  349                  * big one or many requests are pending.
  350                  */
  351                 do {
  352                         ktd->ktd_flags |= KTDF_WAIT;
  353                         ktd_wakeup(ktd);
  354 #ifdef DEBUG
  355                         getmicrouptime(&t1);
  356 #endif
  357                         if (cv_timedwait(&ktd->ktd_sync_cv, &ktrace_lock,
  358                             ktd_timeout * hz) != 0) {
  359                                 ktd->ktd_flags |= KTDF_BLOCKING;
  360                                 /*
  361                                  * Maybe the writer thread is blocking
  362                                  * completely for some reason, but
  363                                  * don't stop target process forever.
  364                                  */
  365                                 log(LOG_NOTICE, "ktrace timeout\n");
  366                                 break;
  367                         }
  368 #ifdef DEBUG
  369                         getmicrouptime(&t2);
  370                         timersub(&t2, &t1, &t2);
  371                         if (t2.tv_sec > 0)
  372                                 log(LOG_NOTICE,
  373                                     "ktrace long wait: %ld.%06ld\n",
  374                                     t2.tv_sec, t2.tv_usec);
  375 #endif
  376                 } while (p->p_tracep == ktd &&
  377                     (ktd->ktd_flags & (KTDF_WAIT | KTDF_DONE)) == KTDF_WAIT);
  378         else {
  379                 /* Schedule delayed wakeup */
  380                 if (ktd->ktd_qcount > ktd->ktd_delayqcnt)
  381                         ktd_wakeup(ktd);        /* Wakeup now */
  382                 else if (!callout_pending(&ktd->ktd_wakch))
  383                         callout_reset(&ktd->ktd_wakch,
  384                             ktd->ktd_flags & KTDF_INTERACTIVE ?
  385                             ktd->ktd_intrwakdl : ktd->ktd_wakedelay,
  386                             ktd_callout, ktd);
  387         }
  388 
  389 skip_sync:
  390         ktdrel(ktd);
  391         mutex_exit(&ktrace_lock);
  392         ktrexit(l);
  393         return;
  394 
  395 relktd:
  396         ktdrel(ktd);
  397 
  398 freekte:
  399         mutex_exit(&ktrace_lock);
  400         ktefree(kte);
  401         ktrexit(l);
  402 }
  403 
  404 void
  405 ktefree(struct ktrace_entry *kte)
  406 {
  407 
  408         if (kte->kte_buf != kte->kte_space)
  409                 kmem_free(kte->kte_buf, kte->kte_bufsz);
  410         pool_cache_put(kte_cache, kte);
  411 }
  412 
  413 /*
  414  * "deep" compare of two files for the purposes of clearing a trace.
  415  * Returns true if they're the same open file, or if they point at the
  416  * same underlying vnode/socket.
  417  */
  418 
  419 int
  420 ktrsamefile(file_t *f1, file_t *f2)
  421 {
  422 
  423         return ((f1 == f2) ||
  424             ((f1 != NULL) && (f2 != NULL) &&
  425                 (f1->f_type == f2->f_type) &&
  426                 (f1->f_data == f2->f_data)));
  427 }
  428 
  429 void
  430 ktrderef(struct proc *p)
  431 {
  432         struct ktr_desc *ktd = p->p_tracep;
  433 
  434         KASSERT(mutex_owned(&ktrace_lock));
  435 
  436         p->p_traceflag = 0;
  437         if (ktd == NULL)
  438                 return;
  439         p->p_tracep = NULL;
  440 
  441         cv_broadcast(&ktd->ktd_sync_cv);
  442         ktdrel(ktd);
  443 }
  444 
  445 void
  446 ktradref(struct proc *p)
  447 {
  448         struct ktr_desc *ktd = p->p_tracep;
  449 
  450         KASSERT(mutex_owned(&ktrace_lock));
  451 
  452         ktdref(ktd);
  453 }
  454 
  455 int
  456 ktrderefall(struct ktr_desc *ktd, int auth)
  457 {
  458         lwp_t *curl = curlwp;
  459         struct proc *p;
  460         int error = 0;
  461 
  462         mutex_enter(proc_lock);
  463         PROCLIST_FOREACH(p, &allproc) {
  464                 if ((p->p_flag & PK_MARKER) != 0 || p->p_tracep != ktd)
  465                         continue;
  466                 mutex_enter(p->p_lock);
  467                 mutex_enter(&ktrace_lock);
  468                 if (p->p_tracep == ktd) {
  469                         if (!auth || ktrcanset(curl, p))
  470                                 ktrderef(p);
  471                         else
  472                                 error = EPERM;
  473                 }
  474                 mutex_exit(&ktrace_lock);
  475                 mutex_exit(p->p_lock);
  476         }
  477         mutex_exit(proc_lock);
  478 
  479         return error;
  480 }
  481 
  482 int
  483 ktealloc(struct ktrace_entry **ktep, void **bufp, lwp_t *l, int type,
  484          size_t sz)
  485 {
  486         struct proc *p = l->l_proc;
  487         struct ktrace_entry *kte;
  488         struct ktr_header *kth;
  489         void *buf;
  490 
  491         if (ktrenter(l))
  492                 return EAGAIN;
  493 
  494         kte = pool_cache_get(kte_cache, PR_WAITOK);
  495         if (sz > sizeof(kte->kte_space)) {
  496                 if ((buf = kmem_alloc(sz, KM_SLEEP)) == NULL) {
  497                         pool_cache_put(kte_cache, kte);
  498                         ktrexit(l);
  499                         return ENOMEM;
  500                 }
  501         } else
  502                 buf = kte->kte_space;
  503 
  504         kte->kte_bufsz = sz;
  505         kte->kte_buf = buf;
  506 
  507         kth = &kte->kte_kth;
  508         (void)memset(kth, 0, sizeof(*kth));
  509         kth->ktr_len = sz;
  510         kth->ktr_type = type;
  511         kth->ktr_pid = p->p_pid;
  512         memcpy(kth->ktr_comm, p->p_comm, MAXCOMLEN);
  513         kth->ktr_version = KTRFAC_VERSION(p->p_traceflag);
  514 
  515         switch (KTRFAC_VERSION(p->p_traceflag)) {
  516         case 0:
  517                 /* This is the original format */
  518                 microtime(&kth->ktr_tv);
  519                 break;
  520         case 1:
  521                 kth->ktr_lid = l->l_lid;
  522                 nanotime(&kth->ktr_time);
  523                 break;
  524         default:
  525                 break;
  526         }
  527 
  528         *ktep = kte;
  529         *bufp = buf;
  530 
  531         return 0;
  532 }
  533 
  534 void
  535 ktr_syscall(register_t code, const register_t args[], int narg)
  536 {
  537         lwp_t *l = curlwp;
  538         struct proc *p = l->l_proc;
  539         struct ktrace_entry *kte;
  540         struct ktr_syscall *ktp;
  541         register_t *argp;
  542         size_t len;
  543         u_int i;
  544 
  545         if (!KTRPOINT(p, KTR_SYSCALL))
  546                 return;
  547 
  548         len = sizeof(struct ktr_syscall) + narg * sizeof argp[0];
  549 
  550         if (ktealloc(&kte, (void *)&ktp, l, KTR_SYSCALL, len))
  551                 return;
  552 
  553         ktp->ktr_code = code;
  554         ktp->ktr_argsize = narg * sizeof argp[0];
  555         argp = (register_t *)(ktp + 1);
  556         for (i = 0; i < narg; i++)
  557                 *argp++ = args[i];
  558 
  559         ktraddentry(l, kte, KTA_WAITOK);
  560 }
  561 
  562 void
  563 ktr_sysret(register_t code, int error, register_t *retval)
  564 {
  565         lwp_t *l = curlwp;
  566         struct ktrace_entry *kte;
  567         struct ktr_sysret *ktp;
  568 
  569         if (!KTRPOINT(l->l_proc, KTR_SYSRET))
  570                 return;
  571 
  572         if (ktealloc(&kte, (void *)&ktp, l, KTR_SYSRET,
  573             sizeof(struct ktr_sysret)))
  574                 return;
  575 
  576         ktp->ktr_code = code;
  577         ktp->ktr_eosys = 0;                     /* XXX unused */
  578         ktp->ktr_error = error;
  579         ktp->ktr_retval = retval ? retval[0] : 0;
  580         ktp->ktr_retval_1 = retval ? retval[1] : 0;
  581 
  582         ktraddentry(l, kte, KTA_WAITOK);
  583 }
  584 
  585 void
  586 ktr_namei(const char *path, size_t pathlen)
  587 {
  588         lwp_t *l = curlwp;
  589 
  590         if (!KTRPOINT(l->l_proc, KTR_NAMEI))
  591                 return;
  592 
  593         ktr_kmem(l, KTR_NAMEI, path, pathlen);
  594 }
  595 
  596 void
  597 ktr_namei2(const char *eroot, size_t erootlen,
  598           const char *path, size_t pathlen)
  599 {
  600         lwp_t *l = curlwp;
  601         struct ktrace_entry *kte;
  602         void *buf;
  603 
  604         if (!KTRPOINT(l->l_proc, KTR_NAMEI))
  605                 return;
  606 
  607         if (ktealloc(&kte, &buf, l, KTR_NAMEI, erootlen + pathlen))
  608                 return;
  609         memcpy(buf, eroot, erootlen);
  610         buf = (char *)buf + erootlen;
  611         memcpy(buf, path, pathlen);
  612         ktraddentry(l, kte, KTA_WAITOK);
  613 }
  614 
  615 void
  616 ktr_emul(void)
  617 {
  618         lwp_t *l = curlwp;
  619         const char *emul = l->l_proc->p_emul->e_name;
  620 
  621         if (!KTRPOINT(l->l_proc, KTR_EMUL))
  622                 return;
  623 
  624         ktr_kmem(l, KTR_EMUL, emul, strlen(emul));
  625 }
  626 
  627 void
  628 ktr_execarg(const void *bf, size_t len)
  629 {
  630         lwp_t *l = curlwp;
  631 
  632         if (!KTRPOINT(l->l_proc, KTR_EXEC_ARG))
  633                 return;
  634 
  635         ktr_kmem(l, KTR_EXEC_ARG, bf, len);
  636 }
  637 
  638 void
  639 ktr_execenv(const void *bf, size_t len)
  640 {
  641         lwp_t *l = curlwp;
  642 
  643         if (!KTRPOINT(l->l_proc, KTR_EXEC_ENV))
  644                 return;
  645 
  646         ktr_kmem(l, KTR_EXEC_ENV, bf, len);
  647 }
  648 
  649 static void
  650 ktr_kmem(lwp_t *l, int type, const void *bf, size_t len)
  651 {
  652         struct ktrace_entry *kte;
  653         void *buf;
  654 
  655         if (ktealloc(&kte, &buf, l, type, len))
  656                 return;
  657         memcpy(buf, bf, len);
  658         ktraddentry(l, kte, KTA_WAITOK);
  659 }
  660 
  661 static void
  662 ktr_io(lwp_t *l, int fd, enum uio_rw rw, struct iovec *iov, size_t len)
  663 {
  664         struct ktrace_entry *kte;
  665         struct ktr_genio *ktp;
  666         size_t resid = len, cnt, buflen;
  667         char *cp;
  668 
  669  next:
  670         buflen = min(PAGE_SIZE, resid + sizeof(struct ktr_genio));
  671 
  672         if (ktealloc(&kte, (void *)&ktp, l, KTR_GENIO, buflen))
  673                 return;
  674 
  675         ktp->ktr_fd = fd;
  676         ktp->ktr_rw = rw;
  677 
  678         cp = (void *)(ktp + 1);
  679         buflen -= sizeof(struct ktr_genio);
  680         kte->kte_kth.ktr_len = sizeof(struct ktr_genio);
  681 
  682         while (buflen > 0) {
  683                 cnt = min(iov->iov_len, buflen);
  684                 if (copyin(iov->iov_base, cp, cnt) != 0)
  685                         goto out;
  686                 kte->kte_kth.ktr_len += cnt;
  687                 cp += cnt;
  688                 buflen -= cnt;
  689                 resid -= cnt;
  690                 iov->iov_len -= cnt;
  691                 if (iov->iov_len == 0)
  692                         iov++;
  693                 else
  694                         iov->iov_base = (char *)iov->iov_base + cnt;
  695         }
  696 
  697         /*
  698          * Don't push so many entry at once.  It will cause kmem map
  699          * shortage.
  700          */
  701         ktraddentry(l, kte, KTA_WAITOK | KTA_LARGE);
  702         if (resid > 0) {
  703                 if (curcpu()->ci_schedstate.spc_flags & SPCF_SHOULDYIELD) {
  704                         (void)ktrenter(l);
  705                         preempt();
  706                         ktrexit(l);
  707                 }
  708 
  709                 goto next;
  710         }
  711 
  712         return;
  713 
  714 out:
  715         ktefree(kte);
  716         ktrexit(l);
  717 }
  718 
  719 void
  720 ktr_genio(int fd, enum uio_rw rw, const void *addr, size_t len, int error)
  721 {
  722         lwp_t *l = curlwp;
  723         struct iovec iov;
  724 
  725         if (!KTRPOINT(l->l_proc, KTR_GENIO) || error != 0)
  726                 return;
  727         iov.iov_base = __UNCONST(addr);
  728         iov.iov_len = len;
  729         ktr_io(l, fd, rw, &iov, len);
  730 }
  731 
  732 void
  733 ktr_geniov(int fd, enum uio_rw rw, struct iovec *iov, size_t len, int error)
  734 {
  735         lwp_t *l = curlwp;
  736 
  737         if (!KTRPOINT(l->l_proc, KTR_GENIO) || error != 0)
  738                 return;
  739         ktr_io(l, fd, rw, iov, len);
  740 }
  741 
  742 void
  743 ktr_mibio(int fd, enum uio_rw rw, const void *addr, size_t len, int error)
  744 {
  745         lwp_t *l = curlwp;
  746         struct iovec iov;
  747 
  748         if (!KTRPOINT(l->l_proc, KTR_MIB) || error != 0)
  749                 return;
  750         iov.iov_base = __UNCONST(addr);
  751         iov.iov_len = len;
  752         ktr_io(l, fd, rw, &iov, len);
  753 }
  754 
  755 void
  756 ktr_psig(int sig, sig_t action, const sigset_t *mask,
  757          const ksiginfo_t *ksi)
  758 {
  759         struct ktrace_entry *kte;
  760         lwp_t *l = curlwp;
  761         struct {
  762                 struct ktr_psig kp;
  763                 siginfo_t       si;
  764         } *kbuf;
  765 
  766         if (!KTRPOINT(l->l_proc, KTR_PSIG))
  767                 return;
  768 
  769         if (ktealloc(&kte, (void *)&kbuf, l, KTR_PSIG, sizeof(*kbuf)))
  770                 return;
  771 
  772         kbuf->kp.signo = (char)sig;
  773         kbuf->kp.action = action;
  774         kbuf->kp.mask = *mask;
  775 
  776         if (ksi) {
  777                 kbuf->kp.code = KSI_TRAPCODE(ksi);
  778                 (void)memset(&kbuf->si, 0, sizeof(kbuf->si));
  779                 kbuf->si._info = ksi->ksi_info;
  780                 kte->kte_kth.ktr_len = sizeof(*kbuf);
  781         } else {
  782                 kbuf->kp.code = 0;
  783                 kte->kte_kth.ktr_len = sizeof(struct ktr_psig);
  784         }
  785 
  786         ktraddentry(l, kte, KTA_WAITOK);
  787 }
  788 
  789 void
  790 ktr_csw(int out, int user)
  791 {
  792         lwp_t *l = curlwp;
  793         struct proc *p = l->l_proc;
  794         struct ktrace_entry *kte;
  795         struct ktr_csw *kc;
  796 
  797         if (!KTRPOINT(p, KTR_CSW))
  798                 return;
  799 
  800         /*
  801          * Don't record context switches resulting from blocking on 
  802          * locks; it's too easy to get duff results.
  803          */
  804         if (l->l_syncobj == &mutex_syncobj || l->l_syncobj == &rw_syncobj)
  805                 return;
  806 
  807         /*
  808          * We can't sleep if we're already going to sleep (if original
  809          * condition is met during sleep, we hang up).
  810          *
  811          * XXX This is not ideal: it would be better to maintain a pool
  812          * of ktes and actually push this to the kthread when context
  813          * switch happens, however given the points where we are called
  814          * from that is difficult to do. 
  815          */
  816         if (out) {
  817                 if (ktrenter(l))
  818                         return;
  819 
  820                 switch (KTRFAC_VERSION(p->p_traceflag)) {
  821                 case 0:
  822                         /* This is the original format */
  823                         microtime(&l->l_ktrcsw.tv);
  824                         l->l_pflag |= LP_KTRCSW;
  825                         break;
  826                 case 1:
  827                         nanotime(&l->l_ktrcsw.ts);
  828                         l->l_pflag |= LP_KTRCSW;
  829                         break;
  830                 default:
  831                         break;
  832                 }
  833 
  834                 if (user)
  835                         l->l_pflag |= LP_KTRCSWUSER;
  836                 else
  837                         l->l_pflag &= ~LP_KTRCSWUSER;
  838 
  839                 ktrexit(l);
  840                 return;
  841         }
  842 
  843         /*
  844          * On the way back in, we need to record twice: once for entry, and
  845          * once for exit.
  846          */
  847         if ((l->l_pflag & LP_KTRCSW) != 0) {
  848                 l->l_pflag &= ~LP_KTRCSW;
  849 
  850                 if (ktealloc(&kte, (void *)&kc, l, KTR_CSW, sizeof(*kc)))
  851                         return;
  852 
  853                 kc->out = 1;
  854                 kc->user = ((l->l_pflag & LP_KTRCSWUSER) != 0);
  855 
  856                 switch (KTRFAC_VERSION(p->p_traceflag)) {
  857                 case 0:
  858                         /* This is the original format */
  859                         memcpy(&kte->kte_kth.ktr_tv, &l->l_ktrcsw.tv,
  860                             sizeof(kte->kte_kth.ktr_tv));
  861                         break;
  862                 case 1:
  863                         memcpy(&kte->kte_kth.ktr_time, &l->l_ktrcsw.ts,
  864                             sizeof(kte->kte_kth.ktr_time));
  865                         break;
  866                 default:
  867                         break;
  868                 }
  869 
  870                 ktraddentry(l, kte, KTA_WAITOK);
  871         }
  872 
  873         if (ktealloc(&kte, (void *)&kc, l, KTR_CSW, sizeof(*kc)))
  874                 return;
  875 
  876         kc->out = 0;
  877         kc->user = user;
  878 
  879         ktraddentry(l, kte, KTA_WAITOK);
  880 }
  881 
  882 bool
  883 ktr_point(int fac_bit)
  884 {
  885         return curlwp->l_proc->p_traceflag & fac_bit;
  886 }
  887 
  888 int
  889 ktruser(const char *id, void *addr, size_t len, int ustr)
  890 {
  891         struct ktrace_entry *kte;
  892         struct ktr_user *ktp;
  893         lwp_t *l = curlwp;
  894         void *user_dta;
  895         int error;
  896 
  897         if (!KTRPOINT(l->l_proc, KTR_USER))
  898                 return 0;
  899 
  900         if (len > KTR_USER_MAXLEN)
  901                 return ENOSPC;
  902 
  903         error = ktealloc(&kte, (void *)&ktp, l, KTR_USER, sizeof(*ktp) + len);
  904         if (error != 0)
  905                 return error;
  906 
  907         if (ustr) {
  908                 if (copyinstr(id, ktp->ktr_id, KTR_USER_MAXIDLEN, NULL) != 0)
  909                         ktp->ktr_id[0] = '\0';
  910         } else
  911                 strncpy(ktp->ktr_id, id, KTR_USER_MAXIDLEN);
  912         ktp->ktr_id[KTR_USER_MAXIDLEN-1] = '\0';
  913 
  914         user_dta = (void *)(ktp + 1);
  915         if ((error = copyin(addr, (void *)user_dta, len)) != 0)
  916                 len = 0;
  917 
  918         ktraddentry(l, kte, KTA_WAITOK);
  919         return error;
  920 }
  921 
  922 void
  923 ktr_kuser(const char *id, void *addr, size_t len)
  924 {
  925         struct ktrace_entry *kte;
  926         struct ktr_user *ktp;
  927         lwp_t *l = curlwp;
  928         int error;
  929 
  930         if (!KTRPOINT(l->l_proc, KTR_USER))
  931                 return;
  932 
  933         if (len > KTR_USER_MAXLEN)
  934                 return;
  935 
  936         error = ktealloc(&kte, (void *)&ktp, l, KTR_USER, sizeof(*ktp) + len);
  937         if (error != 0)
  938                 return;
  939 
  940         strlcpy(ktp->ktr_id, id, KTR_USER_MAXIDLEN);
  941 
  942         memcpy(ktp + 1, addr, len);
  943 
  944         ktraddentry(l, kte, KTA_WAITOK);
  945 }
  946 
  947 void
  948 ktr_mmsg(const void *msgh, size_t size)
  949 {
  950         lwp_t *l = curlwp;
  951 
  952         if (!KTRPOINT(l->l_proc, KTR_MMSG))
  953                 return;
  954 
  955         ktr_kmem(l, KTR_MMSG, msgh, size);
  956 }
  957 
  958 void
  959 ktr_mool(const void *kaddr, size_t size, const void *uaddr)
  960 {
  961         struct ktrace_entry *kte;
  962         struct ktr_mool *kp;
  963         struct ktr_mool *bf;
  964         lwp_t *l = curlwp;
  965 
  966         if (!KTRPOINT(l->l_proc, KTR_MOOL))
  967                 return;
  968 
  969         if (ktealloc(&kte, (void *)&kp, l, KTR_MOOL, size + sizeof(*kp)))
  970                 return;
  971 
  972         kp->uaddr = uaddr;
  973         kp->size = size;
  974         bf = kp + 1; /* Skip uaddr and size */
  975         (void)memcpy(bf, kaddr, size);
  976 
  977         ktraddentry(l, kte, KTA_WAITOK);
  978 }
  979 
  980 void
  981 ktr_saupcall(struct lwp *l, int type, int nevent, int nint, void *sas,
  982     void *ap, void *ksas)
  983 {
  984         struct ktrace_entry *kte;
  985         struct ktr_saupcall *ktp;
  986         size_t len, sz;
  987         struct sa_t **sapp;
  988         int i;
  989 
  990         if (!KTRPOINT(l->l_proc, KTR_SAUPCALL))
  991                 return;
  992 
  993         len = sizeof(struct ktr_saupcall);
  994         sz = len + sizeof(struct sa_t) * (nevent + nint + 1);
  995 
  996         if (ktealloc(&kte, (void *)&ktp, l, KTR_SAUPCALL, sz))
  997                 return;
  998 
  999         ktp->ktr_type = type;
 1000         ktp->ktr_nevent = nevent;
 1001         ktp->ktr_nint = nint;
 1002         ktp->ktr_sas = sas;
 1003         ktp->ktr_ap = ap;
 1004 
 1005         /* Copy the sa_t's */
 1006         sapp = (struct sa_t **) ksas;
 1007 
 1008         for (i = nevent + nint; i >= 0; i--) {
 1009                 memcpy((char *)ktp + len, *sapp, sizeof(struct sa_t));
 1010                 len += sizeof(struct sa_t);
 1011                 sapp++;
 1012         }
 1013 
 1014         kte->kte_kth.ktr_len = len;
 1015         ktraddentry(l, kte, KTA_WAITOK);
 1016 }
 1017 
 1018 void
 1019 ktr_mib(const int *name, u_int namelen)
 1020 {
 1021         struct ktrace_entry *kte;
 1022         int *namep;
 1023         size_t size;
 1024         lwp_t *l = curlwp;
 1025 
 1026         if (!KTRPOINT(l->l_proc, KTR_MIB))
 1027                 return;
 1028 
 1029         size = namelen * sizeof(*name);
 1030 
 1031         if (ktealloc(&kte, (void *)&namep, l, KTR_MIB, size))
 1032                 return;
 1033 
 1034         (void)memcpy(namep, name, namelen * sizeof(*name));
 1035 
 1036         ktraddentry(l, kte, KTA_WAITOK);
 1037 }
 1038 
 1039 /* Interface and common routines */
 1040 
 1041 int
 1042 ktrace_common(lwp_t *curl, int ops, int facs, int pid, file_t *fp)
 1043 {
 1044         struct proc *curp;
 1045         struct proc *p;
 1046         struct pgrp *pg;
 1047         struct ktr_desc *ktd = NULL;
 1048         int ret = 0;
 1049         int error = 0;
 1050         int descend;
 1051 
 1052         curp = curl->l_proc;
 1053         descend = ops & KTRFLAG_DESCEND;
 1054         facs = facs & ~((unsigned) KTRFAC_PERSISTENT);
 1055 
 1056         (void)ktrenter(curl);
 1057 
 1058         switch (KTROP(ops)) {
 1059 
 1060         case KTROP_CLEARFILE:
 1061                 /*
 1062                  * Clear all uses of the tracefile
 1063                  */
 1064                 mutex_enter(&ktrace_lock);
 1065                 ktd = ktd_lookup(fp);
 1066                 mutex_exit(&ktrace_lock);
 1067                 if (ktd == NULL)
 1068                         goto done;
 1069                 error = ktrderefall(ktd, 1);
 1070                 goto done;
 1071 
 1072         case KTROP_SET:
 1073                 mutex_enter(&ktrace_lock);
 1074                 ktd = ktd_lookup(fp);
 1075                 mutex_exit(&ktrace_lock);
 1076                 if (ktd == NULL) {
 1077                         ktd = kmem_alloc(sizeof(*ktd), KM_SLEEP);
 1078                         TAILQ_INIT(&ktd->ktd_queue);
 1079                         callout_init(&ktd->ktd_wakch, CALLOUT_MPSAFE);
 1080                         cv_init(&ktd->ktd_cv, "ktrwait");
 1081                         cv_init(&ktd->ktd_sync_cv, "ktrsync");
 1082                         ktd->ktd_flags = 0;
 1083                         ktd->ktd_qcount = 0;
 1084                         ktd->ktd_error = 0;
 1085                         ktd->ktd_errcnt = 0;
 1086                         ktd->ktd_delayqcnt = ktd_delayqcnt;
 1087                         ktd->ktd_wakedelay = mstohz(ktd_wakedelay);
 1088                         ktd->ktd_intrwakdl = mstohz(ktd_intrwakdl);
 1089                         ktd->ktd_ref = 0;
 1090                         ktd->ktd_fp = fp;
 1091                         mutex_enter(&ktrace_lock);
 1092                         ktdref(ktd);
 1093                         mutex_exit(&ktrace_lock);
 1094 
 1095                         /*
 1096                          * XXX: not correct.  needs an way to detect
 1097                          * whether ktruss or ktrace.
 1098                          */
 1099                         if (fp->f_type == DTYPE_PIPE)
 1100                                 ktd->ktd_flags |= KTDF_INTERACTIVE;
 1101 
 1102                         mutex_enter(&fp->f_lock);
 1103                         fp->f_count++;
 1104                         mutex_exit(&fp->f_lock);
 1105                         error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL,
 1106                             ktrace_thread, ktd, &ktd->ktd_lwp, "ktrace");
 1107                         if (error != 0) {
 1108                                 kmem_free(ktd, sizeof(*ktd));
 1109                                 mutex_enter(&fp->f_lock);
 1110                                 fp->f_count--;
 1111                                 mutex_exit(&fp->f_lock);
 1112                                 goto done;
 1113                         }
 1114 
 1115                         mutex_enter(&ktrace_lock);
 1116                         if (ktd_lookup(fp) != NULL) {
 1117                                 ktdrel(ktd);
 1118                                 ktd = NULL;
 1119                         } else
 1120                                 TAILQ_INSERT_TAIL(&ktdq, ktd, ktd_list);
 1121                         if (ktd == NULL)
 1122                                 cv_wait(&lbolt, &ktrace_lock);
 1123                         mutex_exit(&ktrace_lock);
 1124                         if (ktd == NULL)
 1125                                 goto done;
 1126                 }
 1127                 break;
 1128 
 1129         case KTROP_CLEAR:
 1130                 break;
 1131         }
 1132 
 1133         /*
 1134          * need something to (un)trace (XXX - why is this here?)
 1135          */
 1136         if (!facs) {
 1137                 error = EINVAL;
 1138                 goto done;
 1139         }
 1140 
 1141         /*
 1142          * do it
 1143          */
 1144         mutex_enter(proc_lock);
 1145         if (pid < 0) {
 1146                 /*
 1147                  * by process group
 1148                  */
 1149                 pg = pg_find(-pid, PFIND_LOCKED);
 1150                 if (pg == NULL)
 1151                         error = ESRCH;
 1152                 else {
 1153                         LIST_FOREACH(p, &pg->pg_members, p_pglist) {
 1154                                 if (descend)
 1155                                         ret |= ktrsetchildren(curl, p, ops,
 1156                                             facs, ktd);
 1157                                 else
 1158                                         ret |= ktrops(curl, p, ops, facs,
 1159                                             ktd);
 1160                         }
 1161                 }
 1162 
 1163         } else {
 1164                 /*
 1165                  * by pid
 1166                  */
 1167                 p = p_find(pid, PFIND_LOCKED);
 1168                 if (p == NULL)
 1169                         error = ESRCH;
 1170                 else if (descend)
 1171                         ret |= ktrsetchildren(curl, p, ops, facs, ktd);
 1172                 else
 1173                         ret |= ktrops(curl, p, ops, facs, ktd);
 1174         }
 1175         mutex_exit(proc_lock);
 1176         if (error == 0 && !ret)
 1177                 error = EPERM;
 1178 done:
 1179         if (ktd != NULL) {
 1180                 mutex_enter(&ktrace_lock);
 1181                 if (error != 0) {
 1182                         /*
 1183                          * Wakeup the thread so that it can be die if we
 1184                          * can't trace any process.
 1185                          */
 1186                         ktd_wakeup(ktd);
 1187                 }
 1188                 if (KTROP(ops) == KTROP_SET || KTROP(ops) == KTROP_CLEARFILE)
 1189                         ktdrel(ktd);
 1190                 mutex_exit(&ktrace_lock);
 1191         }
 1192         ktrexit(curl);
 1193         return (error);
 1194 }
 1195 
 1196 /*
 1197  * fktrace system call
 1198  */
 1199 /* ARGSUSED */
 1200 int
 1201 sys_fktrace(struct lwp *l, const struct sys_fktrace_args *uap, register_t *retval)
 1202 {
 1203         /* {
 1204                 syscallarg(int) fd;
 1205                 syscallarg(int) ops;
 1206                 syscallarg(int) facs;
 1207                 syscallarg(int) pid;
 1208         } */
 1209         file_t *fp;
 1210         int error, fd;
 1211 
 1212         fd = SCARG(uap, fd);
 1213         if ((fp = fd_getfile(fd)) == NULL)
 1214                 return (EBADF);
 1215         if ((fp->f_flag & FWRITE) == 0)
 1216                 error = EBADF;
 1217         else
 1218                 error = ktrace_common(l, SCARG(uap, ops),
 1219                     SCARG(uap, facs), SCARG(uap, pid), fp);
 1220         fd_putfile(fd);
 1221         return error;
 1222 }
 1223 
 1224 /*
 1225  * ktrace system call
 1226  */
 1227 /* ARGSUSED */
 1228 int
 1229 sys_ktrace(struct lwp *l, const struct sys_ktrace_args *uap, register_t *retval)
 1230 {
 1231         /* {
 1232                 syscallarg(const char *) fname;
 1233                 syscallarg(int) ops;
 1234                 syscallarg(int) facs;
 1235                 syscallarg(int) pid;
 1236         } */
 1237         struct vnode *vp = NULL;
 1238         file_t *fp = NULL;
 1239         struct nameidata nd;
 1240         int error = 0;
 1241         int fd;
 1242 
 1243         if (ktrenter(l))
 1244                 return EAGAIN;
 1245 
 1246         if (KTROP(SCARG(uap, ops)) != KTROP_CLEAR) {
 1247                 /*
 1248                  * an operation which requires a file argument.
 1249                  */
 1250                 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, fname));
 1251                 if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0) {
 1252                         ktrexit(l);
 1253                         return (error);
 1254                 }
 1255                 vp = nd.ni_vp;
 1256                 VOP_UNLOCK(vp, 0);
 1257                 if (vp->v_type != VREG) {
 1258                         vn_close(vp, FREAD|FWRITE, l->l_cred);
 1259                         ktrexit(l);
 1260                         return (EACCES);
 1261                 }
 1262                 /*
 1263                  * This uses up a file descriptor slot in the
 1264                  * tracing process for the duration of this syscall.
 1265                  * This is not expected to be a problem.
 1266                  */
 1267                 if ((error = fd_allocfile(&fp, &fd)) != 0) {
 1268                         vn_close(vp, FWRITE, l->l_cred);
 1269                         ktrexit(l);
 1270                         return error;
 1271                 }
 1272                 fp->f_flag = FWRITE;
 1273                 fp->f_type = DTYPE_VNODE;
 1274                 fp->f_ops = &vnops;
 1275                 fp->f_data = (void *)vp;
 1276                 vp = NULL;
 1277         }
 1278         error = ktrace_common(l, SCARG(uap, ops), SCARG(uap, facs),
 1279             SCARG(uap, pid), fp);
 1280         if (fp != NULL) {
 1281                 if (error != 0) {
 1282                         /* File unused. */
 1283                         fd_abort(curproc, fp, fd);
 1284                 } else {
 1285                         /* File was used. */
 1286                         fd_abort(curproc, NULL, fd);
 1287                 }
 1288         }
 1289         return (error);
 1290 }
 1291 
 1292 int
 1293 ktrops(lwp_t *curl, struct proc *p, int ops, int facs,
 1294     struct ktr_desc *ktd)
 1295 {
 1296         int vers = ops & KTRFAC_VER_MASK;
 1297         int error = 0;
 1298 
 1299         mutex_enter(p->p_lock);
 1300         mutex_enter(&ktrace_lock);
 1301 
 1302         if (!ktrcanset(curl, p))
 1303                 goto out;
 1304 
 1305         switch (vers) {
 1306         case KTRFACv0:
 1307         case KTRFACv1:
 1308                 break;
 1309         default:
 1310                 error = EINVAL;
 1311                 goto out;
 1312         }
 1313 
 1314         if (KTROP(ops) == KTROP_SET) {
 1315                 if (p->p_tracep != ktd) {
 1316                         /*
 1317                          * if trace file already in use, relinquish
 1318                          */
 1319                         ktrderef(p);
 1320                         p->p_tracep = ktd;
 1321                         ktradref(p);
 1322                 }
 1323                 p->p_traceflag |= facs;
 1324                 if (kauth_authorize_process(curl->l_cred, KAUTH_PROCESS_KTRACE,
 1325                     p, KAUTH_ARG(KAUTH_REQ_PROCESS_KTRACE_PERSISTENT), NULL,
 1326                     NULL) == 0)
 1327                         p->p_traceflag |= KTRFAC_PERSISTENT;
 1328         } else {
 1329                 /* KTROP_CLEAR */
 1330                 if (((p->p_traceflag &= ~facs) & KTRFAC_MASK) == 0) {
 1331                         /* no more tracing */
 1332                         ktrderef(p);
 1333                 }
 1334         }
 1335 
 1336         if (p->p_traceflag)
 1337                 p->p_traceflag |= vers;
 1338         /*
 1339          * Emit an emulation record, every time there is a ktrace
 1340          * change/attach request.
 1341          */
 1342         if (KTRPOINT(p, KTR_EMUL))
 1343                 p->p_traceflag |= KTRFAC_TRC_EMUL;
 1344 
 1345         p->p_trace_enabled = trace_is_enabled(p);
 1346 #ifdef __HAVE_SYSCALL_INTERN
 1347         (*p->p_emul->e_syscall_intern)(p);
 1348 #endif
 1349 
 1350  out:
 1351         mutex_exit(&ktrace_lock);
 1352         mutex_exit(p->p_lock);
 1353 
 1354         return (1);
 1355 }
 1356 
 1357 int
 1358 ktrsetchildren(lwp_t *curl, struct proc *top, int ops, int facs,
 1359     struct ktr_desc *ktd)
 1360 {
 1361         struct proc *p;
 1362         int ret = 0;
 1363 
 1364         KASSERT(mutex_owned(proc_lock));
 1365 
 1366         p = top;
 1367         for (;;) {
 1368                 ret |= ktrops(curl, p, ops, facs, ktd);
 1369                 /*
 1370                  * If this process has children, descend to them next,
 1371                  * otherwise do any siblings, and if done with this level,
 1372                  * follow back up the tree (but not past top).
 1373                  */
 1374                 if (LIST_FIRST(&p->p_children) != NULL) {
 1375                         p = LIST_FIRST(&p->p_children);
 1376                         continue;
 1377                 }
 1378                 for (;;) {
 1379                         if (p == top)
 1380                                 return (ret);
 1381                         if (LIST_NEXT(p, p_sibling) != NULL) {
 1382                                 p = LIST_NEXT(p, p_sibling);
 1383                                 break;
 1384                         }
 1385                         p = p->p_pptr;
 1386                 }
 1387         }
 1388         /*NOTREACHED*/
 1389 }
 1390 
 1391 void
 1392 ktrwrite(struct ktr_desc *ktd, struct ktrace_entry *kte)
 1393 {
 1394         struct uio auio;
 1395         struct iovec aiov[64], *iov;
 1396         struct ktrace_entry *top = kte;
 1397         struct ktr_header *kth;
 1398         file_t *fp = ktd->ktd_fp;
 1399         int error;
 1400 next:
 1401         auio.uio_iov = iov = &aiov[0];
 1402         auio.uio_offset = 0;
 1403         auio.uio_rw = UIO_WRITE;
 1404         auio.uio_resid = 0;
 1405         auio.uio_iovcnt = 0;
 1406         UIO_SETUP_SYSSPACE(&auio);
 1407         do {
 1408                 kth = &kte->kte_kth;
 1409 
 1410                 if (kth->ktr_version == 0) {
 1411                         /*
 1412                          * Convert back to the old format fields
 1413                          */
 1414                         TIMESPEC_TO_TIMEVAL(&kth->ktr_tv, &kth->ktr_time);
 1415                         kth->ktr_unused = NULL;
 1416                 }
 1417                 iov->iov_base = (void *)kth;
 1418                 iov++->iov_len = sizeof(struct ktr_header);
 1419                 auio.uio_resid += sizeof(struct ktr_header);
 1420                 auio.uio_iovcnt++;
 1421                 if (kth->ktr_len > 0) {
 1422                         iov->iov_base = kte->kte_buf;
 1423                         iov++->iov_len = kth->ktr_len;
 1424                         auio.uio_resid += kth->ktr_len;
 1425                         auio.uio_iovcnt++;
 1426                 }
 1427         } while ((kte = TAILQ_NEXT(kte, kte_list)) != NULL &&
 1428             auio.uio_iovcnt < sizeof(aiov) / sizeof(aiov[0]) - 1);
 1429 
 1430 again:
 1431         error = (*fp->f_ops->fo_write)(fp, &fp->f_offset, &auio,
 1432             fp->f_cred, FOF_UPDATE_OFFSET);
 1433         switch (error) {
 1434 
 1435         case 0:
 1436                 if (auio.uio_resid > 0)
 1437                         goto again;
 1438                 if (kte != NULL)
 1439                         goto next;
 1440                 break;
 1441 
 1442         case EWOULDBLOCK:
 1443                 kpause("ktrzzz", false, 1, NULL);
 1444                 goto again;
 1445 
 1446         default:
 1447                 /*
 1448                  * If error encountered, give up tracing on this
 1449                  * vnode.  Don't report EPIPE as this can easily
 1450                  * happen with fktrace()/ktruss.
 1451                  */
 1452 #ifndef DEBUG
 1453                 if (error != EPIPE)
 1454 #endif
 1455                         log(LOG_NOTICE,
 1456                             "ktrace write failed, errno %d, tracing stopped\n",
 1457                             error);
 1458                 (void)ktrderefall(ktd, 0);
 1459         }
 1460 
 1461         while ((kte = top) != NULL) {
 1462                 top = TAILQ_NEXT(top, kte_list);
 1463                 ktefree(kte);
 1464         }
 1465 }
 1466 
 1467 void
 1468 ktrace_thread(void *arg)
 1469 {
 1470         struct ktr_desc *ktd = arg;
 1471         file_t *fp = ktd->ktd_fp;
 1472         struct ktrace_entry *kte;
 1473         int ktrerr, errcnt;
 1474 
 1475         mutex_enter(&ktrace_lock);
 1476         for (;;) {
 1477                 kte = TAILQ_FIRST(&ktd->ktd_queue);
 1478                 if (kte == NULL) {
 1479                         if (ktd->ktd_flags & KTDF_WAIT) {
 1480                                 ktd->ktd_flags &= ~(KTDF_WAIT | KTDF_BLOCKING);
 1481                                 cv_broadcast(&ktd->ktd_sync_cv);
 1482                         }
 1483                         if (ktd->ktd_ref == 0)
 1484                                 break;
 1485                         cv_wait(&ktd->ktd_cv, &ktrace_lock);
 1486                         continue;
 1487                 }
 1488                 TAILQ_INIT(&ktd->ktd_queue);
 1489                 ktd->ktd_qcount = 0;
 1490                 ktrerr = ktd->ktd_error;
 1491                 errcnt = ktd->ktd_errcnt;
 1492                 ktd->ktd_error = ktd->ktd_errcnt = 0;
 1493                 mutex_exit(&ktrace_lock);
 1494 
 1495                 if (ktrerr) {
 1496                         log(LOG_NOTICE,
 1497                             "ktrace failed, fp %p, error 0x%x, total %d\n",
 1498                             fp, ktrerr, errcnt);
 1499                 }
 1500                 ktrwrite(ktd, kte);
 1501                 mutex_enter(&ktrace_lock);
 1502         }
 1503 
 1504         TAILQ_REMOVE(&ktdq, ktd, ktd_list);
 1505         mutex_exit(&ktrace_lock);
 1506 
 1507         /*
 1508          * ktrace file descriptor can't be watched (are not visible to
 1509          * userspace), so no kqueue stuff here
 1510          * XXX: The above comment is wrong, because the fktrace file
 1511          * descriptor is available in userland.
 1512          */
 1513         closef(fp);
 1514 
 1515         cv_destroy(&ktd->ktd_sync_cv);
 1516         cv_destroy(&ktd->ktd_cv);
 1517 
 1518         callout_stop(&ktd->ktd_wakch);
 1519         callout_destroy(&ktd->ktd_wakch);
 1520         kmem_free(ktd, sizeof(*ktd));
 1521 
 1522         kthread_exit(0);
 1523 }
 1524 
 1525 /*
 1526  * Return true if caller has permission to set the ktracing state
 1527  * of target.  Essentially, the target can't possess any
 1528  * more permissions than the caller.  KTRFAC_PERSISTENT signifies that
 1529  * the tracing will persist on sugid processes during exec; it is only
 1530  * settable by a process with appropriate credentials.
 1531  *
 1532  * TODO: check groups.  use caller effective gid.
 1533  */
 1534 int
 1535 ktrcanset(lwp_t *calll, struct proc *targetp)
 1536 {
 1537         KASSERT(mutex_owned(targetp->p_lock));
 1538         KASSERT(mutex_owned(&ktrace_lock));
 1539 
 1540         if (kauth_authorize_process(calll->l_cred, KAUTH_PROCESS_KTRACE,
 1541             targetp, NULL, NULL, NULL) == 0)
 1542                 return (1);
 1543 
 1544         return (0);
 1545 }
 1546 
 1547 /*
 1548  * Put user defined entry to ktrace records.
 1549  */
 1550 int
 1551 sys_utrace(struct lwp *l, const struct sys_utrace_args *uap, register_t *retval)
 1552 {
 1553         /* {
 1554                 syscallarg(const char *) label;
 1555                 syscallarg(void *) addr;
 1556                 syscallarg(size_t) len;
 1557         } */
 1558 
 1559         return ktruser(SCARG(uap, label), SCARG(uap, addr),
 1560             SCARG(uap, len), 1);
 1561 }

Cache object: 81931d1cce0b4d1967db5724dd1de88c


[ 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.