/* key.c: basic authentication token and access key management
 *
 * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved.
 * 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/security.h>
#include <linux/workqueue.h>
#include <linux/err.h>
#include "internal.h"

static kmem_cache_t	*key_jar;
static key_serial_t	key_serial_next = 3;
struct rb_root		key_serial_tree; /* tree of keys indexed by serial */
DEFINE_SPINLOCK(key_serial_lock);

struct rb_root	key_user_tree; /* tree of quota records indexed by UID */
DEFINE_SPINLOCK(key_user_lock);

static LIST_HEAD(key_types_list);
static DECLARE_RWSEM(key_types_sem);

static void key_cleanup(void *data);
static DECLARE_WORK(key_cleanup_task, key_cleanup, NULL);

/* we serialise key instantiation and link */
DECLARE_RWSEM(key_construction_sem);

/* any key who's type gets unegistered will be re-typed to this */
static struct key_type key_type_dead = {
	.name		= "dead",
};

#ifdef KEY_DEBUGGING
void __key_check(const struct key *key)
{
	printk("__key_check: key %p {%08x} should be {%08x}\n",
	       key, key->magic, KEY_DEBUG_MAGIC);
	BUG();
}
#endif

/*****************************************************************************/
/*
 * get the key quota record for a user, allocating a new record if one doesn't
 * already exist
 */
struct key_user *key_user_lookup(uid_t uid)
{
	struct key_user *candidate = NULL, *user;
	struct rb_node *parent = NULL;
	struct rb_node **p;

 try_again:
	p = &key_user_tree.rb_node;
	spin_lock(&key_user_lock);

	/* search the tree for a user record with a matching UID */
	while (*p) {
		parent = *p;
		user = rb_entry(parent, struct key_user, node);

		if (uid < user->uid)
			p = &(*p)->rb_left;
		else if (uid > user->uid)
			p = &(*p)->rb_right;
		else
			goto found;
	}

	/* if we get here, we failed to find a match in the tree */
	if (!candidate) {
		/* allocate a candidate user record if we don't already have
		 * one */
		spin_unlock(&key_user_lock);

		user = NULL;
		candidate = kmalloc(sizeof(struct key_user), GFP_KERNEL);
		if (unlikely(!candidate))
			goto out;

		/* the allocation may have scheduled, so we need to repeat the
		 * search lest someone else added the record whilst we were
		 * asleep */
		goto try_again;
	}

	/* if we get here, then the user record still hadn't appeared on the
	 * second pass - so we use the candidate record */
	atomic_set(&candidate->usage, 1);
	atomic_set(&candidate->nkeys, 0);
	atomic_set(&candidate->nikeys, 0);
	candidate->uid = uid;
	candidate->qnkeys = 0;
	candidate->qnbytes = 0;
	spin_lock_init(&candidate->lock);
	INIT_LIST_HEAD(&candidate->consq);

	rb_link_node(&candidate->node, parent, p);
	rb_insert_color(&candidate->node, &key_user_tree);
	spin_unlock(&key_user_lock);
	user = candidate;
	goto out;

	/* okay - we found a user record for this UID */
 found:
	atomic_inc(&user->usage);
	spin_unlock(&key_user_lock);
	kfree(candidate);
 out:
	return user;

} /* end key_user_lookup() */

/*****************************************************************************/
/*
 * dispose of a user structure
 */
void key_user_put(struct key_user *user)
{
	if (atomic_dec_and_lock(&user->usage, &key_user_lock)) {
		rb_erase(&user->node, &key_user_tree);
		spin_unlock(&key_user_lock);

		kfree(user);
	}

} /* end key_user_put() */

/*****************************************************************************/
/*
 * insert a key with a fixed serial number
 */
static void __init __key_insert_serial(struct key *key)
{
	struct rb_node *parent, **p;
	struct key *xkey;

	parent = NULL;
	p = &key_serial_tree.rb_node;

	while (*p) {
		parent = *p;
		xkey = rb_entry(parent, struct key, serial_node);

		if (key->serial < xkey->serial)
			p = &(*p)->rb_left;
		else if (key->serial > xkey->serial)
			p = &(*p)->rb_right;
		else
			BUG();
	}

	/* we've found a suitable hole - arrange for this key to occupy it */
	rb_link_node(&key->serial_node, parent, p);
	rb_insert_color(&key->serial_node, &key_serial_tree);

} /* end __key_insert_serial() */

