aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c23
-rw-r--r--security/keys/key.c56
-rw-r--r--security/keys/keyctl.c13
-rw-r--r--security/keys/keyring.c21
-rw-r--r--security/keys/permission.c7
-rw-r--r--security/keys/process_keys.c9
6 files changed, 94 insertions, 35 deletions
diff --git a/security/dummy.c b/security/dummy.c
index 2a0337a52d32..3ca5f2b828a0 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -803,6 +803,23 @@ static int dummy_setprocattr(struct task_struct *p, char *name, void *value, siz
803 return -EINVAL; 803 return -EINVAL;
804} 804}
805 805
806#ifdef CONFIG_KEYS
807static inline int dummy_key_alloc(struct key *key)
808{
809 return 0;
810}
811
812static inline void dummy_key_free(struct key *key)
813{
814}
815
816static inline int dummy_key_permission(key_ref_t key_ref,
817 struct task_struct *context,
818 key_perm_t perm)
819{
820 return 0;
821}
822#endif /* CONFIG_KEYS */
806 823
807struct security_operations dummy_security_ops; 824struct security_operations dummy_security_ops;
808 825
@@ -954,5 +971,11 @@ void security_fixup_ops (struct security_operations *ops)
954 set_to_dummy_if_null(ops, sk_alloc_security); 971 set_to_dummy_if_null(ops, sk_alloc_security);
955 set_to_dummy_if_null(ops, sk_free_security); 972 set_to_dummy_if_null(ops, sk_free_security);
956#endif /* CONFIG_SECURITY_NETWORK */ 973#endif /* CONFIG_SECURITY_NETWORK */
974#ifdef CONFIG_KEYS
975 set_to_dummy_if_null(ops, key_alloc);
976 set_to_dummy_if_null(ops, key_free);
977 set_to_dummy_if_null(ops, key_permission);
978#endif /* CONFIG_KEYS */
979
957} 980}
958 981
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);
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 4c670ee6acf9..b7a468fabdf9 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -624,8 +624,8 @@ long keyctl_keyring_search(key_serial_t ringid,
624 624
625 /* link the resulting key to the destination keyring if we can */ 625 /* link the resulting key to the destination keyring if we can */
626 if (dest_ref) { 626 if (dest_ref) {
627 ret = -EACCES; 627 ret = key_permission(key_ref, KEY_LINK);
628 if (!key_permission(key_ref, KEY_LINK)) 628 if (ret < 0)
629 goto error6; 629 goto error6;
630 630
631 ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref)); 631 ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref));
@@ -676,8 +676,11 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
676 key = key_ref_to_ptr(key_ref); 676 key = key_ref_to_ptr(key_ref);
677 677
678 /* see if we can read it directly */ 678 /* see if we can read it directly */
679 if (key_permission(key_ref, KEY_READ)) 679 ret = key_permission(key_ref, KEY_READ);
680 if (ret == 0)
680 goto can_read_key; 681 goto can_read_key;
682 if (ret != -EACCES)
683 goto error;
681 684
682 /* we can't; see if it's searchable from this process's keyrings 685 /* we can't; see if it's searchable from this process's keyrings
683 * - we automatically take account of the fact that it may be 686 * - we automatically take account of the fact that it may be
@@ -726,7 +729,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
726 if (uid == (uid_t) -1 && gid == (gid_t) -1) 729 if (uid == (uid_t) -1 && gid == (gid_t) -1)
727 goto error; 730 goto error;
728 731
729 key_ref = lookup_user_key(NULL, id, 1, 1, 0); 732 key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
730 if (IS_ERR(key_ref)) { 733 if (IS_ERR(key_ref)) {
731 ret = PTR_ERR(key_ref); 734 ret = PTR_ERR(key_ref);
732 goto error; 735 goto error;
@@ -786,7 +789,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
786 if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) 789 if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
787 goto error; 790 goto error;
788 791
789 key_ref = lookup_user_key(NULL, id, 1, 1, 0); 792 key_ref = lookup_user_key(NULL, id, 1, 1, KEY_SETATTR);
790 if (IS_ERR(key_ref)) { 793 if (IS_ERR(key_ref)) {
791 ret = PTR_ERR(key_ref); 794 ret = PTR_ERR(key_ref);
792 goto error; 795 goto error;
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 0639396dd441..e1cc4dd79012 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -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/seq_file.h> 17#include <linux/seq_file.h>
17#include <linux/err.h> 18#include <linux/err.h>
18#include <asm/uaccess.h> 19#include <asm/uaccess.h>
@@ -309,7 +310,9 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
309 int ret; 310 int ret;
310 311
311 keyring = key_alloc(&key_type_keyring, description, 312 keyring = key_alloc(&key_type_keyring, description,
312 uid, gid, KEY_POS_ALL | KEY_USR_ALL, not_in_quota); 313 uid, gid,
314 (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
315 not_in_quota);
313 316
314 if (!IS_ERR(keyring)) { 317 if (!IS_ERR(keyring)) {
315 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); 318 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
@@ -359,9 +362,11 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
359 key_check(keyring); 362 key_check(keyring);
360 363
361 /* top keyring must have search permission to begin the search */ 364 /* top keyring must have search permission to begin the search */
362 key_ref = ERR_PTR(-EACCES); 365 err = key_task_permission(keyring_ref, context, KEY_SEARCH);
363 if (!key_task_permission(keyring_ref, context, KEY_SEARCH)) 366 if (err < 0) {
367 key_ref = ERR_PTR(err);
364 goto error; 368 goto error;
369 }
365 370
366 key_ref = ERR_PTR(-ENOTDIR); 371 key_ref = ERR_PTR(-ENOTDIR);
367 if (keyring->type != &key_type_keyring) 372 if (keyring->type != &key_type_keyring)
@@ -402,8 +407,8 @@ descend:
402 continue; 407 continue;
403 408
404 /* key must have search permissions */ 409 /* key must have search permissions */
405 if (!key_task_permission(make_key_ref(key, possessed), 410 if (key_task_permission(make_key_ref(key, possessed),
406 context, KEY_SEARCH)) 411 context, KEY_SEARCH) < 0)
407 continue; 412 continue;
408 413
409 /* we set a different error code if we find a negative key */ 414 /* we set a different error code if we find a negative key */
@@ -430,7 +435,7 @@ ascend:
430 continue; 435 continue;
431 436
432 if (!key_task_permission(make_key_ref(key, possessed), 437 if (!key_task_permission(make_key_ref(key, possessed),
433 context, KEY_SEARCH)) 438 context, KEY_SEARCH) < 0)
434 continue; 439 continue;
435 440
436 /* stack the current position */ 441 /* stack the current position */
@@ -521,7 +526,7 @@ key_ref_t __keyring_search_one(key_ref_t keyring_ref,
521 (!key->type->match || 526 (!key->type->match ||
522 key->type->match(key, description)) && 527 key->type->match(key, description)) &&
523 key_permission(make_key_ref(key, possessed), 528 key_permission(make_key_ref(key, possessed),
524 perm) && 529 perm) < 0 &&
525 !test_bit(KEY_FLAG_REVOKED, &key->flags) 530 !test_bit(KEY_FLAG_REVOKED, &key->flags)
526 ) 531 )
527 goto found; 532 goto found;
@@ -617,7 +622,7 @@ struct key *find_keyring_by_name(const char *name, key_serial_t bound)
617 continue; 622 continue;
618 623
619 if (!key_permission(make_key_ref(keyring, 0), 624 if (!key_permission(make_key_ref(keyring, 0),
620 KEY_SEARCH)) 625 KEY_SEARCH) < 0)
621 continue; 626 continue;
622 627
623 /* found a potential candidate, but we still need to 628 /* found a potential candidate, but we still need to
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 03db073ba45c..e7f579c0eaf5 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/security.h>
13#include "internal.h" 14#include "internal.h"
14 15
15/*****************************************************************************/ 16/*****************************************************************************/
@@ -63,7 +64,11 @@ use_these_perms:
63 64
64 kperm = kperm & perm & KEY_ALL; 65 kperm = kperm & perm & KEY_ALL;
65 66
66 return kperm == perm; 67 if (kperm != perm)
68 return -EACCES;
69
70 /* let LSM be the final arbiter */
71 return security_key_permission(key_ref, context, perm);
67 72
68} /* end key_task_permission() */ 73} /* end key_task_permission() */
69 74
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index d42d2158ce13..566b1cc0118a 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -39,7 +39,7 @@ struct key root_user_keyring = {
39 .type = &key_type_keyring, 39 .type = &key_type_keyring,
40 .user = &root_key_user, 40 .user = &root_key_user,
41 .sem = __RWSEM_INITIALIZER(root_user_keyring.sem), 41 .sem = __RWSEM_INITIALIZER(root_user_keyring.sem),
42 .perm = KEY_POS_ALL | KEY_USR_ALL, 42 .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
43 .flags = 1 << KEY_FLAG_INSTANTIATED, 43 .flags = 1 << KEY_FLAG_INSTANTIATED,
44 .description = "_uid.0", 44 .description = "_uid.0",
45#ifdef KEY_DEBUGGING 45#ifdef KEY_DEBUGGING
@@ -54,7 +54,7 @@ struct key root_session_keyring = {
54 .type = &key_type_keyring, 54 .type = &key_type_keyring,
55 .user = &root_key_user, 55 .user = &root_key_user,
56 .sem = __RWSEM_INITIALIZER(root_session_keyring.sem), 56 .sem = __RWSEM_INITIALIZER(root_session_keyring.sem),
57 .perm = KEY_POS_ALL | KEY_USR_ALL, 57 .perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL,
58 .flags = 1 << KEY_FLAG_INSTANTIATED, 58 .flags = 1 << KEY_FLAG_INSTANTIATED,
59 .description = "_uid_ses.0", 59 .description = "_uid_ses.0",
60#ifdef KEY_DEBUGGING 60#ifdef KEY_DEBUGGING
@@ -666,9 +666,8 @@ key_ref_t lookup_user_key(struct task_struct *context, key_serial_t id,
666 goto invalid_key; 666 goto invalid_key;
667 667
668 /* check the permissions */ 668 /* check the permissions */
669 ret = -EACCES; 669 ret = key_task_permission(key_ref, context, perm);
670 670 if (ret < 0)
671 if (!key_task_permission(key_ref, context, perm))
672 goto invalid_key; 671 goto invalid_key;
673 672
674error: 673error: