Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S264035AbTEOODY (ORCPT ); Thu, 15 May 2003 10:03:24 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S264036AbTEOODY (ORCPT ); Thu, 15 May 2003 10:03:24 -0400 Received: from pub237.cambridge.redhat.com ([213.86.99.237]:15831 "EHLO warthog.warthog") by vger.kernel.org with ESMTP id S264035AbTEOODO (ORCPT ); Thu, 15 May 2003 10:03:14 -0400 From: David Howells To: Linus Torvalds cc: David Howells , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, openafs-devel@openafs.org Subject: Alternative to PAGs User-Agent: EMH/1.14.1 SEMI/1.14.4 (Hosorogi) FLIM/1.14.4 (=?ISO-8859-4?Q?Kashiharajing=FE-mae?=) APEL/10.4 Emacs/21.2 (i386-redhat-linux-gnu) MULE/5.0 (SAKAKI) MIME-Version: 1.0 (generated by SEMI 1.14.4 - "Hosorogi") Content-Type: text/plain; charset=US-ASCII Date: Thu, 15 May 2003 15:15:49 +0100 Message-ID: <6624.1053008149@warthog.warthog> Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4836 Lines: 155 Hi Linus, Okay, starting with a clean slate and writing PAGs off as a bad idea, how about trying to work out what is required first? As I see it: THE REQUIREMENTS ================ (1) Credentials/tokens/keys/whatever are held in a "keyring". (2) A keyring is destroyed when the last reference goes away (kernel resources are precious, though it may be possible to store credentials in swapspace somehow). (3) Every user has to have a default keyring that is created the first time they log in [Linus demands this]. (4) A user has to be able to override the default keyring, such that they can, for instance, perform operations on a remote filesystem with a different credential. (5) A user has to be able to run a program with a reduced set of credentials. (6) A process must be able to pass a subset of its credentials to a second, already running process so that the second process can perform some service on its behalf. This gets tricky if the service process is performing services for a number of processes simultaneously, each of which has its own set of credentials. (7) A process should be able to discard any credential it has access to, particularly in conjunction with (6). (8) It must be possible to withdraw a credential. (9) The credentials governing access to a file must be associated with a struct file, not with the process context currently accessing a file. (10) A struct file will gain its credentials at the time it is opened. POSSIBLE EXTENSIONS =================== (11) Threads should perhaps share a common set of credentials, but be able to adjust them on a per-thread basis (see (6)). (12) A SUID process should add the credentials it gains from its new user ID to those it inherited from its original context. (13) There's one place Win32 has an advantage, I think: calls for setting up handles (files, mutexes, etc) take security context parameters. I think "groups" specific keyrings and arbitrary joinable keyrings are superfluous (that's what ACLs are for) and a systems maintenance nightmare, so I haven't included them. SUGGESTED IMPLEMENTATION ======================== As far as implementation goes, perhaps each task_struct and each file should point to a stack of keyrings: +------+ | | +--------------------->| USER | | | | | +------+ | +------+ +------+ +------+ +------+ | | | | | | | | | TASK |----->| SUID |---->| PRIV |---->| USER | | | | | | | | | +------+ +------+ +------+ +------+ ^ ^ +------+ | | | | | | | FILE |---------+ | | | | +------+ | | +------+ | | | | | FILE |----------------------+ | | ^ +------+ | | +------+ +------+ +------+ | | | | | | | TASK |----->| FILE |----------------->| USER | | | | | | | +------+ +------+ +------+ The keyrings in the stack would then be refcounted, and the next pointers would be immutable. struct keyring { struct keyring *next; struct keyring *conjunction; struct list_head keys; atomic_t usage; int type; #define KEYRING_USER 0 #define KEYRING_PRIVATE 1 #define KEYRING_SUID 2 #define KEYRING_FD 3 }; struct key { struct list_head link; atomic_t usage; int type; #define KEY_POSITIVE 0 #define KEY_NEGATIVE 1 void *credential; }; And then add the following syscalls: (*) auth_clear_stack(int completely) Totally clear a process's stack (either completely or of everything but the user credentials). (*) auth_add_cred(const char *fs, const char *domain, void *data); Add a new credential to the TOS keyring. The key would be negative if data is NULL. (*) auth_push_empty() Push an empty keyring onto this process's stack. (*) auth_push_fdcreds(int fd) Push the credentials associated with fd onto the stack as a preferred alternative. (*) auth_pop() Pop the top credential off of the stack. 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/