Date: Mon, 3 Feb 2003 12:58:05 -0500 (EST) From: Robert Watson <rwatson@freebsd.org> To: "Ilmar S. Habibulin" <ilmar@watson.org> Cc: freebsd-current@freebsd.org Subject: Re: What is the difference between p_ucred and td_ucred? Message-ID: <Pine.NEB.3.96L.1030203120211.80901B-100000@fledge.watson.org> In-Reply-To: <20030203090133.R78581-100000@fledge.watson.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 3 Feb 2003, Ilmar S. Habibulin wrote:
> Why not to use only credits for proc and make td_ucred macro like
> td_proc->p_ucred? Or it has some meaning that i do not understand?
td_ucred is a cached copy of p_ucred. The cached copy is potentially
updated on any entry to the kernel. The reason for doing this is
multi-fold:
(1) Because of threading, access to p_ucred requires holding the process
lock. Because we don't want to hold the process lock for every access
control check, using a thread-access only reference avoids the lock.
(2) Credential consistency. We perform the update check when we enter the
kernel; if the comparison indicates they differ, we grab the process
lock and update td_ucred. If they don't differ, we can continue.
My understanding is that this is because a pointer comparison to
determine if they are identical is permitted without a lock. It might
be desirable to reason about the safety of this. This guarantees a
single consistent "process credential" for each system call; that way
there aren't races between separate access control checks resulting in
inconsistent enforcement.
So the end semantic is that there is, in effect, a single process
credential. However, there may be divergence from that credential when
threads are blocked in kernel and another thread changes the process
credential, as the threads blocked in kernel won't pick up the new
credential until they exit and re-enter the kernel. This approach, as I
understand it, is taken by several other MP/threaded UNIXes.
The strategy for selecting a credential to check against is generally to
use td_ucred, and to hold no locks. You'll see that suser() does this,
for example. Under some circumstances: specifically, credential updates,
you need to hold the process lock and atomically check the process
credential before updating. If the thread doesn't immediately leave the
kernel (i.e., more checks might be performed), you'll also need to
propagate the cred change to the thread from the process.
Robert N M Watson FreeBSD Core Team, TrustedBSD Projects
robert@fledge.watson.org Network Associates Laboratories
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1030203120211.80901B-100000>
