Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S265325AbUFWMag (ORCPT ); Wed, 23 Jun 2004 08:30:36 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S264984AbUFWMag (ORCPT ); Wed, 23 Jun 2004 08:30:36 -0400 Received: from mx1.redhat.com ([66.187.233.31]:4288 "EHLO mx1.redhat.com") by vger.kernel.org with ESMTP id S262547AbUFWMaC (ORCPT ); Wed, 23 Jun 2004 08:30:02 -0400 From: David Howells In-Reply-To: <643CA25E-C091-11D8-8574-000393ACC76E@mac.com> References: <643CA25E-C091-11D8-8574-000393ACC76E@mac.com> <984AC744-BFFB-11D8-8574-000393ACC76E@mac.com> <1087282990.13680.13.camel@lade.trondhjem.org> <772741DF-BC19-11D8-888F-000393ACC76E@mac.com> <1087080664.4683.8.camel@lade.trondhjem.org> <1087084736.4683.17.camel@lade.trondhjem.org> <87smcxqqa2.fsf@asterisk.co.nz> <8666.1087292194@redhat.com> <10430.1087397355@redhat.com> <30952.1087472906@redhat.com> To: Kyle Moffett Cc: Blair Strang , lkml Subject: Re: In-kernel Authentication Tokens (PAGs) User-Agent: EMH/1.14.1 SEMI/1.14.5 (Awara-Onsen) FLIM/1.14.5 (Demachiyanagi) APEL/10.6 Emacs/21.3 (i386-redhat-linux-gnu) MULE/5.0 (SAKAKI) MIME-Version: 1.0 (generated by SEMI 1.14.5 - "Awara-Onsen") Content-Type: text/plain; charset=US-ASCII Date: Wed, 23 Jun 2004 13:29:49 +0100 Message-ID: <5447.1087993789@redhat.com> Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 8427 Lines: 237 Kyle Moffett 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 path > within a single key-ring: keyring, keyring->parent, keyring->parent->parent, > etc. So you're thinking of a credential stack? That gets tricky when su is thrown 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 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. True. You would still have a "session" keyring, but it would be entirely 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. > > 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. Put a counter in "struct user". > Are the serial numbers unique within a key-ring or within the entire > subsystem? The latter. > 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. Why? > 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" 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:-) > > 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. Let's try not to bend the VFS layer too far. Just add another syscall or prctl() for that. > 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 Make a what? > 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: Perhaps it'd be better to make each key a directory, whether or not it's a keyring: /proc/keys/ types keys/ / type state description payload / type state description => ../ [symlink] > 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. I don't think you can unlink() a directory, and rmdir() might not work if it's got contents. Add a syscall or a prctl(). Perhaps we need a keyctl() syscall... long keyctl(KEYCTL_NEW, keyid_t keyring, char *type, char *desc, void *payload); long keyctl(KEYCTL_UPDATE, keyid_t key, char *type, void *desc, void *payload); long keyctl(KEYCTL_LINK, keyid_t keyring, keyid_t key); long keyctl(KEYCTL_UNLINK, keyid_t keyring, keyid_t key); long keyctl(KEYCTL_CLEAR, keyid_t keyring); long keyctl(KEYCTL_REVOKE, keyid_t key); long keyctl(KEYCTL_FIND, keyid_t keyring, char *type, char *desc); Some prctls()... long prctl(PR_GET_KEYID, keyid_t keyring); long prctl(PR_NEW_SESSION_KEYRING); 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 New rlimits: RLIMIT_KEYS - Amount of memory consumed by a user's keys. And a new filesystem in which extant keys (including keyrings) can be viewed to a greater or a lesser extent. > 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? > As for the first two operations, looking up key-rings, we could just add a > hard-link or soft-link /proc//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. 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. David - 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/