1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. 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 * $FreeBSD$ 35 */ 36 37 #include "opt_ktrace.h" 38 #include "opt_mac.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/fcntl.h> 43 #include <sys/jail.h> 44 #include <sys/kernel.h> 45 #include <sys/kthread.h> 46 #include <sys/lock.h> 47 #include <sys/mutex.h> 48 #include <sys/mac.h> 49 #include <sys/malloc.h> 50 #include <sys/namei.h> 51 #include <sys/proc.h> 52 #include <sys/unistd.h> 53 #include <sys/vnode.h> 54 #include <sys/ktrace.h> 55 #include <sys/sema.h> 56 #include <sys/sx.h> 57 #include <sys/sysctl.h> 58 #include <sys/syslog.h> 59 #include <sys/sysproto.h> 60 61 static MALLOC_DEFINE(M_KTRACE, "KTRACE", "KTRACE"); 62 63 #ifdef KTRACE 64 65 #ifndef KTRACE_REQUEST_POOL 66 #define KTRACE_REQUEST_POOL 100 67 #endif 68 69 struct ktr_request { 70 struct ktr_header ktr_header; 71 struct ucred *ktr_cred; 72 struct vnode *ktr_vp; 73 union { 74 struct ktr_syscall ktr_syscall; 75 struct ktr_sysret ktr_sysret; 76 struct ktr_genio ktr_genio; 77 struct ktr_psig ktr_psig; 78 struct ktr_csw ktr_csw; 79 } ktr_data; 80 STAILQ_ENTRY(ktr_request) ktr_list; 81 }; 82 83 static int data_lengths[] = { 84 0, /* none */ 85 offsetof(struct ktr_syscall, ktr_args), /* KTR_SYSCALL */ 86 sizeof(struct ktr_sysret), /* KTR_SYSRET */ 87 0, /* KTR_NAMEI */ 88 sizeof(struct ktr_genio), /* KTR_GENIO */ 89 sizeof(struct ktr_psig), /* KTR_PSIG */ 90 sizeof(struct ktr_csw), /* KTR_CSW */ 91 0 /* KTR_USER */ 92 }; 93 94 static STAILQ_HEAD(, ktr_request) ktr_todo; 95 static STAILQ_HEAD(, ktr_request) ktr_free; 96 97 SYSCTL_NODE(_kern, OID_AUTO, ktrace, CTLFLAG_RD, 0, "KTRACE options"); 98 99 static uint ktr_requestpool = KTRACE_REQUEST_POOL; 100 TUNABLE_INT("kern.ktrace.request_pool", &ktr_requestpool); 101 102 static uint ktr_geniosize = PAGE_SIZE; 103 TUNABLE_INT("kern.ktrace.genio_size", &ktr_geniosize); 104 SYSCTL_UINT(_kern_ktrace, OID_AUTO, genio_size, CTLFLAG_RW, &ktr_geniosize, 105 0, "Maximum size of genio event payload"); 106 107 static int print_message = 1; 108 struct mtx ktrace_mtx; 109 static struct sema ktrace_sema; 110 111 static void ktrace_init(void *dummy); 112 static int sysctl_kern_ktrace_request_pool(SYSCTL_HANDLER_ARGS); 113 static uint ktrace_resize_pool(uint newsize); 114 static struct ktr_request *ktr_getrequest(int type); 115 static void ktr_submitrequest(struct ktr_request *req); 116 static void ktr_freerequest(struct ktr_request *req); 117 static void ktr_loop(void *dummy); 118 static void ktr_writerequest(struct ktr_request *req); 119 static int ktrcanset(struct thread *,struct proc *); 120 static int ktrsetchildren(struct thread *,struct proc *,int,int,struct vnode *); 121 static int ktrops(struct thread *,struct proc *,int,int,struct vnode *); 122 123 static void 124 ktrace_init(void *dummy) 125 { 126 struct ktr_request *req; 127 int i; 128 129 mtx_init(&ktrace_mtx, "ktrace", NULL, MTX_DEF | MTX_QUIET); 130 sema_init(&ktrace_sema, 0, "ktrace"); 131 STAILQ_INIT(&ktr_todo); 132 STAILQ_INIT(&ktr_free); 133 for (i = 0; i < ktr_requestpool; i++) { 134 req = malloc(sizeof(struct ktr_request), M_KTRACE, M_WAITOK); 135 STAILQ_INSERT_HEAD(&ktr_free, req, ktr_list); 136 } 137 kthread_create(ktr_loop, NULL, NULL, RFHIGHPID, 0, "ktrace"); 138 } 139 SYSINIT(ktrace_init, SI_SUB_KTRACE, SI_ORDER_ANY, ktrace_init, NULL); 140 141 static int 142 sysctl_kern_ktrace_request_pool(SYSCTL_HANDLER_ARGS) 143 { 144 struct thread *td; 145 uint newsize, oldsize, wantsize; 146 int error; 147 148 /* Handle easy read-only case first to avoid warnings from GCC. */ 149 if (!req->newptr) { 150 mtx_lock(&ktrace_mtx); 151 oldsize = ktr_requestpool; 152 mtx_unlock(&ktrace_mtx); 153 return (SYSCTL_OUT(req, &oldsize, sizeof(uint))); 154 } 155 156 error = SYSCTL_IN(req, &wantsize, sizeof(uint)); 157 if (error) 158 return (error); 159 td = curthread; 160 td->td_inktrace = 1; 161 mtx_lock(&ktrace_mtx); 162 oldsize = ktr_requestpool; 163 newsize = ktrace_resize_pool(wantsize); 164 mtx_unlock(&ktrace_mtx); 165 td->td_inktrace = 0; 166 error = SYSCTL_OUT(req, &oldsize, sizeof(uint)); 167 if (error) 168 return (error); 169 if (newsize != wantsize) 170 return (ENOSPC); 171 return (0); 172 } 173 SYSCTL_PROC(_kern_ktrace, OID_AUTO, request_pool, CTLTYPE_UINT|CTLFLAG_RW, 174 &ktr_requestpool, 0, sysctl_kern_ktrace_request_pool, "IU", ""); 175 176 static uint 177 ktrace_resize_pool(uint newsize) 178 { 179 struct ktr_request *req; 180 181 mtx_assert(&ktrace_mtx, MA_OWNED); 182 print_message = 1; 183 if (newsize == ktr_requestpool) 184 return (newsize); 185 if (newsize < ktr_requestpool) 186 /* Shrink pool down to newsize if possible. */ 187 while (ktr_requestpool > newsize) { 188 req = STAILQ_FIRST(&ktr_free); 189 if (req == NULL) 190 return (ktr_requestpool); 191 STAILQ_REMOVE_HEAD(&ktr_free, ktr_list); 192 ktr_requestpool--; 193 mtx_unlock(&ktrace_mtx); 194 free(req, M_KTRACE); 195 mtx_lock(&ktrace_mtx); 196 } 197 else 198 /* Grow pool up to newsize. */ 199 while (ktr_requestpool < newsize) { 200 mtx_unlock(&ktrace_mtx); 201 req = malloc(sizeof(struct ktr_request), M_KTRACE, 202 M_WAITOK); 203 mtx_lock(&ktrace_mtx); 204 STAILQ_INSERT_HEAD(&ktr_free, req, ktr_list); 205 ktr_requestpool++; 206 } 207 return (ktr_requestpool); 208 } 209 210 static struct ktr_request * 211 ktr_getrequest(int type) 212 { 213 struct ktr_request *req; 214 struct thread *td = curthread; 215 struct proc *p = td->td_proc; 216 int pm; 217 218 td->td_inktrace = 1; 219 mtx_lock(&ktrace_mtx); 220 if (!KTRCHECK(td, type)) { 221 mtx_unlock(&ktrace_mtx); 222 td->td_inktrace = 0; 223 return (NULL); 224 } 225 req = STAILQ_FIRST(&ktr_free); 226 if (req != NULL) { 227 STAILQ_REMOVE_HEAD(&ktr_free, ktr_list); 228 req->ktr_header.ktr_type = type; 229 KASSERT(p->p_tracep != NULL, ("ktrace: no trace vnode")); 230 req->ktr_vp = p->p_tracep; 231 VREF(p->p_tracep); 232 mtx_unlock(&ktrace_mtx); 233 microtime(&req->ktr_header.ktr_time); 234 req->ktr_header.ktr_pid = p->p_pid; 235 bcopy(p->p_comm, req->ktr_header.ktr_comm, MAXCOMLEN + 1); 236 req->ktr_cred = crhold(td->td_ucred); 237 req->ktr_header.ktr_buffer = NULL; 238 req->ktr_header.ktr_len = 0; 239 } else { 240 pm = print_message; 241 print_message = 0; 242 mtx_unlock(&ktrace_mtx); 243 if (pm) 244 printf("Out of ktrace request objects.\n"); 245 td->td_inktrace = 0; 246 } 247 return (req); 248 } 249 250 static void 251 ktr_submitrequest(struct ktr_request *req) 252 { 253 254 mtx_lock(&ktrace_mtx); 255 STAILQ_INSERT_TAIL(&ktr_todo, req, ktr_list); 256 sema_post(&ktrace_sema); 257 mtx_unlock(&ktrace_mtx); 258 curthread->td_inktrace = 0; 259 } 260 261 static void 262 ktr_freerequest(struct ktr_request *req) 263 { 264 265 crfree(req->ktr_cred); 266 if (req->ktr_vp != NULL) { 267 mtx_lock(&Giant); 268 vrele(req->ktr_vp); 269 mtx_unlock(&Giant); 270 } 271 if (req->ktr_header.ktr_buffer != NULL) 272 free(req->ktr_header.ktr_buffer, M_KTRACE); 273 mtx_lock(&ktrace_mtx); 274 STAILQ_INSERT_HEAD(&ktr_free, req, ktr_list); 275 mtx_unlock(&ktrace_mtx); 276 } 277 278 static void 279 ktr_loop(void *dummy) 280 { 281 struct ktr_request *req; 282 struct thread *td; 283 struct ucred *cred; 284 285 /* Only cache these values once. */ 286 td = curthread; 287 cred = td->td_ucred; 288 for (;;) { 289 sema_wait(&ktrace_sema); 290 mtx_lock(&ktrace_mtx); 291 req = STAILQ_FIRST(&ktr_todo); 292 STAILQ_REMOVE_HEAD(&ktr_todo, ktr_list); 293 KASSERT(req != NULL, ("got a NULL request")); 294 mtx_unlock(&ktrace_mtx); 295 /* 296 * It is not enough just to pass the cached cred 297 * to the VOP's in ktr_writerequest(). Some VFS 298 * operations use curthread->td_ucred, so we need 299 * to modify our thread's credentials as well. 300 * Evil. 301 */ 302 td->td_ucred = req->ktr_cred; 303 ktr_writerequest(req); 304 td->td_ucred = cred; 305 ktr_freerequest(req); 306 } 307 } 308 309 /* 310 * MPSAFE 311 */ 312 void 313 ktrsyscall(code, narg, args) 314 int code, narg; 315 register_t args[]; 316 { 317 struct ktr_request *req; 318 struct ktr_syscall *ktp; 319 size_t buflen; 320 char *buf = NULL; 321 322 buflen = sizeof(register_t) * narg; 323 if (buflen > 0) { 324 buf = malloc(buflen, M_KTRACE, M_WAITOK); 325 bcopy(args, buf, buflen); 326 } 327 req = ktr_getrequest(KTR_SYSCALL); 328 if (req == NULL) { 329 if (buf != NULL) 330 free(buf, M_KTRACE); 331 return; 332 } 333 ktp = &req->ktr_data.ktr_syscall; 334 ktp->ktr_code = code; 335 ktp->ktr_narg = narg; 336 if (buflen > 0) { 337 req->ktr_header.ktr_len = buflen; 338 req->ktr_header.ktr_buffer = buf; 339 } 340 ktr_submitrequest(req); 341 } 342 343 /* 344 * MPSAFE 345 */ 346 void 347 ktrsysret(code, error, retval) 348 int code, error; 349 register_t retval; 350 { 351 struct ktr_request *req; 352 struct ktr_sysret *ktp; 353 354 req = ktr_getrequest(KTR_SYSRET); 355 if (req == NULL) 356 return; 357 ktp = &req->ktr_data.ktr_sysret; 358 ktp->ktr_code = code; 359 ktp->ktr_error = error; 360 ktp->ktr_retval = retval; /* what about val2 ? */ 361 ktr_submitrequest(req); 362 } 363 364 void 365 ktrnamei(path) 366 char *path; 367 { 368 struct ktr_request *req; 369 int namelen; 370 char *buf = NULL; 371 372 namelen = strlen(path); 373 if (namelen > 0) { 374 buf = malloc(namelen, M_KTRACE, M_WAITOK); 375 bcopy(path, buf, namelen); 376 } 377 req = ktr_getrequest(KTR_NAMEI); 378 if (req == NULL) { 379 if (buf != NULL) 380 free(buf, M_KTRACE); 381 return; 382 } 383 if (namelen > 0) { 384 req->ktr_header.ktr_len = namelen; 385 req->ktr_header.ktr_buffer = buf; 386 } 387 ktr_submitrequest(req); 388 } 389 390 /* 391 * Since the uio may not stay valid, we can not hand off this request to 392 * the thread and need to process it synchronously. However, we wish to 393 * keep the relative order of records in a trace file correct, so we 394 * do put this request on the queue (if it isn't empty) and then block. 395 * The ktrace thread waks us back up when it is time for this event to 396 * be posted and blocks until we have completed writing out the event 397 * and woken it back up. 398 */ 399 void 400 ktrgenio(fd, rw, uio, error) 401 int fd; 402 enum uio_rw rw; 403 struct uio *uio; 404 int error; 405 { 406 struct ktr_request *req; 407 struct ktr_genio *ktg; 408 int datalen; 409 char *buf; 410 411 if (error) 412 return; 413 uio->uio_offset = 0; 414 uio->uio_rw = UIO_WRITE; 415 datalen = imin(uio->uio_resid, ktr_geniosize); 416 buf = malloc(datalen, M_KTRACE, M_WAITOK); 417 if (uiomove(buf, datalen, uio)) { 418 free(buf, M_KTRACE); 419 return; 420 } 421 req = ktr_getrequest(KTR_GENIO); 422 if (req == NULL) { 423 free(buf, M_KTRACE); 424 return; 425 } 426 ktg = &req->ktr_data.ktr_genio; 427 ktg->ktr_fd = fd; 428 ktg->ktr_rw = rw; 429 req->ktr_header.ktr_len = datalen; 430 req->ktr_header.ktr_buffer = buf; 431 ktr_submitrequest(req); 432 } 433 434 void 435 ktrpsig(sig, action, mask, code) 436 int sig; 437 sig_t action; 438 sigset_t *mask; 439 int code; 440 { 441 struct ktr_request *req; 442 struct ktr_psig *kp; 443 444 req = ktr_getrequest(KTR_PSIG); 445 if (req == NULL) 446 return; 447 kp = &req->ktr_data.ktr_psig; 448 kp->signo = (char)sig; 449 kp->action = action; 450 kp->mask = *mask; 451 kp->code = code; 452 ktr_submitrequest(req); 453 } 454 455 void 456 ktrcsw(out, user) 457 int out, user; 458 { 459 struct ktr_request *req; 460 struct ktr_csw *kc; 461 462 req = ktr_getrequest(KTR_CSW); 463 if (req == NULL) 464 return; 465 kc = &req->ktr_data.ktr_csw; 466 kc->out = out; 467 kc->user = user; 468 ktr_submitrequest(req); 469 } 470 #endif 471 472 /* Interface and common routines */ 473 474 /* 475 * ktrace system call 476 */ 477 #ifndef _SYS_SYSPROTO_H_ 478 struct ktrace_args { 479 char *fname; 480 int ops; 481 int facs; 482 int pid; 483 }; 484 #endif 485 /* ARGSUSED */ 486 int 487 ktrace(td, uap) 488 struct thread *td; 489 register struct ktrace_args *uap; 490 { 491 #ifdef KTRACE 492 register struct vnode *vp = NULL; 493 register struct proc *p; 494 struct pgrp *pg; 495 int facs = uap->facs & ~KTRFAC_ROOT; 496 int ops = KTROP(uap->ops); 497 int descend = uap->ops & KTRFLAG_DESCEND; 498 int ret = 0; 499 int flags, error = 0; 500 struct nameidata nd; 501 502 td->td_inktrace = 1; 503 if (ops != KTROP_CLEAR) { 504 /* 505 * an operation which requires a file argument. 506 */ 507 NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_USERSPACE, uap->fname, td); 508 flags = FREAD | FWRITE | O_NOFOLLOW; 509 error = vn_open(&nd, &flags, 0); 510 if (error) { 511 td->td_inktrace = 0; 512 return (error); 513 } 514 NDFREE(&nd, NDF_ONLY_PNBUF); 515 vp = nd.ni_vp; 516 VOP_UNLOCK(vp, 0, td); 517 if (vp->v_type != VREG) { 518 (void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td); 519 td->td_inktrace = 0; 520 return (EACCES); 521 } 522 } 523 /* 524 * Clear all uses of the tracefile. 525 */ 526 if (ops == KTROP_CLEARFILE) { 527 sx_slock(&allproc_lock); 528 LIST_FOREACH(p, &allproc, p_list) { 529 PROC_LOCK(p); 530 if (p->p_tracep == vp) { 531 if (ktrcanset(td, p)) { 532 mtx_lock(&ktrace_mtx); 533 p->p_tracep = NULL; 534 p->p_traceflag = 0; 535 mtx_unlock(&ktrace_mtx); 536 PROC_UNLOCK(p); 537 (void) vn_close(vp, FREAD|FWRITE, 538 td->td_ucred, td); 539 } else { 540 PROC_UNLOCK(p); 541 error = EPERM; 542 } 543 } else 544 PROC_UNLOCK(p); 545 } 546 sx_sunlock(&allproc_lock); 547 goto done; 548 } 549 /* 550 * need something to (un)trace (XXX - why is this here?) 551 */ 552 if (!facs) { 553 error = EINVAL; 554 goto done; 555 } 556 /* 557 * do it 558 */ 559 if (uap->pid < 0) { 560 /* 561 * by process group 562 */ 563 sx_slock(&proctree_lock); 564 pg = pgfind(-uap->pid); 565 if (pg == NULL) { 566 sx_sunlock(&proctree_lock); 567 error = ESRCH; 568 goto done; 569 } 570 /* 571 * ktrops() may call vrele(). Lock pg_members 572 * by the proctree_lock rather than pg_mtx. 573 */ 574 PGRP_UNLOCK(pg); 575 LIST_FOREACH(p, &pg->pg_members, p_pglist) 576 if (descend) 577 ret |= ktrsetchildren(td, p, ops, facs, vp); 578 else 579 ret |= ktrops(td, p, ops, facs, vp); 580 sx_sunlock(&proctree_lock); 581 } else { 582 /* 583 * by pid 584 */ 585 p = pfind(uap->pid); 586 if (p == NULL) { 587 error = ESRCH; 588 goto done; 589 } 590 PROC_UNLOCK(p); 591 /* XXX: UNLOCK above has a race */ 592 if (descend) 593 ret |= ktrsetchildren(td, p, ops, facs, vp); 594 else 595 ret |= ktrops(td, p, ops, facs, vp); 596 } 597 if (!ret) 598 error = EPERM; 599 done: 600 if (vp != NULL) 601 (void) vn_close(vp, FWRITE, td->td_ucred, td); 602 td->td_inktrace = 0; 603 return (error); 604 #else 605 return ENOSYS; 606 #endif 607 } 608 609 /* 610 * utrace system call 611 */ 612 /* ARGSUSED */ 613 int 614 utrace(td, uap) 615 struct thread *td; 616 register struct utrace_args *uap; 617 { 618 619 #ifdef KTRACE 620 struct ktr_request *req; 621 void *cp; 622 int error; 623 624 if (!KTRPOINT(td, KTR_USER)) 625 return (0); 626 if (uap->len > KTR_USER_MAXLEN) 627 return (EINVAL); 628 cp = malloc(uap->len, M_KTRACE, M_WAITOK); 629 error = copyin(uap->addr, cp, uap->len); 630 if (error) { 631 free(cp, M_KTRACE); 632 return (error); 633 } 634 req = ktr_getrequest(KTR_USER); 635 if (req == NULL) { 636 free(cp, M_KTRACE); 637 return (0); 638 } 639 req->ktr_header.ktr_buffer = cp; 640 req->ktr_header.ktr_len = uap->len; 641 ktr_submitrequest(req); 642 return (0); 643 #else 644 return (ENOSYS); 645 #endif 646 } 647 648 #ifdef KTRACE 649 static int 650 ktrops(td, p, ops, facs, vp) 651 struct thread *td; 652 struct proc *p; 653 int ops, facs; 654 struct vnode *vp; 655 { 656 struct vnode *tracevp = NULL; 657 658 PROC_LOCK(p); 659 if (!ktrcanset(td, p)) { 660 PROC_UNLOCK(p); 661 return (0); 662 } 663 mtx_lock(&ktrace_mtx); 664 if (ops == KTROP_SET) { 665 if (p->p_tracep != vp) { 666 /* 667 * if trace file already in use, relinquish below 668 */ 669 tracevp = p->p_tracep; 670 VREF(vp); 671 p->p_tracep = vp; 672 } 673 p->p_traceflag |= facs; 674 if (td->td_ucred->cr_uid == 0) 675 p->p_traceflag |= KTRFAC_ROOT; 676 } else { 677 /* KTROP_CLEAR */ 678 if (((p->p_traceflag &= ~facs) & KTRFAC_MASK) == 0) { 679 /* no more tracing */ 680 p->p_traceflag = 0; 681 tracevp = p->p_tracep; 682 p->p_tracep = NULL; 683 } 684 } 685 mtx_unlock(&ktrace_mtx); 686 PROC_UNLOCK(p); 687 if (tracevp != NULL) 688 vrele(tracevp); 689 690 return (1); 691 } 692 693 static int 694 ktrsetchildren(td, top, ops, facs, vp) 695 struct thread *td; 696 struct proc *top; 697 int ops, facs; 698 struct vnode *vp; 699 { 700 register struct proc *p; 701 register int ret = 0; 702 703 p = top; 704 sx_slock(&proctree_lock); 705 for (;;) { 706 ret |= ktrops(td, p, ops, facs, vp); 707 /* 708 * If this process has children, descend to them next, 709 * otherwise do any siblings, and if done with this level, 710 * follow back up the tree (but not past top). 711 */ 712 if (!LIST_EMPTY(&p->p_children)) 713 p = LIST_FIRST(&p->p_children); 714 else for (;;) { 715 if (p == top) { 716 sx_sunlock(&proctree_lock); 717 return (ret); 718 } 719 if (LIST_NEXT(p, p_sibling)) { 720 p = LIST_NEXT(p, p_sibling); 721 break; 722 } 723 p = p->p_pptr; 724 } 725 } 726 /*NOTREACHED*/ 727 } 728 729 static void 730 ktr_writerequest(struct ktr_request *req) 731 { 732 struct ktr_header *kth; 733 struct vnode *vp; 734 struct proc *p; 735 struct thread *td; 736 struct ucred *cred; 737 struct uio auio; 738 struct iovec aiov[3]; 739 struct mount *mp; 740 int datalen, buflen, vrele_count; 741 int error; 742 743 vp = req->ktr_vp; 744 /* 745 * If vp is NULL, the vp has been cleared out from under this 746 * request, so just drop it. 747 */ 748 if (vp == NULL) 749 return; 750 kth = &req->ktr_header; 751 datalen = data_lengths[kth->ktr_type]; 752 buflen = kth->ktr_len; 753 cred = req->ktr_cred; 754 td = curthread; 755 auio.uio_iov = &aiov[0]; 756 auio.uio_offset = 0; 757 auio.uio_segflg = UIO_SYSSPACE; 758 auio.uio_rw = UIO_WRITE; 759 aiov[0].iov_base = (caddr_t)kth; 760 aiov[0].iov_len = sizeof(struct ktr_header); 761 auio.uio_resid = sizeof(struct ktr_header); 762 auio.uio_iovcnt = 1; 763 auio.uio_td = td; 764 if (datalen != 0) { 765 aiov[1].iov_base = (caddr_t)&req->ktr_data; 766 aiov[1].iov_len = datalen; 767 auio.uio_resid += datalen; 768 auio.uio_iovcnt++; 769 kth->ktr_len += datalen; 770 } 771 if (buflen != 0) { 772 KASSERT(kth->ktr_buffer != NULL, ("ktrace: nothing to write")); 773 aiov[auio.uio_iovcnt].iov_base = kth->ktr_buffer; 774 aiov[auio.uio_iovcnt].iov_len = buflen; 775 auio.uio_resid += buflen; 776 auio.uio_iovcnt++; 777 } 778 mtx_lock(&Giant); 779 vn_start_write(vp, &mp, V_WAIT); 780 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 781 (void)VOP_LEASE(vp, td, cred, LEASE_WRITE); 782 #ifdef MAC 783 error = mac_check_vnode_write(cred, NOCRED, vp); 784 if (error == 0) 785 #endif 786 error = VOP_WRITE(vp, &auio, IO_UNIT | IO_APPEND, cred); 787 VOP_UNLOCK(vp, 0, td); 788 vn_finished_write(mp); 789 mtx_unlock(&Giant); 790 if (!error) 791 return; 792 /* 793 * If error encountered, give up tracing on this vnode. We defer 794 * all the vrele()'s on the vnode until after we are finished walking 795 * the various lists to avoid needlessly holding locks. 796 */ 797 log(LOG_NOTICE, "ktrace write failed, errno %d, tracing stopped\n", 798 error); 799 vrele_count = 0; 800 /* 801 * First, clear this vnode from being used by any processes in the 802 * system. 803 * XXX - If one process gets an EPERM writing to the vnode, should 804 * we really do this? Other processes might have suitable 805 * credentials for the operation. 806 */ 807 sx_slock(&allproc_lock); 808 LIST_FOREACH(p, &allproc, p_list) { 809 PROC_LOCK(p); 810 if (p->p_tracep == vp) { 811 mtx_lock(&ktrace_mtx); 812 p->p_tracep = NULL; 813 p->p_traceflag = 0; 814 mtx_unlock(&ktrace_mtx); 815 vrele_count++; 816 } 817 PROC_UNLOCK(p); 818 } 819 sx_sunlock(&allproc_lock); 820 /* 821 * Second, clear this vnode from any pending requests. 822 */ 823 mtx_lock(&ktrace_mtx); 824 STAILQ_FOREACH(req, &ktr_todo, ktr_list) { 825 if (req->ktr_vp == vp) { 826 req->ktr_vp = NULL; 827 vrele_count++; 828 } 829 } 830 mtx_unlock(&ktrace_mtx); 831 mtx_lock(&Giant); 832 while (vrele_count-- > 0) 833 vrele(vp); 834 mtx_unlock(&Giant); 835 } 836 837 /* 838 * Return true if caller has permission to set the ktracing state 839 * of target. Essentially, the target can't possess any 840 * more permissions than the caller. KTRFAC_ROOT signifies that 841 * root previously set the tracing status on the target process, and 842 * so, only root may further change it. 843 */ 844 static int 845 ktrcanset(td, targetp) 846 struct thread *td; 847 struct proc *targetp; 848 { 849 850 PROC_LOCK_ASSERT(targetp, MA_OWNED); 851 if (targetp->p_traceflag & KTRFAC_ROOT && 852 suser_cred(td->td_ucred, PRISON_ROOT)) 853 return (0); 854 855 if (p_candebug(td, targetp) != 0) 856 return (0); 857 858 return (1); 859 } 860 861 #endif /* KTRACE */ 862