Subject: Re: Process credentials change
To: Jason Thorpe <thorpej@shagadelic.org>
From: Bill Studenmund <wrstuden@netbsd.org>
List: tech-kern
Date: 07/10/2006 16:45:31
--CEUtFxTsmBsHRLs3
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Mon, Jul 10, 2006 at 03:45:49PM -0700, Jason Thorpe wrote:
>=20
> On Jul 10, 2006, at 3:30 PM, Bill Studenmund wrote:
>=20
> >I'm not sure about the cause&effect here. :-) I DO agree that we don't
> >want an lwp to change credentials in the middle of a systemcall. =20
> >However a
> >shared lock with upgrade to exclusive will also do that. :-)
>=20
> 1- Shared -> Exclusive "upgrades" are an icky concept that we happen =20
> to have in lockmgr(), but I would prefer we NOT proliferate.

I perhaps was sloppy with "upgrade." I specificaly meant a reader/writer=20
lock going from reader to writer mode. The exact "upgrade" behavior of=20
lockmgr isn't important to the issue.

My idea is that when we want to change the credentials, we would block new=
=20
system calls until it's done; we have a lock go from reader mode to writer=
=20
mode (change creds), then back to reader mode as all new users come in.

> 2- The key to scalability is to AVOID locking where you can.  Why =20
> block another thread that wants to change the process's credentials =20
> just because another thread in the same process is waiting for disk I/=20
> O?  You avoid contention for the lock when you have a nice short code =20
> path like this:

Depends on the semantics of credential changing w.r.t. threads. If we only=
=20
promise that it applies to future system calls, then what you propose is=20
best. If we are instead promising that nothing is using credentials other=
=20
than what we set to, then we need the blockage.

> void
> lwp_cache_creds(proc_t p, lwp_t l)
> {
> 	ocreds =3D NULL;
> 	mutex_lock(&p->p_cred_mutex);
> 	if (l->l_cred !=3D p->p_cred) {
> 		ocreds =3D l->l_cred;
> 		l->l_cred =3D p->p_cred;
> 		kauth_cred_retain(l->l_cred);
> 	}
> 	mutex_unlock(&p->p_cred_mutex);
> 	if (ocreds !=3D NULL)
> 		kauth_cred_release(ocreds);
> }
>=20
> ...and you don't have to take the lock again.
>=20
> Let's try and design for scalability NOW rather than have to retrofit =20
> it in later.

Agreed. Right now, I think the only question is what we are promising and=
=20
what standards require.

> >But doing the above has an impact on changing credentials. We will =20
> >return
> >success on changing credentials before we've realy finished the =20
> >change.
> >Yes, we've put things in place so the NEXT system call will use the =20
> >new
> >creds, we are still using the old ones. If the unchanged LWP stays =20
> >in the
> >kernel "for a while", then we have a measure of shadiness.
>=20
> Assuming that an LWP entered the kernel with rights to perform an =20
> action, it stands to reason that it should be allowed to complete =20
> that action.

Agreed! We agree on this bit. The question really is if the change has to=
=20
wait for other threads.

> >How do other OSs handle this? Do they care?
>=20
> I haven't looked into how the "change creds of the proc while threads =20
> are blocked in the kernel" aspect, but I know that Mac OS X 10.4 has =20
> per-thread credentials.  The AFP server uses this to ensure that =20
> requests are processed as the user logged into the session.

Oh, that'd be "interesting" if we don't just stay in the kernel since a=20
given userland thread can hop around LWPs. :-)

Take care,

Bill

--CEUtFxTsmBsHRLs3
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (NetBSD)

iD8DBQFEsuabWz+3JHUci9cRAilXAKCVg/qF4Q1c4933k908oZq9k+Y9EwCfd6Rb
+nqXdP65hYwpXylzjEHZQjs=
=jvA/
-----END PGP SIGNATURE-----

--CEUtFxTsmBsHRLs3--