Commit 29db9190634067c5a328ee5fcc2890251b836b4b

Authored by David Howells
Committed by Linus Torvalds
1 parent 2aa349f6e3

[PATCH] Keys: Add LSM hooks for key management [try #3]

The attached patch adds LSM hooks for key management facilities. The notable
changes are:

 (1) The key struct now supports a security pointer for the use of security
     modules. This will permit key labelling and restrictions on which
     programs may access a key.

 (2) Security modules get a chance to note (or abort) the allocation of a key.

 (3) The key permission checking can now be enhanced by the security modules;
     the permissions check consults LSM if all other checks bear out.

 (4) The key permissions checking functions now return an error code rather
     than a boolean value.

 (5) An extra permission has been added to govern the modification of
     attributes (UID, GID, permissions).

Note that there isn't an LSM hook specifically for each keyctl() operation,
but rather the permissions hook allows control of individual operations based
on the permission request bits.

Key management access control through LSM is enabled by automatically if both
CONFIG_KEYS and CONFIG_SECURITY are enabled.

This should be applied on top of the patch ensubjected:

	[PATCH] Keys: Possessor permissions should be additive

Signed-Off-By: David Howells <dhowells@redhat.com>
Signed-off-by: Chris Wright <chrisw@osdl.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 10 changed files with 191 additions and 49 deletions Side-by-side Diff

Documentation/keys.txt
... ... @@ -196,7 +196,7 @@
196 196  
197 197 Keys have an owner user ID, a group access ID, and a permissions mask. The mask
198 198 has up to eight bits each for possessor, user, group and other access. Only
199   -five of each set of eight bits are defined. These permissions granted are:
  199 +six of each set of eight bits are defined. These permissions granted are:
200 200  
201 201 (*) View
202 202  
... ... @@ -224,6 +224,10 @@
224 224 keyring to a key, a process must have Write permission on the keyring and
225 225 Link permission on the key.
226 226  
  227 + (*) Set Attribute
  228 +
  229 + This permits a key's UID, GID and permissions mask to be changed.
  230 +
227 231 For changing the ownership, group ID or permissions mask, being the owner of
228 232 the key or having the sysadmin capability is sufficient.
229 233  
230 234  
... ... @@ -242,15 +246,15 @@
242 246 this way:
243 247  
244 248 SERIAL FLAGS USAGE EXPY PERM UID GID TYPE DESCRIPTION: SUMMARY
245   - 00000001 I----- 39 perm 1f1f0000 0 0 keyring _uid_ses.0: 1/4
246   - 00000002 I----- 2 perm 1f1f0000 0 0 keyring _uid.0: empty
247   - 00000007 I----- 1 perm 1f1f0000 0 0 keyring _pid.1: empty
248   - 0000018d I----- 1 perm 1f1f0000 0 0 keyring _pid.412: empty
249   - 000004d2 I--Q-- 1 perm 1f1f0000 32 -1 keyring _uid.32: 1/4
250   - 000004d3 I--Q-- 3 perm 1f1f0000 32 -1 keyring _uid_ses.32: empty
  249 + 00000001 I----- 39 perm 1f3f0000 0 0 keyring _uid_ses.0: 1/4
  250 + 00000002 I----- 2 perm 1f3f0000 0 0 keyring _uid.0: empty
  251 + 00000007 I----- 1 perm 1f3f0000 0 0 keyring _pid.1: empty
  252 + 0000018d I----- 1 perm 1f3f0000 0 0 keyring _pid.412: empty
  253 + 000004d2 I--Q-- 1 perm 1f3f0000 32 -1 keyring _uid.32: 1/4
  254 + 000004d3 I--Q-- 3 perm 1f3f0000 32 -1 keyring _uid_ses.32: empty
251 255 00000892 I--QU- 1 perm 1f000000 0 0 user metal:copper: 0
252   - 00000893 I--Q-N 1 35s 1f1f0000 0 0 user metal:silver: 0
253   - 00000894 I--Q-- 1 10h 001f0000 0 0 user metal:gold: 0
  256 + 00000893 I--Q-N 1 35s 1f3f0000 0 0 user metal:silver: 0
  257 + 00000894 I--Q-- 1 10h 003f0000 0 0 user metal:gold: 0
254 258  
255 259 The flags are:
256 260  
include/linux/key-ui.h
... ... @@ -24,7 +24,8 @@
24 24 #define KEY_WRITE 0x04 /* require permission to update / modify */
25 25 #define KEY_SEARCH 0x08 /* require permission to search (keyring) or find (key) */
26 26 #define KEY_LINK 0x10 /* require permission to link */
27   -#define KEY_ALL 0x1f /* all the above permissions */
  27 +#define KEY_SETATTR 0x20 /* require permission to change attributes */
  28 +#define KEY_ALL 0x3f /* all the above permissions */
28 29  
29 30 /*
30 31 * the keyring payload contains a list of the keys to which the keyring is
... ... @@ -40,28 +40,32 @@
40 40 #define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */
41 41 #define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */
42 42 #define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */
43   -#define KEY_POS_ALL 0x1f000000
  43 +#define KEY_POS_SETATTR 0x20000000 /* possessor can set key attributes */
  44 +#define KEY_POS_ALL 0x3f000000
44 45  
45 46 #define KEY_USR_VIEW 0x00010000 /* user permissions... */
46 47 #define KEY_USR_READ 0x00020000
47 48 #define KEY_USR_WRITE 0x00040000
48 49 #define KEY_USR_SEARCH 0x00080000
49 50 #define KEY_USR_LINK 0x00100000
50   -#define KEY_USR_ALL 0x001f0000
  51 +#define KEY_USR_SETATTR 0x00200000
  52 +#define KEY_USR_ALL 0x003f0000
51 53  
52 54 #define KEY_GRP_VIEW 0x00000100 /* group permissions... */
53 55 #define KEY_GRP_READ 0x00000200
54 56 #define KEY_GRP_WRITE 0x00000400
55 57 #define KEY_GRP_SEARCH 0x00000800
56 58 #define KEY_GRP_LINK 0x00001000
57   -#define KEY_GRP_ALL 0x00001f00
  59 +#define KEY_GRP_SETATTR 0x00002000
  60 +#define KEY_GRP_ALL 0x00003f00
58 61  
59 62 #define KEY_OTH_VIEW 0x00000001 /* third party permissions... */
60 63 #define KEY_OTH_READ 0x00000002
61 64 #define KEY_OTH_WRITE 0x00000004
62 65 #define KEY_OTH_SEARCH 0x00000008
63 66 #define KEY_OTH_LINK 0x00000010
64   -#define KEY_OTH_ALL 0x0000001f
  67 +#define KEY_OTH_SETATTR 0x00000020
  68 +#define KEY_OTH_ALL 0x0000003f
65 69  
66 70 struct seq_file;
67 71 struct user_struct;
... ... @@ -119,6 +123,7 @@
119 123 struct key_type *type; /* type of key */
120 124 struct rw_semaphore sem; /* change vs change sem */
121 125 struct key_user *user; /* owner of this key */
  126 + void *security; /* security data for this key */
122 127 time_t expiry; /* time at which key expires (or 0) */
123 128 uid_t uid;
124 129 gid_t gid;
include/linux/security.h
... ... @@ -30,6 +30,7 @@
30 30 #include <linux/shm.h>
31 31 #include <linux/msg.h>
32 32 #include <linux/sched.h>
  33 +#include <linux/key.h>
33 34  
34 35 struct ctl_table;
35 36  
... ... @@ -788,6 +789,27 @@
788 789 * @sk_free_security:
789 790 * Deallocate security structure.
790 791 *
  792 + * Security hooks affecting all Key Management operations
  793 + *
  794 + * @key_alloc:
  795 + * Permit allocation of a key and assign security data. Note that key does
  796 + * not have a serial number assigned at this point.
  797 + * @key points to the key.
  798 + * Return 0 if permission is granted, -ve error otherwise.
  799 + * @key_free:
  800 + * Notification of destruction; free security data.
  801 + * @key points to the key.
  802 + * No return value.
  803 + * @key_permission:
  804 + * See whether a specific operational right is granted to a process on a
  805 + * key.
  806 + * @key_ref refers to the key (key pointer + possession attribute bit).
  807 + * @context points to the process to provide the context against which to
  808 + * evaluate the security data on the key.
  809 + * @perm describes the combination of permissions required of this key.
  810 + * Return 1 if permission granted, 0 if permission denied and -ve it the
  811 + * normal permissions model should be effected.
  812 + *
791 813 * Security hooks affecting all System V IPC operations.
792 814 *
793 815 * @ipc_permission:
... ... @@ -1216,6 +1238,17 @@
1216 1238 int (*sk_alloc_security) (struct sock *sk, int family, gfp_t priority);
1217 1239 void (*sk_free_security) (struct sock *sk);
1218 1240 #endif /* CONFIG_SECURITY_NETWORK */
  1241 +
  1242 + /* key management security hooks */
  1243 +#ifdef CONFIG_KEYS
  1244 + int (*key_alloc)(struct key *key);
  1245 + void (*key_free)(struct key *key);
  1246 + int (*key_permission)(key_ref_t key_ref,
  1247 + struct task_struct *context,
  1248 + key_perm_t perm);
  1249 +
  1250 +#endif /* CONFIG_KEYS */
  1251 +
1219 1252 };
1220 1253  
1221 1254 /* global variables */
... ... @@ -2763,6 +2796,46 @@
2763 2796 {
2764 2797 }
2765 2798 #endif /* CONFIG_SECURITY_NETWORK */
  2799 +
  2800 +#ifdef CONFIG_KEYS
  2801 +#ifdef CONFIG_SECURITY
  2802 +static inline int security_key_alloc(struct key *key)
  2803 +{
  2804 + return security_ops->key_alloc(key);
  2805 +}
  2806 +
  2807 +static inline void security_key_free(struct key *key)
  2808 +{
  2809 + security_ops->key_free(key);
  2810 +}
  2811 +
  2812 +static inline int security_key_permission(key_ref_t key_ref,
  2813 + struct task_struct *context,
  2814 + key_perm_t perm)
  2815 +{
  2816 + return security_ops->key_permission(key_ref, context, perm);
  2817 +}
  2818 +
  2819 +#else
  2820 +
  2821 +static inline int security_key_alloc(struct key *key)
  2822 +{
  2823 + return 0;
  2824 +}
  2825 +
  2826 +static inline void security_key_free(struct key *key)
  2827 +{
  2828 +}
  2829 +
  2830 +static inline int security_key_permission(key_ref_t key_ref,
  2831 + struct task_struct *context,
  2832 + key_perm_t perm)
  2833 +{
  2834 + return 0;
  2835 +}
  2836 +
  2837 +#endif
  2838 +#endif /* CONFIG_KEYS */
