diff options
author | David Howells <dhowells@redhat.com> | 2006-03-25 03:06:52 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-25 08:22:50 -0800 |
commit | 1d9b7d97d6661edb44ce08f17e47c66d4ac20e34 (patch) | |
tree | aacf3d99c547d94e4fb1bbeb2a4eb887301c2319 /security/keys/key.c | |
parent | 3dccff8dc00994428777f483922058c554db85bd (diff) | |
download | linux-1d9b7d97d6661edb44ce08f17e47c66d4ac20e34.tar.gz linux-1d9b7d97d6661edb44ce08f17e47c66d4ac20e34.tar.bz2 linux-1d9b7d97d6661edb44ce08f17e47c66d4ac20e34.zip |
[PATCH] Keys: Replace duplicate non-updateable keys rather than failing
Cause an attempt to add a duplicate non-updateable key (such as a keyring) to
a keyring to discard the extant copy in favour of the new one rather than
failing with EEXIST:
# do the test in an empty session
keyctl session
# create a new keyring called "a" and attach to session
keyctl newring a @s
# create another new keyring called "a" and attach to session,
# displacing the keyring added by the second command:
keyctl newring a @s
Without this patch, the third command will fail.
For updateable keys (such as those of "user" type), the update method will
still be called rather than a new key being created.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security/keys/key.c')
-rw-r--r-- | security/keys/key.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/security/keys/key.c b/security/keys/key.c index 627697181e6a..a057e3311aad 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -795,12 +795,16 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref, goto error_3; } - /* search for an existing key of the same type and description in the - * destination keyring + /* 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 */ - key_ref = __keyring_search_one(keyring_ref, ktype, description, 0); - if (!IS_ERR(key_ref)) - goto found_matching_key; + 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; |