lkml.org 
[lkml]   [2004]   [Jun]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
SubjectRe: In-kernel Authentication Tokens (PAGs)
Date
On Jun 17, 2004, at 07:48, David Howells wrote:
> The main reason that there are attachment points for keyrings on UIDs,
> processes, etc, is that there needs to be some way for things like
> open() to
> find them without adding an equivalent syscalls that take a key as
> well.
>
> In a way, you could look at it as these attachment points are like the
> PATH
> variable - they describe a search path. You still need one of those.
>
> LSM modules can always create keyrings and subscribe one of the five
> keyrings
> a task has to them so that they become accessible.

You are referring to the attachment point from the UID to key-ring or
process to
key-ring. I was referring to your method of telling the key-ring what
is attached
to it, though I could have misread your code. Of course a task_struct
should
have a key-ring pointer, but the key-ring shouldn't need to know what
points to
it, just how many things point to it (ref count).

> It supports nested keyrings - up to a certain depth anyway - and when
> you add
> one keyring into another it checks to see you're not trying to create
> a cycle
> (at least, you can from the kernel... you can't from userspace yet).

Ahh, that's basically what I was thinking about, I must have missed it
in your patch.

> I'm not keen on the "parent" idea. I'm not sure what you are thinking
> of
> exactly - a keyring can have multiple parents, and also this sounds
> like it
> may cause a cycle.

I see, we're going about this different ways. For me, the ideal search
path within
a single key-ring: keyring, keyring->parent, keyring->parent->parent,
etc. That
way we wouldn't even need a "session" key-ring in the kernel, a PAM
module
could join processes to the appropriate key-ring when you login. That
way if
I login several times on different console virtual terminals it can
share a key-ring
across all of them, but not when I login remotely.

> Using LSM hooks could represent a chicken vs egg scenario if you want
> to use
> these keys to represent LSM security data (which you might reasonably
> want to
> do).

It just means that LSM modules that want to use keys to hold LSM
security data
must be careful about their access to key-ring FS objects. Besides,
there's no
requirements that LSM use the user-space interfaces, we'd probably need
a
set of kernel-space functions that could ignore the access check if
requested,
and most LSM modules would just use unreadable/unwritable/unusable keys
and ignore the access checks.

> It could be made such that arbitrary keys can be stored there (just
> another
> keytype)... it's just that the keys eat into the kernel low memory
> region. It
> may be better to permit such keys to be stored in highmem or swap
> somehow.

Let's allow user programs to *request* (Could be overridden) that
certain keys
be swappable, and we could always allow them to be in highmem, as long
as
we can ensure that certain keys won't be swapped. There are advantages
to
not allowing keys to be swapped.

> Plus, should there be a quota system?

Definitely, by limiting the amount of memory allocated per security
context.
We should make sure that the extra key-ring struct data also counts, so
the
user can't just allocate thousands of empty keys.

> Keys have a serial number, a type, a description and a payload.
> Currently the
> types can't be arbitrary - a kernel driver or whatever must have
> registered
> that type for it to be used. If that driver unregisters its key type,
> all keys
> of that type are immediately withdrawn.

Are the serial numbers unique within a key-ring or within the entire
subsystem?
Perhaps we should allow user-space to "allocate" a key-type dynamically,
something >=1024, while <1024 is reserved for kernel-registered
key-types.
Key-types should be mappable name=>number and number=>name.

> For instance, my kafs module registers an "afs" key type in which it
> can store
> a Krb5 ticket. Having a type management system like this allows the
> type to
> have operations to validate, match and pretty-print key descriptions.
> The
> first one is the most important, I feel, because we can validate a key
> upon
> addition.

Kernel-registered key-types should definitely be validated by the
kernel.

> It might be possible to make this more flexible. Have userspace upload
> a
> "potential" key with arbitrary type, description and payload; and then
> have,
> say, a kafs's file open routine locate a candidate key and render it
> into
> parsed key form. Hmmm...

User-space should be required to parse the key as much as possible, so
that we can keep clutter out of kernel-space. But it's not an issue if
all AFS
ever does with the key is just perform mathematical operations on it and
it happens to be corrupted, as long as it doesn't break the kernel. If
we
allow user-space key-type allocations then we should allow arbitrary
data
to be stored there, up to quota.

> One thing I want to avoid is having to have the filesystem (or
> whatever)
> validate the key every time it looks at it.

No kidding. Once it's added (And validated if needed), we only need to
check it again if it's modified.

> In this example, you might have something like:
>
> type krbtgt
> desc MY.REALM@MY.REALM
>
> Or:
>
> type user
> desc krbtgt/MY.REALM@MY.REALM
>
> But you'd have to provide the kernel with a type registration for the
> key type
> in question.

Are the types numbers? That would seem simpler and allow differing
user-space and kernel-space key-type allocation. Then it would be:
type: KEYTYPE_KRB5 (1042 or some such user-space allocated number)
desc: "krbtgt/MY.REALM@MY.REALM"

>> Hmm, so going along with these ideas, how about this?
>> /proc/keyring/
>> MODE = 555
>> DESC = keyringfs, contains keyring metadata
> I presume you mean keyringfs or keyfs mounted on /proc/keyring/ (or
> /proc/keys/).
Of course

>> <id>/
>> MODE = Access control for entire keyring
>> DESC = A keyring entry, referenced by number
>> opendir = Increments the ref count to make sure it won't go away.
>>
>> parent => ../<id>
>> DESC = A symlink or hardlink to the parent keyring
>>
>> <typeid>/
>> MODE = 555
>> DESC = A numerical "key-type" (KEYTYPE_KRB5)
>>
>> <service>
>> MODE = Access control for a single key
>> DESC = The key, accessed as a file.
>>
>> <typename> => <typeid>/
>> DESC = A symlink or hardlink to a type number from
>> a type name. These types could be registered
>> by modules that implement them.
>>
>> There would be IOCTLs on the key-ring dir handles for getting the
>> key-ring
>> number
> Why? That's the filename of the keyring dir.
If you were passed a key-ring handle and told to do something with it,
how
would you find out what number the keyring is?

>> adding new keys, etc.
> Some of this could be done by link and rename.
Yeah, but carefully.

>> On key handles there would be IOCTLs for deleting the key,
> unlink.
Duh, I feel stupid now.

>> revoking access, etc.
>
>> We'd also need a few syscalls for creating new key-rings.
>
> mkdir would be nice, but the key manager supplies the ID.
How about a key-ring id directory "-1" that can be opendir()ed to
generate a new key-ring. Then once you have that you can just
use IOCTLs to find out what key-ring ID it has. That gives you a
directory file-handle and makes the retain count management a
little simpler. If they don't use the key-ring and just close the dir
handle then the retain count becomes zero and it disappears.

> I think I'd make the filesystem look like:
>
> /proc/keys/
> types
> keys/
> <keyID>
> <keyringID>/
> <keyID>
> <keyringID> => ../<keyringID> [symlink]
> <keyID>
> <keyID> [hardlink to keyID]
> <keyringID>/
> <keyID>
> <keyID>
> <keyringID>/
> <keyringID>/
> <keyID>

I think we are referring to the same ability here, you just referenced
it as "child"
key-rings, whereas I referenced them as "parent" key-rings. Both have
the same
behavior. I think I like the multiple inheritance idea better. What
we do need is
a way to make a

> Each key would then have a UID, GID and umask which behave like for
> normal
> files. Reading key files would then get you a summary of the key
> contents and
> state. getxattr could be used also. The payload would only be
> accessible
> through getxattr.

Yeah, but I think the payload should be accessible through read(),
write(), etc so
that cat can be used to get a dump of the keys, it makes it easier on
sysadmins
who are trying to debug things. Perhaps we could have two files for
each key in
a kernel-registered key-type:
"123" => summary of key, from kernel handler
"123-raw" => raw binary data of key, if accessible
User-mode key-types wouldn't have kernel functions, and so would only
have a
"123-raw" file.

> I might even permit the use of link() and rename(), provided the keys
> filenames stay the same, and unlink().
What if we have:
<keyring-id>/
0/ => These are sub-key-rings (type=0,desc=<key-ring ID string>)
<keyring-no>
<keyring-no>
<key-type>/
<key-desc>
<key-type>_raw/
<key-desc>
Or something like that. That way key filenames stay the same, are easy
to
locate and use in scripts, and give detailed information just in the
directories.
We can also store sub-key-rings that way. Here "unlink()" of a
directory could
be permitted. If it's a primary key-ring entry then we just remove it
from the
visible database but not from anything that references it (Like
unlink() on an
open file).

> However, I think I'd prefer to extend the syscall interface some more.
> I've got four prctls:
>
> (*) Get process subscribed keyring ID (choose which of the five).
>
> (*) Clear process subscribed keyring ID (choose which of the five).
>
> (*) Request new session keyring for this process.
>
> (*) Add key to process subscribed keyring ID (choose which of the
> five).
>
> I could then add some more syscalls:
>
> (*) Add key to arbitrary keyring.
>
> (*) Update key.
>
> (*) Retire key.
>
> (*) Get list of key IDs from keyring.
>
> (*) Get type of key.
>
> (*) Get description of key.
>
> (*) Get payload of key.
>
> (*) Link key to keyring.
>
> (*) Unlink key from keyring.
>
> All but the first two are trivially easy to do with a keyfs using
> standard
> operations.

Yeah. We ought to have equivalent IOCTLs so that mostly atomic updates
can be done to key-rings, possibly even setting up a mandatory flock()
for
key and key-ring file-handles. Opening a file-handle would be enough to
make sure it doesn't go away, but flocking it would protect against
other
kinds of operations.

As for the first two operations, looking up key-rings, we could just
add a
hard-link or soft-link /proc/<pid>/keyring/process/thread, though we'd
want
sys-calls as well, since the UID and group ones aren't mapped in proc.
I
don't expect those will be used as much, though.

Cheers,
Kyle Moffett

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:03    [from the cache]
©2003-2014 Jasper Spaans. Advertise on this site