Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Apr 2001 00:03:30 -0400 (EDT)
From:      Robert Watson <rwatson@FreeBSD.org>
To:        freebsd-arch@FreeBSD.org
Subject:   Combining pcred and ucred
Message-ID:  <Pine.NEB.3.96L.1010411235010.97720B-100000@fledge.watson.org>

next in thread | raw e-mail | index | archive | help

Right now, two structures are used to define the process credential set. 
First, there is the ucred structure, which maintains what most developers
think of when asked about a credential structure: the effective uid,
effective gid, and additional groups.  More recently, ucred has grown to
include a cached uidinfo reference, and the prison pointer associated with
the jail() code.  There is also a pcred structure, which includes a
reference to the process's ucred, as well as additional process
credentials, such as the real uid and gid, saved uid and gid, and an
additional uidinfo pointer.

The reference semantics are effectively as follows: there is exactly one
pcred structure per process (although the pcred structure does contain a
reference count field, I don't know of situations where it is used--it
seems only to get set to 1, or be decremented, never incremented).  Each
pcred points to a ucred, but that ucred may be shared (in effect,
copy-on-write).  When a process performs an activity requiring a
persistent cached credential, such as a file or socket open, or in the
future, a potentially blocking VFS operation, an additional reference is
added.  When the ucred needs to be modified, a copy-on-write is performed
using crcopy(), allowing the process's ucred to diverge from the cached
ucred's. 

The observation may be made that although one possible rationale for the
division of ucred and pcred is that pcred might get modified while ucred
remains constant, reducing the number of copy-on-writes, in fact ucred is
almost always (if not always) modified when the pcred needs to be
modified.  There is a small space savings associated with not caching the
real and saved uid/gid's all over the place, but this is negligible due to
the power-of-two memory allocation model, overhead of maintaining
additional refcounts, pointers, and uidinfo references, and the
copy-on-write nature of ucred.  In fact, the pcred pointer substantially
complicates proc locking, and increases the cost of credential evaluation
and manipulation by introducing additional structures and dreferences.  I
think there is a reasonable argument to be made that pcred should be
merged back into ucred, making ucred the sole source of credential
information for the process.  In fact, I'd like to propose doing this, as
it allows the more extensive use of direct ucred to ucred comparison in
access control, rather than proces to process (hence the proc locking
issue).

There is one additional piece of information, that I know of, that should
probably move into ucred if pcred moves into ucred: this is the P_SUGID
flag, which is currently in the process flag field, bit might be more
formally considered a credential downgrade or credential modification
flag.  Moving this flag into ucred would allow the flag to be available
for access control operations based on the ucred, which would also have
substantial structural benefits, albeit at the slight increase in cost
associated with ucred caching.

I would welcome thoughts on these issues: I don't currently have patches,
although Thomas Moestl, John Baldwin, and I have discussed subsets of the
overall issue a number of times in the past.  Moving pcred into ucred
would simplify a number of pieces of code, and not be a challenging change
to implement.  The seperation of ucred and xucred means that this will not
introduce binary incompatibility in userland.  In fact, arguably xucred
should undergo similar modifications as consumers of xucred may wish to
evaluate the real/saved credentials also.

Robert N M Watson             FreeBSD Core Team, TrustedBSD Project
robert@fledge.watson.org      NAI Labs, Safeport Network Services


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" 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.1010411235010.97720B-100000>