summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2003-03-13 18:24:22 +0000
committerjhb <jhb@FreeBSD.org>2003-03-13 18:24:22 +0000
commitf02ef380800bd38dbe71222060eb0b63fe324040 (patch)
treef091cf306f923dc1ced5e37882d80b885d47cc2b
parent15b2d31e358554d642da71cfc6c4967e3bea1414 (diff)
downloadFreeBSD-src-f02ef380800bd38dbe71222060eb0b63fe324040.zip
FreeBSD-src-f02ef380800bd38dbe71222060eb0b63fe324040.tar.gz
- Cache a reference to the credential of the thread that starts a ktrace in
struct proc as p_tracecred alongside the current cache of the vnode in p_tracep. This credential is then used for all later ktrace operations on this file rather than using the credential of the current thread at the time of each ktrace event. - Now that we have multiple ktrace-related items in struct proc that are pointers, rename p_tracep to p_tracevp to make it less ambiguous. Requested by: rwatson (1)
-rw-r--r--sys/kern/kern_exec.c11
-rw-r--r--sys/kern/kern_exit.c9
-rw-r--r--sys/kern/kern_fork.c10
-rw-r--r--sys/kern/kern_ktrace.c49
-rw-r--r--sys/kern/kern_proc.c2
-rw-r--r--sys/sys/proc.h3
6 files changed, 60 insertions, 24 deletions
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 2c5df1c..a359b75 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -178,6 +178,7 @@ kern_execve(td, fname, argv, envv, mac_p)
struct procsig *oldprocsig, *newprocsig;
#ifdef KTRACE
struct vnode *tracevp = NULL;
+ struct ucred *tracecred = NULL;
#endif
struct vnode *textvp = NULL;
int credential_changing;
@@ -489,11 +490,13 @@ interpret:
*/
setsugid(p);
#ifdef KTRACE
- if (p->p_tracep && suser_cred(oldcred, PRISON_ROOT)) {
+ if (p->p_tracevp != NULL && suser_cred(oldcred, PRISON_ROOT)) {
mtx_lock(&ktrace_mtx);
p->p_traceflag = 0;
- tracevp = p->p_tracep;
- p->p_tracep = NULL;
+ tracevp = p->p_tracevp;
+ p->p_tracevp = NULL;
+ tracecred = p->p_tracecred;
+ p->p_tracecred = NULL;
mtx_unlock(&ktrace_mtx);
}
#endif
@@ -626,6 +629,8 @@ done1:
#ifdef KTRACE
if (tracevp != NULL)
vrele(tracevp);
+ if (tracecred != NULL)
+ crfree(tracecred);
#endif
if (oldargs != NULL)
pargs_drop(oldargs);
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 22dba08..168900f 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -135,6 +135,7 @@ exit1(td, rv)
struct vnode *vtmp;
#ifdef KTRACE
struct vnode *tracevp;
+ struct ucred *tracecred;
#endif
GIANT_REQUIRED;
@@ -359,12 +360,16 @@ exit1(td, rv)
PROC_LOCK(p);
mtx_lock(&ktrace_mtx);
p->p_traceflag = 0; /* don't trace the vrele() */
- tracevp = p->p_tracep;
- p->p_tracep = NULL;
+ tracevp = p->p_tracevp;
+ p->p_tracevp = NULL;
+ tracecred = p->p_tracecred;
+ p->p_tracecred = NULL;
mtx_unlock(&ktrace_mtx);
PROC_UNLOCK(p);
if (tracevp != NULL)
vrele(tracevp);
+ if (tracecred != NULL)
+ crfree(tracecred);
#endif
/*
* Release reference to text vnode
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index 65a3360..0c24cc6 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -626,11 +626,15 @@ again:
* Copy traceflag and tracefile if enabled.
*/
mtx_lock(&ktrace_mtx);
- KASSERT(p2->p_tracep == NULL, ("new process has a ktrace vnode"));
+ KASSERT(p2->p_tracevp == NULL, ("new process has a ktrace vnode"));
if (p1->p_traceflag & KTRFAC_INHERIT) {
p2->p_traceflag = p1->p_traceflag;
- if ((p2->p_tracep = p1->p_tracep) != NULL)
- VREF(p2->p_tracep);
+ if ((p2->p_tracevp = p1->p_tracevp) != NULL) {
+ VREF(p2->p_tracevp);
+ KASSERT(p1->p_tracecred != NULL,
+ ("ktrace vnode with no cred"));
+ p2->p_tracecred = crhold(p1->p_tracecred);
+ }
}
mtx_unlock(&ktrace_mtx);
#endif
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index bb4642c..8685eb1 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -226,14 +226,15 @@ ktr_getrequest(int type)
if (req != NULL) {
STAILQ_REMOVE_HEAD(&ktr_free, ktr_list);
req->ktr_header.ktr_type = type;
- KASSERT(p->p_tracep != NULL, ("ktrace: no trace vnode"));
- req->ktr_vp = p->p_tracep;
- VREF(p->p_tracep);
+ KASSERT(p->p_tracevp != NULL, ("ktrace: no trace vnode"));
+ KASSERT(p->p_tracecred != NULL, ("ktrace: no trace cred"));
+ req->ktr_vp = p->p_tracevp;
+ VREF(p->p_tracevp);
+ req->ktr_cred = crhold(p->p_tracecred);
mtx_unlock(&ktrace_mtx);
microtime(&req->ktr_header.ktr_time);
req->ktr_header.ktr_pid = p->p_pid;
bcopy(p->p_comm, req->ktr_header.ktr_comm, MAXCOMLEN + 1);
- req->ktr_cred = crhold(td->td_ucred);
req->ktr_header.ktr_buffer = NULL;
req->ktr_header.ktr_len = 0;
} else {
@@ -498,6 +499,7 @@ ktrace(td, uap)
int ret = 0;
int flags, error = 0;
struct nameidata nd;
+ struct ucred *cred;
td->td_inktrace = 1;
if (ops != KTROP_CLEAR) {
@@ -527,15 +529,18 @@ ktrace(td, uap)
sx_slock(&allproc_lock);
LIST_FOREACH(p, &allproc, p_list) {
PROC_LOCK(p);
- if (p->p_tracep == vp) {
+ if (p->p_tracevp == vp) {
if (ktrcanset(td, p)) {
mtx_lock(&ktrace_mtx);
- p->p_tracep = NULL;
+ cred = p->p_tracecred;
+ p->p_tracecred = NULL;
+ p->p_tracevp = NULL;
p->p_traceflag = 0;
mtx_unlock(&ktrace_mtx);
PROC_UNLOCK(p);
(void) vn_close(vp, FREAD|FWRITE,
- td->td_ucred, td);
+ cred, td);
+ crfree(cred);
} else {
PROC_UNLOCK(p);
error = EPERM;
@@ -654,6 +659,7 @@ ktrops(td, p, ops, facs, vp)
struct vnode *vp;
{
struct vnode *tracevp = NULL;
+ struct ucred *tracecred = NULL;
PROC_LOCK(p);
if (!ktrcanset(td, p)) {
@@ -662,13 +668,17 @@ ktrops(td, p, ops, facs, vp)
}
mtx_lock(&ktrace_mtx);
if (ops == KTROP_SET) {
- if (p->p_tracep != vp) {
+ if (p->p_tracevp != vp) {
/*
* if trace file already in use, relinquish below
*/
- tracevp = p->p_tracep;
+ tracevp = p->p_tracevp;
VREF(vp);
- p->p_tracep = vp;
+ p->p_tracevp = vp;
+ }
+ if (p->p_tracecred != td->td_ucred) {
+ tracecred = p->p_tracecred;
+ p->p_tracecred = crhold(td->td_ucred);
}
p->p_traceflag |= facs;
if (td->td_ucred->cr_uid == 0)
@@ -678,14 +688,18 @@ ktrops(td, p, ops, facs, vp)
if (((p->p_traceflag &= ~facs) & KTRFAC_MASK) == 0) {
/* no more tracing */
p->p_traceflag = 0;
- tracevp = p->p_tracep;
- p->p_tracep = NULL;
+ tracevp = p->p_tracevp;
+ p->p_tracevp = NULL;
+ tracecred = p->p_tracecred;
+ p->p_tracecred = NULL;
}
}
mtx_unlock(&ktrace_mtx);
PROC_UNLOCK(p);
if (tracevp != NULL)
vrele(tracevp);
+ if (tracecred != NULL)
+ crfree(tracecred);
return (1);
}
@@ -804,17 +818,24 @@ ktr_writerequest(struct ktr_request *req)
* we really do this? Other processes might have suitable
* credentials for the operation.
*/
+ cred = NULL;
sx_slock(&allproc_lock);
LIST_FOREACH(p, &allproc, p_list) {
PROC_LOCK(p);
- if (p->p_tracep == vp) {
+ if (p->p_tracevp == vp) {
mtx_lock(&ktrace_mtx);
- p->p_tracep = NULL;
+ p->p_tracevp = NULL;
p->p_traceflag = 0;
+ cred = p->p_tracecred;
+ p->p_tracecred = NULL;
mtx_unlock(&ktrace_mtx);
vrele_count++;
}
PROC_UNLOCK(p);
+ if (cred != NULL) {
+ crfree(cred);
+ cred = NULL;
+ }
}
sx_sunlock(&allproc_lock);
/*
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 84b3fc1..752fbf0 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -625,7 +625,7 @@ fill_kinfo_proc(p, kp)
kp->ki_args = p->p_args;
kp->ki_textvp = p->p_textvp;
#ifdef KTRACE
- kp->ki_tracep = p->p_tracep;
+ kp->ki_tracep = p->p_tracevp;
mtx_lock(&ktrace_mtx);
kp->ki_traceflag = p->p_traceflag;
mtx_unlock(&ktrace_mtx);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 270b235..c34d436 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -553,7 +553,8 @@ struct proc {
int p_profthreads; /* (c) Num threads in addupc_task */
int p_maxthrwaits; /* (c) Max threads num waiters */
int p_traceflag; /* (o) Kernel trace points. */
- struct vnode *p_tracep; /* (c + o) Trace to vnode. */
+ struct vnode *p_tracevp; /* (c + o) Trace to vnode. */
+ struct ucred *p_tracecred; /* (o) Credentials to trace with. */
sigset_t p_siglist; /* (c) Sigs arrived, not delivered. */
struct vnode *p_textvp; /* (b) Vnode of executable. */
char p_lock; /* (c) Proclock (prevent swap) count. */
OpenPOWER on IntegriCloud