summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2000-04-20 10:03:44 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2000-04-20 10:03:44 +0000
commitdcc4a09ef0d0caaf7f3266f78db566076dfc5ee7 (patch)
tree13fd0def39cdaedd6c649553bea1ddd13f4f258f /sys
parentac8ba1f2ea6355c1c23627cb91ba3ceabd2142f9 (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.c5
-rw-r--r--sys/kern/kern_exit.c5
-rw-r--r--sys/kern/kern_ktrace.c46
-rw-r--r--sys/sys/ktrace.h4
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 */