diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2000-04-20 10:03:44 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2000-04-20 10:03:44 +0000 |
commit | dcc4a09ef0d0caaf7f3266f78db566076dfc5ee7 (patch) | |
tree | 13fd0def39cdaedd6c649553bea1ddd13f4f258f /sys | |
parent | ac8ba1f2ea6355c1c23627cb91ba3ceabd2142f9 (diff) |
Add a function "ktrsettracevnode", that changes the ktrace vnode for a process
in a correct way. Use it in all places where the vnode was changed.
(most of the earlier code was incorrect and had races).
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_exec.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_exit.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_ktrace.c | 46 | ||||
-rw-r--r-- | sys/sys/ktrace.h | 4 |
4 files changed, 36 insertions, 24 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 15ed8af28fe..b5de0c02c0d 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exec.c,v 1.41 2000/03/23 15:55:52 art Exp $ */ +/* $OpenBSD: kern_exec.c,v 1.42 2000/04/20 10:03:42 art Exp $ */ /* $NetBSD: kern_exec.c,v 1.75 1996/02/09 18:59:28 christos Exp $ */ /*- @@ -497,8 +497,7 @@ sys_execve(p, v, retval) */ if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) { p->p_traceflag = 0; - vrele(p->p_tracep); - p->p_tracep = NULL; + ktrsettracevnode(p, NULL); } #endif p->p_ucred = crcopy(cred); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index 5efdeea121a..97a98643f58 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_exit.c,v 1.22 2000/03/23 15:55:52 art Exp $ */ +/* $OpenBSD: kern_exit.c,v 1.23 2000/04/20 10:03:43 art Exp $ */ /* $NetBSD: kern_exit.c,v 1.39 1996/04/22 01:38:25 christos Exp $ */ /* @@ -63,6 +63,7 @@ #include <sys/filedesc.h> #include <sys/signalvar.h> #include <sys/sched.h> +#include <sys/ktrace.h> #ifdef SYSVSHM #include <sys/shm.h> #endif @@ -210,7 +211,7 @@ exit1(p, rv) */ p->p_traceflag = 0; /* don't trace the vrele() */ if (p->p_tracep) - vrele(p->p_tracep); + ktrsettracevnode(p, NULL); #endif /* * Remove proc from allproc queue and pidhash chain. diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 77d4b6b7bf5..240d13c8fb1 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_ktrace.c,v 1.17 2000/04/19 10:56:41 art Exp $ */ +/* $OpenBSD: kern_ktrace.c,v 1.18 2000/04/20 10:03:42 art Exp $ */ /* $NetBSD: kern_ktrace.c,v 1.23 1996/02/09 18:59:36 christos Exp $ */ /* @@ -60,6 +60,29 @@ int ktrsetchildren __P((struct proc *, struct proc *, int, int, int ktrwrite __P((struct vnode *, struct ktr_header *)); int ktrcanset __P((struct proc *, struct proc *)); +/* + * Change the trace vnode in a correct way (to avoid races). + */ +void +ktrsettracevnode(p, newvp) + struct proc *p; + struct vnode *newvp; +{ + struct vnode *vp; + + if (p->p_tracep == newvp) /* avoid work */ + return; + + if (newvp != NULL) + VREF(newvp); + + vp = p->p_tracep; + p->p_tracep = newvp; + + if (vp != NULL) + vrele(vp); +} + void ktrinitheader(kth, p, type) struct ktr_header *kth; @@ -324,9 +347,8 @@ sys_ktrace(curp, v, retval) for (p = LIST_FIRST(&allproc); p; p = LIST_NEXT(p, p_list)) { if (p->p_tracep == vp) { if (ktrcanset(curp, p)) { - p->p_tracep = NULL; p->p_traceflag = 0; - vrele(vp); + ktrsettracevnode(p, NULL); } else error = EPERM; } @@ -391,15 +413,7 @@ ktrops(curp, p, ops, facs, vp) if (!ktrcanset(curp, p)) return (0); if (ops == KTROP_SET) { - if (p->p_tracep != vp) { - /* - * if trace file already in use, relinquish - */ - if (p->p_tracep != NULL) - vrele(p->p_tracep); - VREF(vp); - p->p_tracep = vp; - } + ktrsettracevnode(p, vp); p->p_traceflag |= facs; if (curp->p_ucred->cr_uid == 0) p->p_traceflag |= KTRFAC_ROOT; @@ -408,10 +422,7 @@ ktrops(curp, p, ops, facs, vp) if (((p->p_traceflag &= ~facs) & KTRFAC_MASK) == 0) { /* no more tracing */ p->p_traceflag = 0; - if (p->p_tracep != NULL) { - vrele(p->p_tracep); - p->p_tracep = NULL; - } + ktrsettracevnode(p, NULL); } } @@ -496,9 +507,8 @@ ktrwrite(vp, kth) error); for (p = LIST_FIRST(&allproc); p != NULL; p = LIST_NEXT(p, p_list)) { if (p->p_tracep == vp) { - p->p_tracep = NULL; p->p_traceflag = 0; - vrele(vp); + ktrsettracevnode(p, NULL); } } diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h index 83e1f7dd30c..2fc4b4b368a 100644 --- a/sys/sys/ktrace.h +++ b/sys/sys/ktrace.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ktrace.h,v 1.2 1996/03/03 12:11:54 niklas Exp $ */ +/* $OpenBSD: ktrace.h,v 1.3 2000/04/20 10:03:41 art Exp $ */ /* $NetBSD: ktrace.h,v 1.12 1996/02/04 02:12:29 christos Exp $ */ /* @@ -173,4 +173,6 @@ void ktrpsig __P((struct vnode *, int, sig_t, int, int)); void ktrsyscall __P((struct vnode *, register_t, size_t, register_t [])); void ktrsysret __P((struct vnode *, register_t, int, register_t)); +void ktrsettracevnode __P((struct proc *, struct vnode *)); + #endif /* !_KERNEL */ |