- 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)
This commit is contained in:
parent
c0796d1cb4
commit
a5881ea55a
@ -178,6 +178,7 @@ kern_execve(td, fname, argv, envv, mac_p)
|
|||||||
struct procsig *oldprocsig, *newprocsig;
|
struct procsig *oldprocsig, *newprocsig;
|
||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
struct vnode *tracevp = NULL;
|
struct vnode *tracevp = NULL;
|
||||||
|
struct ucred *tracecred = NULL;
|
||||||
#endif
|
#endif
|
||||||
struct vnode *textvp = NULL;
|
struct vnode *textvp = NULL;
|
||||||
int credential_changing;
|
int credential_changing;
|
||||||
@ -489,11 +490,13 @@ interpret:
|
|||||||
*/
|
*/
|
||||||
setsugid(p);
|
setsugid(p);
|
||||||
#ifdef KTRACE
|
#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);
|
mtx_lock(&ktrace_mtx);
|
||||||
p->p_traceflag = 0;
|
p->p_traceflag = 0;
|
||||||
tracevp = p->p_tracep;
|
tracevp = p->p_tracevp;
|
||||||
p->p_tracep = NULL;
|
p->p_tracevp = NULL;
|
||||||
|
tracecred = p->p_tracecred;
|
||||||
|
p->p_tracecred = NULL;
|
||||||
mtx_unlock(&ktrace_mtx);
|
mtx_unlock(&ktrace_mtx);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -626,6 +629,8 @@ done1:
|
|||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
if (tracevp != NULL)
|
if (tracevp != NULL)
|
||||||
vrele(tracevp);
|
vrele(tracevp);
|
||||||
|
if (tracecred != NULL)
|
||||||
|
crfree(tracecred);
|
||||||
#endif
|
#endif
|
||||||
if (oldargs != NULL)
|
if (oldargs != NULL)
|
||||||
pargs_drop(oldargs);
|
pargs_drop(oldargs);
|
||||||
|
@ -135,6 +135,7 @@ exit1(td, rv)
|
|||||||
struct vnode *vtmp;
|
struct vnode *vtmp;
|
||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
struct vnode *tracevp;
|
struct vnode *tracevp;
|
||||||
|
struct ucred *tracecred;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GIANT_REQUIRED;
|
GIANT_REQUIRED;
|
||||||
@ -359,12 +360,16 @@ exit1(td, rv)
|
|||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
mtx_lock(&ktrace_mtx);
|
mtx_lock(&ktrace_mtx);
|
||||||
p->p_traceflag = 0; /* don't trace the vrele() */
|
p->p_traceflag = 0; /* don't trace the vrele() */
|
||||||
tracevp = p->p_tracep;
|
tracevp = p->p_tracevp;
|
||||||
p->p_tracep = NULL;
|
p->p_tracevp = NULL;
|
||||||
|
tracecred = p->p_tracecred;
|
||||||
|
p->p_tracecred = NULL;
|
||||||
mtx_unlock(&ktrace_mtx);
|
mtx_unlock(&ktrace_mtx);
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
if (tracevp != NULL)
|
if (tracevp != NULL)
|
||||||
vrele(tracevp);
|
vrele(tracevp);
|
||||||
|
if (tracecred != NULL)
|
||||||
|
crfree(tracecred);
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* Release reference to text vnode
|
* Release reference to text vnode
|
||||||
|
@ -626,11 +626,15 @@ again:
|
|||||||
* Copy traceflag and tracefile if enabled.
|
* Copy traceflag and tracefile if enabled.
|
||||||
*/
|
*/
|
||||||
mtx_lock(&ktrace_mtx);
|
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) {
|
if (p1->p_traceflag & KTRFAC_INHERIT) {
|
||||||
p2->p_traceflag = p1->p_traceflag;
|
p2->p_traceflag = p1->p_traceflag;
|
||||||
if ((p2->p_tracep = p1->p_tracep) != NULL)
|
if ((p2->p_tracevp = p1->p_tracevp) != NULL) {
|
||||||
VREF(p2->p_tracep);
|
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);
|
mtx_unlock(&ktrace_mtx);
|
||||||
#endif
|
#endif
|
||||||
|
@ -226,14 +226,15 @@ ktr_getrequest(int type)
|
|||||||
if (req != NULL) {
|
if (req != NULL) {
|
||||||
STAILQ_REMOVE_HEAD(&ktr_free, ktr_list);
|
STAILQ_REMOVE_HEAD(&ktr_free, ktr_list);
|
||||||
req->ktr_header.ktr_type = type;
|
req->ktr_header.ktr_type = type;
|
||||||
KASSERT(p->p_tracep != NULL, ("ktrace: no trace vnode"));
|
KASSERT(p->p_tracevp != NULL, ("ktrace: no trace vnode"));
|
||||||
req->ktr_vp = p->p_tracep;
|
KASSERT(p->p_tracecred != NULL, ("ktrace: no trace cred"));
|
||||||
VREF(p->p_tracep);
|
req->ktr_vp = p->p_tracevp;
|
||||||
|
VREF(p->p_tracevp);
|
||||||
|
req->ktr_cred = crhold(p->p_tracecred);
|
||||||
mtx_unlock(&ktrace_mtx);
|
mtx_unlock(&ktrace_mtx);
|
||||||
microtime(&req->ktr_header.ktr_time);
|
microtime(&req->ktr_header.ktr_time);
|
||||||
req->ktr_header.ktr_pid = p->p_pid;
|
req->ktr_header.ktr_pid = p->p_pid;
|
||||||
bcopy(p->p_comm, req->ktr_header.ktr_comm, MAXCOMLEN + 1);
|
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_buffer = NULL;
|
||||||
req->ktr_header.ktr_len = 0;
|
req->ktr_header.ktr_len = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -498,6 +499,7 @@ ktrace(td, uap)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
int flags, error = 0;
|
int flags, error = 0;
|
||||||
struct nameidata nd;
|
struct nameidata nd;
|
||||||
|
struct ucred *cred;
|
||||||
|
|
||||||
td->td_inktrace = 1;
|
td->td_inktrace = 1;
|
||||||
if (ops != KTROP_CLEAR) {
|
if (ops != KTROP_CLEAR) {
|
||||||
@ -527,15 +529,18 @@ ktrace(td, uap)
|
|||||||
sx_slock(&allproc_lock);
|
sx_slock(&allproc_lock);
|
||||||
LIST_FOREACH(p, &allproc, p_list) {
|
LIST_FOREACH(p, &allproc, p_list) {
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
if (p->p_tracep == vp) {
|
if (p->p_tracevp == vp) {
|
||||||
if (ktrcanset(td, p)) {
|
if (ktrcanset(td, p)) {
|
||||||
mtx_lock(&ktrace_mtx);
|
mtx_lock(&ktrace_mtx);
|
||||||
p->p_tracep = NULL;
|
cred = p->p_tracecred;
|
||||||
|
p->p_tracecred = NULL;
|
||||||
|
p->p_tracevp = NULL;
|
||||||
p->p_traceflag = 0;
|
p->p_traceflag = 0;
|
||||||
mtx_unlock(&ktrace_mtx);
|
mtx_unlock(&ktrace_mtx);
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
(void) vn_close(vp, FREAD|FWRITE,
|
(void) vn_close(vp, FREAD|FWRITE,
|
||||||
td->td_ucred, td);
|
cred, td);
|
||||||
|
crfree(cred);
|
||||||
} else {
|
} else {
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
error = EPERM;
|
error = EPERM;
|
||||||
@ -654,6 +659,7 @@ ktrops(td, p, ops, facs, vp)
|
|||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
{
|
{
|
||||||
struct vnode *tracevp = NULL;
|
struct vnode *tracevp = NULL;
|
||||||
|
struct ucred *tracecred = NULL;
|
||||||
|
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
if (!ktrcanset(td, p)) {
|
if (!ktrcanset(td, p)) {
|
||||||
@ -662,13 +668,17 @@ ktrops(td, p, ops, facs, vp)
|
|||||||
}
|
}
|
||||||
mtx_lock(&ktrace_mtx);
|
mtx_lock(&ktrace_mtx);
|
||||||
if (ops == KTROP_SET) {
|
if (ops == KTROP_SET) {
|
||||||
if (p->p_tracep != vp) {
|
if (p->p_tracevp != vp) {
|
||||||
/*
|
/*
|
||||||
* if trace file already in use, relinquish below
|
* if trace file already in use, relinquish below
|
||||||
*/
|
*/
|
||||||
tracevp = p->p_tracep;
|
tracevp = p->p_tracevp;
|
||||||
VREF(vp);
|
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;
|
p->p_traceflag |= facs;
|
||||||
if (td->td_ucred->cr_uid == 0)
|
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) {
|
if (((p->p_traceflag &= ~facs) & KTRFAC_MASK) == 0) {
|
||||||
/* no more tracing */
|
/* no more tracing */
|
||||||
p->p_traceflag = 0;
|
p->p_traceflag = 0;
|
||||||
tracevp = p->p_tracep;
|
tracevp = p->p_tracevp;
|
||||||
p->p_tracep = NULL;
|
p->p_tracevp = NULL;
|
||||||
|
tracecred = p->p_tracecred;
|
||||||
|
p->p_tracecred = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mtx_unlock(&ktrace_mtx);
|
mtx_unlock(&ktrace_mtx);
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
if (tracevp != NULL)
|
if (tracevp != NULL)
|
||||||
vrele(tracevp);
|
vrele(tracevp);
|
||||||
|
if (tracecred != NULL)
|
||||||
|
crfree(tracecred);
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -804,17 +818,24 @@ ktr_writerequest(struct ktr_request *req)
|
|||||||
* we really do this? Other processes might have suitable
|
* we really do this? Other processes might have suitable
|
||||||
* credentials for the operation.
|
* credentials for the operation.
|
||||||
*/
|
*/
|
||||||
|
cred = NULL;
|
||||||
sx_slock(&allproc_lock);
|
sx_slock(&allproc_lock);
|
||||||
LIST_FOREACH(p, &allproc, p_list) {
|
LIST_FOREACH(p, &allproc, p_list) {
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
if (p->p_tracep == vp) {
|
if (p->p_tracevp == vp) {
|
||||||
mtx_lock(&ktrace_mtx);
|
mtx_lock(&ktrace_mtx);
|
||||||
p->p_tracep = NULL;
|
p->p_tracevp = NULL;
|
||||||
p->p_traceflag = 0;
|
p->p_traceflag = 0;
|
||||||
|
cred = p->p_tracecred;
|
||||||
|
p->p_tracecred = NULL;
|
||||||
mtx_unlock(&ktrace_mtx);
|
mtx_unlock(&ktrace_mtx);
|
||||||
vrele_count++;
|
vrele_count++;
|
||||||
}
|
}
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
|
if (cred != NULL) {
|
||||||
|
crfree(cred);
|
||||||
|
cred = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sx_sunlock(&allproc_lock);
|
sx_sunlock(&allproc_lock);
|
||||||
/*
|
/*
|
||||||
|
@ -625,7 +625,7 @@ fill_kinfo_proc(p, kp)
|
|||||||
kp->ki_args = p->p_args;
|
kp->ki_args = p->p_args;
|
||||||
kp->ki_textvp = p->p_textvp;
|
kp->ki_textvp = p->p_textvp;
|
||||||
#ifdef KTRACE
|
#ifdef KTRACE
|
||||||
kp->ki_tracep = p->p_tracep;
|
kp->ki_tracep = p->p_tracevp;
|
||||||
mtx_lock(&ktrace_mtx);
|
mtx_lock(&ktrace_mtx);
|
||||||
kp->ki_traceflag = p->p_traceflag;
|
kp->ki_traceflag = p->p_traceflag;
|
||||||
mtx_unlock(&ktrace_mtx);
|
mtx_unlock(&ktrace_mtx);
|
||||||
|
@ -553,7 +553,8 @@ struct proc {
|
|||||||
int p_profthreads; /* (c) Num threads in addupc_task */
|
int p_profthreads; /* (c) Num threads in addupc_task */
|
||||||
int p_maxthrwaits; /* (c) Max threads num waiters */
|
int p_maxthrwaits; /* (c) Max threads num waiters */
|
||||||
int p_traceflag; /* (o) Kernel trace points. */
|
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. */
|
sigset_t p_siglist; /* (c) Sigs arrived, not delivered. */
|
||||||
struct vnode *p_textvp; /* (b) Vnode of executable. */
|
struct vnode *p_textvp; /* (b) Vnode of executable. */
|
||||||
char p_lock; /* (c) Proclock (prevent swap) count. */
|
char p_lock; /* (c) Proclock (prevent swap) count. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user