Kyle Moffett <mrmacman_g4@xxxxxxx> wrote: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).
A keyring doesn't know what points to it, only the keys that it holds. The key
part of the keyring keeps track of the refcount.
A keyring does have a name, though, but it is arbitrary and otherwise ignored.
I see, we're going about this different ways. For me, the ideal search pathSo you're thinking of a credential stack? That gets tricky when su is thrown
within a single key-ring: keyring, keyring->parent, keyring->parent->parent,
etc.
into the mix. Not that I'm saying my method is precisely simple then either.
Actually, you don't need the concept of a parent at all. If the process had a
current credential TOS pointer, you could push another keyring by adding the
TOS pointer as a child of the new keyring, and then redirecting the TOS
pointer. Basically, the old TOS becomes a child of the new TOS.
I've suggested a stack before, but it got rejected for various reasons.
That way we wouldn't even need a "session" key-ring in the kernel, a PAMTrue. You would still have a "session" keyring, but it would be entirely
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.
defined and governed by userspace (PAM) as to what it meant.
I sort of like that idea. The kernel could still pin keyrings for groups and
users, and PAM could bolt them together, so upon login PAM could create:
TOS
|
+--> Session keyring
|
+--> UID keyring
+--> GID keyring
+--> Supplementary Group keyring
+--> Supplementary Group keyring
+--> Supplementary Group keyring
And then a process or a thread that wanted its own private keys could stack a
new ring:
TOS
|
+--> Thread keyring
|
+--> Process keyring
|
+--> Session keyring
However, you have a number of problems to contend with:
(*) How do you handle setuid() and co?
(*) How do you handle setgid() and co?
(*) How do you handle setgroups()?
(*) How do you handle S_SUID?
This last could be handled in three ways: stack a new credential on the
front; have a second TOS pointer (similar to UIDs); or start a new stack.
If having a second TOS pointer, you could have setresuid() clear it if
setting all UIDs to non-zero.
(*) There needs to be a limit on recursion.
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.
I'm not sure making keys swappable is necessarily easy.
Put a counter in "struct user".
That makes it much easier to move keys around between key-rings, I guess.Are the serial numbers unique within a key-ring or within the entireThe latter.
subsystem?
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@xxxxxxxx"
No. The types are names. I suppose they could be made numeric too, but I don't
think there's a need for that. I could just decree that all userspace type
names begin with a '+' or something.
Some of this could be done by link and rename.Yeah, but carefully.
Actually, symlink() would probably be better. Though Al Viro might kill me for
abusing it:-)
Let's try not to bend the VFS layer too far. Just add another syscall or
prctl() for that.
Perhaps it'd be better to make each key a directory, whether or not it's a
keyring:
/proc/keys/
types
keys/
<keyID>/
type
state
description
payload
<keyringID>/
type
state
description
<keyID> => ../<keyID> [symlink]
We can also store sub-key-rings that way. Here "unlink()" of a directory
could be permitted.
I don't think you can unlink() a directory, and rmdir() might not work if it's
got contents.
With some special keyIDs:
0xABCD0001 - This thread's keyring
0xABCD0002 - This process's keyring
0xABCD0003 - This session's keyring
0xABCD0004 - This UID's keyring
0xABCD0005 - This GID's keyring
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.
We don't want to add ioctls if we can avoid it... And I don't think you want
to try mixing flock() in.
What you're suggesting makes filesystem key searching tricky... what happens
when it is running in softirq context and encounters a locked keyring?
hard-link or soft-link to what? Keyrings are directories on another
filesystem, and we can only assume that it's mounted on /proc/keys. Besides,
you can't hard-link directories.