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