summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2002-02-27 18:30:01 +0000
committerjhb <jhb@FreeBSD.org>2002-02-27 18:30:01 +0000
commitec01b5bdbc40025303ba133be03a747c8dc62a2c (patch)
tree2a10480f644fa7d553c28438685c71db5365dc83
parentce9dcc878409c8e9fe6934c5dc7793c6d4f2bc8e (diff)
downloadFreeBSD-src-ec01b5bdbc40025303ba133be03a747c8dc62a2c.zip
FreeBSD-src-ec01b5bdbc40025303ba133be03a747c8dc62a2c.tar.gz
Temporarily lock Giant while we update td_ucred. The proc lock doesn't
fully protect p_ucred yet so Giant is needed until all the p_ucred locking is done. This is the original reason td_ucred was not used immediately after its addition. Unfortunately, not using td_ucred is not enough to avoid problems. Since p_ucred could be stale, we could actually be dereferencing a stale pointer to dink with the refcount, so we really need Giant to avoid foot-shooting. This allows td_ucred to be safely used as well.
-rw-r--r--sys/kern/kern_prot.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index a992e64..cfcef0a 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -1785,17 +1785,17 @@ void
cred_update_thread(struct thread *td)
{
struct proc *p;
+ struct ucred *cred;
p = td->td_proc;
- if (td->td_ucred != NULL) {
- mtx_lock(&Giant);
- crfree(td->td_ucred);
- mtx_unlock(&Giant);
- td->td_ucred = NULL;
- }
+ cred = td->td_ucred;
+ mtx_lock(&Giant);
PROC_LOCK(p);
td->td_ucred = crhold(p->p_ucred);
PROC_UNLOCK(p);
+ if (cred != NULL)
+ crfree(cred);
+ mtx_unlock(&Giant);
}
/*
OpenPOWER on IntegriCloud