Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 973c9f4f authored by David Howells's avatar David Howells Committed by Linus Torvalds
Browse files

KEYS: Fix up comments in key management code



Fix up comments in the key management code.  No functional changes.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent a8b17ed0
Loading
Loading
Loading
Loading
+7 −6
Original line number Original line Diff line number Diff line
/* compat.c: 32-bit compatibility syscall for 64-bit systems
/* 32-bit compatibility syscall for 64-bit systems
 *
 *
 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 * Written by David Howells (dhowells@redhat.com)
@@ -15,11 +15,12 @@
#include "internal.h"
#include "internal.h"


/*
/*
 * the key control system call, 32-bit compatibility version for 64-bit archs
 * The key control system call, 32-bit compatibility version for 64-bit archs
 * - this should only be called if the 64-bit arch uses weird pointers in
 *
 *   32-bit mode or doesn't guarantee that the top 32-bits of the argument
 * This should only be called if the 64-bit arch uses weird pointers in 32-bit
 *   registers on taking a 32-bit syscall are zero
 * mode or doesn't guarantee that the top 32-bits of the argument registers on
 * - if you can, you should call sys_keyctl directly
 * taking a 32-bit syscall are zero.  If you can, you should call sys_keyctl()
 * directly.
 */
 */
asmlinkage long compat_sys_keyctl(u32 option,
asmlinkage long compat_sys_keyctl(u32 option,
				  u32 arg2, u32 arg3, u32 arg4, u32 arg5)
				  u32 arg2, u32 arg3, u32 arg4, u32 arg5)
+7 −7
Original line number Original line Diff line number Diff line
@@ -32,8 +32,8 @@ static time_t key_gc_next_run = LONG_MAX;
static time_t key_gc_new_timer;
static time_t key_gc_new_timer;


/*
/*
 * Schedule a garbage collection run
 * Schedule a garbage collection run.
 * - precision isn't particularly important
 * - time precision isn't particularly important
 */
 */
void key_schedule_gc(time_t gc_at)
void key_schedule_gc(time_t gc_at)
{
{
@@ -61,8 +61,9 @@ static void key_gc_timer_func(unsigned long data)
}
}


/*
/*
 * Garbage collect pointers from a keyring
 * Garbage collect pointers from a keyring.
 * - return true if we altered the keyring
 *
 * Return true if we altered the keyring.
 */
 */
static bool key_gc_keyring(struct key *keyring, time_t limit)
static bool key_gc_keyring(struct key *keyring, time_t limit)
	__releases(key_serial_lock)
	__releases(key_serial_lock)
@@ -107,9 +108,8 @@ do_gc:
}
}


/*
/*
 * Garbage collector for keys
 * Garbage collector for keys.  This involves scanning the keyrings for dead,
 * - this involves scanning the keyrings for dead, expired and revoked keys
 * expired and revoked keys that have overstayed their welcome
 *   that have overstayed their welcome
 */
 */
