diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/dummy.c | 23 | ||||
-rw-r--r-- | security/keys/key.c | 56 | ||||
-rw-r--r-- | security/keys/keyctl.c | 13 | ||||
-rw-r--r-- | security/keys/keyring.c | 21 | ||||
-rw-r--r-- | security/keys/permission.c | 7 | ||||
-rw-r--r-- | security/keys/process_keys.c | 9 |
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 | ||
807 | static inline int dummy_key_alloc(struct key *key) | ||
808 | { | ||
809 | return 0; | ||
810 | } | ||
811 | |||
812 | static inline void dummy_key_free(struct key *key) | ||
813 | { | ||
814 | } | ||
815 | |||
816 | static 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 | ||
807 | struct security_operations dummy_security_ops; | 824 | struct 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: | 330 | error: |
323 | return key; | 331 | return key; |
324 | 332 | ||
325 | no_memory_3: | 333 | security_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 | |||
346 | no_memory_3: | ||
326 | kmem_cache_free(key_jar, key); | 347 | kmem_cache_free(key_jar, key); |
327 | no_memory_2: | 348 | no_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: | 356 | no_memory_1: |
336 | key = ERR_PTR(-ENOMEM); | 357 | key = ERR_PTR(-ENOMEM); |
337 | goto error; | 358 | goto error; |
338 | 359 | ||
339 | no_quota: | 360 | no_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 | ||
674 | error: | 673 | error: |