/*****************************************************************************/
/*
 * assign a key the next unique serial number
 * - we work through all the serial numbers between 2 and 2^31-1 in turn and
 *   then wrap
 */
static inline void key_alloc_serial(struct key *key)
{
	struct rb_node *parent, **p;
	struct key *xkey;

	spin_lock(&key_serial_lock);

	/* propose a likely serial number and look for a hole for it in the
	 * serial number tree */
	key->serial = key_serial_next;
	if (key->serial < 3)
		key->serial = 3;
	key_serial_next = key->serial + 1;

	parent = NULL;
	p = &key_serial_tree.rb_node;

	while (*p) {
		parent = *p;
		xkey = rb_entry(parent, struct key, serial_node);

		if (key->serial < xkey->serial)
			p = &(*p)->rb_left;
		else if (key->serial > xkey->serial)
			p = &(*p)->rb_right;
		else
			goto serial_exists;
	}
	goto insert_here;

	/* we found a key with the proposed serial number - walk the tree from
	 * that point looking for the next unused serial number */
 serial_exists:
	for (;;) {
		key->serial = key_serial_next;
		if (key->serial < 2)
			key->serial = 2;
		key_serial_next = key->serial + 1;

		if (!rb_parent(parent))
			p = &key_serial_tree.rb_node;
		else if (rb_parent(parent)->rb_left == parent)
			p = &(rb_parent(parent)->rb_left);
		else
			p = &(rb_parent(parent)->rb_right);

		parent = rb_next(parent);
		if (!parent)
			break;

		xkey = rb_entry(parent, struct key, serial_node);
		if (key->serial < xkey->serial)
			goto insert_here;
	}

	/* we've found a suitable hole - arrange for this key to occupy it */
 insert_here:
	rb_link_node(&key->serial_node, parent, p);
	rb_insert_color(&key->serial_node, &key_serial_tree);

	spin_unlock(&key_serial_lock);

} /* end key_alloc_serial() */

/*****************************************************************************/
/*
 * allocate a key of the specified type
 * - update the user's quota to reflect the existence of the key
 * - called from a key-type operation with key_types_sem read-locked by
 *   key_create_or_update()
 *   - this prevents unregistration of the key type
 * - upon return the key is as yet uninstantiated; the caller needs to either
 *   instantiate the key or discard it before returning
 */
struct key *key_alloc(struct key_type *type, const char *desc,
		      uid_t uid, gid_t gid, struct task_struct *ctx,
		      key_perm_t perm, int not_in_quota)
{
	struct key_user *user = NULL;
	struct key *key;
	size_t desclen, quotalen;
	int ret;

	key = ERR_PTR(-EINVAL);
	if (!desc || !*desc)
		goto error;

	desclen = strlen(desc) + 1;
	quotalen = desclen + type->def_datalen;

	/* get hold of the key tracking for this user */
	user = key_user_lookup(uid);
	if (!user)
		goto no_memory_1;

	/* check that the user's quota permits allocation of another key and
	 * its description */
	if (!not_in_quota) {
		spin_lock(&user->lock);
		if (user->qnkeys + 1 >= KEYQUOTA_MAX_KEYS ||
		    user->qnbytes + quotalen >= KEYQUOTA_MAX_BYTES
		    )
			goto no_quota;

		user->qnkeys++;
		user->qnbytes += quotalen;
		spin_unlock(&user->lock);
	}

	/* allocate and initialise the key and its description */
	key = kmem_cache_alloc(key_jar, SLAB_KERNEL);
	if (!key)
		goto no_memory_2;

	if (desc) {
		key->description = kmalloc(desclen, GFP_KERNEL);
		if (!key->description)
			goto no_memory_3;

		memcpy(key->description, desc, desclen);
	}

	atomic_set(&key->usage, 1);
	init_rwsem(&key->sem);
	key->type = type;
	key->user = user;
	key->quotalen = quotalen;
	key->datalen = type->def_datalen;
	key->uid = uid;
	key->gid = gid;
	key->perm = perm;
	key->flags = 0;
	key->expiry = 0;
	key->payload.data = NULL;
	key->security = NULL;

	if (!not_in_quota)
		key->flags |= 1 << KEY_FLAG_IN_QUOTA;

	memset(&key->type_data, 0, sizeof(key->type_data));

#ifdef KEY_DEBUGGING
	key->magic = KEY_DEBUG_MAGIC;
#endif

	/* let the security module know about the key */
	ret = security_key_alloc(key, ctx);
	if (ret < 0)
		goto security_error;

	/* publish the key by giving it a serial number */
	atomic_inc(&user->nkeys);
	key_alloc_serial(key);

error:
	return key;

security_error:
	kfree(key->description);
	kmem_cache_free(key_jar, key);
	if (!not_in_quota) {
		spin_lock(&user->lock);
		user->qnkeys--;
		user->qnbytes -= quotalen;
		spin_unlock(&user->lock);
	}
	key_user_put(user);
	key = ERR_PTR(ret);
	goto error;

no_memory_3:
	kmem_cache_free(key_jar, key);
no_memory_2:
	if (!not_in_quota) {
		spin_lock(&user->lock);
		user->qnkeys--;
		user->qnbytes -= quotalen;
		spin_unlock(&user->lock);
	}
	key_user_put(user);
no_memory_1:
	key = ERR_PTR(-ENOMEM);
	goto error;

no_quota:
	spin_unlock(&user->lock);
	key_user_put(user);
	key = ERR_PTR(-EDQUOT);
	goto error;

} /* end key_alloc() */

EXPORT_SYMBOL(key_alloc);

/*****************************************************************************/
/*
 * reserve an amount of quota for the key's payload
 */
int key_payload_reserve(struct key *key, size_t datalen)
{
	int delta = (int) datalen - key->datalen;
	int ret = 0;

	key_check(key);

	/* contemplate the quota adjustment */
	if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
		spin_lock(&key->user->lock);

		if (delta > 0 &&
		    key->user->qnbytes + delta > KEYQUOTA_MAX_BYTES
		    ) {
			ret = -EDQUOT;
		}
		else {
			key->user->qnbytes += delta;
			key->quotalen += delta;
		}
		spin_unlock(&key->user->lock);
	}

	/* change the recorded data length if that didn't generate an error */
	if (ret == 0)
		key->datalen = datalen;

	return ret;

} /* end key_payload_reserve() */

EXPORT_SYMBOL(key_payload_reserve);

/*****************************************************************************/
/*
 * instantiate a key and link it into the target keyring atomically
 * - called with the target keyring's semaphore writelocked
 */
static int __key_instantiate_and_link(struct key *key,
				      const void *data,
				      size_t datalen,
				      struct key *keyring,
				      struct key *instkey)
{
	int ret, awaken;

	key_check(key);
	key_check(keyring);

	awaken = 0;
	ret = -EBUSY;

	down_write(&key_construction_sem);

	/* can't instantiate twice */
	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
		/* instantiate the key */
		ret = key->type->instantiate(key, data, datalen);

		if (ret == 0) {
			/* mark the key as being instantiated */
			atomic_inc(&key->user->nikeys);
			set_bit(KEY_FLAG_INSTANTIATED, &key->flags);

			if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
				awaken = 1;

			/* and link it into the destination keyring */
			if (keyring)
				ret = __key_link(keyring, key);

			/* disable the authorisation key */
			if (instkey)
				key_revoke(instkey);
		}
	}

	up_write(&key_construction_sem);

	/* wake up anyone waiting for a key to be constructed */
	if (awaken)
		wake_up_all(&request_key_conswq);

	return ret;

} /* end __key_instantiate_and_link() */

/*****************************************************************************/
/*
 * instantiate a key and link it into the target keyring atomically
 */
int key_instantiate_and_link(struct key *key,
			     const void *data,
			     size_t datalen,
			     struct key *keyring,
			     struct key *instkey)
{
	int ret;

	if (keyring)
		down_write(&keyring->sem);

	ret = __key_instantiate_and_link(key, data, datalen, keyring, instkey);

	if (keyring)
		up_write(&keyring->sem);

	return ret;

} /* end key_instantiate_and_link() */

EXPORT_SYMBOL(key_instantiate_and_link);

/*****************************************************************************/
/*
 * negatively instantiate a key and link it into the target keyring atomically
 */
int key_negate_and_link(struct key *key,
			unsigned timeout,
			struct key *keyring,
			struct key *instkey)
{
	struct timespec now;
	int ret, awaken;

	key_check(key);
	key_check(keyring);

	awaken = 0;
	ret = -EBUSY;

	if (keyring)
		down_write(&keyring->sem);

	down_write(&key_construction_sem);

	/* can't instantiate twice */
	if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
		/* mark the key as being negatively instantiated */
		atomic_inc(&key->user->nikeys);
		set_bit(KEY_FLAG_NEGATIVE, &key->flags);
		set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
		now = current_kernel_time();
		key->expiry = now.tv_sec + timeout;

		if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
			awaken = 1;

		ret = 0;

		/* and link it into the destination keyring */
		if (keyring)
			ret = __key_link(keyring, key);

		/* disable the authorisation key */
		if (instkey)
			key_revoke(instkey);
	}

	up_write(&key_construction_sem);

	if (keyring)
		up_write(&keyring->sem);

	/* wake up anyone waiting for a key to be constructed */
	if (awaken)
		wake_up_all(&request_key_conswq);

	return ret;

} /* end key_negate_and_link() */

EXPORT_SYMBOL(key_negate_and_link);

/*****************************************************************************/
/*
 * do cleaning up in process context so that we don't have to disable
 * interrupts all over the place
 */
static void key_cleanup(void *data)
{
	struct rb_node *_n;
	struct key *key;

 go_again:
	/* look for a dead key in the tree */
	spin_lock(&key_serial_lock);

	for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
		key = rb_entry(_n, struct key, serial_node);

		if (atomic_read(&key->usage) == 0)
			goto found_dead_key;
	}

	spin_unlock(&key_serial_lock);
	return;

 found_dead_key:
	/* we found a dead key - once we've removed it from the tree, we can
	 * drop the lock */
	rb_erase(&key->serial_node, &key_serial_tree);
	spin_unlock(&key_serial_lock);

	key_check(key);

	security_key_free(key);

	/* deal with the user's key tracking and quota */
	if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
		spin_lock(&key->user->lock);
		key->user->qnkeys--;
		key->user->qnbytes -= key->quotalen;
		spin_unlock(&key->user->lock);
	}

	atomic_dec(&key->user->nkeys);
	if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
		atomic_dec(&key->user->nikeys);

	key_user_put(key->user);

	/* now throw away the key memory */
	if (key->type->destroy)
		key->type->destroy(key);

	kfree(key->description);

#ifdef KEY_DEBUGGING
	key->magic = KEY_DEBUG_MAGIC_X;
#endif
	kmem_cache_free(key_jar, key);

	/* there may, of course, be more than one key to destroy */
	goto go_again;

} /* end key_cleanup() */

/*****************************************************************************/
/*
 * dispose of a reference to a key
 * - when all the references are gone, we schedule the cleanup task to come and
 *   pull it out of the tree in definite process context
 */
void key_put(struct key *key)
{
	if (key) {
		key_check(key);

		if (atomic_dec_and_test(&key->usage))
			schedule_work(&key_cleanup_task);
	}

} /* end key_put() */

EXPORT_SYMBOL(key_put);

/*****************************************************************************/
/*
 * find a key by its serial number
 */
struct key *key_lookup(key_serial_t id)
{
	struct rb_node *n;
	struct key *key;

	spin_lock(&key_serial_lock);

	/* search the tree for the specified key */
	n = key_serial_tree.rb_node;
	while (n) {
		key = rb_entry(n, struct key, serial_node);

		if (id < key->serial)
			n = n->rb_left;
		else if (id > key->serial)
			n = n->rb_right;
		else
			goto found;
	}

 not_found:
	key = ERR_PTR(-ENOKEY);
	goto error;

 found:
	/* pretend it doesn't exist if it's dead */
	if (atomic_read(&key->usage) == 0 ||
	    test_bit(KEY_FLAG_DEAD, &key->flags) ||
	    key->type == &key_type_dead)
		goto not_found;

	/* this races with key_put(), but that doesn't matter since key_put()
	 * doesn't actually change the key
	 */
	atomic_inc(&key->usage);

 error:
	spin_unlock(&key_serial_lock);
	return key;

} /* end key_lookup() */

/*****************************************************************************/
/*
 * find and lock the specified key type against removal
 * - we return with the sem readlocked
 */
struct key_type *key_type_lookup(const char *type)
{
	struct key_type *ktype;

	down_read(&key_types_sem);

	/* look up the key type to see if it's one of the registered kernel
	 * types */
	list_for_each_entry(ktype, &key_types_list, link) {
		if (strcmp(ktype->name, type) == 0)
			goto found_kernel_type;
	}

	up_read(&key_types_sem);
	ktype = ERR_PTR(-ENOKEY);

 found_kernel_type:
	return ktype;

} /* end key_type_lookup() */

/*****************************************************************************/
/*
 * unlock a key type
 */
void key_type_put(struct key_type *ktype)
{
	up_read(&key_types_sem);

} /* end key_type_put() */

/*****************************************************************************/
/*
 * attempt to update an existing key
 * - the key has an incremented refcount
 * - we need to put the key if we get an error
 */
static inline key_ref_t __key_update(key_ref_t key_ref,
				     const void *payload, size_t plen)
{
	struct key *key = key_ref_to_ptr(key_ref);
	int ret;

	/* need write permission on the key to update it */
	ret = key_permission(key_ref, KEY_WRITE);
	if (ret < 0)
		goto error;

	ret = -EEXIST;
	if (!key->type->update)
		goto error;

	down_write(&key->sem);

	ret = key->type->update(key, payload, plen);
	if (ret == 0)
		/* updating a negative key instantiates it */
		clear_bit(KEY_FLAG_NEGATIVE, &key->flags);

	up_write(&key->sem);

	if (ret < 0)
		goto error;
out:
	return key_ref;

error:
	key_put(key);
	key_ref = ERR_PTR(ret);
	goto out;

} /* end __key_update() */

/*****************************************************************************/
/*
 * search the specified keyring for a key of the same description; if one is
 * found, update it, otherwise add a new one
 */
key_ref_t key_create_or_update(key_ref_t keyring_ref,
			       const char *type,
			       const char *description,
			       const void *payload,
			       size_t plen,
			       int not_in_quota)
{
	struct key_type *ktype;
	struct key *keyring, *key = NULL;
	key_perm_t perm;
	key_ref_t key_ref;
	int ret;

	/* look up the key type to see if it's one of the registered kernel
	 * types */
	ktype = key_type_lookup(type);
	if (IS_ERR(ktype)) {
		key_ref = ERR_PTR(-ENODEV);
		goto error;
	}

	key_ref = ERR_PTR(-EINVAL);
	if (!ktype->match || !ktype->instantiate)
		goto error_2;

	keyring = key_ref_to_ptr(keyring_ref);

	key_check(keyring);

	key_ref = ERR_PTR(-ENOTDIR);
	if (keyring->type != &key_type_keyring)
		goto error_2;

	down_write(&keyring->sem);

	/* if we're going to allocate a new key, we're going to have
	 * to modify the keyring */
	ret = key_permission(keyring_ref, KEY_WRITE);
	if (ret < 0) {
		key_ref = ERR_PTR(ret);
		goto error_3;
	}

	/* if it's possible to update this type of key, search for an existing
	 * key of the same type and description in the destination keyring and
	 * update that instead if possible
	 */
	if (ktype->update) {
		key_ref = __keyring_search_one(keyring_ref, ktype, description,
					       0);
		if (!IS_ERR(key_ref))
			goto found_matching_key;
	}

	/* decide on the permissions we want */
	perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
	perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;

	if (ktype->read)
		perm |= KEY_POS_READ | KEY_USR_READ;

	if (ktype == &key_type_keyring || ktype->update)
		perm |= KEY_USR_WRITE;

	/* allocate a new key */
	key = key_alloc(ktype, description, current->fsuid, current->fsgid,
			current, perm, not_in_quota);
	if (IS_ERR(key)) {
		key_ref = ERR_PTR(PTR_ERR(key));
		goto error_3;
	}

	/* instantiate it and link it into the target keyring */
	ret = __key_instantiate_and_link(key, payload, plen, keyring, NULL);
	if (ret < 0) {
		key_put(key);
		key_ref = ERR_PTR(ret);
		goto error_3;
	}

	key_ref = make_key_ref(key, is_key_possessed(keyring_ref));

 error_3:
	up_write(&keyring->sem);
 error_2:
	key_type_put(ktype);
 error:
	return key_ref;

 found_matching_key:
	/* we found a matching key, so we're going to try to update it
	 * - we can drop the locks first as we have the key pinned
	 */
	up_write(&keyring->sem);
	key_type_put(ktype);

	key_ref = __key_update(key_ref, payload, plen);
	goto error;

} /* end key_create_or_update() */

EXPORT_SYMBOL(key_create_or_update);

/*****************************************************************************/
/*
 * update a key
 */
int key_update(key_ref_t key_ref, const void *payload, size_t plen)
{
	struct key *key = key_ref_to_ptr(key_ref);
	int ret;

	key_check(key);

	/* the key must be writable */
	ret = key_permission(key_ref, KEY_WRITE);
	if (ret < 0)
		goto error;

	/* attempt to update it if supported */
	ret = -EOPNOTSUPP;
	if (key->type->update) {
		down_write(&key->sem);

		ret = key->type->update(key, payload, plen);
		if (ret == 0)
			/* updating a negative key instantiates it */
			clear_bit(KEY_FLAG_NEGATIVE, &key->flags);

		up_write(&key->sem);
	}

 error:
	return ret;

} /* end key_update() */

EXPORT_SYMBOL(key_update);

/*****************************************************************************/
/*
 * revoke a key
 */
void key_revoke(struct key *key)
{
	key_check(key);

	/* make sure no one's trying to change or use the key when we mark
	 * it */
	down_write(&key->sem);
	set_bit(KEY_FLAG_REVOKED, &key->flags);

	if (key->type->revoke)
		key->type->revoke(key);

	up_write(&key->sem);

} /* end key_revoke() */

EXPORT_SYMBOL(key_revoke);

/*****************************************************************************/
/*
 * register a type of key
 */
int register_key_type(struct key_type *ktype)
{
	struct key_type *p;
	int ret;

	ret = -EEXIST;
	down_write(&key_types_sem);

	/* disallow key types with the same name */
	list_for_each_entry(p, &key_types_list, link) {
		if (strcmp(p->name, ktype->name) == 0)
			goto out;
	}

	/* store the type */
	list_add(&ktype->link, &key_types_list);
	ret = 0;

 out:
	up_write(&key_types_sem);
	return ret;

} /* end register_key_type() */

EXPORT_SYMBOL(register_key_type);

/*****************************************************************************/
/*
 * unregister a type of key
 */
void unregister_key_type(struct key_type *ktype)
{
	struct rb_node *_n;
	struct key *key;

	down_write(&key_types_sem);

	/* withdraw the key type */
	list_del_init(&ktype->link);

	/* mark all the keys of this type dead */
	spin_lock(&key_serial_lock);

	for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
		key = rb_entry(_n, struct key, serial_node);

		if (key->type == ktype)
			key->type = &key_type_dead;
	}

	spin_unlock(&key_serial_lock);

	/* make sure everyone revalidates their keys */
	synchronize_rcu();

	/* we should now be able to destroy the payloads of all the keys of
	 * this type with impunity */
	spin_lock(&key_serial_lock);

	for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) {
		key = rb_entry(_n, struct key, serial_node);

		if (key->type == ktype) {
			if (ktype->destroy)
				ktype->destroy(key);
			memset(&key->payload, 0xbd, sizeof(key->payload));
		}
	}

	spin_unlock(&key_serial_lock);
	up_write(&key_types_sem);

} /* end unregister_key_type() */

EXPORT_SYMBOL(unregister_key_type);

/*****************************************************************************/
/*
 * initialise the key management stuff
 */
void __init key_init(void)
{
	/* allocate a slab in which we can store keys */
	key_jar = kmem_cache_create("key_jar", sizeof(struct key),
			0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);

	/* add the special key types */
	list_add_tail(&key_type_keyring.link, &key_types_list);
	list_add_tail(&key_type_dead.link, &key_types_list);
	list_add_tail(&key_type_user.link, &key_types_list);

	/* record the root user tracking */
	rb_link_node(&root_key_user.node,
		     NULL,
		     &key_user_tree.rb_node);

	rb_insert_color(&root_key_user.node,
			&key_user_tree);

	/* record root's user standard keyrings */
	key_check(&root_user_keyring);
	key_check(&root_session_keyring);

	__key_insert_serial(&root_user_keyring);
	__key_insert_serial(&root_session_keyring);

	keyring_publish_name(&root_user_keyring);
	keyring_publish_name(&root_session_keyring);

	/* link the two root keyrings together */
	key_link(&root_session_keyring, &root_user_keyring);

} /* end key_init() */