static void key_garbage_collector(struct work_struct *work)
static void key_garbage_collector(struct work_struct *work)
{
{
+14 −12
Original line number Original line Diff line number Diff line
/* internal.h: authentication token and access key management internal defs
/* Authentication token and access key management internal defs
 *
 *
 * Copyright (C) 2003-5, 2007 Red Hat, Inc. All Rights Reserved.
 * Copyright (C) 2003-5, 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 * Written by David Howells (dhowells@redhat.com)
@@ -35,10 +35,12 @@ extern struct key_type key_type_user;


/*****************************************************************************/
/*****************************************************************************/
/*
/*
 * keep track of keys for a user
 * Keep track of keys for a user.
 * - this needs to be separate to user_struct to avoid a refcount-loop
 *
 *   (user_struct pins some keyrings which pin this struct)
 * This needs to be separate to user_struct to avoid a refcount-loop
 * - this also keeps track of keys under request from userspace for this UID
 * (user_struct pins some keyrings which pin this struct).
 *
 * We also keep track of keys under request from userspace for this UID here.
 */
 */
struct key_user {
struct key_user {
	struct rb_node		node;
	struct rb_node		node;
@@ -62,7 +64,7 @@ extern struct key_user *key_user_lookup(uid_t uid,
extern void key_user_put(struct key_user *user);
extern void key_user_put(struct key_user *user);


/*
/*
 * key quota limits
 * Key quota limits.
 * - root has its own separate limits to everyone else
 * - root has its own separate limits to everyone else
 */
 */
extern unsigned key_quota_root_maxkeys;
extern unsigned key_quota_root_maxkeys;
@@ -146,13 +148,13 @@ extern unsigned key_gc_delay;
extern void keyring_gc(struct key *keyring, time_t limit);
extern void keyring_gc(struct key *keyring, time_t limit);
extern void key_schedule_gc(time_t expiry_at);
extern void key_schedule_gc(time_t expiry_at);


/*
 * check to see whether permission is granted to use a key in the desired way
 */
extern int key_task_permission(const key_ref_t key_ref,
extern int key_task_permission(const key_ref_t key_ref,
			       const struct cred *cred,
			       const struct cred *cred,
			       key_perm_t perm);
			       key_perm_t perm);


/*
 * Check to see whether permission is granted to use a key in the desired way.
 */
static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
{
{
	return key_task_permission(key_ref, current_cred(), perm);
	return key_task_permission(key_ref, current_cred(), perm);
@@ -168,7 +170,7 @@ static inline int key_permission(const key_ref_t key_ref, key_perm_t perm)
#define	KEY_ALL		0x3f	/* all the above permissions */
#define	KEY_ALL		0x3f	/* all the above permissions */


/*
/*
 * request_key authorisation
 * Authorisation record for request_key().
 */
 */
struct request_key_auth {
struct request_key_auth {
	struct key		*target_key;
	struct key		*target_key;
@@ -188,7 +190,7 @@ extern struct key *request_key_auth_new(struct key *target,
extern struct key *key_get_instantiation_authkey(key_serial_t target_id);
extern struct key *key_get_instantiation_authkey(key_serial_t target_id);


/*
/*
 * keyctl functions
 * keyctl() functions
 */
 */
extern long keyctl_get_keyring_ID(key_serial_t, int);
extern long keyctl_get_keyring_ID(key_serial_t, int);
extern long keyctl_join_session_keyring(const char __user *);
extern long keyctl_join_session_keyring(const char __user *);
@@ -214,7 +216,7 @@ extern long keyctl_get_security(key_serial_t keyid, char __user *buffer,
extern long keyctl_session_to_parent(void);
extern long keyctl_session_to_parent(void);


/*
/*
 * debugging key validation
 * Debugging key validation
 */
 */
#ifdef KEY_DEBUGGING
#ifdef KEY_DEBUGGING
extern void __key_check(const struct key *);
extern void __key_check(const struct key *);
+173 −67
Original line number Original line Diff line number Diff line
@@ -39,10 +39,10 @@ static DECLARE_RWSEM(key_types_sem);
static void key_cleanup(struct work_struct *work);
static void key_cleanup(struct work_struct *work);
static DECLARE_WORK(key_cleanup_task, key_cleanup);
static DECLARE_WORK(key_cleanup_task, key_cleanup);


/* we serialise key instantiation and link */
/* We serialise key instantiation and link */
DEFINE_MUTEX(key_construction_mutex);
DEFINE_MUTEX(key_construction_mutex);


/* any key who's type gets unegistered will be re-typed to this */
/* Any key who's type gets unegistered will be re-typed to this */
static struct key_type key_type_dead = {
static struct key_type key_type_dead = {
	.name		= "dead",
	.name		= "dead",
};
};
@@ -57,8 +57,8 @@ void __key_check(const struct key *key)
#endif
#endif


/*
/*
 * get the key quota record for a user, allocating a new record if one doesn't
 * Get the key quota record for a user, allocating a new record if one doesn't
 * already exist
 * already exist.
 */
 */
struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns)
struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns)
{
{
@@ -132,7 +132,7 @@ struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns)
}
}


/*
/*
 * dispose of a user structure
 * Dispose of a user structure
 */
 */
void key_user_put(struct key_user *user)
void key_user_put(struct key_user *user)
{
{
@@ -146,9 +146,8 @@ void key_user_put(struct key_user *user)
}
}


/*
/*
 * assign a key the next unique serial number
 * Allocate a serial number for a key.  These are assigned randomly to avoid
 * - these are assigned randomly to avoid security issues through covert
 * security issues through covert channel problems.
 *   channel problems
 */
 */
static inline void key_alloc_serial(struct key *key)
static inline void key_alloc_serial(struct key *key)
{
{
@@ -208,14 +207,34 @@ serial_exists:
	}
	}
}
}


/*
/**
 * allocate a key of the specified type
 * key_alloc - Allocate a key of the specified type.
 * - update the user's quota to reflect the existence of the key
 * @type: The type of key to allocate.
 * - called from a key-type operation with key_types_sem read-locked by
 * @desc: The key description to allow the key to be searched out.
 *   key_create_or_update()
 * @uid: The owner of the new key.
 *   - this prevents unregistration of the key type
 * @gid: The group ID for the new key's group permissions.
 * - upon return the key is as yet uninstantiated; the caller needs to either
 * @cred: The credentials specifying UID namespace.
 *   instantiate the key or discard it before returning
 * @perm: The permissions mask of the new key.
 * @flags: Flags specifying quota properties.
 *
 * Allocate a key of the specified type with the attributes given.  The key is
 * returned in an uninstantiated state and the caller needs to instantiate the
 * key before returning.
 *
 * The user's key count quota is updated to reflect the creation of the key and
 * the user's key data quota has the default for the key type reserved.  The
 * instantiation function should amend this as necessary.  If insufficient
 * quota is available, -EDQUOT will be returned.
 *
 * The LSM security modules can prevent a key being created, in which case
 * -EACCES will be returned.
 *
 * Returns a pointer to the new key if successful and an error code otherwise.
 *
 * Note that the caller needs to ensure the key type isn't uninstantiated.
 * Internally this can be done by locking key_types_sem.  Externally, this can
 * be done by either never unregistering the key type, or making sure
 * key_alloc() calls don't race with module unloading.
 */
 */
struct key *key_alloc(struct key_type *type, const char *desc,
struct key *key_alloc(struct key_type *type, const char *desc,
		      uid_t uid, gid_t gid, const struct cred *cred,
		      uid_t uid, gid_t gid, const struct cred *cred,
@@ -338,11 +357,18 @@ no_quota:
	key = ERR_PTR(-EDQUOT);
	key = ERR_PTR(-EDQUOT);
	goto error;
	goto error;
}
}

EXPORT_SYMBOL(key_alloc);
EXPORT_SYMBOL(key_alloc);


/*
/**
 * reserve an amount of quota for the key's payload
 * key_payload_reserve - Adjust data quota reservation for the key's payload
 * @key: The key to make the reservation for.
 * @datalen: The amount of data payload the caller now wants.
 *
 * Adjust the amount of the owning user's key data quota that a key reserves.
 * If the amount is increased, then -EDQUOT may be returned if there isn't
 * enough free quota available.
 *
 * If successful, 0 is returned.
 */
 */
int key_payload_reserve(struct key *key, size_t datalen)
int key_payload_reserve(struct key *key, size_t datalen)
{
{
@@ -376,12 +402,13 @@ int key_payload_reserve(struct key *key, size_t datalen)


	return ret;
	return ret;
}
}

EXPORT_SYMBOL(key_payload_reserve);
EXPORT_SYMBOL(key_payload_reserve);


/*
/*
 * instantiate a key and link it into the target keyring atomically
 * Instantiate a key and link it into the target keyring atomically.  Must be
 * - called with the target keyring's semaphore writelocked
 * called with the target keyring's semaphore writelocked.  The target key's
 * semaphore need not be locked as instantiation is serialised by
 * key_construction_mutex.
 */
 */
static int __key_instantiate_and_link(struct key *key,
static int __key_instantiate_and_link(struct key *key,
				      const void *data,
				      const void *data,
@@ -432,8 +459,21 @@ static int __key_instantiate_and_link(struct key *key,
	return ret;
	return ret;
}
}


/*
/**
 * instantiate a key and link it into the target keyring atomically
 * key_instantiate_and_link - Instantiate a key and link it into the keyring.
 * @key: The key to instantiate.
 * @data: The data to use to instantiate the keyring.
 * @datalen: The length of @data.
 * @keyring: Keyring to create a link in on success (or NULL).
 * @authkey: The authorisation token permitting instantiation.
 *
 * Instantiate a key that's in the uninstantiated state using the provided data
 * and, if successful, link it in to the destination keyring if one is
 * supplied.
 *
 * If successful, 0 is returned, the authorisation token is revoked and anyone
 * waiting for the key is woken up.  If the key was already instantiated,
 * -EBUSY will be returned.
 */
 */
int key_instantiate_and_link(struct key *key,
int key_instantiate_and_link(struct key *key,
			     const void *data,
			     const void *data,
@@ -462,8 +502,24 @@ int key_instantiate_and_link(struct key *key,


EXPORT_SYMBOL(key_instantiate_and_link);
EXPORT_SYMBOL(key_instantiate_and_link);


/*
/**
 * negatively instantiate a key and link it into the target keyring atomically
 * key_negate_and_link - Negatively instantiate a key and link it into the keyring.
 * @key: The key to instantiate.
 * @timeout: The timeout on the negative key.
 * @keyring: Keyring to create a link in on success (or NULL).
 * @authkey: The authorisation token permitting instantiation.
 *
 * Negatively instantiate a key that's in the uninstantiated state and, if
 * successful, set its timeout and link it in to the destination keyring if one
 * is supplied.  The key and any links to the key will be automatically garbage
 * collected after the timeout expires.
 *
 * Negative keys are used to rate limit repeated request_key() calls by causing
 * them to return -ENOKEY until the negative key expires.
 *
 * If successful, 0 is returned, the authorisation token is revoked and anyone
 * waiting for the key is woken up.  If the key was already instantiated,
 * -EBUSY will be returned.
 */
 */
int key_negate_and_link(struct key *key,
int key_negate_and_link(struct key *key,
			unsigned timeout,
			unsigned timeout,
@@ -525,8 +581,11 @@ int key_negate_and_link(struct key *key,
EXPORT_SYMBOL(key_negate_and_link);
EXPORT_SYMBOL(key_negate_and_link);


/*
/*
 * do cleaning up in process context so that we don't have to disable
 * Garbage collect keys in process context so that we don't have to disable
 * interrupts all over the place
 * interrupts all over the place.
 *
 * key_put() schedules this rather than trying to do the cleanup itself, which
 * means key_put() doesn't have to sleep.
 */
 */
static void key_cleanup(struct work_struct *work)
static void key_cleanup(struct work_struct *work)
{
{
@@ -586,10 +645,13 @@ static void key_cleanup(struct work_struct *work)
	goto go_again;
	goto go_again;
}
}


/*
/**
 * dispose of a reference to a key
 * key_put - Discard a reference to a key.
 * - when all the references are gone, we schedule the cleanup task to come and
 * @key: The key to discard a reference from.
 *   pull it out of the tree in definite process context
 *
 * Discard a reference to a key, and when all the references are gone, we
 * schedule the cleanup task to come and pull it out of the tree in process
 * context at some later time.
 */
 */
void key_put(struct key *key)
void key_put(struct key *key)
{
{
@@ -600,11 +662,10 @@ void key_put(struct key *key)
			schedule_work(&key_cleanup_task);
			schedule_work(&key_cleanup_task);
	}
	}
}
}

EXPORT_SYMBOL(key_put);
EXPORT_SYMBOL(key_put);


/*
/*
 * find a key by its serial number
 * Find a key by its serial number.
 */
 */
struct key *key_lookup(key_serial_t id)
struct key *key_lookup(key_serial_t id)
{
{
@@ -646,8 +707,10 @@ struct key *key_lookup(key_serial_t id)
}
}


/*
/*
 * find and lock the specified key type against removal
 * Find and lock the specified key type against removal.
 * - we return with the sem readlocked
 *
 * We return with the sem read-locked if successful.  If the type wasn't
 * available -ENOKEY is returned instead.
 */
 */
struct key_type *key_type_lookup(const char *type)
struct key_type *key_type_lookup(const char *type)
{
{
@@ -670,7 +733,7 @@ struct key_type *key_type_lookup(const char *type)
}
}


/*
/*
 * unlock a key type
 * Unlock a key type locked by key_type_lookup().
 */
 */
void key_type_put(struct key_type *ktype)
void key_type_put(struct key_type *ktype)
{
{
@@ -678,9 +741,10 @@ void key_type_put(struct key_type *ktype)
}
}


/*
/*
 * attempt to update an existing key
 * Attempt to update an existing key.
 * - the key has an incremented refcount
 *
 * - we need to put the key if we get an error
 * The key is given to us with an incremented refcount that we need to discard
 * if we get an error.
 */
 */
static inline key_ref_t __key_update(key_ref_t key_ref,
static inline key_ref_t __key_update(key_ref_t key_ref,
				     const void *payload, size_t plen)
				     const void *payload, size_t plen)
@@ -717,9 +781,30 @@ error:
	goto out;
	goto out;
}
}


/*
/**
 * search the specified keyring for a key of the same description; if one is
 * key_create_or_update - Update or create and instantiate a key.
 * found, update it, otherwise add a new one
 * @keyring_ref: A pointer to the destination keyring with possession flag.
 * @type: The type of key.
 * @description: The searchable description for the key.
 * @payload: The data to use to instantiate or update the key.
 * @plen: The length of @payload.
 * @perm: The permissions mask for a new key.
 * @flags: The quota flags for a new key.
 *
 * Search the destination keyring for a key of the same description and if one
 * is found, update it, otherwise create and instantiate a new one and create a
 * link to it from that keyring.
 *
 * If perm is KEY_PERM_UNDEF then an appropriate key permissions mask will be
 * concocted.
 *
 * Returns a pointer to the new key if successful, -ENODEV if the key type
 * wasn't available, -ENOTDIR if the keyring wasn't a keyring, -EACCES if the
 * caller isn't permitted to modify the keyring or the LSM did not permit
 * creation of the key.
 *
 * On success, the possession flag from the keyring ref will be tacked on to
 * the key ref before it is returned.
 */
 */
key_ref_t key_create_or_update(key_ref_t keyring_ref,
key_ref_t key_create_or_update(key_ref_t keyring_ref,
			       const char *type,
			       const char *type,
@@ -827,11 +912,20 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
	key_ref = __key_update(key_ref, payload, plen);
	key_ref = __key_update(key_ref, payload, plen);
	goto error;
	goto error;
}
}

EXPORT_SYMBOL(key_create_or_update);
EXPORT_SYMBOL(key_create_or_update);


/*
/**
 * update a key
 * key_update - Update a key's contents.
 * @key_ref: The pointer (plus possession flag) to the key.
 * @payload: The data to be used to update the key.
 * @plen: The length of @payload.
 *
 * Attempt to update the contents of a key with the given payload data.  The
 * caller must be granted Write permission on the key.  Negative keys can be
 * instantiated by this method.
 *
 * Returns 0 on success, -EACCES if not permitted and -EOPNOTSUPP if the key
 * type does not support updating.  The key type may return other errors.
 */
 */
int key_update(key_ref_t key_ref, const void *payload, size_t plen)
int key_update(key_ref_t key_ref, const void *payload, size_t plen)
{
{
@@ -861,11 +955,16 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
 error:
 error:
	return ret;
	return ret;
}
}

EXPORT_SYMBOL(key_update);
EXPORT_SYMBOL(key_update);


/*
/**
 * revoke a key
 * key_revoke - Revoke a key.
 * @key: The key to be revoked.
 *
 * Mark a key as being revoked and ask the type to free up its resources.  The
 * revocation timeout is set and the key and all its links will be
 * automatically garbage collected after key_gc_delay amount of time if they
 * are not manually dealt with first.
 */
 */
void key_revoke(struct key *key)
void key_revoke(struct key *key)
{
{
@@ -894,11 +993,15 @@ void key_revoke(struct key *key)


	up_write(&key->sem);
	up_write(&key->sem);
}
}

EXPORT_SYMBOL(key_revoke);
EXPORT_SYMBOL(key_revoke);


/*
/**
 * register a type of key
 * register_key_type - Register a type of key.
 * @ktype: The new key type.
 *
 * Register a new key type.
 *
 * Returns 0 on success or -EEXIST if a type of this name already exists.
 */
 */
int register_key_type(struct key_type *ktype)
int register_key_type(struct key_type *ktype)
{
{
@@ -922,11 +1025,15 @@ int register_key_type(struct key_type *ktype)
	up_write(&key_types_sem);
	up_write(&key_types_sem);
	return ret;
	return ret;
}
}

EXPORT_SYMBOL(register_key_type);
EXPORT_SYMBOL(register_key_type);


/*
/**
 * unregister a type of key
 * unregister_key_type - Unregister a type of key.
 * @ktype: The key type.
 *
 * Unregister a key type and mark all the extant keys of this type as dead.
 * Those keys of this type are then destroyed to get rid of their payloads and
 * they and their links will be garbage collected as soon as possible.
 */
 */
void unregister_key_type(struct key_type *ktype)
void unregister_key_type(struct key_type *ktype)
{
{
@@ -974,11 +1081,10 @@ void unregister_key_type(struct key_type *ktype)


	key_schedule_gc(0);
	key_schedule_gc(0);
}
}

EXPORT_SYMBOL(unregister_key_type);
EXPORT_SYMBOL(unregister_key_type);


/*
/*
 * initialise the key management stuff
 * Initialise the key management state.
 */
 */
void __init key_init(void)
void __init key_init(void)
{
{
+186 −92

File changed.

Preview size limit exceeded, changes collapsed.

Loading