Skip to content

Commit

Permalink
[PATCH] Keys: Remove key duplication
Browse files Browse the repository at this point in the history
Remove the key duplication stuff since there's nothing that uses it, no way
to get at it and it's awkward to deal with for LSM purposes.

Signed-off-by: David Howells <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
dhowells authored and Linus Torvalds committed Jan 6, 2006
1 parent 32725ad commit 8d9067b
Show file tree
Hide file tree
Showing 6 changed files with 3 additions and 177 deletions.
18 changes: 0 additions & 18 deletions Documentation/keys.txt
Original file line number Diff line number Diff line change
Expand Up @@ -860,24 +860,6 @@ The structure has a number of fields, some of which are mandatory:
It is safe to sleep in this method.


(*) int (*duplicate)(struct key *key, const struct key *source);

If this type of key can be duplicated, then this method should be
provided. It is called to copy the payload attached to the source into the
new key. The data length on the new key will have been updated and the
quota adjusted already.

This method will be called with the source key's semaphore read-locked to
prevent its payload from being changed, thus RCU constraints need not be
applied to the source key.

This method does not have to lock the destination key in order to attach a
payload. The fact that KEY_FLAG_INSTANTIATED is not set in key->flags
prevents anything else from gaining access to the key.

It is safe to sleep in this method.


(*) int (*update)(struct key *key, const void *data, size_t datalen);

If this type of key can be updated, then this method should be provided.
Expand Down
1 change: 0 additions & 1 deletion include/keys/user-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ struct user_key_payload {
extern struct key_type key_type_user;

extern int user_instantiate(struct key *key, const void *data, size_t datalen);
extern int user_duplicate(struct key *key, const struct key *source);
extern int user_update(struct key *key, const void *data, size_t datalen);
extern int user_match(const struct key *key, const void *criterion);
extern void user_destroy(struct key *key);
Expand Down
8 changes: 0 additions & 8 deletions include/linux/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,6 @@ struct key_type {
*/
int (*instantiate)(struct key *key, const void *data, size_t datalen);

/* duplicate a key of this type (optional)
* - the source key will be locked against change
* - the new description will be attached
* - the quota will have been adjusted automatically from
* source->quotalen
*/
int (*duplicate)(struct key *key, const struct key *source);

/* update a key of this type (optional)
* - this method should call key_payload_reserve() to recalculate the
* quota consumption
Expand Down
56 changes: 3 additions & 53 deletions security/keys/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,9 @@ static inline void key_alloc_serial(struct key *key)
/*
* 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 either
* key_create_or_update() or by key_duplicate(); this prevents unregistration
* of the key type
* - 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
*/
Expand Down Expand Up @@ -887,56 +887,6 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)

EXPORT_SYMBOL(key_update);

/*****************************************************************************/
/*
* duplicate a key, potentially with a revised description
* - must be supported by the keytype (keyrings for instance can be duplicated)
*/
struct key *key_duplicate(struct key *source, const char *desc)
{
struct key *key;
int ret;

key_check(source);

if (!desc)
desc = source->description;

down_read(&key_types_sem);

ret = -EINVAL;
if (!source->type->duplicate)
goto error;

/* allocate and instantiate a key */
key = key_alloc(source->type, desc, current->fsuid, current->fsgid,
source->perm, 0);
if (IS_ERR(key))
goto error_k;

down_read(&source->sem);
ret = key->type->duplicate(key, source);
up_read(&source->sem);
if (ret < 0)
goto error2;

atomic_inc(&key->user->nikeys);
set_bit(KEY_FLAG_INSTANTIATED, &key->flags);

error_k:
up_read(&key_types_sem);
out:
return key;

error2:
key_put(key);
error:
up_read(&key_types_sem);
key = ERR_PTR(ret);
goto out;

} /* end key_duplicate() */

/*****************************************************************************/
/*
* revoke a key
Expand Down
64 changes: 0 additions & 64 deletions security/keys/keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ static inline unsigned keyring_hash(const char *desc)
*/
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);
Expand All @@ -59,7 +58,6 @@ 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,
Expand Down Expand Up @@ -118,68 +116,6 @@ static int keyring_instantiate(struct key *keyring,

} /* 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
Expand Down
33 changes: 0 additions & 33 deletions security/keys/user_defined.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
struct key_type key_type_user = {
.name = "user",
.instantiate = user_instantiate,
.duplicate = user_duplicate,
.update = user_update,
.match = user_match,
.destroy = user_destroy,
Expand Down Expand Up @@ -68,40 +67,8 @@ int user_instantiate(struct key *key, const void *data, size_t datalen)
return ret;

} /* end user_instantiate() */

EXPORT_SYMBOL_GPL(user_instantiate);

/*****************************************************************************/
/*
* duplicate a user defined key
* - both keys' semaphores are locked against further modification
* - the new key cannot yet be accessed
*/
int user_duplicate(struct key *key, const struct key *source)
{
struct user_key_payload *upayload, *spayload;
int ret;

/* just copy the payload */
ret = -ENOMEM;
upayload = kmalloc(sizeof(*upayload) + source->datalen, GFP_KERNEL);
if (upayload) {
spayload = rcu_dereference(source->payload.data);
BUG_ON(source->datalen != spayload->datalen);

upayload->datalen = key->datalen = spayload->datalen;
memcpy(upayload->data, spayload->data, key->datalen);

key->payload.data = upayload;
ret = 0;
}

return ret;

} /* end user_duplicate() */

EXPORT_SYMBOL_GPL(user_duplicate);

/*****************************************************************************/
/*
* dispose of the old data from an updated user defined key
Expand Down

0 comments on commit 8d9067b

Please sign in to comment.