diff options
author | jhb <jhb@FreeBSD.org> | 2002-02-27 18:30:01 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2002-02-27 18:30:01 +0000 |
commit | ec01b5bdbc40025303ba133be03a747c8dc62a2c (patch) | |
tree | 2a10480f644fa7d553c28438685c71db5365dc83 | |
parent | ce9dcc878409c8e9fe6934c5dc7793c6d4f2bc8e (diff) | |
download | FreeBSD-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.c | 12 |
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); } /* |