aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/key.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/key.c')
-rw-r--r--security/keys/key.c56
1 files changed, 40 insertions, 16 deletions
diff --git a/security/keys/key.c b/security/keys/key.c
index 2182be9e9309..ccde17aff616 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -1,6 +1,6 @@
1/* key.c: basic authentication token and access key management 1/* key.c: basic authentication token and access key management
2 * 2 *
3 * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
@@ -13,6 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/security.h>
16#include <linux/workqueue.h> 17#include <linux/workqueue.h>
17#include <linux/err.h> 18#include <linux/err.h>
18#include "internal.h" 19#include "internal.h"
@@ -253,6 +254,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
253 struct key_user *user = NULL; 254 struct key_user *user = NULL;
254 struct key *key; 255 struct key *key;
255 size_t desclen, quotalen; 256 size_t desclen, quotalen;
257 int ret;
256 258
257 key = ERR_PTR(-EINVAL); 259 key = ERR_PTR(-EINVAL);
258 if (!desc || !*desc) 260 if (!desc || !*desc)
@@ -305,6 +307,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
305 key->flags = 0; 307 key->flags = 0;
306 key->expiry = 0; 308 key->expiry = 0;
307 key->payload.data = NULL; 309 key->payload.data = NULL;
310 key->security = NULL;
308 311
309 if (!not_in_quota) 312 if (!not_in_quota)
310 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 313 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
@@ -315,16 +318,34 @@ struct key *key_alloc(struct key_type *type, const char *desc,
315 key->magic = KEY_DEBUG_MAGIC; 318 key->magic = KEY_DEBUG_MAGIC;
316#endif 319#endif
317 320
321 /* let the security module know about the key */
322 ret = security_key_alloc(key);
323 if (ret < 0)
324 goto security_error;
325
318 /* publish the key by giving it a serial number */ 326 /* publish the key by giving it a serial number */
319 atomic_inc(&user->nkeys); 327 atomic_inc(&user->nkeys);
320 key_alloc_serial(key); 328 key_alloc_serial(key);
321 329
322 error: 330error:
323 return key; 331 return key;
324 332
325 no_memory_3: 333security_error:
334 kfree(key->description);
335 kmem_cache_free(key_jar, key);
336 if (!not_in_quota) {
337 spin_lock(&user->lock);
338 user->qnkeys--;
339 user->qnbytes -= quotalen;
340 spin_unlock(&user->lock);
341 }
342 key_user_put(user);
343 key = ERR_PTR(ret);
344 goto error;
345
346no_memory_3:
326 kmem_cache_free(key_jar, key); 347 kmem_cache_free(key_jar, key);
327 no_memory_2: 348no_memory_2:
328 if (!not_in_quota) { 349 if (!not_in_quota) {
329 spin_lock(&user->lock); 350 spin_lock(&user->lock);
330 user->qnkeys--; 351 user->qnkeys--;
@@ -332,11 +353,11 @@ struct key *key_alloc(struct key_type *type, const char *desc,
332 spin_unlock(&user->lock); 353 spin_unlock(&user->lock);
333 } 354 }
334 key_user_put(user); 355 key_user_put(user);
335 no_memory_1: 356no_memory_1:
336 key = ERR_PTR(-ENOMEM); 357 key = ERR_PTR(-ENOMEM);
337 goto error; 358 goto error;
338 359
339 no_quota: 360no_quota:
340 spin_unlock(&user->lock); 361 spin_unlock(&user->lock);
341 key_user_put(user); 362 key_user_put(user);
342 key = ERR_PTR(-EDQUOT); 363 key = ERR_PTR(-EDQUOT);
@@ -556,6 +577,8 @@ static void key_cleanup(void *data)
556 577
557 key_check(key); 578 key_check(key);
558 579
580 security_key_free(key);
581
559 /* deal with the user's key tracking and quota */ 582 /* deal with the user's key tracking and quota */
560 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { 583 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
561 spin_lock(&key->user->lock); 584 spin_lock(&key->user->lock);
@@ -700,8 +723,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
700 int ret; 723 int ret;
701 724
702 /* need write permission on the key to update it */ 725 /* need write permission on the key to update it */
703 ret = -EACCES; 726 ret = key_permission(key_ref, KEY_WRITE);
704 if (!key_permission(key_ref, KEY_WRITE)) 727 if (ret < 0)
705 goto error; 728 goto error;
706 729
707 ret = -EEXIST; 730 ret = -EEXIST;
@@ -711,7 +734,6 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
711 down_write(&key->sem); 734 down_write(&key->sem);
712 735
713 ret = key->type->update(key, payload, plen); 736 ret = key->type->update(key, payload, plen);
714
715 if (ret == 0) 737 if (ret == 0)
716 /* updating a negative key instantiates it */ 738 /* updating a negative key instantiates it */
717 clear_bit(KEY_FLAG_NEGATIVE, &key->flags); 739 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
@@ -768,9 +790,11 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
768 790
769 /* if we're going to allocate a new key, we're going to have 791 /* if we're going to allocate a new key, we're going to have
770 * to modify the keyring */ 792 * to modify the keyring */
771 key_ref = ERR_PTR(-EACCES); 793 ret = key_permission(keyring_ref, KEY_WRITE);
772 if (!key_permission(keyring_ref, KEY_WRITE)) 794 if (ret < 0) {
795 key_ref = ERR_PTR(ret);
773 goto error_3; 796 goto error_3;
797 }
774 798
775 /* search for an existing key of the same type and description in the 799 /* search for an existing key of the same type and description in the
776 * destination keyring 800 * destination keyring
@@ -780,8 +804,8 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
780 goto found_matching_key; 804 goto found_matching_key;
781 805
782 /* decide on the permissions we want */ 806 /* decide on the permissions we want */
783 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK; 807 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
784 perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK; 808 perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;
785 809
786 if (ktype->read) 810 if (ktype->read)
787 perm |= KEY_POS_READ | KEY_USR_READ; 811 perm |= KEY_POS_READ | KEY_USR_READ;
@@ -840,16 +864,16 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
840 key_check(key); 864 key_check(key);
841 865
842 /* the key must be writable */ 866 /* the key must be writable */
843 ret = -EACCES; 867 ret = key_permission(key_ref, KEY_WRITE);
844 if (!key_permission(key_ref, KEY_WRITE)) 868 if (ret < 0)
845 goto error; 869 goto error;
846 870
847 /* attempt to update it if supported */ 871 /* attempt to update it if supported */
848 ret = -EOPNOTSUPP; 872 ret = -EOPNOTSUPP;
849 if (key->type->update) { 873 if (key->type->update) {
850 down_write(&key->sem); 874 down_write(&key->sem);
851 ret = key->type->update(key, payload, plen);
852 875
876 ret = key->type->update(key, payload, plen);
853 if (ret == 0) 877 if (ret == 0)
854 /* updating a negative key instantiates it */ 878 /* updating a negative key instantiates it */
855 clear_bit(KEY_FLAG_NEGATIVE, &key->flags); 879 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);