diff options
author | julian <julian@FreeBSD.org> | 2002-02-17 01:09:56 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 2002-02-17 01:09:56 +0000 |
commit | abe785e035306225e97c6f57f5c2e4f6345f3b8d (patch) | |
tree | 3dd328b38aee15fdbfd88129f31df6365b57a0d8 | |
parent | 6308e9245c1de5e4199690f0516a64f552824f07 (diff) | |
download | FreeBSD-src-abe785e035306225e97c6f57f5c2e4f6345f3b8d.zip FreeBSD-src-abe785e035306225e97c6f57f5c2e4f6345f3b8d.tar.gz |
If the credential on an incoming thread is correct, don't bother
reaquiring it. In the same vein, don't bother dropping the thread cred
when goinf ot userland. We are guaranteed to nned it when we come back,
(which we are guaranteed to do).
Reviewed by: jhb@freebsd.org, bde@freebsd.org (slightly different version)
-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); |