2766 2839  
2767 2840 #endif /* ! __LINUX_SECURITY_H */
... ... @@ -803,7 +803,24 @@
803 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 +}
806 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 */
  823 +
807 824 struct security_operations dummy_security_ops;
808 825  
809 826 #define set_to_dummy_if_null(ops, function) \
... ... @@ -954,5 +971,11 @@
954 971 set_to_dummy_if_null(ops, sk_alloc_security);
955 972 set_to_dummy_if_null(ops, sk_free_security);
956 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 }
1 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 4 * Written by David Howells (dhowells@redhat.com)
5 5 *
6 6 * This program is free software; you can redistribute it and/or
... ... @@ -13,6 +13,7 @@
13 13 #include <linux/init.h>
14 14 #include <linux/sched.h>
15 15 #include <linux/slab.h>
  16 +#include <linux/security.h>
16 17 #include <linux/workqueue.h>
17 18 #include <linux/err.h>
18 19 #include "internal.h"
... ... @@ -253,6 +254,7 @@
253 254 struct key_user *user = NULL;
254 255 struct key *key;
255 256 size_t desclen, quotalen;
  257 + int ret;
256 258  
257 259 key = ERR_PTR(-EINVAL);
258 260 if (!desc || !*desc)
... ... @@ -305,6 +307,7 @@
305 307 key->flags = 0;
306 308 key->expiry = 0;
307 309 key->payload.data = NULL;
  310 + key->security = NULL;
308 311  
309 312 if (!not_in_quota)
310 313 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
311 314  
312 315  
313 316  
... ... @@ -315,16 +318,21 @@
315 318 key->magic = KEY_DEBUG_MAGIC;
316 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 326 /* publish the key by giving it a serial number */
319 327 atomic_inc(&user->nkeys);
320 328 key_alloc_serial(key);
321 329  
322   - error:
  330 +error:
323 331 return key;
324 332  
325   - no_memory_3:
  333 +security_error:
  334 + kfree(key->description);
326 335 kmem_cache_free(key_jar, key);
327   - no_memory_2:
328 336 if (!not_in_quota) {
329 337 spin_lock(&user->lock);
330 338 user->qnkeys--;
331 339  
... ... @@ -332,11 +340,24 @@
332 340 spin_unlock(&user->lock);
333 341 }
334 342 key_user_put(user);
335   - no_memory_1:
  343 + key = ERR_PTR(ret);
  344 + goto error;
  345 +
  346 +no_memory_3:
  347 + kmem_cache_free(key_jar, key);
  348 +no_memory_2:
  349 + if (!not_in_quota) {
  350 + spin_lock(&user->lock);
  351 + user->qnkeys--;
  352 + user->qnbytes -= quotalen;
  353 + spin_unlock(&user->lock);
  354 + }
  355 + key_user_put(user);
  356 +no_memory_1:
