Skip site navigation (1)Skip section navigation (2)
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>