[OpenAFS-devel] Linux PAGs, keyrings, and setgroups

Andrew Deason adeason@sinenomine.net
Fri, 7 Aug 2009 11:38:25 -0500


(BCC'd bugs)

I have noticed a bit of interesting PAG behavior in Linux when keyring-
and group-based PAG tracking are in effect. Specifically, say someone
does something like this in a process (as root):

(1) setpag(), set tokens
(2) x = getgroups(n, grouplist)
(3) setpag(), set tokens
(4) setgroups(x, grouplist)

I'll call the PAG acquired in step (1) PAG X, and the one acquired in
step (3) PAG Y.

After step (3), the refcount for the _pag key for PAG X goes to zero,
and linux tells us to destroy the PAG X _pag key, and we set PAG X's
ct.EndTimestamp to 0. After step (4), the process is effectively back in
PAG X, since the grouplist we got in (2) contains PAG X's id. The
setgroups() hook only adds a PAG id if one doesn't already exist, so it
of course allows setting that id.

So now the process is in a rather confusing state where the process has
access to AFS according to the tokens it acquired in step (1), up until
PAG X gets GC'd in afs_GCUserData as part of the ten minute check. After
a max of ten minutes, the process's access seems to mysteriously
dissappear (from the point of view of the user). No kernel messages or
anything; you just lose access.

I can think of a at least few ways to prevent this from happening. I'm
not sure which one(s) is/are the most 'correct' moving forward:

A. In the setgroups() hook, ignore any supplied PAG-ish gids; or at
least ignore ones that are invalid or expired (this is a bit annoying at
present due to the way the setgroups() hook doesn't have any
common-platform code right now, I don't think)

B. Turn off group-based PAG tracking entirely when we have keyring-based
PAG tracking

C. In PagInCred, fall through to getting the PAG from the keyring if the
group-derived PAG is invalid/expired

D. In PagInCred, check the keyring PAG first

Actually, now from writing this, B and D look most correct. With just C
or D, we still have the 'wrong' PAG groupid in the group list, though.
Obviously A won't work when we haven't installed the setgroups hook.

B might still have the problem with GCPAGs that I just mentioned in the
PAGs/tokens/threads thread, but that's easily fixable by turning off
GCPAGs as well (or fixing PagInCred to actually look at the specific
process's keyring).

But enough rambling. Thoughts?

-- 
Andrew Deason
adeason@sinenomine.net