336 357 key = ERR_PTR(-ENOMEM);
337 358 goto error;
338 359  
339   - no_quota:
  360 +no_quota:
340 361 spin_unlock(&user->lock);
341 362 key_user_put(user);
342 363 key = ERR_PTR(-EDQUOT);
... ... @@ -556,6 +577,8 @@
556 577  
557 578 key_check(key);
558 579  
  580 + security_key_free(key);
  581 +
559 582 /* deal with the user's key tracking and quota */
560 583 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
561 584 spin_lock(&key->user->lock);
... ... @@ -700,8 +723,8 @@
700 723 int ret;
701 724  
702 725 /* need write permission on the key to update it */
703   - ret = -EACCES;
704   - if (!key_permission(key_ref, KEY_WRITE))
  726 + ret = key_permission(key_ref, KEY_WRITE);
  727 + if (ret < 0)
705 728 goto error;
706 729  
707 730 ret = -EEXIST;
... ... @@ -711,7 +734,6 @@
711 734 down_write(&key->sem);
712 735  
713 736 ret = key->type->update(key, payload, plen);
714   -
715 737 if (ret == 0)
716 738 /* updating a negative key instantiates it */
717 739 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
718 740  
... ... @@ -768,9 +790,11 @@
768 790  
769 791 /* if we're going to allocate a new key, we're going to have
770 792 * to modify the keyring */
771   - key_ref = ERR_PTR(-EACCES);
772   - if (!key_permission(keyring_ref, KEY_WRITE))
  793 + ret = key_permission(keyring_ref, KEY_WRITE);
  794 + if (ret < 0) {
  795 + key_ref = ERR_PTR(ret);
773 796 goto error_3;
  797 + }
774 798  
775 799 /* search for an existing key of the same type and description in the
776 800 * destination keyring
... ... @@ -780,8 +804,8 @@
780 804 goto found_matching_key;
781 805  
782 806 /* decide on the permissions we want */
783   - perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK;
784   - perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK;
  807 + perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
  808 + perm |= KEY_USR_VIEW | KEY_USR_SEARCH | KEY_USR_LINK | KEY_USR_SETATTR;
785 809  
786 810 if (ktype->read)
787 811 perm |= KEY_POS_READ | KEY_USR_READ;
788 812  
789 813  
... ... @@ -840,16 +864,16 @@
840 864 key_check(key);
841 865  
842 866 /* the key must be writable */
843   - ret = -EACCES;
844   - if (!key_permission(key_ref, KEY_WRITE))
  867 + ret = key_permission(key_ref, KEY_WRITE);
  868 + if (ret < 0)
