diff options
-rw-r--r-- | sys/amd64/amd64/trap.c | 14 | ||||
-rw-r--r-- | sys/i386/i386/trap.c | 14 | ||||
-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 | ||||
-rw-r--r-- | sys/sys/ucred.h | 1 |
6 files changed, 44 insertions, 15 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 07067c4..bc31c8c 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -256,9 +256,8 @@ trap(frame) sticks = td->td_kse->ke_sticks; td->td_frame = &frame; KASSERT(td->td_ucred == NULL, ("already have a ucred")); - PROC_LOCK(p); - td->td_ucred = crhold(p->p_ucred); - PROC_UNLOCK(p); + if (td->td_ucred != p->p_ucred) + cred_update_thread(td); switch (type) { case T_PRIVINFLT: /* privileged instruction fault */ @@ -644,10 +643,12 @@ user: userret(td, &frame, sticks); mtx_assert(&Giant, MA_NOTOWNED); userout: +#ifdef INVARIANTS mtx_lock(&Giant); crfree(td->td_ucred); mtx_unlock(&Giant); td->td_ucred = NULL; +#endif out: return; } @@ -954,9 +955,8 @@ syscall(frame) sticks = td->td_kse->ke_sticks; td->td_frame = &frame; KASSERT(td->td_ucred == NULL, ("already have a ucred")); - PROC_LOCK(p); - td->td_ucred = crhold(p->p_ucred); - PROC_UNLOCK(p); + if (td->td_ucred != p->p_ucred) + cred_update_thread(td); params = (caddr_t)frame.tf_esp + sizeof(int); code = frame.tf_eax; orig_tf_eflags = frame.tf_eflags; @@ -1099,10 +1099,12 @@ bad: */ STOPEVENT(p, S_SCX, code); +#ifdef INVARIANTS mtx_lock(&Giant); crfree(td->td_ucred); mtx_unlock(&Giant); td->td_ucred = NULL; +#endif #ifdef WITNESS if (witness_list(td)) { panic("system call %s returning with mutex(s) held\n", diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 07067c4..bc31c8c 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -256,9 +256,8 @@ trap(frame) sticks = td->td_kse->ke_sticks; td->td_frame = &frame; KASSERT(td->td_ucred == NULL, ("already have a ucred")); - PROC_LOCK(p); - td->td_ucred = crhold(p->p_ucred); - PROC_UNLOCK(p); + if (td->td_ucred != p->p_ucred) + cred_update_thread(td); switch (type) { case T_PRIVINFLT: /* privileged instruction fault */ @@ -644,10 +643,12 @@ user: userret(td, &frame, sticks); mtx_assert(&Giant, MA_NOTOWNED); userout: +#ifdef INVARIANTS mtx_lock(&Giant); crfree(td->td_ucred); mtx_unlock(&Giant); td->td_ucred = NULL; +#endif out: return; } @@ -954,9 +955,8 @@ syscall(frame) sticks = td->td_kse->ke_sticks; td->td_frame = &frame; KASSERT(td->td_ucred == NULL, ("already have a ucred")); - PROC_LOCK(p); - td->td_ucred = crhold(p->p_ucred); - PROC_UNLOCK(p); + if (td->td_ucred != p->p_ucred) + cred_update_thread(td); params = (caddr_t)frame.tf_esp + sizeof(int); code = frame.tf_eax; orig_tf_eflags = frame.tf_eflags; @@ -1099,10 +1099,12 @@ bad: */ STOPEVENT(p, S_SCX, code); +#ifdef INVARIANTS mtx_lock(&Giant); crfree(td->td_ucred); mtx_unlock(&Giant); td->td_ucred = NULL; +#endif #ifdef WITNESS if (witness_list(td)) { panic("system call %s returning with mutex(s) held\n", 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); diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index d92b45d..d26f318 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -83,6 +83,7 @@ struct xucred { #ifdef _KERNEL +void cred_update_thread(struct thread *td); void change_egid (struct ucred *newcred, gid_t egid); void change_euid (struct ucred *newcred, uid_t euid); void change_rgid (struct ucred *newcred, gid_t rgid); |