2008-04-29 08:01:31 +00:00
|
|
|
/* Management of a process's keyrings
|
2005-04-16 22:20:36 +00:00
|
|
|
*
|
2008-04-29 08:01:31 +00:00
|
|
|
* Copyright (C) 2004-2005, 2008 Red Hat, Inc. All Rights Reserved.
|
2005-04-16 22:20:36 +00:00
|
|
|
* Written by David Howells (dhowells@redhat.com)
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version
|
|
|
|
* 2 of the License, or (at your option) any later version.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/sched.h>
|
|
|
|
#include <linux/slab.h>
|
|
|
|
#include <linux/keyctl.h>
|
|
|
|
#include <linux/fs.h>
|
|
|
|
#include <linux/err.h>
|
2006-03-22 08:09:14 +00:00
|
|
|
#include <linux/mutex.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <asm/uaccess.h>
|
|
|
|
#include "internal.h"
|
|
|
|
|
|
|
|
/* session keyring create vs join semaphore */
|
2006-03-22 08:09:14 +00:00
|
|
|
static DEFINE_MUTEX(key_session_mutex);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-04-29 08:01:31 +00:00
|
|
|
/* user keyring creation semaphore */
|
|
|
|
static DEFINE_MUTEX(key_user_keyring_mutex);
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* the root user's tracking struct */
|
|
|
|
struct key_user root_key_user = {
|
|
|
|
.usage = ATOMIC_INIT(3),
|
2007-10-17 06:29:46 +00:00
|
|
|
.cons_lock = __MUTEX_INITIALIZER(root_key_user.cons_lock),
|
2006-12-07 04:37:22 +00:00
|
|
|
.lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock),
|
2005-04-16 22:20:36 +00:00
|
|
|
.nkeys = ATOMIC_INIT(2),
|
|
|
|
.nikeys = ATOMIC_INIT(2),
|
|
|
|
.uid = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
2008-04-29 08:01:31 +00:00
|
|
|
* install user and user session keyrings for a particular UID
|
2005-04-16 22:20:36 +00:00
|
|
|
*/
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
int install_user_keyrings(void)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
2008-11-13 23:39:16 +00:00
|
|
|
struct user_struct *user = current->cred->user;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct key *uid_keyring, *session_keyring;
|
|
|
|
char buf[20];
|
|
|
|
int ret;
|
|
|
|
|
2008-04-29 08:01:31 +00:00
|
|
|
kenter("%p{%u}", user, user->uid);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-04-29 08:01:31 +00:00
|
|
|
if (user->uid_keyring) {
|
|
|
|
kleave(" = 0 [exist]");
|
|
|
|
return 0;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2008-04-29 08:01:31 +00:00
|
|
|
mutex_lock(&key_user_keyring_mutex);
|
|
|
|
ret = 0;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-04-29 08:01:31 +00:00
|
|
|
if (!user->uid_keyring) {
|
|
|
|
/* get the UID-specific keyring
|
|
|
|
* - there may be one in existence already as it may have been
|
|
|
|
* pinned by a session, but the user_struct pointing to it
|
|
|
|
* may have been destroyed by setuid */
|
|
|
|
sprintf(buf, "_uid.%u", user->uid);
|
|
|
|
|
|
|
|
uid_keyring = find_keyring_by_name(buf, true);
|
|
|
|
if (IS_ERR(uid_keyring)) {
|
|
|
|
uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1,
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
current, KEY_ALLOC_IN_QUOTA,
|
2008-04-29 08:01:31 +00:00
|
|
|
NULL);
|
|
|
|
if (IS_ERR(uid_keyring)) {
|
|
|
|
ret = PTR_ERR(uid_keyring);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get a default session keyring (which might also exist
|
|
|
|
* already) */
|
|
|
|
sprintf(buf, "_uid_ses.%u", user->uid);
|
|
|
|
|
|
|
|
session_keyring = find_keyring_by_name(buf, true);
|
|
|
|
if (IS_ERR(session_keyring)) {
|
|
|
|
session_keyring =
|
|
|
|
keyring_alloc(buf, user->uid, (gid_t) -1,
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
current, KEY_ALLOC_IN_QUOTA,
|
|
|
|
NULL);
|
2008-04-29 08:01:31 +00:00
|
|
|
if (IS_ERR(session_keyring)) {
|
|
|
|
ret = PTR_ERR(session_keyring);
|
|
|
|
goto error_release;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we install a link from the user session keyring to
|
|
|
|
* the user keyring */
|
|
|
|
ret = key_link(session_keyring, uid_keyring);
|
|
|
|
if (ret < 0)
|
|
|
|
goto error_release_both;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* install the keyrings */
|
|
|
|
user->uid_keyring = uid_keyring;
|
|
|
|
user->session_keyring = session_keyring;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2008-04-29 08:01:31 +00:00
|
|
|
mutex_unlock(&key_user_keyring_mutex);
|
|
|
|
kleave(" = 0");
|
|
|
|
return 0;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-04-29 08:01:31 +00:00
|
|
|
error_release_both:
|
|
|
|
key_put(session_keyring);
|
|
|
|
error_release:
|
|
|
|
key_put(uid_keyring);
|
2005-09-28 16:03:15 +00:00
|
|
|
error:
|
2008-04-29 08:01:31 +00:00
|
|
|
mutex_unlock(&key_user_keyring_mutex);
|
|
|
|
kleave(" = %d", ret);
|
2005-04-16 22:20:36 +00:00
|
|
|
return ret;
|
2008-04-29 08:01:31 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* deal with the UID changing
|
|
|
|
*/
|
|
|
|
void switch_uid_keyring(struct user_struct *new_user)
|
|
|
|
{
|
|
|
|
#if 0 /* do nothing for now */
|
|
|
|
struct key *old;
|
|
|
|
|
|
|
|
/* switch to the new user's session keyring if we were running under
|
|
|
|
* root's default session keyring */
|
|
|
|
if (new_user->uid != 0 &&
|
|
|
|
current->session_keyring == &root_session_keyring
|
|
|
|
) {
|
|
|
|
atomic_inc(&new_user->session_keyring->usage);
|
|
|
|
|
|
|
|
task_lock(current);
|
|
|
|
old = current->session_keyring;
|
|
|
|
current->session_keyring = new_user->session_keyring;
|
|
|
|
task_unlock(current);
|
|
|
|
|
|
|
|
key_put(old);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
} /* end switch_uid_keyring() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* install a fresh thread keyring, discarding the old one
|
|
|
|
*/
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
int install_thread_keyring(void)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
struct task_struct *tsk = current;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct key *keyring, *old;
|
|
|
|
char buf[20];
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
sprintf(buf, "_tid.%u", tsk->pid);
|
|
|
|
|
2008-11-13 23:39:16 +00:00
|
|
|
keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, tsk,
|
2006-06-26 07:24:50 +00:00
|
|
|
KEY_ALLOC_QUOTA_OVERRUN, NULL);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (IS_ERR(keyring)) {
|
|
|
|
ret = PTR_ERR(keyring);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
task_lock(tsk);
|
2008-11-13 23:39:16 +00:00
|
|
|
old = tsk->cred->thread_keyring;
|
|
|
|
tsk->cred->thread_keyring = keyring;
|
2005-04-16 22:20:36 +00:00
|
|
|
task_unlock(tsk);
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
key_put(old);
|
2005-09-28 16:03:15 +00:00
|
|
|
error:
|
2005-04-16 22:20:36 +00:00
|
|
|
return ret;
|
|
|
|
|
|
|
|
} /* end install_thread_keyring() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* make sure a process keyring is installed
|
|
|
|
*/
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
int install_process_keyring(void)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
struct task_struct *tsk = current;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct key *keyring;
|
|
|
|
char buf[20];
|
|
|
|
int ret;
|
|
|
|
|
2006-04-11 05:54:26 +00:00
|
|
|
might_sleep();
|
|
|
|
|
2008-11-13 23:39:20 +00:00
|
|
|
if (!tsk->cred->tgcred->process_keyring) {
|
2005-04-16 22:20:36 +00:00
|
|
|
sprintf(buf, "_pid.%u", tsk->tgid);
|
|
|
|
|
2008-11-13 23:39:16 +00:00
|
|
|
keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid, tsk,
|
2006-06-26 07:24:50 +00:00
|
|
|
KEY_ALLOC_QUOTA_OVERRUN, NULL);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (IS_ERR(keyring)) {
|
|
|
|
ret = PTR_ERR(keyring);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2005-06-24 05:00:53 +00:00
|
|
|
/* attach keyring */
|
2008-11-13 23:39:20 +00:00
|
|
|
spin_lock_irq(&tsk->cred->tgcred->lock);
|
|
|
|
if (!tsk->cred->tgcred->process_keyring) {
|
|
|
|
tsk->cred->tgcred->process_keyring = keyring;
|
2005-04-16 22:20:36 +00:00
|
|
|
keyring = NULL;
|
|
|
|
}
|
2008-11-13 23:39:20 +00:00
|
|
|
spin_unlock_irq(&tsk->cred->tgcred->lock);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
key_put(keyring);
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
2005-09-28 16:03:15 +00:00
|
|
|
error:
|
2005-04-16 22:20:36 +00:00
|
|
|
return ret;
|
|
|
|
|
|
|
|
} /* end install_process_keyring() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* install a session keyring, discarding the old one
|
|
|
|
* - if a keyring is not supplied, an empty one is invented
|
|
|
|
*/
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
static int install_session_keyring(struct key *keyring)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
struct task_struct *tsk = current;
|
2006-06-26 07:24:50 +00:00
|
|
|
unsigned long flags;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct key *old;
|
|
|
|
char buf[20];
|
2006-04-11 05:54:26 +00:00
|
|
|
|
|
|
|
might_sleep();
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* create an empty session keyring */
|
|
|
|
if (!keyring) {
|
|
|
|
sprintf(buf, "_ses.%u", tsk->tgid);
|
|
|
|
|
2006-06-26 07:24:50 +00:00
|
|
|
flags = KEY_ALLOC_QUOTA_OVERRUN;
|
2008-11-13 23:39:20 +00:00
|
|
|
if (tsk->cred->tgcred->session_keyring)
|
2006-06-26 07:24:50 +00:00
|
|
|
flags = KEY_ALLOC_IN_QUOTA;
|
|
|
|
|
2008-11-13 23:39:20 +00:00
|
|
|
keyring = keyring_alloc(buf, tsk->cred->uid, tsk->cred->gid,
|
|
|
|
tsk, flags, NULL);
|
2006-04-11 05:54:26 +00:00
|
|
|
if (IS_ERR(keyring))
|
|
|
|
return PTR_ERR(keyring);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
atomic_inc(&keyring->usage);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* install the keyring */
|
2008-11-13 23:39:20 +00:00
|
|
|
spin_lock_irq(&tsk->cred->tgcred->lock);
|
|
|
|
old = tsk->cred->tgcred->session_keyring;
|
|
|
|
rcu_assign_pointer(tsk->cred->tgcred->session_keyring, keyring);
|
|
|
|
spin_unlock_irq(&tsk->cred->tgcred->lock);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-04-11 05:54:26 +00:00
|
|
|
/* we're using RCU on the pointer, but there's no point synchronising
|
|
|
|
* on it if it didn't previously point to anything */
|
|
|
|
if (old) {
|
|
|
|
synchronize_rcu();
|
|
|
|
key_put(old);
|
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-04-11 05:54:26 +00:00
|
|
|
return 0;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
} /* end install_session_keyring() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* copy the keys for fork
|
|
|
|
*/
|
|
|
|
int copy_keys(unsigned long clone_flags, struct task_struct *tsk)
|
|
|
|
{
|
2008-11-13 23:39:16 +00:00
|
|
|
key_check(tsk->cred->thread_keyring);
|
|
|
|
key_check(tsk->cred->request_key_auth);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* no thread keyring yet */
|
2008-11-13 23:39:16 +00:00
|
|
|
tsk->cred->thread_keyring = NULL;
|
2006-01-08 09:02:47 +00:00
|
|
|
|
|
|
|
/* copy the request_key() authorisation for this thread */
|
2008-11-13 23:39:16 +00:00
|
|
|
key_get(tsk->cred->request_key_auth);
|
2006-01-08 09:02:47 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
} /* end copy_keys() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
2006-01-08 09:02:47 +00:00
|
|
|
* dispose of per-thread keys upon thread exit
|
2005-04-16 22:20:36 +00:00
|
|
|
*/
|
|
|
|
void exit_keys(struct task_struct *tsk)
|
|
|
|
{
|
2008-11-13 23:39:16 +00:00
|
|
|
key_put(tsk->cred->thread_keyring);
|
|
|
|
key_put(tsk->cred->request_key_auth);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
} /* end exit_keys() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* deal with execve()
|
|
|
|
*/
|
|
|
|
int exec_keys(struct task_struct *tsk)
|
|
|
|
{
|
|
|
|
struct key *old;
|
|
|
|
|
|
|
|
/* newly exec'd tasks don't get a thread keyring */
|
|
|
|
task_lock(tsk);
|
2008-11-13 23:39:16 +00:00
|
|
|
old = tsk->cred->thread_keyring;
|
|
|
|
tsk->cred->thread_keyring = NULL;
|
2005-04-16 22:20:36 +00:00
|
|
|
task_unlock(tsk);
|
|
|
|
|
|
|
|
key_put(old);
|
|
|
|
|
|
|
|
/* discard the process keyring from a newly exec'd task */
|
2008-11-13 23:39:20 +00:00
|
|
|
spin_lock_irq(&tsk->cred->tgcred->lock);
|
|
|
|
old = tsk->cred->tgcred->process_keyring;
|
|
|
|
tsk->cred->tgcred->process_keyring = NULL;
|
|
|
|
spin_unlock_irq(&tsk->cred->tgcred->lock);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
key_put(old);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
} /* end exec_keys() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* deal with SUID programs
|
|
|
|
* - we might want to make this invent a new session keyring
|
|
|
|
*/
|
|
|
|
int suid_keys(struct task_struct *tsk)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
} /* end suid_keys() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* the filesystem user ID changed
|
|
|
|
*/
|
|
|
|
void key_fsuid_changed(struct task_struct *tsk)
|
|
|
|
{
|
|
|
|
/* update the ownership of the thread keyring */
|
2008-11-13 23:39:16 +00:00
|
|
|
BUG_ON(!tsk->cred);
|
|
|
|
if (tsk->cred->thread_keyring) {
|
|
|
|
down_write(&tsk->cred->thread_keyring->sem);
|
|
|
|
tsk->cred->thread_keyring->uid = tsk->cred->fsuid;
|
|
|
|
up_write(&tsk->cred->thread_keyring->sem);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} /* end key_fsuid_changed() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* the filesystem group ID changed
|
|
|
|
*/
|
|
|
|
void key_fsgid_changed(struct task_struct *tsk)
|
|
|
|
{
|
|
|
|
/* update the ownership of the thread keyring */
|
2008-11-13 23:39:16 +00:00
|
|
|
BUG_ON(!tsk->cred);
|
|
|
|
if (tsk->cred->thread_keyring) {
|
|
|
|
down_write(&tsk->cred->thread_keyring->sem);
|
|
|
|
tsk->cred->thread_keyring->gid = tsk->cred->fsgid;
|
|
|
|
up_write(&tsk->cred->thread_keyring->sem);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} /* end key_fsgid_changed() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* search the process keyrings for the first matching key
|
|
|
|
* - we use the supplied match function to see if the description (or other
|
|
|
|
* feature of interest) matches
|
|
|
|
* - we return -EAGAIN if we didn't find any matching key
|
|
|
|
* - we return -ENOKEY if we found only negative matching keys
|
|
|
|
*/
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref_t search_process_keyrings(struct key_type *type,
|
|
|
|
const void *description,
|
|
|
|
key_match_func_t match,
|
|
|
|
struct task_struct *context)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
struct request_key_auth *rka;
|
2008-11-13 23:39:19 +00:00
|
|
|
struct cred *cred;
|
2006-01-08 09:02:47 +00:00
|
|
|
key_ref_t key_ref, ret, err;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2006-06-22 21:47:18 +00:00
|
|
|
might_sleep();
|
|
|
|
|
2008-11-13 23:39:19 +00:00
|
|
|
cred = get_task_cred(context);
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/* we want to return -EAGAIN or -ENOKEY if any of the keyrings were
|
|
|
|
* searchable, but we failed to find a key or we found a negative key;
|
|
|
|
* otherwise we want to return a sample error (probably -EACCES) if
|
|
|
|
* none of the keyrings were searchable
|
|
|
|
*
|
|
|
|
* in terms of priority: success > -ENOKEY > -EAGAIN > other error
|
|
|
|
*/
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = NULL;
|
2005-04-16 22:20:36 +00:00
|
|
|
ret = NULL;
|
|
|
|
err = ERR_PTR(-EAGAIN);
|
|
|
|
|
|
|
|
/* search the thread keyring first */
|
2008-11-13 23:39:19 +00:00
|
|
|
if (cred->thread_keyring) {
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = keyring_search_aux(
|
2008-11-13 23:39:19 +00:00
|
|
|
make_key_ref(cred->thread_keyring, 1),
|
2005-09-28 16:03:15 +00:00
|
|
|
context, type, description, match);
|
|
|
|
if (!IS_ERR(key_ref))
|
2005-04-16 22:20:36 +00:00
|
|
|
goto found;
|
|
|
|
|
2005-09-28 16:03:15 +00:00
|
|
|
switch (PTR_ERR(key_ref)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
case -EAGAIN: /* no key */
|
|
|
|
if (ret)
|
|
|
|
break;
|
|
|
|
case -ENOKEY: /* negative key */
|
2005-09-28 16:03:15 +00:00
|
|
|
ret = key_ref;
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
default:
|
2005-09-28 16:03:15 +00:00
|
|
|
err = key_ref;
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* search the process keyring second */
|
2008-11-13 23:39:20 +00:00
|
|
|
if (cred->tgcred->process_keyring) {
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = keyring_search_aux(
|
2008-11-13 23:39:20 +00:00
|
|
|
make_key_ref(cred->tgcred->process_keyring, 1),
|
2005-09-28 16:03:15 +00:00
|
|
|
context, type, description, match);
|
|
|
|
if (!IS_ERR(key_ref))
|
2005-04-16 22:20:36 +00:00
|
|
|
goto found;
|
|
|
|
|
2005-09-28 16:03:15 +00:00
|
|
|
switch (PTR_ERR(key_ref)) {
|
2005-04-16 22:20:36 +00:00
|
|
|
case -EAGAIN: /* no key */
|
|
|
|
if (ret)
|
|
|
|
break;
|
|
|
|
case -ENOKEY: /* negative key */
|
2005-09-28 16:03:15 +00:00
|
|
|
ret = key_ref;
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
default:
|
2005-09-28 16:03:15 +00:00
|
|
|
err = key_ref;
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
/* search the session keyring */
|
2008-11-13 23:39:20 +00:00
|
|
|
if (cred->tgcred->session_keyring) {
|
2005-06-24 05:00:53 +00:00
|
|
|
rcu_read_lock();
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = keyring_search_aux(
|
|
|
|
make_key_ref(rcu_dereference(
|
2008-11-13 23:39:20 +00:00
|
|
|
cred->tgcred->session_keyring),
|
2005-09-28 16:03:15 +00:00
|
|
|
1),
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
context, type, description, match);
|
2005-06-24 05:00:53 +00:00
|
|
|
rcu_read_unlock();
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
|
2005-09-28 16:03:15 +00:00
|
|
|
if (!IS_ERR(key_ref))
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
goto found;
|
|
|
|
|
2005-09-28 16:03:15 +00:00
|
|
|
switch (PTR_ERR(key_ref)) {
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
case -EAGAIN: /* no key */
|
|
|
|
if (ret)
|
|
|
|
break;
|
|
|
|
case -ENOKEY: /* negative key */
|
2005-09-28 16:03:15 +00:00
|
|
|
ret = key_ref;
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
break;
|
|
|
|
default:
|
2005-09-28 16:03:15 +00:00
|
|
|
err = key_ref;
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-01-08 09:02:47 +00:00
|
|
|
}
|
|
|
|
/* or search the user-session keyring */
|
2008-11-13 23:39:19 +00:00
|
|
|
else if (cred->user->session_keyring) {
|
2006-01-08 09:02:47 +00:00
|
|
|
key_ref = keyring_search_aux(
|
2008-11-13 23:39:19 +00:00
|
|
|
make_key_ref(cred->user->session_keyring, 1),
|
2006-01-08 09:02:47 +00:00
|
|
|
context, type, description, match);
|
2005-09-28 16:03:15 +00:00
|
|
|
if (!IS_ERR(key_ref))
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
goto found;
|
|
|
|
|
2005-09-28 16:03:15 +00:00
|
|
|
switch (PTR_ERR(key_ref)) {
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
case -EAGAIN: /* no key */
|
|
|
|
if (ret)
|
|
|
|
break;
|
|
|
|
case -ENOKEY: /* negative key */
|
2005-09-28 16:03:15 +00:00
|
|
|
ret = key_ref;
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
break;
|
|
|
|
default:
|
2005-09-28 16:03:15 +00:00
|
|
|
err = key_ref;
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
break;
|
|
|
|
}
|
2005-06-24 05:00:53 +00:00
|
|
|
}
|
2006-01-08 09:02:47 +00:00
|
|
|
|
|
|
|
/* if this process has an instantiation authorisation key, then we also
|
|
|
|
* search the keyrings of the process mentioned there
|
|
|
|
* - we don't permit access to request_key auth keys via this method
|
|
|
|
*/
|
2008-11-13 23:39:19 +00:00
|
|
|
if (cred->request_key_auth &&
|
2006-01-08 09:02:47 +00:00
|
|
|
context == current &&
|
2006-06-22 21:47:18 +00:00
|
|
|
type != &key_type_request_key_auth
|
2006-01-08 09:02:47 +00:00
|
|
|
) {
|
2006-06-22 21:47:18 +00:00
|
|
|
/* defend against the auth key being revoked */
|
2008-11-13 23:39:19 +00:00
|
|
|
down_read(&cred->request_key_auth->sem);
|
2006-01-08 09:02:47 +00:00
|
|
|
|
2008-11-13 23:39:19 +00:00
|
|
|
if (key_validate(cred->request_key_auth) == 0) {
|
|
|
|
rka = cred->request_key_auth->payload.data;
|
2006-01-08 09:02:47 +00:00
|
|
|
|
2006-06-22 21:47:18 +00:00
|
|
|
key_ref = search_process_keyrings(type, description,
|
|
|
|
match, rka->context);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-11-13 23:39:19 +00:00
|
|
|
up_read(&cred->request_key_auth->sem);
|
2006-06-22 21:47:18 +00:00
|
|
|
|
|
|
|
if (!IS_ERR(key_ref))
|
|
|
|
goto found;
|
|
|
|
|
|
|
|
switch (PTR_ERR(key_ref)) {
|
|
|
|
case -EAGAIN: /* no key */
|
|
|
|
if (ret)
|
|
|
|
break;
|
|
|
|
case -ENOKEY: /* negative key */
|
|
|
|
ret = key_ref;
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
break;
|
2006-06-22 21:47:18 +00:00
|
|
|
default:
|
|
|
|
err = key_ref;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
2008-11-13 23:39:19 +00:00
|
|
|
up_read(&cred->request_key_auth->sem);
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
}
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* no key - decide on the error we're going to go for */
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = ret ? ret : err;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
found:
|
2008-11-13 23:39:19 +00:00
|
|
|
put_cred(cred);
|
2005-09-28 16:03:15 +00:00
|
|
|
return key_ref;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
} /* end search_process_keyrings() */
|
|
|
|
|
2005-09-28 16:03:15 +00:00
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* see if the key we're looking at is the target key
|
|
|
|
*/
|
|
|
|
static int lookup_user_key_possessed(const struct key *key, const void *target)
|
|
|
|
{
|
|
|
|
return key == target;
|
|
|
|
|
|
|
|
} /* end lookup_user_key_possessed() */
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* lookup a key given a key ID from userspace with a given permissions mask
|
|
|
|
* - don't create special keyrings unless so requested
|
|
|
|
* - partially constructed keys aren't found unless requested
|
|
|
|
*/
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
key_ref_t lookup_user_key(key_serial_t id, int create, int partial,
|
|
|
|
key_perm_t perm)
|
2005-04-16 22:20:36 +00:00
|
|
|
{
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
struct request_key_auth *rka;
|
|
|
|
struct task_struct *t = current;
|
2008-11-13 23:39:20 +00:00
|
|
|
struct cred *cred;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct key *key;
|
2008-11-13 23:39:16 +00:00
|
|
|
key_ref_t key_ref, skey_ref;
|
2005-04-16 22:20:36 +00:00
|
|
|
int ret;
|
|
|
|
|
2008-11-13 23:39:20 +00:00
|
|
|
try_again:
|
|
|
|
cred = get_current_cred();
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = ERR_PTR(-ENOKEY);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
switch (id) {
|
|
|
|
case KEY_SPEC_THREAD_KEYRING:
|
2008-11-13 23:39:16 +00:00
|
|
|
if (!cred->thread_keyring) {
|
2005-04-16 22:20:36 +00:00
|
|
|
if (!create)
|
|
|
|
goto error;
|
|
|
|
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
ret = install_thread_keyring();
|
2005-04-16 22:20:36 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
key = ERR_PTR(ret);
|
|
|
|
goto error;
|
|
|
|
}
|
2008-11-13 23:39:20 +00:00
|
|
|
goto reget_creds;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2008-11-13 23:39:16 +00:00
|
|
|
key = cred->thread_keyring;
|
2005-04-16 22:20:36 +00:00
|
|
|
atomic_inc(&key->usage);
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = make_key_ref(key, 1);
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_SPEC_PROCESS_KEYRING:
|
2008-11-13 23:39:20 +00:00
|
|
|
if (!cred->tgcred->process_keyring) {
|
2005-04-16 22:20:36 +00:00
|
|
|
if (!create)
|
|
|
|
goto error;
|
|
|
|
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
ret = install_process_keyring();
|
2005-04-16 22:20:36 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
key = ERR_PTR(ret);
|
|
|
|
goto error;
|
|
|
|
}
|
2008-11-13 23:39:20 +00:00
|
|
|
goto reget_creds;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
2008-11-13 23:39:20 +00:00
|
|
|
key = cred->tgcred->process_keyring;
|
2005-04-16 22:20:36 +00:00
|
|
|
atomic_inc(&key->usage);
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = make_key_ref(key, 1);
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_SPEC_SESSION_KEYRING:
|
2008-11-13 23:39:20 +00:00
|
|
|
if (!cred->tgcred->session_keyring) {
|
2005-04-16 22:20:36 +00:00
|
|
|
/* always install a session keyring upon access if one
|
|
|
|
* doesn't exist yet */
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
ret = install_user_keyrings();
|
2008-04-29 08:01:31 +00:00
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
2008-11-13 23:39:16 +00:00
|
|
|
ret = install_session_keyring(
|
|
|
|
cred->user->session_keyring);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
2008-11-13 23:39:20 +00:00
|
|
|
goto reget_creds;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
rcu_read_lock();
|
2008-11-13 23:39:20 +00:00
|
|
|
key = rcu_dereference(cred->tgcred->session_keyring);
|
2005-04-16 22:20:36 +00:00
|
|
|
atomic_inc(&key->usage);
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
rcu_read_unlock();
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = make_key_ref(key, 1);
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_SPEC_USER_KEYRING:
|
2008-11-13 23:39:16 +00:00
|
|
|
if (!cred->user->uid_keyring) {
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
ret = install_user_keyrings();
|
2008-04-29 08:01:31 +00:00
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2008-11-13 23:39:16 +00:00
|
|
|
key = cred->user->uid_keyring;
|
2005-04-16 22:20:36 +00:00
|
|
|
atomic_inc(&key->usage);
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = make_key_ref(key, 1);
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_SPEC_USER_SESSION_KEYRING:
|
2008-11-13 23:39:16 +00:00
|
|
|
if (!cred->user->session_keyring) {
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
ret = install_user_keyrings();
|
2008-04-29 08:01:31 +00:00
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2008-11-13 23:39:16 +00:00
|
|
|
key = cred->user->session_keyring;
|
2005-04-16 22:20:36 +00:00
|
|
|
atomic_inc(&key->usage);
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = make_key_ref(key, 1);
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case KEY_SPEC_GROUP_KEYRING:
|
|
|
|
/* group keyrings are not yet supported */
|
|
|
|
key = ERR_PTR(-EINVAL);
|
|
|
|
goto error;
|
|
|
|
|
2006-01-08 09:02:47 +00:00
|
|
|
case KEY_SPEC_REQKEY_AUTH_KEY:
|
2008-11-13 23:39:16 +00:00
|
|
|
key = cred->request_key_auth;
|
2006-01-08 09:02:47 +00:00
|
|
|
if (!key)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
atomic_inc(&key->usage);
|
|
|
|
key_ref = make_key_ref(key, 1);
|
|
|
|
break;
|
|
|
|
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
case KEY_SPEC_REQUESTOR_KEYRING:
|
2008-11-13 23:39:16 +00:00
|
|
|
if (!cred->request_key_auth)
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
goto error;
|
|
|
|
|
2008-11-13 23:39:16 +00:00
|
|
|
down_read(&cred->request_key_auth->sem);
|
|
|
|
if (cred->request_key_auth->flags & KEY_FLAG_REVOKED) {
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
key_ref = ERR_PTR(-EKEYREVOKED);
|
|
|
|
key = NULL;
|
|
|
|
} else {
|
2008-11-13 23:39:16 +00:00
|
|
|
rka = cred->request_key_auth->payload.data;
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
key = rka->dest_keyring;
|
|
|
|
atomic_inc(&key->usage);
|
|
|
|
}
|
2008-11-13 23:39:16 +00:00
|
|
|
up_read(&cred->request_key_auth->sem);
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
if (!key)
|
|
|
|
goto error;
|
|
|
|
key_ref = make_key_ref(key, 1);
|
|
|
|
break;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
default:
|
2005-09-28 16:03:15 +00:00
|
|
|
key_ref = ERR_PTR(-EINVAL);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (id < 1)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
key = key_lookup(id);
|
2005-09-28 16:03:15 +00:00
|
|
|
if (IS_ERR(key)) {
|
2008-02-07 08:15:26 +00:00
|
|
|
key_ref = ERR_CAST(key);
|
2005-04-16 22:20:36 +00:00
|
|
|
goto error;
|
2005-09-28 16:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
key_ref = make_key_ref(key, 0);
|
|
|
|
|
|
|
|
/* check to see if we possess the key */
|
|
|
|
skey_ref = search_process_keyrings(key->type, key,
|
|
|
|
lookup_user_key_possessed,
|
|
|
|
current);
|
|
|
|
|
|
|
|
if (!IS_ERR(skey_ref)) {
|
|
|
|
key_put(key);
|
|
|
|
key_ref = skey_ref;
|
|
|
|
}
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2007-10-17 06:29:46 +00:00
|
|
|
if (!partial) {
|
|
|
|
ret = wait_for_key_construction(key, true);
|
|
|
|
switch (ret) {
|
|
|
|
case -ERESTARTSYS:
|
|
|
|
goto invalid_key;
|
|
|
|
default:
|
|
|
|
if (perm)
|
|
|
|
goto invalid_key;
|
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else if (perm) {
|
2005-04-16 22:20:36 +00:00
|
|
|
ret = key_validate(key);
|
|
|
|
if (ret < 0)
|
|
|
|
goto invalid_key;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = -EIO;
|
2005-06-24 05:00:49 +00:00
|
|
|
if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
|
2005-04-16 22:20:36 +00:00
|
|
|
goto invalid_key;
|
|
|
|
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
/* check the permissions */
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
ret = key_task_permission(key_ref, t, perm);
|
2005-10-30 23:02:44 +00:00
|
|
|
if (ret < 0)
|
2005-04-16 22:20:36 +00:00
|
|
|
goto invalid_key;
|
|
|
|
|
2005-09-28 16:03:15 +00:00
|
|
|
error:
|
2008-11-13 23:39:20 +00:00
|
|
|
put_cred(cred);
|
2005-09-28 16:03:15 +00:00
|
|
|
return key_ref;
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2005-09-28 16:03:15 +00:00
|
|
|
invalid_key:
|
|
|
|
key_ref_put(key_ref);
|
|
|
|
key_ref = ERR_PTR(ret);
|
2005-04-16 22:20:36 +00:00
|
|
|
goto error;
|
|
|
|
|
2008-11-13 23:39:20 +00:00
|
|
|
/* if we attempted to install a keyring, then it may have caused new
|
|
|
|
* creds to be installed */
|
|
|
|
reget_creds:
|
|
|
|
put_cred(cred);
|
|
|
|
goto try_again;
|
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
} /* end lookup_user_key() */
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
/*
|
|
|
|
* join the named keyring as the session keyring if possible, or attempt to
|
|
|
|
* create a new one of that name if not
|
|
|
|
* - if the name is NULL, an empty anonymous keyring is installed instead
|
|
|
|
* - named session keyring joining is done with a semaphore held
|
|
|
|
*/
|
|
|
|
long join_session_keyring(const char *name)
|
|
|
|
{
|
|
|
|
struct task_struct *tsk = current;
|
2008-11-13 23:39:20 +00:00
|
|
|
struct cred *cred = current->cred;
|
2005-04-16 22:20:36 +00:00
|
|
|
struct key *keyring;
|
|
|
|
long ret;
|
|
|
|
|
|
|
|
/* if no name is provided, install an anonymous keyring */
|
|
|
|
if (!name) {
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
ret = install_session_keyring(NULL);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
rcu_read_lock();
|
2008-11-13 23:39:20 +00:00
|
|
|
ret = rcu_dereference(cred->tgcred->session_keyring)->serial;
|
[PATCH] Keys: Make request-key create an authorisation key
The attached patch makes the following changes:
(1) There's a new special key type called ".request_key_auth".
This is an authorisation key for when one process requests a key and
another process is started to construct it. This type of key cannot be
created by the user; nor can it be requested by kernel services.
Authorisation keys hold two references:
(a) Each refers to a key being constructed. When the key being
constructed is instantiated the authorisation key is revoked,
rendering it of no further use.
(b) The "authorising process". This is either:
(i) the process that called request_key(), or:
(ii) if the process that called request_key() itself had an
authorisation key in its session keyring, then the authorising
process referred to by that authorisation key will also be
referred to by the new authorisation key.
This means that the process that initiated a chain of key requests
will authorise the lot of them, and will, by default, wind up with
the keys obtained from them in its keyrings.
(2) request_key() creates an authorisation key which is then passed to
/sbin/request-key in as part of a new session keyring.
(3) When request_key() is searching for a key to hand back to the caller, if
it comes across an authorisation key in the session keyring of the
calling process, it will also search the keyrings of the process
specified therein and it will use the specified process's credentials
(fsuid, fsgid, groups) to do that rather than the calling process's
credentials.
This allows a process started by /sbin/request-key to find keys belonging
to the authorising process.
(4) A key can be read, even if the process executing KEYCTL_READ doesn't have
direct read or search permission if that key is contained within the
keyrings of a process specified by an authorisation key found within the
calling process's session keyring, and is searchable using the
credentials of the authorising process.
This allows a process started by /sbin/request-key to read keys belonging
to the authorising process.
(5) The magic KEY_SPEC_*_KEYRING key IDs when passed to KEYCTL_INSTANTIATE or
KEYCTL_NEGATE will specify a keyring of the authorising process, rather
than the process doing the instantiation.
(6) One of the process keyrings can be nominated as the default to which
request_key() should attach new keys if not otherwise specified. This is
done with KEYCTL_SET_REQKEY_KEYRING and one of the KEY_REQKEY_DEFL_*
constants. The current setting can also be read using this call.
(7) request_key() is partially interruptible. If it is waiting for another
process to finish constructing a key, it can be interrupted. This permits
a request-key cycle to be broken without recourse to rebooting.
Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-Off-By: Benoit Boissinot <benoit.boissinot@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-24 05:00:56 +00:00
|
|
|
rcu_read_unlock();
|
2005-04-16 22:20:36 +00:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* allow the user to join or create a named keyring */
|
2006-03-22 08:09:14 +00:00
|
|
|
mutex_lock(&key_session_mutex);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
/* look for an existing keyring of this name */
|
2008-04-29 08:01:31 +00:00
|
|
|
keyring = find_keyring_by_name(name, false);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (PTR_ERR(keyring) == -ENOKEY) {
|
|
|
|
/* not found - try and create a new one */
|
2008-11-13 23:39:20 +00:00
|
|
|
keyring = keyring_alloc(name, cred->uid, cred->gid, tsk,
|
2006-06-26 07:24:50 +00:00
|
|
|
KEY_ALLOC_IN_QUOTA, NULL);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (IS_ERR(keyring)) {
|
|
|
|
ret = PTR_ERR(keyring);
|
2005-08-04 20:07:06 +00:00
|
|
|
goto error2;
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (IS_ERR(keyring)) {
|
|
|
|
ret = PTR_ERR(keyring);
|
|
|
|
goto error2;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* we've got a keyring - now to install it */
|
KEYS: Alter use of key instantiation link-to-keyring argument
Alter the use of the key instantiation and negation functions' link-to-keyring
arguments. Currently this specifies a keyring in the target process to link
the key into, creating the keyring if it doesn't exist. This, however, can be
a problem for copy-on-write credentials as it means that the instantiating
process can alter the credentials of the requesting process.
This patch alters the behaviour such that:
(1) If keyctl_instantiate_key() or keyctl_negate_key() are given a specific
keyring by ID (ringid >= 0), then that keyring will be used.
(2) If keyctl_instantiate_key() or keyctl_negate_key() are given one of the
special constants that refer to the requesting process's keyrings
(KEY_SPEC_*_KEYRING, all <= 0), then:
(a) If sys_request_key() was given a keyring to use (destringid) then the
key will be attached to that keyring.
(b) If sys_request_key() was given a NULL keyring, then the key being
instantiated will be attached to the default keyring as set by
keyctl_set_reqkey_keyring().
(3) No extra link will be made.
Decision point (1) follows current behaviour, and allows those instantiators
who've searched for a specifically named keyring in the requestor's keyring so
as to partition the keys by type to still have their named keyrings.
Decision point (2) allows the requestor to make sure that the key or keys that
get produced by request_key() go where they want, whilst allowing the
instantiator to request that the key is retained. This is mainly useful for
situations where the instantiator makes a secondary request, the key for which
should be retained by the initial requestor:
+-----------+ +--------------+ +--------------+
| | | | | |
| Requestor |------->| Instantiator |------->| Instantiator |
| | | | | |
+-----------+ +--------------+ +--------------+
request_key() request_key()
This might be useful, for example, in Kerberos, where the requestor requests a
ticket, and then the ticket instantiator requests the TGT, which someone else
then has to go and fetch. The TGT, however, should be retained in the
keyrings of the requestor, not the first instantiator. To make this explict
an extra special keyring constant is also added.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: James Morris <jmorris@namei.org>
Signed-off-by: James Morris <jmorris@namei.org>
2008-11-13 23:39:14 +00:00
|
|
|
ret = install_session_keyring(keyring);
|
2005-04-16 22:20:36 +00:00
|
|
|
if (ret < 0)
|
|
|
|
goto error2;
|
|
|
|
|
|
|
|
ret = keyring->serial;
|
|
|
|
key_put(keyring);
|
|
|
|
|
2005-09-28 16:03:15 +00:00
|
|
|
error2:
|
2006-03-22 08:09:14 +00:00
|
|
|
mutex_unlock(&key_session_mutex);
|
2005-09-28 16:03:15 +00:00
|
|
|
error:
|
2005-04-16 22:20:36 +00:00
|
|
|
return ret;
|
|
|
|
|
|
|
|
} /* end join_session_keyring() */
|