[OpenAFS-devel] [LKML] Re: In-kernel Authentication Tokens (PAGs)

Kyle Moffett mrmacman_g4@mac.com
Thu, 15 Jul 2004 17:47:40 -0400


On Jul 15, 2004, at 11:27, Jeffrey Hutzelman wrote:
> Wait..  So types that don't begin with a + are just random data that
> can be manipulated by things in user space?

Exactly.  This provides a nice mechanism for OpenSSH to use for a
credentials cache, without any specific kernel support.  One of the
important things about this is it is a small amount of un-swappable
memory, so there is no risk that it will ever be written to swap.

> I assume there will be some mechanism to limit how much storage a user 
> can allocate in this fashion.

A ulimit, most likely.  It would probably be set very low, no more than
maybe a couple pages per-user.  It would of course be tunable using
the standard ulimit adjustment.

> OK, except I can't necessarily just "store all the data in the key".
> There has to be notification, since these data structures don't exist 
> in isolation (a connection, for example, belongs to a hash table that 
> allows the rx listener to determine which connection an incoming 
> packet belongs to; cached filesystem metadata is stored in the vnode 
> status cache), and since they might actually belong to a user-mode 
> process that can't access kernel memory directly (arlad).

That is what the key_type structures are for.  A module (Like OpenAFS),
can register itself with a key_type that installs certain handlers so 
that
any time a key of that type is created, destroyed, expired, renewed, 
etc,
the module will know about it.

> So again, there needs to be some sort of identifier which either
> (a) is unique across an entire run of the system, or
> (b) has a notification mechanism for when it goes away.

The key-type stuff will be registered at module load and unregistered
on unload.  All keys maintain reference counts.  I have two types of
identifiers right now.  There is a unique (at one instant) global 
identifier
number that identifies a key or key-ring, but unless keyfs is mounted
that number is useless to any process.  In order to interact with a key,
you must have a file-descriptor that represents the key.  If you dup() a
key file-descriptor, you get a new descriptor that has the same perms
as the old one (They can be lowered, but not raised).  One of the other
features is that a file-descriptor can be revoked with a keyctl, which
automatically revokes all descriptors created from it with dup().  When
a handle is closed or revoked, the key loses that reference, and when
all references are gone, it is deallocated.

> So, a naive use of this mechanism would be to just store a PAG ID in a 
> key rather than in the groups list, and leave everything else the way 
> it is. That won't work, because the kernel would let a user specify 
> any value he wants for that key, and thus join any PAG.

Not really.  The user must get a file-descriptor for the key, by opening
the file in keyfs (Requires access under keyfs permissions), or by
receiving one from a process that sends it one.  Such a key can be
completely revoked by the sending process at any time, and can be
set to only provide whatever permissions are needed.

> So, the "label" we use to mark connections, cached rights data, etc 
> cannot simply be the value of the key blob.  It needs to be something 
> the user cannot simply set to whatever he wants.

The user can set it to whatever he wants, so long as already has it. If
the user is never given a handle to the key, and keyfs is never mounted
or has too-strict permissions, then he can't assign himself somebody
else's keys.

Cheers,
Kyle Moffett

-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCM/CS/IT/U d- s++: a17 C++++>$ UB/L/X/*++++(+)>$ P+++(++++)>$
L++++(+++) E W++(+) N+++(++) o? K? w--- O? M++ V? PS+() PE+(-) Y+
PGP+++ t+(+++) 5 X R? tv-(--) b++++(++) DI+ D+ G e->++++$ h!*()>++$ r  
!y?(-)
------END GEEK CODE BLOCK------