845 869 goto error;
846 870  
847 871 /* attempt to update it if supported */
848 872 ret = -EOPNOTSUPP;
849 873 if (key->type->update) {
850 874 down_write(&key->sem);
851   - ret = key->type->update(key, payload, plen);
852 875  
  876 + ret = key->type->update(key, payload, plen);
853 877 if (ret == 0)
854 878 /* updating a negative key instantiates it */
855 879 clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
security/keys/keyctl.c
... ... @@ -624,8 +624,8 @@
624 624  
625 625 /* link the resulting key to the destination keyring if we can */
626 626 if (dest_ref) {
627   - ret = -EACCES;
628   - if (!key_permission(key_ref, KEY_LINK))
  627 + ret = key_permission(key_ref, KEY_LINK);
  628 + if (ret < 0)
629 629 goto error6;
630 630  
631 631 ret = key_link(key_ref_to_ptr(dest_ref), key_ref_to_ptr(key_ref));
632 632  
... ... @@ -676,8 +676,11 @@
676 676 key = key_ref_to_ptr(key_ref);
677 677  
678 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 681 goto can_read_key;
  682 + if (ret != -EACCES)
  683 + goto error;
681 684  
682 685 /* we can't; see if it's searchable from this process's keyrings
683 686 * - we automatically take account of the fact that it may be
... ... @@ -726,7 +729,7 @@
726 729 if (uid == (uid_t) -1 && gid == (gid_t) -1)
727 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 733 if (IS_ERR(key_ref)) {
731 734 ret = PTR_ERR(key_ref);
732 735 goto error;
... ... @@ -786,7 +789,7 @@
786 789 if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
787 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 793 if (IS_ERR(key_ref)) {
791 794 ret = PTR_ERR(key_ref);
792 795 goto error;
security/keys/keyring.c
... ... @@ -13,6 +13,7 @@
13 13 #include <linux/init.h>
14 14 #include <linux/sched.h>
15 15 #include <linux/slab.h>
  16 +#include <linux/security.h>
16 17 #include <linux/seq_file.h>
17 18 #include <linux/err.h>
18 19 #include <asm/uaccess.h>
... ... @@ -309,7 +310,9 @@
309 310 int ret;
310 311  
311 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 317 if (!IS_ERR(keyring)) {
315 318 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
316 319  
... ... @@ -359,9 +362,11 @@
359 362 key_check(keyring);
360 363  
361 364 /* top keyring must have search permission to begin the search */
362   - key_ref = ERR_PTR(-EACCES);
363   - if (!key_task_permission(keyring_ref, context, KEY_SEARCH))
  365 + err = key_task_permission(keyring_ref, context, KEY_SEARCH);
  366 + if (err < 0) {
  367 + key_ref = ERR_PTR(err);
364 368 goto error;
  369 + }
365 370  
366 371 key_ref = ERR_PTR(-ENOTDIR);
367 372 if (keyring->type != &key_type_keyring)
... ... @@ -402,8 +407,8 @@
402 407 continue;
403 408  
404 409 /* key must have search permissions */
405   - if (!key_task_permission(make_key_ref(key, possessed),
406   - context, KEY_SEARCH))
  410 + if (key_task_permission(make_key_ref(key, possessed),
  411 + context, KEY_SEARCH) < 0)
407 412 continue;
408 413  
409 414 /* we set a different error code if we find a negative key */
... ... @@ -430,7 +435,7 @@
430 435 continue;
431 436  
432 437 if (!key_task_permission(make_key_ref(key, possessed),
433   - context, KEY_SEARCH))
  438 + context, KEY_SEARCH) < 0)
434 439 continue;
435 440  
436 441 /* stack the current position */
... ... @@ -521,7 +526,7 @@
521 526 (!key->type->match ||
522 527 key->type->match(key, description)) &&
523 528 key_permission(make_key_ref(key, possessed),
524   - perm) &&
  529 + perm) < 0 &&
525 530 !test_bit(KEY_FLAG_REVOKED, &key->flags)
526 531 )
527 532 goto found;
... ... @@ -617,7 +622,7 @@
617 622 continue;
618 623  
619 624 if (!key_permission(make_key_ref(keyring, 0),
620   - KEY_SEARCH))
  625 + KEY_SEARCH) < 0)
621 626 continue;
622 627  
623 628 /* found a potential candidate, but we still need to
security/keys/permission.c
... ... @@ -10,6 +10,7 @@
10 10 */
11 11  
12 12 #include <linux/module.h>
  13 +#include <linux/security.h>
13 14 #include "internal.h"
14 15  
15 16 /*****************************************************************************/
... ... @@ -63,7 +64,11 @@
63 64  
64 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 73 } /* end key_task_permission() */
69 74  
security/keys/process_keys.c
... ... @@ -39,7 +39,7 @@
39 39 .type = &key_type_keyring,
40 40 .user = &root_key_user,
41 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 43 .flags = 1 << KEY_FLAG_INSTANTIATED,
44 44 .description = "_uid.0",
45 45 #ifdef KEY_DEBUGGING
... ... @@ -54,7 +54,7 @@
54 54 .type = &key_type_keyring,
55 55 .user = &root_key_user,
56 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 58 .flags = 1 << KEY_FLAG_INSTANTIATED,
59 59 .description = "_uid_ses.0",
60 60 #ifdef KEY_DEBUGGING
... ... @@ -666,9 +666,8 @@
666 666 goto invalid_key;
667 667  
668 668 /* check the permissions */
669   - ret = -EACCES;
670   -
671   - if (!key_task_permission(key_ref, context, perm))
  669 + ret = key_task_permission(key_ref, context, perm);
  670 + if (ret < 0)
672 671 goto invalid_key;
673 672  
674 673 error: