/* keyring.c: keyring handling
 *
 * Copyright (C) 2004-5 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/seq_file.h>
#include <linux/err.h>
#include <asm/uaccess.h>
#include "internal.h"

/*
 * when plumbing the depths of the key tree, this sets a hard limit set on how
 * deep we're willing to go
 */
#define KEYRING_SEARCH_MAX_DEPTH 6

/*
 * we keep all named keyrings in a hash to speed looking them up
 */
#define KEYRING_NAME_HASH_SIZE	(1 << 5)

static struct list_head	keyring_name_hash[KEYRING_NAME_HASH_SIZE];
static DEFINE_RWLOCK(keyring_name_lock);

static inline unsigned keyring_hash(const char *desc)
{
	unsigned bucket = 0;

	for (; *desc; desc++)
		bucket += (unsigned char) *desc;

	return bucket & (KEYRING_NAME_HASH_SIZE - 1);
}

/*
 * the keyring type definition
 */
static int keyring_instantiate(struct key *keyring,
			       const void *data, size_t datalen);
static int keyring_duplicate(struct key *keyring, const struct key *source);
static int keyring_match(const struct key *keyring, const void *criterion);
static void keyring_destroy(struct key *keyring);
static void keyring_describe(const struct key *keyring, struct seq_file *m);
static long keyring_read(const struct key *keyring,
			 char __user *buffer, size_t buflen);

struct key_type key_type_keyring = {
	.name		= "keyring",
	.def_datalen	= sizeof(struct keyring_list),
	.instantiate	= keyring_instantiate,
	.duplicate	= keyring_duplicate,
	.match		= keyring_match,
	.destroy	= keyring_destroy,
	.describe	= keyring_describe,
	.read		= keyring_read,
};

/*
 * semaphore to serialise link/link calls to prevent two link calls in parallel
 * introducing a cycle
 */
DECLARE_RWSEM(keyring_serialise_link_sem);

/*****************************************************************************/
/*
 * publish the name of a keyring so that it can be found by name (if it has
 * one)
 */
void keyring_publish_name(struct key *keyring)
{
	int bucket;

	if (keyring->description) {
		bucket = keyring_hash(keyring->description);

		write_lock(&keyring_name_lock);

		if (!keyring_name_hash[bucket].next)
			INIT_LIST_HEAD(&keyring_name_hash[bucket]);

		list_add_tail(&keyring->type_data.link,
			      &keyring_name_hash[bucket]);

		write_unlock(&keyring_name_lock);
	}

} /* end keyring_publish_name() */

/*****************************************************************************/
/*
 * initialise a keyring
 * - we object if we were given any data
 */
static int keyring_instantiate(struct key *keyring,
			       const void *data, size_t datalen)
{
	int ret;

	ret = -EINVAL;
	if (datalen == 0) {
		/* make the keyring available by name if it has one */
		keyring_publish_name(keyring);
		ret = 0;
	}

	return ret;

} /* end keyring_instantiate() */

/*****************************************************************************/
/*
 * duplicate the list of subscribed keys from a source keyring into this one
 */
static int keyring_duplicate(struct key *keyring, const struct key *source)
{
	struct keyring_list *sklist, *klist;
	unsigned max;
	size_t size;
	int loop, ret;

	const unsigned limit =
		(PAGE_SIZE - sizeof(*klist)) / sizeof(struct key *);

	ret = 0;

	/* find out how many keys are currently linked */
	rcu_read_lock();
	sklist = rcu_dereference(source->payload.subscriptions);
	max = 0;
	if (sklist)
		max = sklist->nkeys;
	rcu_read_unlock();

	/* allocate a new payload and stuff load with key links */
	if (max > 0) {
		BUG_ON(max > limit);

		max = (max + 3) & ~3;
		if (max > limit)
			max = limit;

		ret = -ENOMEM;
		size = sizeof(*klist) + sizeof(struct key *) * max;
		klist = kmalloc(size, GFP_KERNEL);
		if (!klist)
			goto error;

		/* set links */
		rcu_read_lock();
		sklist = rcu_dereference(source->payload.subscriptions);

		klist->maxkeys = max;
		klist->nkeys = sklist->nkeys;
		memcpy(klist->keys,
		       sklist->keys,
		       sklist->nkeys * sizeof(struct key *));

		for (loop = klist->nkeys - 1; loop >= 0; loop--)
			atomic_inc(&klist->keys[loop]->usage);

		rcu_read_unlock();

		rcu_assign_pointer(keyring->payload.subscriptions, klist);
		ret = 0;
	}

 error:
	return ret;

} /* end keyring_duplicate() */

/*****************************************************************************/
/*
 * match keyrings on their name
 */
static int keyring_match(const struct key *keyring, const void *description)
{
	return keyring->description &&
		strcmp(keyring->description, description) == 0;

} /* end keyring_match() */

/*****************************************************************************/
/*
 * dispose of the data dangling from the corpse of a keyring
 */
static void keyring_destroy(struct key *keyring)
{
	struct keyring_list *klist;
	int loop;

	if (keyring->description) {
		write_lock(&keyring_name_lock);

		if (keyring->type_data.link.next != NULL &&
		    !list_empty(&keyring->type_data.link))
			list_del(&keyring->type_data.link);

		write_unlock(&keyring_name_lock);
	}

	klist = rcu_dereference(keyring->payload.subscriptions);
	if (klist) {
		for (loop = klist->nkeys - 1; loop >= 0; loop--)
			key_put(klist->keys[loop]);
		kfree(klist);
	}

} /* end keyring_destroy() */

/*****************************************************************************/
/*
 * describe the keyring
 */
static void keyring_describe(const struct key *keyring, struct seq_file *m)
{
	struct keyring_list *klist;

	if (keyring->description) {
		seq_puts(m, keyring->description);
	}
	else {
		seq_puts(m, "[anon]");
	}

	rcu_read_lock();
	klist = rcu_dereference(keyring->payload.subscriptions);
	if (klist)
		seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
	else
		seq_puts(m, ": empty");
	rcu_read_unlock();

} /* end keyring_describe() */

/*****************************************************************************/
/*
 * read a list of key IDs from the keyring's contents
 * - the keyring's semaphore is read-locked
 */
static long keyring_read(const struct key *keyring,
			 char __user *buffer, size_t buflen)
{
	struct keyring_list *klist;
	struct key *key;
	size_t qty, tmp;
	int loop, ret;

	ret = 0;
	klist = rcu_dereference(keyring->payload.subscriptions);

	if (klist) {
		/* calculate how much data we could return */
		qty = klist->nkeys * sizeof(key_serial_t);

		if (buffer && buflen > 0) {
			if (buflen > qty)
				buflen = qty;

			/* copy the IDs of the subscribed keys into the
			 * buffer */
			ret = -EFAULT;

			for (loop = 0; loop < klist->nkeys; loop++) {
				key = klist->keys[loop];

				tmp = sizeof(key_serial_t);
				if (tmp > buflen)
					tmp = buflen;

				if (copy_to_user(buffer,
						 &key->serial,
						 tmp) != 0)
					goto error;

				buflen -= tmp;
				if (buflen == 0)
					break;
				buffer += tmp;
			}
		}

		ret = qty;
	}

 error:
	return ret;

} /* end keyring_read() */

/*****************************************************************************/
/*
 * allocate a keyring and link into the destination keyring
 */
struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
			  int not_in_quota, struct key *dest)
{
	struct key *keyring;
	int ret;

	keyring = key_alloc(&key_type_keyring, description,
			    uid, gid, KEY_USR_ALL, not_in_quota);

	if (!IS_ERR(keyring)) {
		ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
		if (ret < 0) {
			key_put(keyring);
			keyring = ERR_PTR(ret);
		}
	}

	return keyring;

} /* end keyring_alloc() */

/*****************************************************************************/
/*
 * search the supplied keyring tree for a key that matches the criterion
 * - perform a breadth-then-depth search up to the prescribed limit
 * - we only find keys on which we have search permission
 * - we use the supplied match function to see if the description (or other
 *   feature of interest) matches
 * - we rely on RCU to prevent the keyring lists from disappearing on us
 * - we return -EAGAIN if we didn't find any matching key
 * - we return -ENOKEY if we only found negative matching keys
 */
struct key *keyring_search_aux(struct key *keyring,
			       struct task_struct *context,
			       struct key_type *type,
			       const void *description,
			       key_match_func_t match)
{
	struct {
		struct keyring_list *keylist;
		int kix;
	} stack[KEYRING_SEARCH_MAX_DEPTH];

	struct keyring_list *keylist;
	struct timespec now;
	struct key *key;
	long err;
	int sp, kix;

	key_check(keyring);

	rcu_read_lock();

	/* top keyring must have search permission to begin the search */
	key = ERR_PTR(-EACCES);
	if (!key_task_permission(keyring, context, KEY_SEARCH))
		goto error;

	key = ERR_PTR(-ENOTDIR);
	if (keyring->type != &key_type_keyring)
		goto error;

	now = current_kernel_time();
	err = -EAGAIN;
	sp = 0;

	/* start processing a new keyring */
 descend:
	if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
		goto not_this_keyring;

	keylist = rcu_dereference(keyring->payload.subscriptions);
	if (!keylist)
		goto not_this_keyring;

	/* iterate through the keys in this keyring first */
	for (kix = 0; kix < keylist->nkeys; kix++) {
		key = keylist->keys[kix];

		/* ignore keys not of this type */
		if (key->type != type)
			continue;

		/* skip revoked keys and expired keys */
		if (test_bit(KEY_FLAG_REVOKED, &key->flags))
			continue;

		if (key->expiry && now.tv_sec >= key->expiry)
			continue;

		/* keys that don't match */
		if (!match(key, description))
			continue;

		/* key must have search permissions */
		if (!key_task_permission(key, context, KEY_SEARCH))
			continue;

		/* we set a different error code if we find a negative key */
		if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
			err = -ENOKEY;
			continue;
		}

		goto found;
	}

	/* search through the keyrings nested in this one */
	kix = 0;
 ascend:
	for (; kix < keylist->nkeys; kix++) {
		key = keylist->keys[kix];
		if (key->type != &key_type_keyring)
			continue;

		/* recursively search nested keyrings
		 * - only search keyrings for which we have search permission
		 */
		if (sp >= KEYRING_SEARCH_MAX_DEPTH)
			continue;

		if (!key_task_permission(key, context, KEY_SEARCH))
			continue;

		/* stack the current position */
		stack[sp].keylist = keylist;
		stack[sp].kix = kix;
		sp++;

		/* begin again with the new keyring */
		keyring = key;
		goto descend;
	}

	/* the keyring we're looking at was disqualified or didn't contain a
	 * matching key */
 not_this_keyring:
	if (sp > 0) {
		/* resume the processing of a keyring higher up in the tree */
		sp--;
		keylist = stack[sp].keylist;
		kix = stack[sp].kix + 1;
		goto ascend;
	}

	key = ERR_PTR(err);
	goto error;

	/* we found a viable match */
 found:
	atomic_inc(&key->usage);
	key_check(key);
 error:
	rcu_read_unlock();
	return key;

} /* end keyring_search_aux() */

/*****************************************************************************/
/*
 * search the supplied keyring tree for a key that matches the criterion
 * - perform a breadth-then-depth search up to the prescribed limit
 * - we only find keys on which we have search permission
 * - we readlock the keyrings as we search down the tree
 * - we return -EAGAIN if we didn't find any matching key
 * - we return -ENOKEY if we only found negative matching keys
 */
struct key *keyring_search(struct key *keyring,
			   struct key_type *type,
			   const char *description)
{
	if (!type->match)
		return ERR_PTR(-ENOKEY);

	return keyring_search_aux(keyring, current,
				  type, description, type->match);

} /* end keyring_search() */

EXPORT_SYMBOL(keyring_search);

/*****************************************************************************/
/*
 * search the given keyring only (no recursion)
 * - keyring must be locked by caller
 */
struct key *__keyring_search_one(struct key *keyring,
				 const struct key_type *ktype,
				 const char *description,
				 key_perm_t perm)
{
	struct keyring_list *klist;
	struct key *key;
	int loop;

	rcu_read_lock();

	klist = rcu_dereference(keyring->payload.subscriptions);
	if (klist) {
		for (loop = 0; loop < klist->nkeys; loop++) {
			key = klist->keys[loop];

			if (key->type == ktype &&
			    (!key->type->match ||
			     key->type->match(key, description)) &&
			    key_permission(key, perm) &&
			    !test_bit(KEY_FLAG_REVOKED, &key->flags)
			    )
				goto found;
		}
	}

	key = ERR_PTR(-ENOKEY);
	goto error;

 found:
	atomic_inc(&key->usage);
 error:
	rcu_read_unlock();
	return key;

} /* end __keyring_search_one() */

/*****************************************************************************/
/*
 * search for an instantiation authorisation key matching a target key
 * - the RCU read lock must be held by the caller
 * - a target_id of zero specifies any valid token
 */
struct key *keyring_search_instkey(struct key *keyring,
				   key_serial_t target_id)
{
	struct request_key_auth *rka;
	struct keyring_list *klist;
	struct key *instkey;
	int loop;

	klist = rcu_dereference(keyring->payload.subscriptions);
	if (klist) {
		for (loop = 0; loop < klist->nkeys; loop++) {
			instkey = klist->keys[loop];

			if (instkey->type != &key_type_request_key_auth)
				continue;

			rka = instkey->payload.data;
			if (target_id && rka->target_key->serial != target_id)
				continue;

			/* the auth key is revoked during instantiation */
			if (!test_bit(KEY_FLAG_REVOKED, &instkey->flags))
				goto found;

			instkey = ERR_PTR(-EKEYREVOKED);
			goto error;
		}
	}

	instkey = ERR_PTR(-EACCES);
	goto error;

found:
	atomic_inc(&instkey->usage);
error:
	return instkey;

} /* end keyring_search_instkey() */

/*****************************************************************************/
/*
 * find a keyring with the specified name
 * - all named keyrings are searched
 * - only find keyrings with search permission for the process
 * - only find keyrings with a serial number greater than the one specified
 */
struct key *find_keyring_by_name(const char *name, key_serial_t bound)
{
	struct key *keyring;
	int bucket;

	keyring = ERR_PTR(-EINVAL);
	if (!name)
		goto error;

	bucket = keyring_hash(name);

	read_lock(&keyring_name_lock);

	if (keyring_name_hash[bucket].next) {
		/* search this hash bucket for a keyring with a matching name
		 * that's readable and that hasn't been revoked */
		list_for_each_entry(keyring,
				    &keyring_name_hash[bucket],
				    type_data.link
				    ) {
			if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
				continue;

			if (strcmp(keyring->description, name) != 0)
				continue;

			if (!key_permission(keyring, KEY_SEARCH))
				continue;

			/* found a potential candidate, but we still need to
			 * check the serial number */
			if (keyring->serial <= bound)
				continue;

			/* we've got a match */
			atomic_inc(&keyring->usage);
			read_unlock(&keyring_name_lock);
			goto error;
		}
	}

	read_unlock(&keyring_name_lock);
	keyring = ERR_PTR(-ENOKEY);

 error:
	return keyring;

} /* end find_keyring_by_name() */

/*****************************************************************************/
/*
 * see if a cycle will will be created by inserting acyclic tree B in acyclic
 * tree A at the topmost level (ie: as a direct child of A)
 * - since we are adding B to A at the top level, checking for cycles should
 *   just be a matter of seeing if node A is somewhere in tree B
 */
static int keyring_detect_cycle(struct key *A, struct key *B)
{
	struct {
		struct keyring_list *keylist;
		int kix;
	} stack[KEYRING_SEARCH_MAX_DEPTH];

	struct keyring_list *keylist;
	struct key *subtree, *key;
	int sp, kix, ret;

	rcu_read_lock();

	ret = -EDEADLK;
	if (A == B)
		goto cycle_detected;

	subtree = B;
	sp = 0;

	/* start processing a new keyring */
 descend:
	if (test_bit(KEY_FLAG_REVOKED, &subtree->flags))
		goto not_this_keyring;

	keylist = rcu_dereference(subtree->payload.subscriptions);
	if (!keylist)
		goto not_this_keyring;
	kix = 0;

 ascend:
	/* iterate through the remaining keys in this keyring */
	for (; kix < keylist->nkeys; kix++) {
		key = keylist->keys[kix];

		if (key == A)
			goto cycle_detected;

		/* recursively check nested keyrings */
		if (key->type == &key_type_keyring) {
			if (sp >= KEYRING_SEARCH_MAX_DEPTH)
				goto too_deep;

			/* stack the current position */
			stack[sp].keylist = keylist;
			stack[sp].kix = kix;
			sp++;

			/* begin again with the new keyring */
			subtree = key;
			goto descend;
		}
	}

	/* the keyring we're looking at was disqualified or didn't contain a
	 * matching key */
 not_this_keyring:
	if (sp > 0) {
		/* resume the checking of a keyring higher up in the tree */
		sp--;
		keylist = stack[sp].keylist;
		kix = stack[sp].kix + 1;
		goto ascend;
	}

	ret = 0; /* no cycles detected */

 error:
	rcu_read_unlock();
	return ret;

 too_deep:
	ret = -ELOOP;
	goto error;

 cycle_detected:
	ret = -EDEADLK;
	goto error;

} /* end keyring_detect_cycle() */

/*****************************************************************************/
/*
 * dispose of a keyring list after the RCU grace period
 */
static void keyring_link_rcu_disposal(struct rcu_head *rcu)
{
	struct keyring_list *klist =
		container_of(rcu, struct keyring_list, rcu);

	kfree(klist);

} /* end keyring_link_rcu_disposal() */

/*****************************************************************************/
/*
 * link a key into to a keyring
 * - must be called with the keyring's semaphore write-locked
 */
int __key_link(struct key *keyring, struct key *key)
{
	struct keyring_list *klist, *nklist;
	unsigned max;
	size_t size;
	int ret;

	ret = -EKEYREVOKED;
	if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
		goto error;

	ret = -ENOTDIR;
	if (keyring->type != &key_type_keyring)
		goto error;

	/* serialise link/link calls to prevent parallel calls causing a
	 * cycle when applied to two keyring in opposite orders */
	down_write(&keyring_serialise_link_sem);

	/* check that we aren't going to create a cycle adding one keyring to
	 * another */
	if (key->type == &key_type_keyring) {
		ret = keyring_detect_cycle(keyring, key);
		if (ret < 0)
			goto error2;
	}

	/* check that we aren't going to overrun the user's quota */
	ret = key_payload_reserve(keyring,
				  keyring->datalen + KEYQUOTA_LINK_BYTES);
	if (ret < 0)
		goto error2;

	klist = keyring->payload.subscriptions;

	if (klist && klist->nkeys < klist->maxkeys) {
		/* there's sufficient slack space to add directly */
		atomic_inc(&key->usage);

		klist->keys[klist->nkeys] = key;
		smp_wmb();
		klist->nkeys++;
		smp_wmb();

		ret = 0;
	}
	else {
		/* grow the key list */
		max = 4;
		if (klist)
			max += klist->maxkeys;

		ret = -ENFILE;
		if (max > 65535)
			goto error3;
		size = sizeof(*klist) + sizeof(struct key *) * max;
		if (size > PAGE_SIZE)
			goto error3;

		ret = -ENOMEM;
		nklist = kmalloc(size, GFP_KERNEL);
		if (!nklist)
			goto error3;
		nklist->maxkeys = max;
		nklist->nkeys = 0;

		if (klist) {
			nklist->nkeys = klist->nkeys;
			memcpy(nklist->keys,
			       klist->keys,
			       sizeof(struct key *) * klist->nkeys);
		}

		/* add the key into the new space */
		atomic_inc(&key->usage);
		nklist->keys[nklist->nkeys++] = key;

		rcu_assign_pointer(keyring->payload.subscriptions, nklist);

		/* dispose of the old keyring list */
		if (klist)
			call_rcu(&klist->rcu, keyring_link_rcu_disposal);

		ret = 0;
	}

 error2:
	up_write(&keyring_serialise_link_sem);
 error:
	return ret;

 error3:
	/* undo the quota changes */
	key_payload_reserve(keyring,
			    keyring->datalen - KEYQUOTA_LINK_BYTES);
	goto error2;

} /* end __key_link() */

/*****************************************************************************/
/*
 * link a key to a keyring
 */
int key_link(struct key *keyring, struct key *key)
{
	int ret;

	key_check(keyring);
	key_check(key);

	down_write(&keyring->sem);
	ret = __key_link(keyring, key);
	up_write(&keyring->sem);

	return ret;

} /* end key_link() */

EXPORT_SYMBOL(key_link);

/*****************************************************************************/
/*
 * dispose of a keyring list after the RCU grace period, freeing the unlinked
 * key
 */
static void keyring_unlink_rcu_disposal(struct rcu_head *rcu)
{
	struct keyring_list *klist =
		container_of(rcu, struct keyring_list, rcu);

	key_put(klist->keys[klist->delkey]);
	kfree(klist);

} /* end keyring_unlink_rcu_disposal() */

/*****************************************************************************/
/*
 * unlink the first link to a key from a keyring
 */
int key_unlink(struct key *keyring, struct key *key)
{
	struct keyring_list *klist, *nklist;
	int loop, ret;

	key_check(keyring);
	key_check(key);

	ret = -ENOTDIR;
	if (keyring->type != &key_type_keyring)
		goto error;

	down_write(&keyring->sem);

	klist = keyring->payload.subscriptions;
	if (klist) {
		/* search the keyring for the key */
		for (loop = 0; loop < klist->nkeys; loop++)
			if (klist->keys[loop] == key)
				goto key_is_present;
	}

	up_write(&keyring->sem);
	ret = -ENOENT;
	goto error;

key_is_present:
	/* we need to copy the key list for RCU purposes */
	nklist = kmalloc(sizeof(*klist) +
			 sizeof(struct key *) * klist->maxkeys,
			 GFP_KERNEL);
	if (!nklist)
		goto nomem;
	nklist->maxkeys = klist->maxkeys;
	nklist->nkeys = klist->nkeys - 1;

	if (loop > 0)
		memcpy(&nklist->keys[0],
		       &klist->keys[0],
		       loop * sizeof(struct key *));

	if (loop < nklist->nkeys)
		memcpy(&nklist->keys[loop],
		       &klist->keys[loop + 1],
		       (nklist->nkeys - loop) * sizeof(struct key *));

	/* adjust the user's quota */
	key_payload_reserve(keyring,
			    keyring->datalen - KEYQUOTA_LINK_BYTES);

	rcu_assign_pointer(keyring->payload.subscriptions, nklist);

	up_write(&keyring->sem);

	/* schedule for later cleanup */
	klist->delkey = loop;
	call_rcu(&klist->rcu, keyring_unlink_rcu_disposal);

	ret = 0;

error:
	return ret;
nomem:
	ret = -ENOMEM;
	up_write(&keyring->sem);
	goto error;

} /* end key_unlink() */

EXPORT_SYMBOL(key_unlink);

/*****************************************************************************/
/*
 * dispose of a keyring list after the RCU grace period, releasing the keys it
 * links to
 */
static void keyring_clear_rcu_disposal(struct rcu_head *rcu)
{
	struct keyring_list *klist;
	int loop;

	klist = container_of(rcu, struct keyring_list, rcu);

	for (loop = klist->nkeys - 1; loop >= 0; loop--)
		key_put(klist->keys[loop]);

	kfree(klist);

} /* end keyring_clear_rcu_disposal() */

/*****************************************************************************/
/*
 * clear the specified process keyring
 * - implements keyctl(KEYCTL_CLEAR)
 */
int keyring_clear(struct key *keyring)
{
	struct keyring_list *klist;
	int ret;

	ret = -ENOTDIR;
	if (keyring->type == &key_type_keyring) {
		/* detach the pointer block with the locks held */
		down_write(&keyring->sem);

		klist = keyring->payload.subscriptions;
		if (klist) {
			/* adjust the quota */
			key_payload_reserve(keyring,
					    sizeof(struct keyring_list));

			rcu_assign_pointer(keyring->payload.subscriptions,
					   NULL);
		}

		up_write(&keyring->sem);

		/* free the keys after the locks have been dropped */
		if (klist)
			call_rcu(&klist->rcu, keyring_clear_rcu_disposal);

		ret = 0;
	}

	return ret;

} /* end keyring_clear() */

EXPORT_SYMBOL(keyring_clear);
