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