Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Dec 2000 08:13:25 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        jhb@FreeBSD.org (John Baldwin)
Cc:        tlambert@primenet.com (Terry Lambert), arch@FreeBSD.org
Subject:   Re: Can !curproc touch
Message-ID:  <200012130813.BAA25955@usr08.primenet.com>
In-Reply-To: <XFMail.001211143716.jhb@FreeBSD.org> from "John Baldwin" at Dec 11, 2000 02:37:16 PM

next in thread | previous in thread | raw e-mail | index | archive | help
> >> I've got a question about p_cred in proc, specifically
> >> p_cred->pc_ucred.  In several VOP's and other places we
> >> use p_cred->pc_ucred (aka p_ucred) as the credentials
> >> if we don't already have one.  The problem arises if
> >> another process can crfree() that ucred either by a
> >> crcopy() or a direct crfree() of p_ucred.

This was incorrectly attributed to me.


> We already share ucred's, and we already do reference counting
> for ucred structures.  xref crfree()/crcopy()/crhold(), etc.
> Really, Terry, reading the code and reading the questions in
> detail would help here.

Please read my statements in the contect of the question.  In
particular, I think that "crfree" should be hidden in crunref()
(or whatever the inverse of "crhold" is) on the 1->0 reference
decrement, and "crcopy" needs to die.

Sorry if that wasn't clear from my posting.


> My question is about protecting the p_ucred pointer that is part
> of struct proc.  I'm not trying to lock the ucred itself, I'm
> trying to figure out how to ensure that the pointer to a ucred
> I get out of proc is valid when I pass it to a VOP and that it
> _stays_ valid the entire time.  I know that if need be I can do
> it by protecting the p_ucred pointer with the proc lock and
> bumping the refcount before passing it down the VOP stack, but
> if I can get away w/o having to do that I'd like to avoid the
> cost.

My point was that holding the proc lock is implicit in the
addition of the reference and the assignment of the pointer
in the proc structure initially.

I was under the impression that your function that you are
entering for the purpose of dereferencing the value out of
the proc structure could hold _its own_ reference to the
credential on entry, releasing it on exit.

Given the approach I outlined, this would prevent the 1->0
reansition, since there would be a positive reference which
could not go away.  Therefore the credential you entered
with is valid _at least_ until you exit.

The interaction of the credential modifying POSIX functions
and threads is a pain.  I think that any operation that is
begun with a particular credential should remain with that
credential until the kernel returns to user space.  This
implies to me that the credential reference is handled on
kernel entry, and that a reference is created at that time,
and that it's the reference, not the dereference value,
which would be used.

This kind of implies to me that, since a credential change is
a rare and unlikely event, that the reference should probably
be cached on a per KSE basis, rather than referenced out of
the proc structure anyway.

It seems to me that on exit to user space, the KSE value would
be compared to the proc value, and if they did not match, a
reference would be added to the proc value, subtracted from
the KSE value, and the KSE value replaced.  Obviously, the
KSE would be locked over the subtract/replace operation, since
the old credential could become invalid during this process,
and you want it in a consistant state.

I don't see this as being different from what I outlined
previously (though more detailed, here), and I see it being
very different from the current code.

To my mind, doing lazy binding of the credentials in the proc
structure to those referenced by the thread/KSE structure is
the best way of reducing the need for locking in all but the
exceptional circumstance of a credential change: since that
is very rare, and requires priviledge, in any case, I really
don't have a problem with an exit-to-user-space penalty that
might seem a bit steep at first glance.

I also think that whatever approach is used shouldn't really
architect against the possibility of handing around opaque
objects like NT domain credentials, Kerberos tickets, or
similar things that aren't currently on FreeBSD's radar.

Does my suggested approach make more sense, and appear more
distinct from the current implementation, now?


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.


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?200012130813.BAA25955>