diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_fork.c | 2 | ||||
-rw-r--r-- | sys/kern/kern_prot.c | 21 | ||||
-rw-r--r-- | sys/kern/subr_trap.c | 7 |
3 files changed, 27 insertions, 3 deletions
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 3223f8b..c7cbf28 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -799,10 +799,12 @@ fork_exit(callout, arg, frame) kthread_exit(0); } PROC_UNLOCK(p); +#ifdef INVARIANTS mtx_lock(&Giant); crfree(td->td_ucred); mtx_unlock(&Giant); td->td_ucred = NULL; +#endif mtx_assert(&Giant, MA_NOTOWNED); } diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 4214cc1..f7056a0 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -1684,6 +1684,27 @@ crdup(cr) } /* + * small routine to swap a thread's current ucred for the correct one + * taken from the process. + */ +void +cred_update_thread(struct thread *td) +{ + struct proc *p; + + p = td->td_proc; + if (td->td_ucred != NULL) { + mtx_lock(&Giant); + crfree(td->td_ucred); + mtx_unlock(&Giant); + td->td_ucred = NULL; + } + PROC_LOCK(p); + td->td_ucred = crhold(p->p_ucred); + PROC_UNLOCK(p); +} + +/* * Get login name, if available. */ #ifndef _SYS_SYSPROTO_H_ diff --git a/sys/kern/subr_trap.c b/sys/kern/subr_trap.c index 9c24e17..d599b91 100644 --- a/sys/kern/subr_trap.c +++ b/sys/kern/subr_trap.c @@ -161,9 +161,8 @@ ast(framep) p->p_stats->p_prof.pr_ticks = 0; } mtx_unlock_spin(&sched_lock); - PROC_LOCK(p); - td->td_ucred = crhold(p->p_ucred); - PROC_UNLOCK(p); + if (td->td_ucred != p->p_ucred) + cred_update_thread(td); if (flags & KEF_OWEUPC && sflag & PS_PROFIL) addupc_task(ke, p->p_stats->p_prof.pr_addr, prticks); if (sflag & PS_ALRMPEND) { @@ -188,10 +187,12 @@ ast(framep) } userret(td, framep, sticks); +#ifdef INVARIANTS mtx_lock(&Giant); crfree(td->td_ucred); mtx_unlock(&Giant); td->td_ucred = NULL; +#endif s = cpu_critical_enter(); } mtx_assert(&Giant, MA_NOTOWNED); |