summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2019-06-27 18:03:07 -0400
committerDavid Howells <dhowells@redhat.com>2019-06-27 18:03:07 -0400
commit2e12256b9a76584fa3a6da19210509d4775aee36 (patch)
treed25d8a5868dadab6086230223afeb9d26fac001b
parenta58946c158a040068e7c94dc1d58bbd273258068 (diff)
keys: Replace uid/gid/perm permissions checking with an ACL
Replace the uid/gid/perm permissions checking on a key with an ACL to allow the SETATTR and SEARCH permissions to be split. This will also allow a greater range of subjects to represented. ============ WHY DO THIS? ============ The problem is that SETATTR and SEARCH cover a slew of actions, not all of which should be grouped together. For SETATTR, this includes actions that are about controlling access to a key: (1) Changing a key's ownership. (2) Changing a key's security information. (3) Setting a keyring's restriction. And actions that are about managing a key's lifetime: (4) Setting an expiry time. (5) Revoking a key. and (proposed) managing a key as part of a cache: (6) Invalidating a key. Managing a key's lifetime doesn't really have anything to do with controlling access to that key. Expiry time is awkward since it's more about the lifetime of the content and so, in some ways goes better with WRITE permission. It can, however, be set unconditionally by a process with an appropriate authorisation token for instantiating a key, and can also be set by the key type driver when a key is instantiated, so lumping it with the access-controlling actions is probably okay. As for SEARCH permission, that currently covers: (1) Finding keys in a keyring tree during a search. (2) Permitting keyrings to be joined. (3) Invalidation. But these don't really belong together either, since these actions really need to be controlled separately. Finally, there are number of special cases to do with granting the administrator special rights to invalidate or clear keys that I would like to handle with the ACL rather than key flags and special checks. =============== WHAT IS CHANGED =============== The SETATTR permission is split to create two new permissions: (1) SET_SECURITY - which allows the key's owner, group and ACL to be changed and a restriction to be placed on a keyring. (2) REVOKE - which allows a key to be revoked. The SEARCH permission is split to create: (1) SEARCH - which allows a keyring to be search and a key to be found. (2) JOIN - which allows a keyring to be joined as a session keyring. (3) INVAL - which allows a key to be invalidated. The WRITE permission is also split to create: (1) WRITE - which allows a key's content to be altered and links to be added, removed and replaced in a keyring. (2) CLEAR - which allows a keyring to be cleared completely. This is split out to make it possible to give just this to an administrator. (3) REVOKE - see above. Keys acquire ACLs which consist of a series of ACEs, and all that apply are unioned together. An ACE specifies a subject, such as: (*) Possessor - permitted to anyone who 'possesses' a key (*) Owner - permitted to the key owner (*) Group - permitted to the key group (*) Everyone - permitted to everyone Note that 'Other' has been replaced with 'Everyone' on the assumption that you wouldn't grant a permit to 'Other' that you wouldn't also grant to everyone else. Further subjects may be made available by later patches. The ACE also specifies a permissions mask. The set of permissions is now: VIEW Can view the key metadata READ Can read the key content WRITE Can update/modify the key content SEARCH Can find the key by searching/requesting LINK Can make a link to the key SET_SECURITY Can change owner, ACL, expiry INVAL Can invalidate REVOKE Can revoke JOIN Can join this keyring CLEAR Can clear this keyring The KEYCTL_SETPERM function is then deprecated. The KEYCTL_SET_TIMEOUT function then is permitted if SET_SECURITY is set, or if the caller has a valid instantiation auth token. The KEYCTL_INVALIDATE function then requires INVAL. The KEYCTL_REVOKE function then requires REVOKE. The KEYCTL_JOIN_SESSION_KEYRING function then requires JOIN to join an existing keyring. The JOIN permission is enabled by default for session keyrings and manually created keyrings only. ====================== BACKWARD COMPATIBILITY ====================== To maintain backward compatibility, KEYCTL_SETPERM will translate the permissions mask it is given into a new ACL for a key - unless KEYCTL_SET_ACL has been called on that key, in which case an error will be returned. It will convert possessor, owner, group and other permissions into separate ACEs, if each portion of the mask is non-zero. SETATTR permission turns on all of INVAL, REVOKE and SET_SECURITY. WRITE permission turns on WRITE, REVOKE and, if a keyring, CLEAR. JOIN is turned on if a keyring is being altered. The KEYCTL_DESCRIBE function translates the ACL back into a permissions mask to return depending on possessor, owner, group and everyone ACEs. It will make the following mappings: (1) INVAL, JOIN -> SEARCH (2) SET_SECURITY -> SETATTR (3) REVOKE -> WRITE if SETATTR isn't already set (4) CLEAR -> WRITE Note that the value subsequently returned by KEYCTL_DESCRIBE may not match the value set with KEYCTL_SETATTR. ======= TESTING ======= This passes the keyutils testsuite for all but a couple of tests: (1) tests/keyctl/dh_compute/badargs: The first wrong-key-type test now returns EOPNOTSUPP rather than ENOKEY as READ permission isn't removed if the type doesn't have ->read(). You still can't actually read the key. (2) tests/keyctl/permitting/valid: The view-other-permissions test doesn't work as Other has been replaced with Everyone in the ACL. Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r--Documentation/security/keys/core.rst128
-rw-r--r--Documentation/security/keys/request-key.rst9
-rw-r--r--certs/blacklist.c7
-rw-r--r--certs/system_keyring.c12
-rw-r--r--drivers/md/dm-crypt.c2
-rw-r--r--drivers/nvdimm/security.c2
-rw-r--r--fs/afs/security.c2
-rw-r--r--fs/cifs/cifs_spnego.c25
-rw-r--r--fs/cifs/cifsacl.c28
-rw-r--r--fs/cifs/connect.c4
-rw-r--r--fs/crypto/keyinfo.c2
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h2
-rw-r--r--fs/ecryptfs/keystore.c2
-rw-r--r--fs/fscache/object-list.c2
-rw-r--r--fs/nfs/nfs4idmap.c30
-rw-r--r--fs/ubifs/auth.c2
-rw-r--r--include/linux/key.h121
-rw-r--r--include/uapi/linux/keyctl.h63
-rw-r--r--lib/digsig.c2
-rw-r--r--net/ceph/ceph_common.c2
-rw-r--r--net/dns_resolver/dns_key.c12
-rw-r--r--net/dns_resolver/dns_query.c15
-rw-r--r--net/rxrpc/key.c19
-rw-r--r--net/wireless/reg.c6
-rw-r--r--security/integrity/digsig.c31
-rw-r--r--security/integrity/digsig_asymmetric.c2
-rw-r--r--security/integrity/evm/evm_crypto.c2
-rw-r--r--security/integrity/ima/ima_mok.c13
-rw-r--r--security/integrity/integrity.h6
-rw-r--r--security/integrity/platform_certs/platform_keyring.c14
-rw-r--r--security/keys/encrypted-keys/encrypted.c2
-rw-r--r--security/keys/encrypted-keys/masterkey_trusted.c2
-rw-r--r--security/keys/gc.c2
-rw-r--r--security/keys/internal.h11
-rw-r--r--security/keys/key.c29
-rw-r--r--security/keys/keyctl.c96
-rw-r--r--security/keys/keyring.c27
-rw-r--r--security/keys/permission.c242
-rw-r--r--security/keys/persistent.c27
-rw-r--r--security/keys/proc.c22
-rw-r--r--security/keys/process_keys.c86
-rw-r--r--security/keys/request_key.c34
-rw-r--r--security/keys/request_key_auth.c15
-rw-r--r--security/selinux/hooks.c16
-rw-r--r--security/smack/smack_lsm.c3
45 files changed, 857 insertions, 324 deletions
diff --git a/Documentation/security/keys/core.rst b/Documentation/security/keys/core.rst
index 0e74f372e58c..1b3c907980ad 100644
--- a/Documentation/security/keys/core.rst
+++ b/Documentation/security/keys/core.rst
@@ -57,9 +57,9 @@ Each key has a number of attributes:
57 type provides an operation to perform a match between the description on a 57 type provides an operation to perform a match between the description on a
58 key and a criterion string. 58 key and a criterion string.
59 59
60 * Each key has an owner user ID, a group ID and a permissions mask. These 60 * Each key has an owner user ID, a group ID and an ACL. These are used to
61 are used to control what a process may do to a key from userspace, and 61 control what a process may do to a key from userspace, and whether a
62 whether a kernel service will be able to find the key. 62 kernel service will be able to find the key.
63 63
64 * Each key can be set to expire at a specific time by the key type's 64 * Each key can be set to expire at a specific time by the key type's
65 instantiation function. Keys can also be immortal. 65 instantiation function. Keys can also be immortal.
@@ -198,43 +198,110 @@ The key service provides a number of features besides keys:
198Key Access Permissions 198Key Access Permissions
199====================== 199======================
200 200
201Keys have an owner user ID, a group access ID, and a permissions mask. The mask 201Keys have an owner user ID, a group ID and an ACL. The ACL is made up of a
202has up to eight bits each for possessor, user, group and other access. Only 202sequence of ACEs that each contain three elements:
203six of each set of eight bits are defined. These permissions granted are:
204 203
205 * View 204 * The type of subject.
205 * The subject.
206 206
207 This permits a key or keyring's attributes to be viewed - including key 207 These two together indicate the subject to whom the permits are granted.
208 type and description. 208 The type can be one of:
209 209
210 * Read 210 * ``KEY_ACE_SUBJ_STANDARD``
211 211
212 This permits a key's payload to be viewed or a keyring's list of linked 212 The subject is a standard 'macro' type. The subject can be one of:
213 keys. 213
214 * ``KEY_ACE_EVERYONE``
215
216 The permits are granted to everyone. It replaces the old 'other'
217 type on the assumption that you wouldn't grant a permission to other
218 that you you wouldn't grant to everyone else.
219
220 * ``KEY_ACE_OWNER``
221
222 The permits are granted to the owner of the key (key->uid).
223
224 * ``KEY_ACE_GROUP``
225
226 The permits are granted to the key's group (key->gid).
227
228 * ``KEY_ACE_POSSESSOR``
229
230 The permits are granted to anyone who possesses the key.
231
232 * The set of permits granted to the subject. These include:
233
234 * ``KEY_ACE_VIEW``
235
236 This permits a key or keyring's attributes to be viewed - including the
237 key type and description.
238
239 * ``KEY_ACE_READ``
240
241 This permits a key's payload to be viewed or a keyring's list of linked
242 keys.
214 243
215 * Write 244 * ``KEY_ACE_WRITE``
216 245
217 This permits a key's payload to be instantiated or updated, or it allows a 246 This permits a key's payload to be instantiated or updated, or it allows
218 link to be added to or removed from a keyring. 247 a link to be added to or removed from a keyring.
219 248
220 * Search 249 * ``KEY_ACE_SEARCH``
221 250
222 This permits keyrings to be searched and keys to be found. Searches can 251 This permits keyrings to be searched and keys to be found. Searches can
223 only recurse into nested keyrings that have search permission set. 252 only recurse into nested keyrings that have search permission set.
224 253
225 * Link 254 * ``KEY_ACE_LINK``
226 255
227 This permits a key or keyring to be linked to. To create a link from a 256 This permits a key or keyring to be linked to. To create a link from a
228 keyring to a key, a process must have Write permission on the keyring and 257 keyring to a key, a process must have Write permission on the keyring
229 Link permission on the key. 258 and Link permission on the key.
230 259
231 * Set Attribute 260 * ``KEY_ACE_SET_SECURITY``
232 261
233 This permits a key's UID, GID and permissions mask to be changed. 262 This permits a key's UID, GID and permissions mask to be changed.
263
264 * ``KEY_ACE_INVAL``
265
266 This permits a key to be invalidated with KEYCTL_INVALIDATE.
267
268 * ``KEY_ACE_REVOKE``
269
270 This permits a key to be revoked with KEYCTL_REVOKE.
271
272 * ``KEY_ACE_JOIN``
273
274 This permits a keyring to be joined as a session by
275 KEYCTL_JOIN_SESSION_KEYRING or KEYCTL_SESSION_TO_PARENT.
276
277 * ``KEY_ACE_CLEAR``
278
279 This permits a keyring to be cleared.
234 280
235For changing the ownership, group ID or permissions mask, being the owner of 281For changing the ownership, group ID or permissions mask, being the owner of
236the key or having the sysadmin capability is sufficient. 282the key or having the sysadmin capability is sufficient.
237 283
284The legacy KEYCTL_SETPERM and KEYCTL_DESCRIBE functions can only see/generate
285View, Read, Write, Search, Link and SetAttr permits, and do this for each of
286possessor, user, group and other permission sets as a 32-bit flag mask. These
287will be approximated/inferred:
288
289 SETPERM Permit Implied ACE Permit
290 =============== =======================
291 Search Inval, Join
292 Write Revoke, Clear
293 Setattr Set Security, Revoke
294
295 ACE Permit Described as
296 =============== =======================
297 Inval Search
298 Join Search
299 Revoke Write (unless Setattr)
300 Clear write
301 Set Security Setattr
302
303'Other' will be approximated as/inferred from the 'Everyone' subject.
304
238 305
239SELinux Support 306SELinux Support
240=============== 307===============
@@ -1084,7 +1151,8 @@ payload contents" for more information.
1084 1151
1085 struct key *request_key(const struct key_type *type, 1152 struct key *request_key(const struct key_type *type,
1086 const char *description, 1153 const char *description,
1087 const char *callout_info); 1154 const char *callout_info,
1155 struct key_acl *acl);
1088 1156
1089 This is used to request a key or keyring with a description that matches 1157 This is used to request a key or keyring with a description that matches
1090 the description specified according to the key type's match_preparse() 1158 the description specified according to the key type's match_preparse()
@@ -1099,6 +1167,8 @@ payload contents" for more information.
1099 If successful, the key will have been attached to the default keyring for 1167 If successful, the key will have been attached to the default keyring for
1100 implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING. 1168 implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
1101 1169
1170 If a key is created, it will be given the specified ACL.
1171
1102 See also Documentation/security/keys/request-key.rst. 1172 See also Documentation/security/keys/request-key.rst.
1103 1173
1104 1174
@@ -1107,7 +1177,8 @@ payload contents" for more information.
1107 struct key *request_key_tag(const struct key_type *type, 1177 struct key *request_key_tag(const struct key_type *type,
1108 const char *description, 1178 const char *description,
1109 struct key_tag *domain_tag, 1179 struct key_tag *domain_tag,
1110 const char *callout_info); 1180 const char *callout_info,
1181 struct key_acl *acl);
1111 1182
1112 This is identical to request_key(), except that a domain tag may be 1183 This is identical to request_key(), except that a domain tag may be
1113 specifies that causes search algorithm to only match keys matching that 1184 specifies that causes search algorithm to only match keys matching that
@@ -1122,7 +1193,8 @@ payload contents" for more information.
1122 struct key_tag *domain_tag, 1193 struct key_tag *domain_tag,
1123 const void *callout_info, 1194 const void *callout_info,
1124 size_t callout_len, 1195 size_t callout_len,
1125 void *aux); 1196 void *aux,
1197 struct key_acl *acl);
1126 1198
1127 This is identical to request_key_tag(), except that the auxiliary data is 1199 This is identical to request_key_tag(), except that the auxiliary data is
1128 passed to the key_type->request_key() op if it exists, and the 1200 passed to the key_type->request_key() op if it exists, and the
@@ -1195,7 +1267,7 @@ payload contents" for more information.
1195 1267
1196 struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 1268 struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
1197 const struct cred *cred, 1269 const struct cred *cred,
1198 key_perm_t perm, 1270 struct key_acl *acl,
1199 struct key_restriction *restrict_link, 1271 struct key_restriction *restrict_link,
1200 unsigned long flags, 1272 unsigned long flags,
1201 struct key *dest); 1273 struct key *dest);
diff --git a/Documentation/security/keys/request-key.rst b/Documentation/security/keys/request-key.rst
index 35f2296b704a..f356fd06c8d5 100644
--- a/Documentation/security/keys/request-key.rst
+++ b/Documentation/security/keys/request-key.rst
@@ -11,14 +11,16 @@ The process starts by either the kernel requesting a service by calling
11 11
12 struct key *request_key(const struct key_type *type, 12 struct key *request_key(const struct key_type *type,
13 const char *description, 13 const char *description,
14 const char *callout_info); 14 const char *callout_info,
15 struct key_acl *acl);
15 16
16or:: 17or::
17 18
18 struct key *request_key_tag(const struct key_type *type, 19 struct key *request_key_tag(const struct key_type *type,
19 const char *description, 20 const char *description,
20 const struct key_tag *domain_tag, 21 const struct key_tag *domain_tag,
21 const char *callout_info); 22 const char *callout_info,
23 struct key_acl *acl);
22 24
23or:: 25or::
24 26
@@ -27,7 +29,8 @@ or::
27 const struct key_tag *domain_tag, 29 const struct key_tag *domain_tag,
28 const char *callout_info, 30 const char *callout_info,
29 size_t callout_len, 31 size_t callout_len,
30 void *aux); 32 void *aux,
33 struct key_acl *acl);
31 34
32or:: 35or::
33 36
diff --git a/certs/blacklist.c b/certs/blacklist.c
index 181cb7fa9540..39de9d68b21e 100644
--- a/certs/blacklist.c
+++ b/certs/blacklist.c
@@ -93,8 +93,7 @@ int mark_hash_blacklisted(const char *hash)
93 hash, 93 hash,
94 NULL, 94 NULL,
95 0, 95 0,
96 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 96 &internal_key_acl,
97 KEY_USR_VIEW),
98 KEY_ALLOC_NOT_IN_QUOTA | 97 KEY_ALLOC_NOT_IN_QUOTA |
99 KEY_ALLOC_BUILT_IN); 98 KEY_ALLOC_BUILT_IN);
100 if (IS_ERR(key)) { 99 if (IS_ERR(key)) {
@@ -153,9 +152,7 @@ static int __init blacklist_init(void)
153 keyring_alloc(".blacklist", 152 keyring_alloc(".blacklist",
154 KUIDT_INIT(0), KGIDT_INIT(0), 153 KUIDT_INIT(0), KGIDT_INIT(0),
155 current_cred(), 154 current_cred(),
156 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 155 &internal_keyring_acl,
157 KEY_USR_VIEW | KEY_USR_READ |
158 KEY_USR_SEARCH,
159 KEY_ALLOC_NOT_IN_QUOTA | 156 KEY_ALLOC_NOT_IN_QUOTA |
160 KEY_FLAG_KEEP, 157 KEY_FLAG_KEEP,
161 NULL, NULL); 158 NULL, NULL);
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index c05c29ae4d5d..2873a4ce2828 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -103,9 +103,7 @@ static __init int system_trusted_keyring_init(void)
103 builtin_trusted_keys = 103 builtin_trusted_keys =
104 keyring_alloc(".builtin_trusted_keys", 104 keyring_alloc(".builtin_trusted_keys",
105 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 105 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
106 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 106 &internal_key_acl, KEY_ALLOC_NOT_IN_QUOTA,
107 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
108 KEY_ALLOC_NOT_IN_QUOTA,
109 NULL, NULL); 107 NULL, NULL);
110 if (IS_ERR(builtin_trusted_keys)) 108 if (IS_ERR(builtin_trusted_keys))
111 panic("Can't allocate builtin trusted keyring\n"); 109 panic("Can't allocate builtin trusted keyring\n");
@@ -114,10 +112,7 @@ static __init int system_trusted_keyring_init(void)
114 secondary_trusted_keys = 112 secondary_trusted_keys =
115 keyring_alloc(".secondary_trusted_keys", 113 keyring_alloc(".secondary_trusted_keys",
116 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 114 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
117 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 115 &internal_writable_keyring_acl, KEY_ALLOC_NOT_IN_QUOTA,
118 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH |
119 KEY_USR_WRITE),
120 KEY_ALLOC_NOT_IN_QUOTA,
121 get_builtin_and_secondary_restriction(), 116 get_builtin_and_secondary_restriction(),
122 NULL); 117 NULL);
123 if (IS_ERR(secondary_trusted_keys)) 118 if (IS_ERR(secondary_trusted_keys))
@@ -167,8 +162,7 @@ static __init int load_system_certificate_list(void)
167 NULL, 162 NULL,
168 p, 163 p,
169 plen, 164 plen,
170 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 165 &internal_key_acl,
171 KEY_USR_VIEW | KEY_USR_READ),
172 KEY_ALLOC_NOT_IN_QUOTA | 166 KEY_ALLOC_NOT_IN_QUOTA |
173 KEY_ALLOC_BUILT_IN | 167 KEY_ALLOC_BUILT_IN |
174 KEY_ALLOC_BYPASS_RESTRICTION); 168 KEY_ALLOC_BYPASS_RESTRICTION);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 1b16d34bb785..0fd3ca9bfe54 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -2035,7 +2035,7 @@ static int crypt_set_keyring_key(struct crypt_config *cc, const char *key_string
2035 return -ENOMEM; 2035 return -ENOMEM;
2036 2036
2037 key = request_key(key_string[0] == 'l' ? &key_type_logon : &key_type_user, 2037 key = request_key(key_string[0] == 'l' ? &key_type_logon : &key_type_user,
2038 key_desc + 1, NULL); 2038 key_desc + 1, NULL, NULL);
2039 if (IS_ERR(key)) { 2039 if (IS_ERR(key)) {
2040 kzfree(new_key_string); 2040 kzfree(new_key_string);
2041 return PTR_ERR(key); 2041 return PTR_ERR(key);
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index a570f2263a42..99a5708b37e3 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -55,7 +55,7 @@ static struct key *nvdimm_request_key(struct nvdimm *nvdimm)
55 struct device *dev = &nvdimm->dev; 55 struct device *dev = &nvdimm->dev;
56 56
57 sprintf(desc, "%s%s", NVDIMM_PREFIX, nvdimm->dimm_id); 57 sprintf(desc, "%s%s", NVDIMM_PREFIX, nvdimm->dimm_id);
58 key = request_key(&key_type_encrypted, desc, ""); 58 key = request_key(&key_type_encrypted, desc, "", NULL);
59 if (IS_ERR(key)) { 59 if (IS_ERR(key)) {
60 if (PTR_ERR(key) == -ENOKEY) 60 if (PTR_ERR(key) == -ENOKEY)
61 dev_dbg(dev, "request_key() found no key\n"); 61 dev_dbg(dev, "request_key() found no key\n");
diff --git a/fs/afs/security.c b/fs/afs/security.c
index 5d8ece98561e..3185898237b2 100644
--- a/fs/afs/security.c
+++ b/fs/afs/security.c
@@ -32,7 +32,7 @@ struct key *afs_request_key(struct afs_cell *cell)
32 32
33 _debug("key %s", cell->anonymous_key->description); 33 _debug("key %s", cell->anonymous_key->description);
34 key = request_key(&key_type_rxrpc, cell->anonymous_key->description, 34 key = request_key(&key_type_rxrpc, cell->anonymous_key->description,
35 NULL); 35 NULL, NULL);
36 if (IS_ERR(key)) { 36 if (IS_ERR(key)) {
37 if (PTR_ERR(key) != -ENOKEY) { 37 if (PTR_ERR(key) != -ENOKEY) {
38 _leave(" = %ld", PTR_ERR(key)); 38 _leave(" = %ld", PTR_ERR(key));
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 7f01c6e60791..d1b439ad0f1a 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -32,6 +32,25 @@
32#include "cifsproto.h" 32#include "cifsproto.h"
33static const struct cred *spnego_cred; 33static const struct cred *spnego_cred;
34 34
35static struct key_acl cifs_spnego_key_acl = {
36 .usage = REFCOUNT_INIT(1),
37 .nr_ace = 2,
38 .possessor_viewable = true,
39 .aces = {
40 KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_SEARCH | KEY_ACE_READ),
41 KEY_OWNER_ACE(KEY_ACE_VIEW),
42 }
43};
44
45static struct key_acl cifs_spnego_keyring_acl = {
46 .usage = REFCOUNT_INIT(1),
47 .nr_ace = 2,
48 .aces = {
49 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE),
50 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_CLEAR),
51 }
52};
53
35/* create a new cifs key */ 54/* create a new cifs key */
36static int 55static int
37cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep) 56cifs_spnego_key_instantiate(struct key *key, struct key_preparsed_payload *prep)
@@ -170,7 +189,8 @@ cifs_get_spnego_key(struct cifs_ses *sesInfo)
170 189
171 cifs_dbg(FYI, "key description = %s\n", description); 190 cifs_dbg(FYI, "key description = %s\n", description);
172 saved_cred = override_creds(spnego_cred); 191 saved_cred = override_creds(spnego_cred);
173 spnego_key = request_key(&cifs_spnego_key_type, description, ""); 192 spnego_key = request_key(&cifs_spnego_key_type, description, "",
193 &cifs_spnego_key_acl);
174 revert_creds(saved_cred); 194 revert_creds(saved_cred);
175 195
176#ifdef CONFIG_CIFS_DEBUG2 196#ifdef CONFIG_CIFS_DEBUG2
@@ -207,8 +227,7 @@ init_cifs_spnego(void)
207 227
208 keyring = keyring_alloc(".cifs_spnego", 228 keyring = keyring_alloc(".cifs_spnego",
209 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 229 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
210 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 230 &cifs_spnego_keyring_acl,
211 KEY_USR_VIEW | KEY_USR_READ,
212 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); 231 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
213 if (IS_ERR(keyring)) { 232 if (IS_ERR(keyring)) {
214 ret = PTR_ERR(keyring); 233 ret = PTR_ERR(keyring);
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 1d377b7f2860..78eed72f3af0 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -33,6 +33,25 @@
33#include "cifsproto.h" 33#include "cifsproto.h"
34#include "cifs_debug.h" 34#include "cifs_debug.h"
35 35
36static struct key_acl cifs_idmap_key_acl = {
37 .usage = REFCOUNT_INIT(1),
38 .nr_ace = 2,
39 .possessor_viewable = true,
40 .aces = {
41 KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_SEARCH | KEY_ACE_READ),
42 KEY_OWNER_ACE(KEY_ACE_VIEW),
43 }
44};
45
46static struct key_acl cifs_idmap_keyring_acl = {
47 .usage = REFCOUNT_INIT(1),
48 .nr_ace = 2,
49 .aces = {
50 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE),
51 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
52 }
53};
54
36/* security id for everyone/world system group */ 55/* security id for everyone/world system group */
37static const struct cifs_sid sid_everyone = { 56static const struct cifs_sid sid_everyone = {
38 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; 57 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
@@ -298,7 +317,8 @@ id_to_sid(unsigned int cid, uint sidtype, struct cifs_sid *ssid)
298 317
299 rc = 0; 318 rc = 0;
300 saved_cred = override_creds(root_cred); 319 saved_cred = override_creds(root_cred);
301 sidkey = request_key(&cifs_idmap_key_type, desc, ""); 320 sidkey = request_key(&cifs_idmap_key_type, desc, "",
321 &cifs_idmap_key_acl);
302 if (IS_ERR(sidkey)) { 322 if (IS_ERR(sidkey)) {
303 rc = -EINVAL; 323 rc = -EINVAL;
304 cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n", 324 cifs_dbg(FYI, "%s: Can't map %cid %u to a SID\n",
@@ -403,7 +423,8 @@ try_upcall_to_get_id:
403 return -ENOMEM; 423 return -ENOMEM;
404 424
405 saved_cred = override_creds(root_cred); 425 saved_cred = override_creds(root_cred);
406 sidkey = request_key(&cifs_idmap_key_type, sidstr, ""); 426 sidkey = request_key(&cifs_idmap_key_type, sidstr, "",
427 &cifs_idmap_key_acl);
407 if (IS_ERR(sidkey)) { 428 if (IS_ERR(sidkey)) {
408 rc = -EINVAL; 429 rc = -EINVAL;
409 cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n", 430 cifs_dbg(FYI, "%s: Can't map SID %s to a %cid\n",
@@ -481,8 +502,7 @@ init_cifs_idmap(void)
481 502
482 keyring = keyring_alloc(".cifs_idmap", 503 keyring = keyring_alloc(".cifs_idmap",
483 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 504 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
484 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 505 &cifs_idmap_keyring_acl,
485 KEY_USR_VIEW | KEY_USR_READ,
486 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); 506 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
487 if (IS_ERR(keyring)) { 507 if (IS_ERR(keyring)) {
488 ret = PTR_ERR(keyring); 508 ret = PTR_ERR(keyring);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8c4121da624e..6e50d3e87948 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2990,7 +2990,7 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
2990 } 2990 }
2991 2991
2992 cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc); 2992 cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc);
2993 key = request_key(&key_type_logon, desc, ""); 2993 key = request_key(&key_type_logon, desc, "", NULL);
2994 if (IS_ERR(key)) { 2994 if (IS_ERR(key)) {
2995 if (!ses->domainName) { 2995 if (!ses->domainName) {
2996 cifs_dbg(FYI, "domainName is NULL\n"); 2996 cifs_dbg(FYI, "domainName is NULL\n");
@@ -3001,7 +3001,7 @@ cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
3001 /* didn't work, try to find a domain key */ 3001 /* didn't work, try to find a domain key */
3002 sprintf(desc, "cifs:d:%s", ses->domainName); 3002 sprintf(desc, "cifs:d:%s", ses->domainName);
3003 cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc); 3003 cifs_dbg(FYI, "%s: desc=%s\n", __func__, desc);
3004 key = request_key(&key_type_logon, desc, ""); 3004 key = request_key(&key_type_logon, desc, "", NULL);
3005 if (IS_ERR(key)) { 3005 if (IS_ERR(key)) {
3006 rc = PTR_ERR(key); 3006 rc = PTR_ERR(key);
3007 goto out_err; 3007 goto out_err;
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index dcd91a3fbe49..4f85af8ab239 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -92,7 +92,7 @@ find_and_lock_process_key(const char *prefix,
92 if (!description) 92 if (!description)
93 return ERR_PTR(-ENOMEM); 93 return ERR_PTR(-ENOMEM);
94 94
95 key = request_key(&key_type_logon, description, NULL); 95 key = request_key(&key_type_logon, description, NULL, NULL);
96 kfree(description); 96 kfree(description);
97 if (IS_ERR(key)) 97 if (IS_ERR(key))
98 return key; 98 return key;
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index e74cb2a0b299..6460bd2a4e9d 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -105,7 +105,7 @@ ecryptfs_get_encrypted_key_payload_data(struct key *key)
105 105
106static inline struct key *ecryptfs_get_encrypted_key(char *sig) 106static inline struct key *ecryptfs_get_encrypted_key(char *sig)
107{ 107{
108 return request_key(&key_type_encrypted, sig, NULL); 108 return request_key(&key_type_encrypted, sig, NULL, NULL);
109} 109}
110 110
111#else 111#else
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 90fbac5d485b..923a6006ccea 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1624,7 +1624,7 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
1624{ 1624{
1625 int rc = 0; 1625 int rc = 0;
1626 1626
1627 (*auth_tok_key) = request_key(&key_type_user, sig, NULL); 1627 (*auth_tok_key) = request_key(&key_type_user, sig, NULL, NULL);
1628 if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { 1628 if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
1629 (*auth_tok_key) = ecryptfs_get_encrypted_key(sig); 1629 (*auth_tok_key) = ecryptfs_get_encrypted_key(sig);
1630 if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) { 1630 if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c
index 43e6e28c164f..6a672289e5ec 100644
--- a/fs/fscache/object-list.c
+++ b/fs/fscache/object-list.c
@@ -321,7 +321,7 @@ static void fscache_objlist_config(struct fscache_objlist_data *data)
321 const char *buf; 321 const char *buf;
322 int len; 322 int len;
323 323
324 key = request_key(&key_type_user, "fscache:objlist", NULL); 324 key = request_key(&key_type_user, "fscache:objlist", NULL, NULL);
325 if (IS_ERR(key)) 325 if (IS_ERR(key))
326 goto no_config; 326 goto no_config;
327 327
diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c
index 1e7296395d71..69679f4f2e6c 100644
--- a/fs/nfs/nfs4idmap.c
+++ b/fs/nfs/nfs4idmap.c
@@ -72,6 +72,25 @@ struct idmap {
72 const struct cred *cred; 72 const struct cred *cred;
73}; 73};
74 74
75static struct key_acl nfs_idmap_key_acl = {
76 .usage = REFCOUNT_INIT(1),
77 .nr_ace = 2,
78 .possessor_viewable = true,
79 .aces = {
80 KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_SEARCH | KEY_ACE_READ),
81 KEY_OWNER_ACE(KEY_ACE_VIEW),
82 }
83};
84
85static struct key_acl nfs_idmap_keyring_acl = {
86 .usage = REFCOUNT_INIT(1),
87 .nr_ace = 2,
88 .aces = {
89 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE),
90 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
91 }
92};
93
75static struct user_namespace *idmap_userns(const struct idmap *idmap) 94static struct user_namespace *idmap_userns(const struct idmap *idmap)
76{ 95{
77 if (idmap && idmap->cred) 96 if (idmap && idmap->cred)
@@ -208,8 +227,7 @@ int nfs_idmap_init(void)
208 227
209 keyring = keyring_alloc(".id_resolver", 228 keyring = keyring_alloc(".id_resolver",
210 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 229 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
211 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 230 &nfs_idmap_keyring_acl,
212 KEY_USR_VIEW | KEY_USR_READ,
213 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); 231 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
214 if (IS_ERR(keyring)) { 232 if (IS_ERR(keyring)) {
215 ret = PTR_ERR(keyring); 233 ret = PTR_ERR(keyring);
@@ -287,11 +305,13 @@ static struct key *nfs_idmap_request_key(const char *name, size_t namelen,
287 return ERR_PTR(ret); 305 return ERR_PTR(ret);
288 306
289 if (!idmap->cred || idmap->cred->user_ns == &init_user_ns) 307 if (!idmap->cred || idmap->cred->user_ns == &init_user_ns)
290 rkey = request_key(&key_type_id_resolver, desc, ""); 308 rkey = request_key(&key_type_id_resolver, desc, "",
309 &nfs_idmap_key_acl);
291 if (IS_ERR(rkey)) { 310 if (IS_ERR(rkey)) {
292 mutex_lock(&idmap->idmap_mutex); 311 mutex_lock(&idmap->idmap_mutex);
293 rkey = request_key_with_auxdata(&key_type_id_resolver_legacy, 312 rkey = request_key_with_auxdata(&key_type_id_resolver_legacy,
294 desc, NULL, "", 0, idmap); 313 desc, NULL, "", 0, idmap,
314 &nfs_idmap_key_acl);
295 mutex_unlock(&idmap->idmap_mutex); 315 mutex_unlock(&idmap->idmap_mutex);
296 } 316 }
297 if (!IS_ERR(rkey)) 317 if (!IS_ERR(rkey))
@@ -320,8 +340,6 @@ static ssize_t nfs_idmap_get_key(const char *name, size_t namelen,
320 } 340 }
321 341
322 rcu_read_lock(); 342 rcu_read_lock();
323 rkey->perm |= KEY_USR_VIEW;
324
325 ret = key_validate(rkey); 343 ret = key_validate(rkey);
326 if (ret < 0) 344 if (ret < 0)
327 goto out_up; 345 goto out_up;
diff --git a/fs/ubifs/auth.c b/fs/ubifs/auth.c
index 60f43b93d06e..38718026ad0b 100644
--- a/fs/ubifs/auth.c
+++ b/fs/ubifs/auth.c
@@ -227,7 +227,7 @@ int ubifs_init_authentication(struct ubifs_info *c)
227 snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)", 227 snprintf(hmac_name, CRYPTO_MAX_ALG_NAME, "hmac(%s)",
228 c->auth_hash_name); 228 c->auth_hash_name);
229 229
230 keyring_key = request_key(&key_type_logon, c->auth_key_name, NULL); 230 keyring_key = request_key(&key_type_logon, c->auth_key_name, NULL, NULL);
231 231
232 if (IS_ERR(keyring_key)) { 232 if (IS_ERR(keyring_key)) {
233 ubifs_err(c, "Failed to request key: %ld", 233 ubifs_err(c, "Failed to request key: %ld",
diff --git a/include/linux/key.h b/include/linux/key.h
index 18d7f62ab6b0..bc4adfd254fe 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -32,49 +32,14 @@
32/* key handle serial number */ 32/* key handle serial number */
33typedef int32_t key_serial_t; 33typedef int32_t key_serial_t;
34 34
35/* key handle permissions mask */
36typedef uint32_t key_perm_t;
37
38struct key; 35struct key;
39struct net; 36struct net;
40 37
41#ifdef CONFIG_KEYS 38#ifdef CONFIG_KEYS
42 39
43#undef KEY_DEBUGGING 40#include <linux/keyctl.h>
44 41
45#define KEY_POS_VIEW 0x01000000 /* possessor can view a key's attributes */ 42#undef KEY_DEBUGGING
46#define KEY_POS_READ 0x02000000 /* possessor can read key payload / view keyring */
47#define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */
48#define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */
49#define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */
50#define KEY_POS_SETATTR 0x20000000 /* possessor can set key attributes */
51#define KEY_POS_ALL 0x3f000000
52
53#define KEY_USR_VIEW 0x00010000 /* user permissions... */
54#define KEY_USR_READ 0x00020000
55#define KEY_USR_WRITE 0x00040000
56#define KEY_USR_SEARCH 0x00080000
57#define KEY_USR_LINK 0x00100000
58#define KEY_USR_SETATTR 0x00200000
59#define KEY_USR_ALL 0x003f0000
60
61#define KEY_GRP_VIEW 0x00000100 /* group permissions... */
62#define KEY_GRP_READ 0x00000200
63#define KEY_GRP_WRITE 0x00000400
64#define KEY_GRP_SEARCH 0x00000800
65#define KEY_GRP_LINK 0x00001000
66#define KEY_GRP_SETATTR 0x00002000
67#define KEY_GRP_ALL 0x00003f00
68
69#define KEY_OTH_VIEW 0x00000001 /* third party permissions... */
70#define KEY_OTH_READ 0x00000002
71#define KEY_OTH_WRITE 0x00000004
72#define KEY_OTH_SEARCH 0x00000008
73#define KEY_OTH_LINK 0x00000010
74#define KEY_OTH_SETATTR 0x00000020
75#define KEY_OTH_ALL 0x0000003f
76
77#define KEY_PERM_UNDEF 0xffffffff
78 43
79struct seq_file; 44struct seq_file;
80struct user_struct; 45struct user_struct;
@@ -118,6 +83,36 @@ union key_payload {
118 void *data[4]; 83 void *data[4];
119}; 84};
120 85
86struct key_ace {
87 unsigned int type;
88 unsigned int perm;
89 union {
90 kuid_t uid;
91 kgid_t gid;
92 unsigned int subject_id;
93 };
94};
95
96struct key_acl {
97 refcount_t usage;
98 unsigned short nr_ace;
99 bool possessor_viewable;
100 struct rcu_head rcu;
101 struct key_ace aces[];
102};
103
104#define KEY_POSSESSOR_ACE(perms) { \
105 .type = KEY_ACE_SUBJ_STANDARD, \
106 .perm = perms, \
107 .subject_id = KEY_ACE_POSSESSOR \
108 }
109
110#define KEY_OWNER_ACE(perms) { \
111 .type = KEY_ACE_SUBJ_STANDARD, \
112 .perm = perms, \
113 .subject_id = KEY_ACE_OWNER \
114 }
115
121/*****************************************************************************/ 116/*****************************************************************************/
122/* 117/*
123 * key reference with possession attribute handling 118 * key reference with possession attribute handling
@@ -184,6 +179,7 @@ struct key {
184 struct rw_semaphore sem; /* change vs change sem */ 179 struct rw_semaphore sem; /* change vs change sem */
185 struct key_user *user; /* owner of this key */ 180 struct key_user *user; /* owner of this key */
186 void *security; /* security data for this key */ 181 void *security; /* security data for this key */
182 struct key_acl __rcu *acl;
187 union { 183 union {
188 time64_t expiry; /* time at which key expires (or 0) */ 184 time64_t expiry; /* time at which key expires (or 0) */
189 time64_t revoked_at; /* time at which key was revoked */ 185 time64_t revoked_at; /* time at which key was revoked */
@@ -191,7 +187,6 @@ struct key {
191 time64_t last_used_at; /* last time used for LRU keyring discard */ 187 time64_t last_used_at; /* last time used for LRU keyring discard */
192 kuid_t uid; 188 kuid_t uid;
193 kgid_t gid; 189 kgid_t gid;
194 key_perm_t perm; /* access permissions */
195 unsigned short quotalen; /* length added to quota */ 190 unsigned short quotalen; /* length added to quota */
196 unsigned short datalen; /* payload data length 191 unsigned short datalen; /* payload data length
197 * - may not match RCU dereferenced payload 192 * - may not match RCU dereferenced payload
@@ -215,6 +210,7 @@ struct key {
215#define KEY_FLAG_ROOT_CAN_INVAL 7 /* set if key can be invalidated by root without permission */ 210#define KEY_FLAG_ROOT_CAN_INVAL 7 /* set if key can be invalidated by root without permission */
216#define KEY_FLAG_KEEP 8 /* set if key should not be removed */ 211#define KEY_FLAG_KEEP 8 /* set if key should not be removed */
217#define KEY_FLAG_UID_KEYRING 9 /* set if key is a user or user session keyring */ 212#define KEY_FLAG_UID_KEYRING 9 /* set if key is a user or user session keyring */
213#define KEY_FLAG_HAS_ACL 10 /* Set if KEYCTL_SETACL called on key */
218 214
219 /* the key type and key description string 215 /* the key type and key description string
220 * - the desc is used to match a key against search criteria 216 * - the desc is used to match a key against search criteria
@@ -263,7 +259,7 @@ extern struct key *key_alloc(struct key_type *type,
263 const char *desc, 259 const char *desc,
264 kuid_t uid, kgid_t gid, 260 kuid_t uid, kgid_t gid,
265 const struct cred *cred, 261 const struct cred *cred,
266 key_perm_t perm, 262 struct key_acl *acl,
267 unsigned long flags, 263 unsigned long flags,
268 struct key_restriction *restrict_link); 264 struct key_restriction *restrict_link);
269 265
@@ -300,7 +296,8 @@ static inline void key_ref_put(key_ref_t key_ref)
300extern struct key *request_key_tag(struct key_type *type, 296extern struct key *request_key_tag(struct key_type *type,
301 const char *description, 297 const char *description,
302 struct key_tag *domain_tag, 298 struct key_tag *domain_tag,
303 const char *callout_info); 299 const char *callout_info,
300 struct key_acl *acl);
304 301
305extern struct key *request_key_rcu(struct key_type *type, 302extern struct key *request_key_rcu(struct key_type *type,
306 const char *description, 303 const char *description,
@@ -311,21 +308,24 @@ extern struct key *request_key_with_auxdata(struct key_type *type,
311 struct key_tag *domain_tag, 308 struct key_tag *domain_tag,
312 const void *callout_info, 309 const void *callout_info,
313 size_t callout_len, 310 size_t callout_len,
314 void *aux); 311 void *aux,
312 struct key_acl *acl);
315 313
316/** 314/**
317 * request_key - Request a key and wait for construction 315 * request_key - Request a key and wait for construction
318 * @type: Type of key. 316 * @type: Type of key.
319 * @description: The searchable description of the key. 317 * @description: The searchable description of the key.
320 * @callout_info: The data to pass to the instantiation upcall (or NULL). 318 * @callout_info: The data to pass to the instantiation upcall (or NULL).
319 * @acl: The ACL to attach to a new key (or NULL).
321 * 320 *
322 * As for request_key_tag(), but with the default global domain tag. 321 * As for request_key_tag(), but with the default global domain tag.
323 */ 322 */
324static inline struct key *request_key(struct key_type *type, 323static inline struct key *request_key(struct key_type *type,
325 const char *description, 324 const char *description,
326 const char *callout_info) 325 const char *callout_info,
326 struct key_acl *acl)
327{ 327{
328 return request_key_tag(type, description, NULL, callout_info); 328 return request_key_tag(type, description, NULL, callout_info, acl);
329} 329}
330 330
331#ifdef CONFIG_NET 331#ifdef CONFIG_NET
@@ -335,6 +335,7 @@ static inline struct key *request_key(struct key_type *type,
335 * @description: The searchable description of the key. 335 * @description: The searchable description of the key.
336 * @net: The network namespace that is the key's domain of operation. 336 * @net: The network namespace that is the key's domain of operation.
337 * @callout_info: The data to pass to the instantiation upcall (or NULL). 337 * @callout_info: The data to pass to the instantiation upcall (or NULL).
338 * @acl: The ACL to attach to a new key (or NULL).
338 * 339 *
339 * As for request_key() except that it does not add the returned key to a 340 * As for request_key() except that it does not add the returned key to a
340 * keyring if found, new keys are always allocated in the user's quota, the 341 * keyring if found, new keys are always allocated in the user's quota, the
@@ -344,8 +345,8 @@ static inline struct key *request_key(struct key_type *type,
344 * Furthermore, it then works as wait_for_key_construction() to wait for the 345 * Furthermore, it then works as wait_for_key_construction() to wait for the
345 * completion of keys undergoing construction with a non-interruptible wait. 346 * completion of keys undergoing construction with a non-interruptible wait.
346 */ 347 */
347#define request_key_net(type, description, net, callout_info) \ 348#define request_key_net(type, description, net, callout_info, acl) \
348 request_key_tag(type, description, net->key_domain, callout_info); 349 request_key_tag(type, description, net->key_domain, callout_info, acl);
349#endif /* CONFIG_NET */ 350#endif /* CONFIG_NET */
350 351
351extern int wait_for_key_construction(struct key *key, bool intr); 352extern int wait_for_key_construction(struct key *key, bool intr);
@@ -357,7 +358,7 @@ extern key_ref_t key_create_or_update(key_ref_t keyring,
357 const char *description, 358 const char *description,
358 const void *payload, 359 const void *payload,
359 size_t plen, 360 size_t plen,
360 key_perm_t perm, 361 struct key_acl *acl,
361 unsigned long flags); 362 unsigned long flags);
362 363
363extern int key_update(key_ref_t key, 364extern int key_update(key_ref_t key,
@@ -377,7 +378,7 @@ extern int key_unlink(struct key *keyring,
377 378
378extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, 379extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
379 const struct cred *cred, 380 const struct cred *cred,
380 key_perm_t perm, 381 struct key_acl *acl,
381 unsigned long flags, 382 unsigned long flags,
382 struct key_restriction *restrict_link, 383 struct key_restriction *restrict_link,
383 struct key *dest); 384 struct key *dest);
@@ -410,19 +411,29 @@ static inline key_serial_t key_serial(const struct key *key)
410extern void key_set_timeout(struct key *, unsigned); 411extern void key_set_timeout(struct key *, unsigned);
411 412
412extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags, 413extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
413 key_perm_t perm); 414 u32 desired_perm);
414extern void key_free_user_ns(struct user_namespace *); 415extern void key_free_user_ns(struct user_namespace *);
415 416
416/* 417/*
417 * The permissions required on a key that we're looking up. 418 * The permissions required on a key that we're looking up.
418 */ 419 */
419#define KEY_NEED_VIEW 0x01 /* Require permission to view attributes */ 420#define KEY_NEED_VIEW 0x001 /* Require permission to view attributes */
420#define KEY_NEED_READ 0x02 /* Require permission to read content */ 421#define KEY_NEED_READ 0x002 /* Require permission to read content */
421#define KEY_NEED_WRITE 0x04 /* Require permission to update / modify */ 422#define KEY_NEED_WRITE 0x004 /* Require permission to update / modify */
422#define KEY_NEED_SEARCH 0x08 /* Require permission to search (keyring) or find (key) */ 423#define KEY_NEED_SEARCH 0x008 /* Require permission to search (keyring) or find (key) */
423#define KEY_NEED_LINK 0x10 /* Require permission to link */ 424#define KEY_NEED_LINK 0x010 /* Require permission to link */
424#define KEY_NEED_SETATTR 0x20 /* Require permission to change attributes */ 425#define KEY_NEED_SETSEC 0x020 /* Require permission to set owner, group, ACL */
425#define KEY_NEED_ALL 0x3f /* All the above permissions */ 426#define KEY_NEED_INVAL 0x040 /* Require permission to invalidate key */
427#define KEY_NEED_REVOKE 0x080 /* Require permission to revoke key */
428#define KEY_NEED_JOIN 0x100 /* Require permission to join keyring as session */
429#define KEY_NEED_CLEAR 0x200 /* Require permission to clear a keyring */
430#define KEY_NEED_ALL 0x3ff
431
432#define OLD_KEY_NEED_SETATTR 0x20 /* Used to be Require permission to change attributes */
433
434extern struct key_acl internal_key_acl;
435extern struct key_acl internal_keyring_acl;
436extern struct key_acl internal_writable_keyring_acl;
426 437
427static inline short key_read_state(const struct key *key) 438static inline short key_read_state(const struct key *key)
428{ 439{
diff --git a/include/uapi/linux/keyctl.h b/include/uapi/linux/keyctl.h
index ed3d5893830d..e783bf957da8 100644
--- a/include/uapi/linux/keyctl.h
+++ b/include/uapi/linux/keyctl.h
@@ -15,6 +15,69 @@
15 15
16#include <linux/types.h> 16#include <linux/types.h>
17 17
18/*
19 * Keyring permission grant definitions
20 */
21enum key_ace_subject_type {
22 KEY_ACE_SUBJ_STANDARD = 0, /* subject is one of key_ace_standard_subject */
23 nr__key_ace_subject_type
24};
25
26enum key_ace_standard_subject {
27 KEY_ACE_EVERYONE = 0, /* Everyone, including owner and group */
28 KEY_ACE_GROUP = 1, /* The key's group */
29 KEY_ACE_OWNER = 2, /* The owner of the key */
30 KEY_ACE_POSSESSOR = 3, /* Any process that possesses of the key */
31 nr__key_ace_standard_subject
32};
33
34#define KEY_ACE_VIEW 0x00000001 /* Can describe the key */
35#define KEY_ACE_READ 0x00000002 /* Can read the key content */
36#define KEY_ACE_WRITE 0x00000004 /* Can update/modify the key content */
37#define KEY_ACE_SEARCH 0x00000008 /* Can find the key by search */
38#define KEY_ACE_LINK 0x00000010 /* Can make a link to the key */
39#define KEY_ACE_SET_SECURITY 0x00000020 /* Can set owner, group, ACL */
40#define KEY_ACE_INVAL 0x00000040 /* Can invalidate the key */
41#define KEY_ACE_REVOKE 0x00000080 /* Can revoke the key */
42#define KEY_ACE_JOIN 0x00000100 /* Can join keyring */
43#define KEY_ACE_CLEAR 0x00000200 /* Can clear keyring */
44#define KEY_ACE__PERMS 0xffffffff
45
46/*
47 * Old-style permissions mask, deprecated in favour of ACL.
48 */
49#define KEY_POS_VIEW 0x01000000 /* possessor can view a key's attributes */
50#define KEY_POS_READ 0x02000000 /* possessor can read key payload / view keyring */
51#define KEY_POS_WRITE 0x04000000 /* possessor can update key payload / add link to keyring */
52#define KEY_POS_SEARCH 0x08000000 /* possessor can find a key in search / search a keyring */
53#define KEY_POS_LINK 0x10000000 /* possessor can create a link to a key/keyring */
54#define KEY_POS_SETATTR 0x20000000 /* possessor can set key attributes */
55#define KEY_POS_ALL 0x3f000000
56
57#define KEY_USR_VIEW 0x00010000 /* user permissions... */
58#define KEY_USR_READ 0x00020000
59#define KEY_USR_WRITE 0x00040000
60#define KEY_USR_SEARCH 0x00080000
61#define KEY_USR_LINK 0x00100000
62#define KEY_USR_SETATTR 0x00200000
63#define KEY_USR_ALL 0x003f0000
64
65#define KEY_GRP_VIEW 0x00000100 /* group permissions... */
66#define KEY_GRP_READ 0x00000200
67#define KEY_GRP_WRITE 0x00000400
68#define KEY_GRP_SEARCH 0x00000800
69#define KEY_GRP_LINK 0x00001000
70#define KEY_GRP_SETATTR 0x00002000
71#define KEY_GRP_ALL 0x00003f00
72
73#define KEY_OTH_VIEW 0x00000001 /* third party permissions... */
74#define KEY_OTH_READ 0x00000002
75#define KEY_OTH_WRITE 0x00000004
76#define KEY_OTH_SEARCH 0x00000008
77#define KEY_OTH_LINK 0x00000010
78#define KEY_OTH_SETATTR 0x00000020
79#define KEY_OTH_ALL 0x0000003f
80
18/* special process keyring shortcut IDs */ 81/* special process keyring shortcut IDs */
19#define KEY_SPEC_THREAD_KEYRING -1 /* - key ID for thread-specific keyring */ 82#define KEY_SPEC_THREAD_KEYRING -1 /* - key ID for thread-specific keyring */
20#define KEY_SPEC_PROCESS_KEYRING -2 /* - key ID for process-specific keyring */ 83#define KEY_SPEC_PROCESS_KEYRING -2 /* - key ID for process-specific keyring */
diff --git a/lib/digsig.c b/lib/digsig.c
index 3782af401c68..ce87ca2e0929 100644
--- a/lib/digsig.c
+++ b/lib/digsig.c
@@ -227,7 +227,7 @@ int digsig_verify(struct key *keyring, const char *sig, int siglen,
227 else 227 else
228 key = key_ref_to_ptr(kref); 228 key = key_ref_to_ptr(kref);
229 } else { 229 } else {
230 key = request_key(&key_type_user, name, NULL); 230 key = request_key(&key_type_user, name, NULL, NULL);
231 } 231 }
232 if (IS_ERR(key)) { 232 if (IS_ERR(key)) {
233 pr_err("key not found, id: %s\n", name); 233 pr_err("key not found, id: %s\n", name);
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 79eac465ec65..d4af93a35e2b 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -305,7 +305,7 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name) {
305 int err = 0; 305 int err = 0;
306 struct ceph_crypto_key *ckey; 306 struct ceph_crypto_key *ckey;
307 307
308 ukey = request_key(&key_type_ceph, name, NULL); 308 ukey = request_key(&key_type_ceph, name, NULL, NULL);
309 if (IS_ERR(ukey)) { 309 if (IS_ERR(ukey)) {
310 /* request_key errors don't map nicely to mount(2) 310 /* request_key errors don't map nicely to mount(2)
311 errors; don't even try, but still printk */ 311 errors; don't even try, but still printk */
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index 3e1a90669006..6b201531b165 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -46,6 +46,15 @@ const struct cred *dns_resolver_cache;
46 46
47#define DNS_ERRORNO_OPTION "dnserror" 47#define DNS_ERRORNO_OPTION "dnserror"
48 48
49static struct key_acl dns_keyring_acl = {
50 .usage = REFCOUNT_INIT(1),
51 .nr_ace = 2,
52 .aces = {
53 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE),
54 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_CLEAR),
55 }
56};
57
49/* 58/*
50 * Preparse instantiation data for a dns_resolver key. 59 * Preparse instantiation data for a dns_resolver key.
51 * 60 *
@@ -343,8 +352,7 @@ static int __init init_dns_resolver(void)
343 352
344 keyring = keyring_alloc(".dns_resolver", 353 keyring = keyring_alloc(".dns_resolver",
345 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 354 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
346 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 355 &dns_keyring_acl,
347 KEY_USR_VIEW | KEY_USR_READ,
348 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); 356 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
349 if (IS_ERR(keyring)) { 357 if (IS_ERR(keyring)) {
350 ret = PTR_ERR(keyring); 358 ret = PTR_ERR(keyring);
diff --git a/net/dns_resolver/dns_query.c b/net/dns_resolver/dns_query.c
index cab4e0df924f..236baf2bfa4c 100644
--- a/net/dns_resolver/dns_query.c
+++ b/net/dns_resolver/dns_query.c
@@ -47,6 +47,16 @@
47 47
48#include "internal.h" 48#include "internal.h"
49 49
50static struct key_acl dns_key_acl = {
51 .usage = REFCOUNT_INIT(1),
52 .nr_ace = 2,
53 .possessor_viewable = true,
54 .aces = {
55 KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_SEARCH | KEY_ACE_READ),
56 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_INVAL),
57 }
58};
59
50/** 60/**
51 * dns_query - Query the DNS 61 * dns_query - Query the DNS
52 * @net: The network namespace to operate in. 62 * @net: The network namespace to operate in.
@@ -125,7 +135,8 @@ int dns_query(struct net *net,
125 * add_key() to preinstall malicious redirections 135 * add_key() to preinstall malicious redirections
126 */ 136 */
127 saved_cred = override_creds(dns_resolver_cache); 137 saved_cred = override_creds(dns_resolver_cache);
128 rkey = request_key_net(&key_type_dns_resolver, desc, net, options); 138 rkey = request_key_net(&key_type_dns_resolver, desc, net, options,
139 &dns_key_acl);
129 revert_creds(saved_cred); 140 revert_creds(saved_cred);
130 kfree(desc); 141 kfree(desc);
131 if (IS_ERR(rkey)) { 142 if (IS_ERR(rkey)) {
@@ -135,8 +146,6 @@ int dns_query(struct net *net,
135 146
136 down_read(&rkey->sem); 147 down_read(&rkey->sem);
137 set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags); 148 set_bit(KEY_FLAG_ROOT_CAN_INVAL, &rkey->flags);
138 rkey->perm |= KEY_USR_VIEW;
139
140 ret = key_validate(rkey); 149 ret = key_validate(rkey);
141 if (ret < 0) 150 if (ret < 0)
142 goto put; 151 goto put;
diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
index 1cc6b0c6cc42..207d621d18c0 100644
--- a/net/rxrpc/key.c
+++ b/net/rxrpc/key.c
@@ -27,6 +27,14 @@
27#include <keys/user-type.h> 27#include <keys/user-type.h>
28#include "ar-internal.h" 28#include "ar-internal.h"
29 29
30static struct key_acl rxrpc_null_key_acl = {
31 .usage = REFCOUNT_INIT(1),
32 .nr_ace = 1,
33 .aces = {
34 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_READ),
35 }
36};
37
30static int rxrpc_vet_description_s(const char *); 38static int rxrpc_vet_description_s(const char *);
31static int rxrpc_preparse(struct key_preparsed_payload *); 39static int rxrpc_preparse(struct key_preparsed_payload *);
32static int rxrpc_preparse_s(struct key_preparsed_payload *); 40static int rxrpc_preparse_s(struct key_preparsed_payload *);
@@ -914,7 +922,8 @@ int rxrpc_request_key(struct rxrpc_sock *rx, char __user *optval, int optlen)
914 if (IS_ERR(description)) 922 if (IS_ERR(description))
915 return PTR_ERR(description); 923 return PTR_ERR(description);
916 924
917 key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk), NULL); 925 key = request_key_net(&key_type_rxrpc, description, sock_net(&rx->sk),
926 NULL, NULL);
918 if (IS_ERR(key)) { 927 if (IS_ERR(key)) {
919 kfree(description); 928 kfree(description);
920 _leave(" = %ld", PTR_ERR(key)); 929 _leave(" = %ld", PTR_ERR(key));
@@ -945,7 +954,8 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
945 if (IS_ERR(description)) 954 if (IS_ERR(description))
946 return PTR_ERR(description); 955 return PTR_ERR(description);
947 956
948 key = request_key_net(&key_type_keyring, description, sock_net(&rx->sk), NULL); 957 key = request_key_net(&key_type_keyring, description, sock_net(&rx->sk),
958 NULL, NULL);
949 if (IS_ERR(key)) { 959 if (IS_ERR(key)) {
950 kfree(description); 960 kfree(description);
951 _leave(" = %ld", PTR_ERR(key)); 961 _leave(" = %ld", PTR_ERR(key));
@@ -978,7 +988,8 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
978 _enter(""); 988 _enter("");
979 989
980 key = key_alloc(&key_type_rxrpc, "x", 990 key = key_alloc(&key_type_rxrpc, "x",
981 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0, 991 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
992 &internal_key_acl,
982 KEY_ALLOC_NOT_IN_QUOTA, NULL); 993 KEY_ALLOC_NOT_IN_QUOTA, NULL);
983 if (IS_ERR(key)) { 994 if (IS_ERR(key)) {
984 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); 995 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
@@ -1026,7 +1037,7 @@ struct key *rxrpc_get_null_key(const char *keyname)
1026 1037
1027 key = key_alloc(&key_type_rxrpc, keyname, 1038 key = key_alloc(&key_type_rxrpc, keyname,
1028 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 1039 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
1029 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL); 1040 &rxrpc_null_key_acl, KEY_ALLOC_NOT_IN_QUOTA, NULL);
1030 if (IS_ERR(key)) 1041 if (IS_ERR(key))
1031 return key; 1042 return key;
1032 1043
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 4831ad745f91..298fe91557f7 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -741,8 +741,7 @@ static void __init load_keys_from_buffer(const u8 *p, unsigned int buflen)
741 741
742 key = key_create_or_update(make_key_ref(builtin_regdb_keys, 1), 742 key = key_create_or_update(make_key_ref(builtin_regdb_keys, 1),
743 "asymmetric", NULL, p, plen, 743 "asymmetric", NULL, p, plen,
744 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 744 &internal_key_acl,
745 KEY_USR_VIEW | KEY_USR_READ),
746 KEY_ALLOC_NOT_IN_QUOTA | 745 KEY_ALLOC_NOT_IN_QUOTA |
747 KEY_ALLOC_BUILT_IN | 746 KEY_ALLOC_BUILT_IN |
748 KEY_ALLOC_BYPASS_RESTRICTION); 747 KEY_ALLOC_BYPASS_RESTRICTION);
@@ -768,8 +767,7 @@ static int __init load_builtin_regdb_keys(void)
768 builtin_regdb_keys = 767 builtin_regdb_keys =
769 keyring_alloc(".builtin_regdb_keys", 768 keyring_alloc(".builtin_regdb_keys",
770 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 769 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
771 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 770 &internal_keyring_acl,
772 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
773 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); 771 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
774 if (IS_ERR(builtin_regdb_keys)) 772 if (IS_ERR(builtin_regdb_keys))
775 return PTR_ERR(builtin_regdb_keys); 773 return PTR_ERR(builtin_regdb_keys);
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index e19c2eb72c51..3bd2cc28f4f5 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -51,7 +51,8 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
51 51
52 if (!keyring[id]) { 52 if (!keyring[id]) {
53 keyring[id] = 53 keyring[id] =
54 request_key(&key_type_keyring, keyring_name[id], NULL); 54 request_key(&key_type_keyring, keyring_name[id],
55 NULL, NULL);
55 if (IS_ERR(keyring[id])) { 56 if (IS_ERR(keyring[id])) {
56 int err = PTR_ERR(keyring[id]); 57 int err = PTR_ERR(keyring[id]);
57 pr_err("no %s keyring: %d\n", keyring_name[id], err); 58 pr_err("no %s keyring: %d\n", keyring_name[id], err);
@@ -73,14 +74,14 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
73 return -EOPNOTSUPP; 74 return -EOPNOTSUPP;
74} 75}
75 76
76static int __integrity_init_keyring(const unsigned int id, key_perm_t perm, 77static int __integrity_init_keyring(const unsigned int id, struct key_acl *acl,
77 struct key_restriction *restriction) 78 struct key_restriction *restriction)
78{ 79{
79 const struct cred *cred = current_cred(); 80 const struct cred *cred = current_cred();
80 int err = 0; 81 int err = 0;
81 82
82 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0), 83 keyring[id] = keyring_alloc(keyring_name[id], KUIDT_INIT(0),
83 KGIDT_INIT(0), cred, perm, 84 KGIDT_INIT(0), cred, acl,
84 KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL); 85 KEY_ALLOC_NOT_IN_QUOTA, restriction, NULL);
85 if (IS_ERR(keyring[id])) { 86 if (IS_ERR(keyring[id])) {
86 err = PTR_ERR(keyring[id]); 87 err = PTR_ERR(keyring[id]);
@@ -98,10 +99,7 @@ static int __integrity_init_keyring(const unsigned int id, key_perm_t perm,
98int __init integrity_init_keyring(const unsigned int id) 99int __init integrity_init_keyring(const unsigned int id)
99{ 100{
100 struct key_restriction *restriction; 101 struct key_restriction *restriction;
101 key_perm_t perm; 102 struct key_acl *acl = &internal_keyring_acl;
102
103 perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW
104 | KEY_USR_READ | KEY_USR_SEARCH;
105 103
106 if (id == INTEGRITY_KEYRING_PLATFORM) { 104 if (id == INTEGRITY_KEYRING_PLATFORM) {
107 restriction = NULL; 105 restriction = NULL;
@@ -116,14 +114,14 @@ int __init integrity_init_keyring(const unsigned int id)
116 return -ENOMEM; 114 return -ENOMEM;
117 115
118 restriction->check = restrict_link_to_ima; 116 restriction->check = restrict_link_to_ima;
119 perm |= KEY_USR_WRITE; 117 acl = &internal_writable_keyring_acl;
120 118
121out: 119out:
122 return __integrity_init_keyring(id, perm, restriction); 120 return __integrity_init_keyring(id, acl, restriction);
123} 121}
124 122
125int __init integrity_add_key(const unsigned int id, const void *data, 123static int __init integrity_add_key(const unsigned int id, const void *data,
126 off_t size, key_perm_t perm) 124 off_t size, struct key_acl *acl)
127{ 125{
128 key_ref_t key; 126 key_ref_t key;
129 int rc = 0; 127 int rc = 0;
@@ -132,7 +130,7 @@ int __init integrity_add_key(const unsigned int id, const void *data,
132 return -EINVAL; 130 return -EINVAL;
133 131
134 key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric", 132 key = key_create_or_update(make_key_ref(keyring[id], 1), "asymmetric",
135 NULL, data, size, perm, 133 NULL, data, size, acl ?: &internal_key_acl,
136 KEY_ALLOC_NOT_IN_QUOTA); 134 KEY_ALLOC_NOT_IN_QUOTA);
137 if (IS_ERR(key)) { 135 if (IS_ERR(key)) {
138 rc = PTR_ERR(key); 136 rc = PTR_ERR(key);
@@ -152,7 +150,6 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
152 void *data; 150 void *data;
153 loff_t size; 151 loff_t size;
154 int rc; 152 int rc;
155 key_perm_t perm;
156 153
157 rc = kernel_read_file_from_path(path, &data, &size, 0, 154 rc = kernel_read_file_from_path(path, &data, &size, 0,
158 READING_X509_CERTIFICATE); 155 READING_X509_CERTIFICATE);
@@ -161,21 +158,19 @@ int __init integrity_load_x509(const unsigned int id, const char *path)
161 return rc; 158 return rc;
162 } 159 }
163 160
164 perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW | KEY_USR_READ;
165
166 pr_info("Loading X.509 certificate: %s\n", path); 161 pr_info("Loading X.509 certificate: %s\n", path);
167 rc = integrity_add_key(id, (const void *)data, size, perm); 162 rc = integrity_add_key(id, data, size, NULL);
168 163
169 vfree(data); 164 vfree(data);
170 return rc; 165 return rc;
171} 166}
172 167
173int __init integrity_load_cert(const unsigned int id, const char *source, 168int __init integrity_load_cert(const unsigned int id, const char *source,
174 const void *data, size_t len, key_perm_t perm) 169 const void *data, size_t len, struct key_acl *acl)
175{ 170{
176 if (!data) 171 if (!data)
177 return -EINVAL; 172 return -EINVAL;
178 173
179 pr_info("Loading X.509 certificate: %s\n", source); 174 pr_info("Loading X.509 certificate: %s\n", source);
180 return integrity_add_key(id, data, len, perm); 175 return integrity_add_key(id, data, len, acl);
181} 176}
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 358f614811e8..a8bd8b2f4fce 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -57,7 +57,7 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
57 else 57 else
58 key = key_ref_to_ptr(kref); 58 key = key_ref_to_ptr(kref);
59 } else { 59 } else {
60 key = request_key(&key_type_asymmetric, name, NULL); 60 key = request_key(&key_type_asymmetric, name, NULL, NULL);
61 } 61 }
62 62
63 if (IS_ERR(key)) { 63 if (IS_ERR(key)) {
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index e11564eb645b..304cb0b21f7a 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -356,7 +356,7 @@ int evm_init_key(void)
356 struct encrypted_key_payload *ekp; 356 struct encrypted_key_payload *ekp;
357 int rc; 357 int rc;
358 358
359 evm_key = request_key(&key_type_encrypted, EVMKEY, NULL); 359 evm_key = request_key(&key_type_encrypted, EVMKEY, NULL, NULL);
360 if (IS_ERR(evm_key)) 360 if (IS_ERR(evm_key))
361 return -ENOENT; 361 return -ENOENT;
362 362
diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c
index 073ddc9bce5b..ce48303cfacc 100644
--- a/security/integrity/ima/ima_mok.c
+++ b/security/integrity/ima/ima_mok.c
@@ -21,6 +21,15 @@
21#include <keys/system_keyring.h> 21#include <keys/system_keyring.h>
22 22
23 23
24static struct key_acl integrity_blacklist_keyring_acl = {
25 .usage = REFCOUNT_INIT(1),
26 .nr_ace = 2,
27 .aces = {
28 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE),
29 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_WRITE | KEY_ACE_SEARCH),
30 }
31};
32
24struct key *ima_blacklist_keyring; 33struct key *ima_blacklist_keyring;
25 34
26/* 35/*
@@ -40,9 +49,7 @@ __init int ima_mok_init(void)
40 49
41 ima_blacklist_keyring = keyring_alloc(".ima_blacklist", 50 ima_blacklist_keyring = keyring_alloc(".ima_blacklist",
42 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 51 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
43 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 52 &integrity_blacklist_keyring_acl,
44 KEY_USR_VIEW | KEY_USR_READ |
45 KEY_USR_WRITE | KEY_USR_SEARCH,
46 KEY_ALLOC_NOT_IN_QUOTA, 53 KEY_ALLOC_NOT_IN_QUOTA,
47 restriction, NULL); 54 restriction, NULL);
48 55
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 7de59f44cba3..1c50aff6f65a 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -17,6 +17,8 @@
17#include <linux/key.h> 17#include <linux/key.h>
18#include <linux/audit.h> 18#include <linux/audit.h>
19 19
20struct key_acl;
21
20/* iint action cache flags */ 22/* iint action cache flags */
21#define IMA_MEASURE 0x00000001 23#define IMA_MEASURE 0x00000001
22#define IMA_MEASURED 0x00000002 24#define IMA_MEASURED 0x00000002
@@ -154,7 +156,7 @@ int integrity_digsig_verify(const unsigned int id, const char *sig, int siglen,
154int __init integrity_init_keyring(const unsigned int id); 156int __init integrity_init_keyring(const unsigned int id);
155int __init integrity_load_x509(const unsigned int id, const char *path); 157int __init integrity_load_x509(const unsigned int id, const char *path);
156int __init integrity_load_cert(const unsigned int id, const char *source, 158int __init integrity_load_cert(const unsigned int id, const char *source,
157 const void *data, size_t len, key_perm_t perm); 159 const void *data, size_t len, struct key_acl *acl);
158#else 160#else
159 161
160static inline int integrity_digsig_verify(const unsigned int id, 162static inline int integrity_digsig_verify(const unsigned int id,
@@ -172,7 +174,7 @@ static inline int integrity_init_keyring(const unsigned int id)
172static inline int __init integrity_load_cert(const unsigned int id, 174static inline int __init integrity_load_cert(const unsigned int id,
173 const char *source, 175 const char *source,
174 const void *data, size_t len, 176 const void *data, size_t len,
175 key_perm_t perm) 177 struct key_acl *acl)
176{ 178{
177 return 0; 179 return 0;
178} 180}
diff --git a/security/integrity/platform_certs/platform_keyring.c b/security/integrity/platform_certs/platform_keyring.c
index bcafd7387729..7646e35f2d91 100644
--- a/security/integrity/platform_certs/platform_keyring.c
+++ b/security/integrity/platform_certs/platform_keyring.c
@@ -14,6 +14,15 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include "../integrity.h" 15#include "../integrity.h"
16 16
17static struct key_acl platform_key_acl = {
18 .usage = REFCOUNT_INIT(1),
19 .nr_ace = 2,
20 .aces = {
21 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_READ),
22 KEY_OWNER_ACE(KEY_ACE_VIEW),
23 }
24};
25
17/** 26/**
18 * add_to_platform_keyring - Add to platform keyring without validation. 27 * add_to_platform_keyring - Add to platform keyring without validation.
19 * @source: Source of key 28 * @source: Source of key
@@ -26,13 +35,10 @@
26void __init add_to_platform_keyring(const char *source, const void *data, 35void __init add_to_platform_keyring(const char *source, const void *data,
27 size_t len) 36 size_t len)
28{ 37{
29 key_perm_t perm;
30 int rc; 38 int rc;
31 39
32 perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_VIEW;
33
34 rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len, 40 rc = integrity_load_cert(INTEGRITY_KEYRING_PLATFORM, source, data, len,
35 perm); 41 &platform_key_acl);
36 if (rc) 42 if (rc)
37 pr_info("Error adding keys to platform keyring %s\n", source); 43 pr_info("Error adding keys to platform keyring %s\n", source);
38} 44}
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 1b1456b21a93..dc76c60a27a6 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -307,7 +307,7 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k
307 const struct user_key_payload *upayload; 307 const struct user_key_payload *upayload;
308 struct key *ukey; 308 struct key *ukey;
309 309
310 ukey = request_key(&key_type_user, master_desc, NULL); 310 ukey = request_key(&key_type_user, master_desc, NULL, NULL);
311 if (IS_ERR(ukey)) 311 if (IS_ERR(ukey))
312 goto error; 312 goto error;
313 313
diff --git a/security/keys/encrypted-keys/masterkey_trusted.c b/security/keys/encrypted-keys/masterkey_trusted.c
index dc3d18cae642..3322e7eeafce 100644
--- a/security/keys/encrypted-keys/masterkey_trusted.c
+++ b/security/keys/encrypted-keys/masterkey_trusted.c
@@ -33,7 +33,7 @@ struct key *request_trusted_key(const char *trusted_desc,
33 struct trusted_key_payload *tpayload; 33 struct trusted_key_payload *tpayload;
34 struct key *tkey; 34 struct key *tkey;
35 35
36 tkey = request_key(&key_type_trusted, trusted_desc, NULL); 36 tkey = request_key(&key_type_trusted, trusted_desc, NULL, NULL);
37 if (IS_ERR(tkey)) 37 if (IS_ERR(tkey))
38 goto error; 38 goto error;
39 39
diff --git a/security/keys/gc.c b/security/keys/gc.c
index 83d279fb7793..3b13fb62827f 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -155,6 +155,7 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
155 155
156 key_user_put(key->user); 156 key_user_put(key->user);
157 key_put_tag(key->domain_tag); 157 key_put_tag(key->domain_tag);
158 key_put_acl(rcu_access_pointer(key->acl));
158 kfree(key->description); 159 kfree(key->description);
159 160
160 memzero_explicit(key, sizeof(*key)); 161 memzero_explicit(key, sizeof(*key));
@@ -224,7 +225,6 @@ continue_scanning:
224 if (key->type == key_gc_dead_keytype) { 225 if (key->type == key_gc_dead_keytype) {
225 gc_state |= KEY_GC_FOUND_DEAD_KEY; 226 gc_state |= KEY_GC_FOUND_DEAD_KEY;
226 set_bit(KEY_FLAG_DEAD, &key->flags); 227 set_bit(KEY_FLAG_DEAD, &key->flags);
227 key->perm = 0;
228 goto skip_dead_key; 228 goto skip_dead_key;
229 } else if (key->type == &key_type_keyring && 229 } else if (key->type == &key_type_keyring &&
230 key->restrict_link) { 230 key->restrict_link) {
diff --git a/security/keys/internal.h b/security/keys/internal.h
index f1f2b076f3a1..9375d6289bb9 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -88,8 +88,11 @@ extern struct rb_root key_serial_tree;
88extern spinlock_t key_serial_lock; 88extern spinlock_t key_serial_lock;
89extern struct mutex key_construction_mutex; 89extern struct mutex key_construction_mutex;
90extern wait_queue_head_t request_key_conswq; 90extern wait_queue_head_t request_key_conswq;
91extern struct key_acl default_key_acl;
92extern struct key_acl joinable_keyring_acl;
91 93
92extern void key_set_index_key(struct keyring_index_key *index_key); 94extern void key_set_index_key(struct keyring_index_key *index_key);
95
93extern struct key_type *key_type_lookup(const char *type); 96extern struct key_type *key_type_lookup(const char *type);
94extern void key_type_put(struct key_type *ktype); 97extern void key_type_put(struct key_type *ktype);
95 98
@@ -160,6 +163,7 @@ extern struct key *request_key_and_link(struct key_type *type,
160 const void *callout_info, 163 const void *callout_info,
161 size_t callout_len, 164 size_t callout_len,
162 void *aux, 165 void *aux,
166 struct key_acl *acl,
163 struct key *dest_keyring, 167 struct key *dest_keyring,
164 unsigned long flags); 168 unsigned long flags);
165 169
@@ -183,7 +187,10 @@ extern void key_gc_keytype(struct key_type *ktype);
183 187
184extern int key_task_permission(const key_ref_t key_ref, 188extern int key_task_permission(const key_ref_t key_ref,
185 const struct cred *cred, 189 const struct cred *cred,
186 key_perm_t perm); 190 u32 desired_perm);
191extern unsigned int key_acl_to_perm(const struct key_acl *acl);
192extern long key_set_acl(struct key *key, struct key_acl *acl);
193extern void key_put_acl(struct key_acl *acl);
187 194
188/* 195/*
189 * Check to see whether permission is granted to use a key in the desired way. 196 * Check to see whether permission is granted to use a key in the desired way.
@@ -230,7 +237,7 @@ extern long keyctl_keyring_search(key_serial_t, const char __user *,
230 const char __user *, key_serial_t); 237 const char __user *, key_serial_t);
231extern long keyctl_read_key(key_serial_t, char __user *, size_t); 238extern long keyctl_read_key(key_serial_t, char __user *, size_t);
232extern long keyctl_chown_key(key_serial_t, uid_t, gid_t); 239extern long keyctl_chown_key(key_serial_t, uid_t, gid_t);
233extern long keyctl_setperm_key(key_serial_t, key_perm_t); 240extern long keyctl_setperm_key(key_serial_t, unsigned int);
234extern long keyctl_instantiate_key(key_serial_t, const void __user *, 241extern long keyctl_instantiate_key(key_serial_t, const void __user *,
235 size_t, key_serial_t); 242 size_t, key_serial_t);
236extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t); 243extern long keyctl_negate_key(key_serial_t, unsigned, key_serial_t);
diff --git a/security/keys/key.c b/security/keys/key.c
index 85fdc2ea6c14..bb96d6235ea2 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -199,7 +199,7 @@ serial_exists:
199 * @uid: The owner of the new key. 199 * @uid: The owner of the new key.
200 * @gid: The group ID for the new key's group permissions. 200 * @gid: The group ID for the new key's group permissions.
201 * @cred: The credentials specifying UID namespace. 201 * @cred: The credentials specifying UID namespace.
202 * @perm: The permissions mask of the new key. 202 * @acl: The ACL to attach to the new key.
203 * @flags: Flags specifying quota properties. 203 * @flags: Flags specifying quota properties.
204 * @restrict_link: Optional link restriction for new keyrings. 204 * @restrict_link: Optional link restriction for new keyrings.
205 * 205 *
@@ -227,7 +227,7 @@ serial_exists:
227 */ 227 */
228struct key *key_alloc(struct key_type *type, const char *desc, 228struct key *key_alloc(struct key_type *type, const char *desc,
229 kuid_t uid, kgid_t gid, const struct cred *cred, 229 kuid_t uid, kgid_t gid, const struct cred *cred,
230 key_perm_t perm, unsigned long flags, 230 struct key_acl *acl, unsigned long flags,
231 struct key_restriction *restrict_link) 231 struct key_restriction *restrict_link)
232{ 232{
233 struct key_user *user = NULL; 233 struct key_user *user = NULL;
@@ -250,6 +250,9 @@ struct key *key_alloc(struct key_type *type, const char *desc,
250 desclen = strlen(desc); 250 desclen = strlen(desc);
251 quotalen = desclen + 1 + type->def_datalen; 251 quotalen = desclen + 1 + type->def_datalen;
252 252
253 if (!acl)
254 acl = &default_key_acl;
255
253 /* get hold of the key tracking for this user */ 256 /* get hold of the key tracking for this user */
254 user = key_user_lookup(uid); 257 user = key_user_lookup(uid);
255 if (!user) 258 if (!user)
@@ -296,7 +299,8 @@ struct key *key_alloc(struct key_type *type, const char *desc,
296 key->datalen = type->def_datalen; 299 key->datalen = type->def_datalen;
297 key->uid = uid; 300 key->uid = uid;
298 key->gid = gid; 301 key->gid = gid;
299 key->perm = perm; 302 refcount_inc(&acl->usage);
303 rcu_assign_pointer(key->acl, acl);
300 key->restrict_link = restrict_link; 304 key->restrict_link = restrict_link;
301 key->last_used_at = ktime_get_real_seconds(); 305 key->last_used_at = ktime_get_real_seconds();
302 306
@@ -791,7 +795,7 @@ error:
791 * @description: The searchable description for the key. 795 * @description: The searchable description for the key.
792 * @payload: The data to use to instantiate or update the key. 796 * @payload: The data to use to instantiate or update the key.
793 * @plen: The length of @payload. 797 * @plen: The length of @payload.
794 * @perm: The permissions mask for a new key. 798 * @acl: The ACL to attach if a key is created.
795 * @flags: The quota flags for a new key. 799 * @flags: The quota flags for a new key.
796 * 800 *
797 * Search the destination keyring for a key of the same description and if one 801 * Search the destination keyring for a key of the same description and if one
@@ -814,7 +818,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
814 const char *description, 818 const char *description,
815 const void *payload, 819 const void *payload,
816 size_t plen, 820 size_t plen,
817 key_perm_t perm, 821 struct key_acl *acl,
818 unsigned long flags) 822 unsigned long flags)
819{ 823{
820 struct keyring_index_key index_key = { 824 struct keyring_index_key index_key = {
@@ -911,22 +915,9 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
911 goto found_matching_key; 915 goto found_matching_key;
912 } 916 }
913 917
914 /* if the client doesn't provide, decide on the permissions we want */
915 if (perm == KEY_PERM_UNDEF) {
916 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
917 perm |= KEY_USR_VIEW;
918
919 if (index_key.type->read)
920 perm |= KEY_POS_READ;
921
922 if (index_key.type == &key_type_keyring ||
923 index_key.type->update)
924 perm |= KEY_POS_WRITE;
925 }
926
927 /* allocate a new key */ 918 /* allocate a new key */
928 key = key_alloc(index_key.type, index_key.description, 919 key = key_alloc(index_key.type, index_key.description,
929 cred->fsuid, cred->fsgid, cred, perm, flags, NULL); 920 cred->fsuid, cred->fsgid, cred, acl, flags, NULL);
930 if (IS_ERR(key)) { 921 if (IS_ERR(key)) {
931 key_ref = ERR_CAST(key); 922 key_ref = ERR_CAST(key);
932 goto error_link_end; 923 goto error_link_end;
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index d2f8eabcbcf4..c8911b430e59 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -134,8 +134,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type,
134 /* create or update the requested key and add it to the target 134 /* create or update the requested key and add it to the target
135 * keyring */ 135 * keyring */
136 key_ref = key_create_or_update(keyring_ref, type, description, 136 key_ref = key_create_or_update(keyring_ref, type, description,
137 payload, plen, KEY_PERM_UNDEF, 137 payload, plen, NULL, KEY_ALLOC_IN_QUOTA);
138 KEY_ALLOC_IN_QUOTA);
139 if (!IS_ERR(key_ref)) { 138 if (!IS_ERR(key_ref)) {
140 ret = key_ref_to_ptr(key_ref)->serial; 139 ret = key_ref_to_ptr(key_ref)->serial;
141 key_ref_put(key_ref); 140 key_ref_put(key_ref);
@@ -225,7 +224,8 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
225 224
226 /* do the search */ 225 /* do the search */
227 key = request_key_and_link(ktype, description, NULL, callout_info, 226 key = request_key_and_link(ktype, description, NULL, callout_info,
228 callout_len, NULL, key_ref_to_ptr(dest_ref), 227 callout_len, NULL, NULL,
228 key_ref_to_ptr(dest_ref),
229 KEY_ALLOC_IN_QUOTA); 229 KEY_ALLOC_IN_QUOTA);
230 if (IS_ERR(key)) { 230 if (IS_ERR(key)) {
231 ret = PTR_ERR(key); 231 ret = PTR_ERR(key);
@@ -387,16 +387,10 @@ long keyctl_revoke_key(key_serial_t id)
387 struct key *key; 387 struct key *key;
388 long ret; 388 long ret;
389 389
390 key_ref = lookup_user_key(id, 0, KEY_NEED_WRITE); 390 key_ref = lookup_user_key(id, 0, KEY_NEED_REVOKE);
391 if (IS_ERR(key_ref)) { 391 if (IS_ERR(key_ref)) {
392 ret = PTR_ERR(key_ref); 392 ret = PTR_ERR(key_ref);
393 if (ret != -EACCES) 393 goto error;
394 goto error;
395 key_ref = lookup_user_key(id, 0, KEY_NEED_SETATTR);
396 if (IS_ERR(key_ref)) {
397 ret = PTR_ERR(key_ref);
398 goto error;
399 }
400 } 394 }
401 395
402 key = key_ref_to_ptr(key_ref); 396 key = key_ref_to_ptr(key_ref);
@@ -430,7 +424,7 @@ long keyctl_invalidate_key(key_serial_t id)
430 424
431 kenter("%d", id); 425 kenter("%d", id);
432 426
433 key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH); 427 key_ref = lookup_user_key(id, 0, KEY_NEED_INVAL);
434 if (IS_ERR(key_ref)) { 428 if (IS_ERR(key_ref)) {
435 ret = PTR_ERR(key_ref); 429 ret = PTR_ERR(key_ref);
436 430
@@ -475,7 +469,7 @@ long keyctl_keyring_clear(key_serial_t ringid)
475 struct key *keyring; 469 struct key *keyring;
476 long ret; 470 long ret;
477 471
478 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_WRITE); 472 keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_NEED_CLEAR);
479 if (IS_ERR(keyring_ref)) { 473 if (IS_ERR(keyring_ref)) {
480 ret = PTR_ERR(keyring_ref); 474 ret = PTR_ERR(keyring_ref);
481 475
@@ -650,6 +644,7 @@ long keyctl_describe_key(key_serial_t keyid,
650 size_t buflen) 644 size_t buflen)
651{ 645{
652 struct key *key, *instkey; 646 struct key *key, *instkey;
647 unsigned int perm;
653 key_ref_t key_ref; 648 key_ref_t key_ref;
654 char *infobuf; 649 char *infobuf;
655 long ret; 650 long ret;
@@ -679,6 +674,10 @@ okay:
679 key = key_ref_to_ptr(key_ref); 674 key = key_ref_to_ptr(key_ref);
680 desclen = strlen(key->description); 675 desclen = strlen(key->description);
681 676
677 rcu_read_lock();
678 perm = key_acl_to_perm(rcu_dereference(key->acl));
679 rcu_read_unlock();
680
682 /* calculate how much information we're going to return */ 681 /* calculate how much information we're going to return */
683 ret = -ENOMEM; 682 ret = -ENOMEM;
684 infobuf = kasprintf(GFP_KERNEL, 683 infobuf = kasprintf(GFP_KERNEL,
@@ -686,7 +685,7 @@ okay:
686 key->type->name, 685 key->type->name,
687 from_kuid_munged(current_user_ns(), key->uid), 686 from_kuid_munged(current_user_ns(), key->uid),
688 from_kgid_munged(current_user_ns(), key->gid), 687 from_kgid_munged(current_user_ns(), key->gid),
689 key->perm); 688 perm);
690 if (!infobuf) 689 if (!infobuf)
691 goto error2; 690 goto error2;
692 infolen = strlen(infobuf); 691 infolen = strlen(infobuf);
@@ -903,7 +902,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
903 goto error; 902 goto error;
904 903
905 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, 904 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
906 KEY_NEED_SETATTR); 905 KEY_NEED_SETSEC);
907 if (IS_ERR(key_ref)) { 906 if (IS_ERR(key_ref)) {
908 ret = PTR_ERR(key_ref); 907 ret = PTR_ERR(key_ref);
909 goto error; 908 goto error;
@@ -998,18 +997,25 @@ quota_overrun:
998 * the key need not be fully instantiated yet. If the caller does not have 997 * the key need not be fully instantiated yet. If the caller does not have
999 * sysadmin capability, it may only change the permission on keys that it owns. 998 * sysadmin capability, it may only change the permission on keys that it owns.
1000 */ 999 */
1001long keyctl_setperm_key(key_serial_t id, key_perm_t perm) 1000long keyctl_setperm_key(key_serial_t id, unsigned int perm)
1002{ 1001{
1002 struct key_acl *acl;
1003 struct key *key; 1003 struct key *key;
1004 key_ref_t key_ref; 1004 key_ref_t key_ref;
1005 long ret; 1005 long ret;
1006 int nr, i, j;
1006 1007
1007 ret = -EINVAL;
1008 if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) 1008 if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL))
1009 goto error; 1009 return -EINVAL;
1010
1011 nr = 0;
1012 if (perm & KEY_POS_ALL) nr++;
1013 if (perm & KEY_USR_ALL) nr++;
1014 if (perm & KEY_GRP_ALL) nr++;
1015 if (perm & KEY_OTH_ALL) nr++;
1010 1016
1011 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, 1017 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
1012 KEY_NEED_SETATTR); 1018 KEY_NEED_SETSEC);
1013 if (IS_ERR(key_ref)) { 1019 if (IS_ERR(key_ref)) {
1014 ret = PTR_ERR(key_ref); 1020 ret = PTR_ERR(key_ref);
1015 goto error; 1021 goto error;
@@ -1017,17 +1023,45 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
1017 1023
1018 key = key_ref_to_ptr(key_ref); 1024 key = key_ref_to_ptr(key_ref);
1019 1025
1020 /* make the changes with the locks held to prevent chown/chmod races */ 1026 ret = -EOPNOTSUPP;
1021 ret = -EACCES; 1027 if (test_bit(KEY_FLAG_HAS_ACL, &key->flags))
1022 down_write(&key->sem); 1028 goto error_key;
1023 1029
1024 /* if we're not the sysadmin, we can only change a key that we own */ 1030 ret = -ENOMEM;
1025 if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) { 1031 acl = kzalloc(struct_size(acl, aces, nr), GFP_KERNEL);
1026 key->perm = perm; 1032 if (!acl)
1027 ret = 0; 1033 goto error_key;
1034
1035 refcount_set(&acl->usage, 1);
1036 acl->nr_ace = nr;
1037 j = 0;
1038 for (i = 0; i < 4; i++) {
1039 struct key_ace *ace = &acl->aces[j];
1040 unsigned int subset = (perm >> (i * 8)) & KEY_OTH_ALL;
1041
1042 if (!subset)
1043 continue;
1044 ace->type = KEY_ACE_SUBJ_STANDARD;
1045 ace->subject_id = KEY_ACE_EVERYONE + i;
1046 ace->perm = subset;
1047 if (subset & (KEY_OTH_WRITE | KEY_OTH_SETATTR))
1048 ace->perm |= KEY_ACE_REVOKE;
1049 if (subset & KEY_OTH_SEARCH)
1050 ace->perm |= KEY_ACE_INVAL;
1051 if (key->type == &key_type_keyring) {
1052 if (subset & KEY_OTH_SEARCH)
1053 ace->perm |= KEY_ACE_JOIN;
1054 if (subset & KEY_OTH_WRITE)
1055 ace->perm |= KEY_ACE_CLEAR;
1056 }
1057 j++;
1028 } 1058 }
1029 1059
1060 /* make the changes with the locks held to prevent chown/chmod races */
1061 down_write(&key->sem);
1062 ret = key_set_acl(key, acl);
1030 up_write(&key->sem); 1063 up_write(&key->sem);
1064error_key:
1031 key_put(key); 1065 key_put(key);
1032error: 1066error:
1033 return ret; 1067 return ret;
@@ -1392,7 +1426,7 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout)
1392 long ret; 1426 long ret;
1393 1427
1394 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, 1428 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
1395 KEY_NEED_SETATTR); 1429 KEY_NEED_SETSEC);
1396 if (IS_ERR(key_ref)) { 1430 if (IS_ERR(key_ref)) {
1397 /* setting the timeout on a key under construction is permitted 1431 /* setting the timeout on a key under construction is permitted
1398 * if we have the authorisation token handy */ 1432 * if we have the authorisation token handy */
@@ -1543,7 +1577,7 @@ long keyctl_get_security(key_serial_t keyid,
1543 * Attempt to install the calling process's session keyring on the process's 1577 * Attempt to install the calling process's session keyring on the process's
1544 * parent process. 1578 * parent process.
1545 * 1579 *
1546 * The keyring must exist and must grant the caller LINK permission, and the 1580 * The keyring must exist and must grant the caller JOIN permission, and the
1547 * parent process must be single-threaded and must have the same effective 1581 * parent process must be single-threaded and must have the same effective
1548 * ownership as this process and mustn't be SUID/SGID. 1582 * ownership as this process and mustn't be SUID/SGID.
1549 * 1583 *
@@ -1560,7 +1594,7 @@ long keyctl_session_to_parent(void)
1560 struct cred *cred; 1594 struct cred *cred;
1561 int ret; 1595 int ret;
1562 1596
1563 keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_NEED_LINK); 1597 keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_NEED_JOIN);
1564 if (IS_ERR(keyring_r)) 1598 if (IS_ERR(keyring_r))
1565 return PTR_ERR(keyring_r); 1599 return PTR_ERR(keyring_r);
1566 1600
@@ -1662,7 +1696,7 @@ long keyctl_restrict_keyring(key_serial_t id, const char __user *_type,
1662 char *restriction = NULL; 1696 char *restriction = NULL;
1663 long ret; 1697 long ret;
1664 1698
1665 key_ref = lookup_user_key(id, 0, KEY_NEED_SETATTR); 1699 key_ref = lookup_user_key(id, 0, KEY_NEED_SETSEC);
1666 if (IS_ERR(key_ref)) 1700 if (IS_ERR(key_ref))
1667 return PTR_ERR(key_ref); 1701 return PTR_ERR(key_ref);
1668 1702
@@ -1768,7 +1802,7 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3,
1768 1802
1769 case KEYCTL_SETPERM: 1803 case KEYCTL_SETPERM:
1770 return keyctl_setperm_key((key_serial_t) arg2, 1804 return keyctl_setperm_key((key_serial_t) arg2,
1771 (key_perm_t) arg3); 1805 (unsigned int)arg3);
1772 1806
1773 case KEYCTL_INSTANTIATE: 1807 case KEYCTL_INSTANTIATE:
1774 return keyctl_instantiate_key((key_serial_t) arg2, 1808 return keyctl_instantiate_key((key_serial_t) arg2,
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 29c31585ed61..62fb26c61968 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -519,11 +519,19 @@ static long keyring_read(const struct key *keyring,
519 return ret; 519 return ret;
520} 520}
521 521
522/* 522/**
523 * Allocate a keyring and link into the destination keyring. 523 * keyring_alloc - Allocate a keyring and link into the destination
524 * @description: The key description to allow the key to be searched out.
525 * @uid: The owner of the new key.
526 * @gid: The group ID for the new key's group permissions.
527 * @cred: The credentials specifying UID namespace.
528 * @acl: The ACL to attach to the new key.
529 * @flags: Flags specifying quota properties.
530 * @restrict_link: Optional link restriction for new keyrings.
531 * @dest: Destination keyring.
524 */ 532 */
525struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, 533struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
526 const struct cred *cred, key_perm_t perm, 534 const struct cred *cred, struct key_acl *acl,
527 unsigned long flags, 535 unsigned long flags,
528 struct key_restriction *restrict_link, 536 struct key_restriction *restrict_link,
529 struct key *dest) 537 struct key *dest)
@@ -532,7 +540,7 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
532 int ret; 540 int ret;
533 541
534 keyring = key_alloc(&key_type_keyring, description, 542 keyring = key_alloc(&key_type_keyring, description,
535 uid, gid, cred, perm, flags, restrict_link); 543 uid, gid, cred, acl, flags, restrict_link);
536 if (!IS_ERR(keyring)) { 544 if (!IS_ERR(keyring)) {
537 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); 545 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
538 if (ret < 0) { 546 if (ret < 0) {
@@ -1136,10 +1144,11 @@ found:
1136/* 1144/*
1137 * Find a keyring with the specified name. 1145 * Find a keyring with the specified name.
1138 * 1146 *
1139 * Only keyrings that have nonzero refcount, are not revoked, and are owned by a 1147 * Only keyrings that have nonzero refcount, are not revoked, and are owned by
1140 * user in the current user namespace are considered. If @uid_keyring is %true, 1148 * a user in the current user namespace are considered. If @uid_keyring is
1141 * the keyring additionally must have been allocated as a user or user session 1149 * %true, the keyring additionally must have been allocated as a user or user
1142 * keyring; otherwise, it must grant Search permission directly to the caller. 1150 * session keyring; otherwise, it must grant JOIN permission directly to the
1151 * caller (ie. not through possession).
1143 * 1152 *
1144 * Returns a pointer to the keyring with the keyring's refcount having being 1153 * Returns a pointer to the keyring with the keyring's refcount having being
1145 * incremented on success. -ENOKEY is returned if a key could not be found. 1154 * incremented on success. -ENOKEY is returned if a key could not be found.
@@ -1173,7 +1182,7 @@ struct key *find_keyring_by_name(const char *name, bool uid_keyring)
1173 continue; 1182 continue;
1174 } else { 1183 } else {
1175 if (key_permission(make_key_ref(keyring, 0), 1184 if (key_permission(make_key_ref(keyring, 0),
1176 KEY_NEED_SEARCH) < 0) 1185 KEY_NEED_JOIN) < 0)
1177 continue; 1186 continue;
1178 } 1187 }
1179 1188
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 06df9d5e7572..e3237bb2e970 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -11,13 +11,67 @@
11 11
12#include <linux/export.h> 12#include <linux/export.h>
13#include <linux/security.h> 13#include <linux/security.h>
14#include <linux/user_namespace.h>
15#include <linux/uaccess.h>
14#include "internal.h" 16#include "internal.h"
15 17
18struct key_acl default_key_acl = {
19 .usage = REFCOUNT_INIT(1),
20 .nr_ace = 2,
21 .possessor_viewable = true,
22 .aces = {
23 KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~KEY_ACE_JOIN),
24 KEY_OWNER_ACE(KEY_ACE_VIEW),
25 }
26};
27EXPORT_SYMBOL(default_key_acl);
28
29struct key_acl joinable_keyring_acl = {
30 .usage = REFCOUNT_INIT(1),
31 .nr_ace = 2,
32 .possessor_viewable = true,
33 .aces = {
34 KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~KEY_ACE_JOIN),
35 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_LINK | KEY_ACE_JOIN),
36 }
37};
38EXPORT_SYMBOL(joinable_keyring_acl);
39
40struct key_acl internal_key_acl = {
41 .usage = REFCOUNT_INIT(1),
42 .nr_ace = 2,
43 .aces = {
44 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH),
45 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_SEARCH),
46 }
47};
48EXPORT_SYMBOL(internal_key_acl);
49
50struct key_acl internal_keyring_acl = {
51 .usage = REFCOUNT_INIT(1),
52 .nr_ace = 2,
53 .aces = {
54 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH),
55 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_SEARCH),
56 }
57};
58EXPORT_SYMBOL(internal_keyring_acl);
59
60struct key_acl internal_writable_keyring_acl = {
61 .usage = REFCOUNT_INIT(1),
62 .nr_ace = 2,
63 .aces = {
64 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE),
65 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_WRITE | KEY_ACE_SEARCH),
66 }
67};
68EXPORT_SYMBOL(internal_writable_keyring_acl);
69
16/** 70/**
17 * key_task_permission - Check a key can be used 71 * key_task_permission - Check a key can be used
18 * @key_ref: The key to check. 72 * @key_ref: The key to check.
19 * @cred: The credentials to use. 73 * @cred: The credentials to use.
20 * @perm: The permissions to check for. 74 * @desired_perm: The permission to check for.
21 * 75 *
22 * Check to see whether permission is granted to use a key in the desired way, 76 * Check to see whether permission is granted to use a key in the desired way,
23 * but permit the security modules to override. 77 * but permit the security modules to override.
@@ -28,53 +82,73 @@
28 * permissions bits or the LSM check. 82 * permissions bits or the LSM check.
29 */ 83 */
30int key_task_permission(const key_ref_t key_ref, const struct cred *cred, 84int key_task_permission(const key_ref_t key_ref, const struct cred *cred,
31 unsigned perm) 85 unsigned int desired_perm)
32{ 86{
33 struct key *key; 87 const struct key_acl *acl;
34 key_perm_t kperm; 88 const struct key *key;
35 int ret; 89 unsigned int allow = 0;
90 int i;
91
92 BUILD_BUG_ON(KEY_NEED_VIEW != KEY_ACE_VIEW ||
93 KEY_NEED_READ != KEY_ACE_READ ||
94 KEY_NEED_WRITE != KEY_ACE_WRITE ||
95 KEY_NEED_SEARCH != KEY_ACE_SEARCH ||
96 KEY_NEED_LINK != KEY_ACE_LINK ||
97 KEY_NEED_SETSEC != KEY_ACE_SET_SECURITY ||
98 KEY_NEED_INVAL != KEY_ACE_INVAL ||
99 KEY_NEED_REVOKE != KEY_ACE_REVOKE ||
100 KEY_NEED_JOIN != KEY_ACE_JOIN ||
101 KEY_NEED_CLEAR != KEY_ACE_CLEAR);
36 102
37 key = key_ref_to_ptr(key_ref); 103 key = key_ref_to_ptr(key_ref);
38 104
39 /* use the second 8-bits of permissions for keys the caller owns */ 105 rcu_read_lock();
40 if (uid_eq(key->uid, cred->fsuid)) {
41 kperm = key->perm >> 16;
42 goto use_these_perms;
43 }
44 106
45 /* use the third 8-bits of permissions for keys the caller has a group 107 acl = rcu_dereference(key->acl);
46 * membership in common with */ 108 if (!acl || acl->nr_ace == 0)
47 if (gid_valid(key->gid) && key->perm & KEY_GRP_ALL) { 109 goto no_access_rcu;
48 if (gid_eq(key->gid, cred->fsgid)) { 110
49 kperm = key->perm >> 8; 111 for (i = 0; i < acl->nr_ace; i++) {
50 goto use_these_perms; 112 const struct key_ace *ace = &acl->aces[i];
51 }
52 113
53 ret = groups_search(cred->group_info, key->gid); 114 switch (ace->type) {
54 if (ret) { 115 case KEY_ACE_SUBJ_STANDARD:
55 kperm = key->perm >> 8; 116 switch (ace->subject_id) {
56 goto use_these_perms; 117 case KEY_ACE_POSSESSOR:
118 if (is_key_possessed(key_ref))
119 allow |= ace->perm;
120 break;
121 case KEY_ACE_OWNER:
122 if (uid_eq(key->uid, cred->fsuid))
123 allow |= ace->perm;
124 break;
125 case KEY_ACE_GROUP:
126 if (gid_valid(key->gid)) {
127 if (gid_eq(key->gid, cred->fsgid))
128 allow |= ace->perm;
129 else if (groups_search(cred->group_info, key->gid))
130 allow |= ace->perm;
131 }
132 break;
133 case KEY_ACE_EVERYONE:
134 allow |= ace->perm;
135 break;
136 }
137 break;
57 } 138 }
58 } 139 }
59 140
60 /* otherwise use the least-significant 8-bits */ 141 rcu_read_unlock();
61 kperm = key->perm;
62
63use_these_perms:
64 142
65 /* use the top 8-bits of permissions for keys the caller possesses 143 if (!(allow & desired_perm))
66 * - possessor permissions are additive with other permissions 144 goto no_access;
67 */
68 if (is_key_possessed(key_ref))
69 kperm |= key->perm >> 24;
70 145
71 kperm = kperm & perm & KEY_NEED_ALL; 146 return security_key_permission(key_ref, cred, desired_perm);
72 147
73 if (kperm != perm) 148no_access_rcu:
74 return -EACCES; 149 rcu_read_unlock();
75 150no_access:
76 /* let LSM be the final arbiter */ 151 return -EACCES;
77 return security_key_permission(key_ref, cred, perm);
78} 152}
79EXPORT_SYMBOL(key_task_permission); 153EXPORT_SYMBOL(key_task_permission);
80 154
@@ -108,3 +182,99 @@ int key_validate(const struct key *key)
108 return 0; 182 return 0;
109} 183}
110EXPORT_SYMBOL(key_validate); 184EXPORT_SYMBOL(key_validate);
185
186/*
187 * Roughly render an ACL to an old-style permissions mask. We cannot
188 * accurately render what the ACL, particularly if it has ACEs that represent
189 * subjects outside of { poss, user, group, other }.
190 */
191unsigned int key_acl_to_perm(const struct key_acl *acl)
192{
193 unsigned int perm = 0, tperm;
194 int i;
195
196 BUILD_BUG_ON(KEY_OTH_VIEW != KEY_ACE_VIEW ||
197 KEY_OTH_READ != KEY_ACE_READ ||
198 KEY_OTH_WRITE != KEY_ACE_WRITE ||
199 KEY_OTH_SEARCH != KEY_ACE_SEARCH ||
200 KEY_OTH_LINK != KEY_ACE_LINK ||
201 KEY_OTH_SETATTR != KEY_ACE_SET_SECURITY);
202
203 if (!acl || acl->nr_ace == 0)
204 return 0;
205
206 for (i = 0; i < acl->nr_ace; i++) {
207 const struct key_ace *ace = &acl->aces[i];
208
209 switch (ace->type) {
210 case KEY_ACE_SUBJ_STANDARD:
211 tperm = ace->perm & KEY_OTH_ALL;
212
213 /* Invalidation and joining were allowed by SEARCH */
214 if (ace->perm & (KEY_ACE_INVAL | KEY_ACE_JOIN))
215 tperm |= KEY_OTH_SEARCH;
216
217 /* Revocation was allowed by either SETATTR or WRITE */
218 if ((ace->perm & KEY_ACE_REVOKE) && !(tperm & KEY_OTH_SETATTR))
219 tperm |= KEY_OTH_WRITE;
220
221 /* Clearing was allowed by WRITE */
222 if (ace->perm & KEY_ACE_CLEAR)
223 tperm |= KEY_OTH_WRITE;
224
225 switch (ace->subject_id) {
226 case KEY_ACE_POSSESSOR:
227 perm |= tperm << 24;
228 break;
229 case KEY_ACE_OWNER:
230 perm |= tperm << 16;
231 break;
232 case KEY_ACE_GROUP:
233 perm |= tperm << 8;
234 break;
235 case KEY_ACE_EVERYONE:
236 perm |= tperm << 0;
237 break;
238 }
239 }
240 }
241
242 return perm;
243}
244
245/*
246 * Destroy a key's ACL.
247 */
248void key_put_acl(struct key_acl *acl)
249{
250 if (acl && refcount_dec_and_test(&acl->usage))
251 kfree_rcu(acl, rcu);
252}
253
254/*
255 * Try to set the ACL. This either attaches or discards the proposed ACL.
256 */
257long key_set_acl(struct key *key, struct key_acl *acl)
258{
259 int i;
260
261 /* If we're not the sysadmin, we can only change a key that we own. */
262 if (!capable(CAP_SYS_ADMIN) && !uid_eq(key->uid, current_fsuid())) {
263 key_put_acl(acl);
264 return -EACCES;
265 }
266
267 for (i = 0; i < acl->nr_ace; i++) {
268 const struct key_ace *ace = &acl->aces[i];
269 if (ace->type == KEY_ACE_SUBJ_STANDARD &&
270 ace->subject_id == KEY_ACE_POSSESSOR) {
271 if (ace->perm & KEY_ACE_VIEW)
272 acl->possessor_viewable = true;
273 break;
274 }
275 }
276
277 rcu_swap_protected(key->acl, acl, lockdep_is_held(&key->sem));
278 key_put_acl(acl);
279 return 0;
280}
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
index 9944d855a28d..c4c480f630ea 100644
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -16,6 +16,27 @@
16 16
17unsigned persistent_keyring_expiry = 3 * 24 * 3600; /* Expire after 3 days of non-use */ 17unsigned persistent_keyring_expiry = 3 * 24 * 3600; /* Expire after 3 days of non-use */
18 18
19static struct key_acl persistent_register_keyring_acl = {
20 .usage = REFCOUNT_INIT(1),
21 .nr_ace = 2,
22 .aces = {
23 KEY_POSSESSOR_ACE(KEY_ACE_SEARCH | KEY_ACE_WRITE),
24 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
25 }
26};
27
28static struct key_acl persistent_keyring_acl = {
29 .usage = REFCOUNT_INIT(1),
30 .nr_ace = 2,
31 .possessor_viewable = true,
32 .aces = {
33 KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_WRITE |
34 KEY_ACE_SEARCH | KEY_ACE_LINK |
35 KEY_ACE_CLEAR | KEY_ACE_INVAL),
36 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
37 }
38};
39
19/* 40/*
20 * Create the persistent keyring register for the current user namespace. 41 * Create the persistent keyring register for the current user namespace.
21 * 42 *
@@ -26,8 +47,7 @@ static int key_create_persistent_register(struct user_namespace *ns)
26 struct key *reg = keyring_alloc(".persistent_register", 47 struct key *reg = keyring_alloc(".persistent_register",
27 KUIDT_INIT(0), KGIDT_INIT(0), 48 KUIDT_INIT(0), KGIDT_INIT(0),
28 current_cred(), 49 current_cred(),
29 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 50 &persistent_register_keyring_acl,
30 KEY_USR_VIEW | KEY_USR_READ),
31 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); 51 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
32 if (IS_ERR(reg)) 52 if (IS_ERR(reg))
33 return PTR_ERR(reg); 53 return PTR_ERR(reg);
@@ -60,8 +80,7 @@ static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
60 80
61 persistent = keyring_alloc(index_key->description, 81 persistent = keyring_alloc(index_key->description,
62 uid, INVALID_GID, current_cred(), 82 uid, INVALID_GID, current_cred(),
63 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 83 &persistent_keyring_acl,
64 KEY_USR_VIEW | KEY_USR_READ),
65 KEY_ALLOC_NOT_IN_QUOTA, NULL, 84 KEY_ALLOC_NOT_IN_QUOTA, NULL,
66 ns->persistent_keyring_register); 85 ns->persistent_keyring_register);
67 if (IS_ERR(persistent)) 86 if (IS_ERR(persistent))
diff --git a/security/keys/proc.c b/security/keys/proc.c
index b4f5ba56b9cb..0056fe2dc39b 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -114,11 +114,13 @@ static struct key *find_ge_key(struct seq_file *p, key_serial_t id)
114} 114}
115 115
116static void *proc_keys_start(struct seq_file *p, loff_t *_pos) 116static void *proc_keys_start(struct seq_file *p, loff_t *_pos)
117 __acquires(rcu)
117 __acquires(key_serial_lock) 118 __acquires(key_serial_lock)
118{ 119{
119 key_serial_t pos = *_pos; 120 key_serial_t pos = *_pos;
120 struct key *key; 121 struct key *key;
121 122
123 rcu_read_lock();
122 spin_lock(&key_serial_lock); 124 spin_lock(&key_serial_lock);
123 125
124 if (*_pos > INT_MAX) 126 if (*_pos > INT_MAX)
@@ -148,12 +150,15 @@ static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos)
148 150
149static void proc_keys_stop(struct seq_file *p, void *v) 151static void proc_keys_stop(struct seq_file *p, void *v)
150 __releases(key_serial_lock) 152 __releases(key_serial_lock)
153 __releases(rcu)
151{ 154{
152 spin_unlock(&key_serial_lock); 155 spin_unlock(&key_serial_lock);
156 rcu_read_unlock();
153} 157}
154 158
155static int proc_keys_show(struct seq_file *m, void *v) 159static int proc_keys_show(struct seq_file *m, void *v)
156{ 160{
161 const struct key_acl *acl;
157 struct rb_node *_p = v; 162 struct rb_node *_p = v;
158 struct key *key = rb_entry(_p, struct key, serial_node); 163 struct key *key = rb_entry(_p, struct key, serial_node);
159 unsigned long flags; 164 unsigned long flags;
@@ -161,6 +166,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
161 time64_t now, expiry; 166 time64_t now, expiry;
162 char xbuf[16]; 167 char xbuf[16];
163 short state; 168 short state;
169 bool check_pos;
164 u64 timo; 170 u64 timo;
165 int rc; 171 int rc;
166 172
@@ -174,15 +180,15 @@ static int proc_keys_show(struct seq_file *m, void *v)
174 KEYRING_SEARCH_RECURSE), 180 KEYRING_SEARCH_RECURSE),
175 }; 181 };
176 182
177 key_ref = make_key_ref(key, 0); 183 acl = rcu_dereference(key->acl);
184 check_pos = acl->possessor_viewable;
178 185
179 /* determine if the key is possessed by this process (a test we can 186 /* determine if the key is possessed by this process (a test we can
180 * skip if the key does not indicate the possessor can view it 187 * skip if the key does not indicate the possessor can view it
181 */ 188 */
182 if (key->perm & KEY_POS_VIEW) { 189 key_ref = make_key_ref(key, 0);
183 rcu_read_lock(); 190 if (check_pos) {
184 skey_ref = search_cred_keyrings_rcu(&ctx); 191 skey_ref = search_cred_keyrings_rcu(&ctx);
185 rcu_read_unlock();
186 if (!IS_ERR(skey_ref)) { 192 if (!IS_ERR(skey_ref)) {
187 key_ref_put(skey_ref); 193 key_ref_put(skey_ref);
188 key_ref = make_key_ref(key, 1); 194 key_ref = make_key_ref(key, 1);
@@ -192,12 +198,10 @@ static int proc_keys_show(struct seq_file *m, void *v)
192 /* check whether the current task is allowed to view the key */ 198 /* check whether the current task is allowed to view the key */
193 rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW); 199 rc = key_task_permission(key_ref, ctx.cred, KEY_NEED_VIEW);
194 if (rc < 0) 200 if (rc < 0)
195 return 0; 201 goto out;
196 202
197 now = ktime_get_real_seconds(); 203 now = ktime_get_real_seconds();
198 204
199 rcu_read_lock();
200
201 /* come up with a suitable timeout value */ 205 /* come up with a suitable timeout value */
202 expiry = READ_ONCE(key->expiry); 206 expiry = READ_ONCE(key->expiry);
203 if (expiry == 0) { 207 if (expiry == 0) {
@@ -236,7 +240,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
236 showflag(flags, 'i', KEY_FLAG_INVALIDATED), 240 showflag(flags, 'i', KEY_FLAG_INVALIDATED),
237 refcount_read(&key->usage), 241 refcount_read(&key->usage),
238 xbuf, 242 xbuf,
239 key->perm, 243 key_acl_to_perm(acl),
240 from_kuid_munged(seq_user_ns(m), key->uid), 244 from_kuid_munged(seq_user_ns(m), key->uid),
241 from_kgid_munged(seq_user_ns(m), key->gid), 245 from_kgid_munged(seq_user_ns(m), key->gid),
242 key->type->name); 246 key->type->name);
@@ -247,7 +251,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
247 key->type->describe(key, m); 251 key->type->describe(key, m);
248 seq_putc(m, '\n'); 252 seq_putc(m, '\n');
249 253
250 rcu_read_unlock(); 254out:
251 return 0; 255 return 0;
252} 256}
253 257
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index f74d64215942..ddda8544630d 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -36,6 +36,47 @@ struct key_user root_key_user = {
36 .uid = GLOBAL_ROOT_UID, 36 .uid = GLOBAL_ROOT_UID,
37}; 37};
38 38
39static struct key_acl user_reg_keyring_acl = {
40 .usage = REFCOUNT_INIT(1),
41 .possessor_viewable = true,
42 .nr_ace = 2,
43 .aces = {
44 KEY_POSSESSOR_ACE(KEY_ACE_WRITE | KEY_ACE_SEARCH),
45 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
46 }
47};
48
49static struct key_acl user_keyring_acl = {
50 .usage = REFCOUNT_INIT(1),
51 .possessor_viewable = true,
52 .nr_ace = 2,
53 .aces = {
54 KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_WRITE |
55 KEY_ACE_SEARCH | KEY_ACE_LINK),
56 KEY_OWNER_ACE(KEY_ACE__PERMS & ~(KEY_ACE_JOIN | KEY_ACE_SET_SECURITY)),
57 }
58};
59
60static struct key_acl session_keyring_acl = {
61 .usage = REFCOUNT_INIT(1),
62 .possessor_viewable = true,
63 .nr_ace = 2,
64 .aces = {
65 KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~KEY_ACE_JOIN),
66 KEY_OWNER_ACE(KEY_ACE_VIEW | KEY_ACE_READ),
67 }
68};
69
70static struct key_acl thread_and_process_keyring_acl = {
71 .usage = REFCOUNT_INIT(1),
72 .possessor_viewable = true,
73 .nr_ace = 2,
74 .aces = {
75 KEY_POSSESSOR_ACE(KEY_ACE__PERMS & ~(KEY_ACE_JOIN | KEY_ACE_SET_SECURITY)),
76 KEY_OWNER_ACE(KEY_ACE_VIEW),
77 }
78};
79
39/* 80/*
40 * Get or create a user register keyring. 81 * Get or create a user register keyring.
41 */ 82 */
@@ -55,11 +96,8 @@ static struct key *get_user_register(struct user_namespace *user_ns)
55 if (!reg_keyring) { 96 if (!reg_keyring) {
56 reg_keyring = keyring_alloc(".user_reg", 97 reg_keyring = keyring_alloc(".user_reg",
57 user_ns->owner, INVALID_GID, 98 user_ns->owner, INVALID_GID,
58 &init_cred, 99 &init_cred, &user_reg_keyring_acl,
59 KEY_POS_WRITE | KEY_POS_SEARCH | 100 0, NULL, NULL);
60 KEY_USR_VIEW | KEY_USR_READ,
61 0,
62 NULL, NULL);
63 if (!IS_ERR(reg_keyring)) 101 if (!IS_ERR(reg_keyring))
64 smp_store_release(&user_ns->user_keyring_register, 102 smp_store_release(&user_ns->user_keyring_register,
65 reg_keyring); 103 reg_keyring);
@@ -81,14 +119,11 @@ int look_up_user_keyrings(struct key **_user_keyring,
81 const struct cred *cred = current_cred(); 119 const struct cred *cred = current_cred();
82 struct user_namespace *user_ns = current_user_ns(); 120 struct user_namespace *user_ns = current_user_ns();
83 struct key *reg_keyring, *uid_keyring, *session_keyring; 121 struct key *reg_keyring, *uid_keyring, *session_keyring;
84 key_perm_t user_keyring_perm;
85 key_ref_t uid_keyring_r, session_keyring_r; 122 key_ref_t uid_keyring_r, session_keyring_r;
86 uid_t uid = from_kuid(user_ns, cred->user->uid); 123 uid_t uid = from_kuid(user_ns, cred->user->uid);
87 char buf[20]; 124 char buf[20];
88 int ret; 125 int ret;
89 126
90 user_keyring_perm = (KEY_POS_ALL & ~KEY_POS_SETATTR) | KEY_USR_ALL;
91
92 kenter("%u", uid); 127 kenter("%u", uid);
93 128
94 reg_keyring = get_user_register(user_ns); 129 reg_keyring = get_user_register(user_ns);
@@ -108,7 +143,7 @@ int look_up_user_keyrings(struct key **_user_keyring,
108 kdebug("_uid %p", uid_keyring_r); 143 kdebug("_uid %p", uid_keyring_r);
109 if (uid_keyring_r == ERR_PTR(-EAGAIN)) { 144 if (uid_keyring_r == ERR_PTR(-EAGAIN)) {
110 uid_keyring = keyring_alloc(buf, cred->user->uid, INVALID_GID, 145 uid_keyring = keyring_alloc(buf, cred->user->uid, INVALID_GID,
111 cred, user_keyring_perm, 146 cred, &user_keyring_acl,
112 KEY_ALLOC_UID_KEYRING | 147 KEY_ALLOC_UID_KEYRING |
113 KEY_ALLOC_IN_QUOTA, 148 KEY_ALLOC_IN_QUOTA,
114 NULL, reg_keyring); 149 NULL, reg_keyring);
@@ -130,7 +165,7 @@ int look_up_user_keyrings(struct key **_user_keyring,
130 kdebug("_uid_ses %p", session_keyring_r); 165 kdebug("_uid_ses %p", session_keyring_r);
131 if (session_keyring_r == ERR_PTR(-EAGAIN)) { 166 if (session_keyring_r == ERR_PTR(-EAGAIN)) {
132 session_keyring = keyring_alloc(buf, cred->user->uid, INVALID_GID, 167 session_keyring = keyring_alloc(buf, cred->user->uid, INVALID_GID,
133 cred, user_keyring_perm, 168 cred, &user_keyring_acl,
134 KEY_ALLOC_UID_KEYRING | 169 KEY_ALLOC_UID_KEYRING |
135 KEY_ALLOC_IN_QUOTA, 170 KEY_ALLOC_IN_QUOTA,
136 NULL, NULL); 171 NULL, NULL);
@@ -230,7 +265,7 @@ int install_thread_keyring_to_cred(struct cred *new)
230 return 0; 265 return 0;
231 266
232 keyring = keyring_alloc("_tid", new->uid, new->gid, new, 267 keyring = keyring_alloc("_tid", new->uid, new->gid, new,
233 KEY_POS_ALL | KEY_USR_VIEW, 268 &thread_and_process_keyring_acl,
234 KEY_ALLOC_QUOTA_OVERRUN, 269 KEY_ALLOC_QUOTA_OVERRUN,
235 NULL, NULL); 270 NULL, NULL);
236 if (IS_ERR(keyring)) 271 if (IS_ERR(keyring))
@@ -277,7 +312,7 @@ int install_process_keyring_to_cred(struct cred *new)
277 return 0; 312 return 0;
278 313
279 keyring = keyring_alloc("_pid", new->uid, new->gid, new, 314 keyring = keyring_alloc("_pid", new->uid, new->gid, new,
280 KEY_POS_ALL | KEY_USR_VIEW, 315 &thread_and_process_keyring_acl,
281 KEY_ALLOC_QUOTA_OVERRUN, 316 KEY_ALLOC_QUOTA_OVERRUN,
282 NULL, NULL); 317 NULL, NULL);
283 if (IS_ERR(keyring)) 318 if (IS_ERR(keyring))
@@ -332,8 +367,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
332 flags = KEY_ALLOC_IN_QUOTA; 367 flags = KEY_ALLOC_IN_QUOTA;
333 368
334 keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred, 369 keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred,
335 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, 370 &session_keyring_acl, flags, NULL, NULL);
336 flags, NULL, NULL);
337 if (IS_ERR(keyring)) 371 if (IS_ERR(keyring))
338 return PTR_ERR(keyring); 372 return PTR_ERR(keyring);
339 } else { 373 } else {
@@ -613,7 +647,7 @@ bool lookup_user_key_possessed(const struct key *key,
613 * returned key reference. 647 * returned key reference.
614 */ 648 */
615key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, 649key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
616 key_perm_t perm) 650 unsigned int desired_perm)
617{ 651{
618 struct keyring_search_context ctx = { 652 struct keyring_search_context ctx = {
619 .match_data.cmp = lookup_user_key_possessed, 653 .match_data.cmp = lookup_user_key_possessed,
@@ -788,12 +822,12 @@ try_again:
788 case -ERESTARTSYS: 822 case -ERESTARTSYS:
789 goto invalid_key; 823 goto invalid_key;
790 default: 824 default:
791 if (perm) 825 if (desired_perm)
792 goto invalid_key; 826 goto invalid_key;
793 case 0: 827 case 0:
794 break; 828 break;
795 } 829 }
796 } else if (perm) { 830 } else if (desired_perm) {
797 ret = key_validate(key); 831 ret = key_validate(key);
798 if (ret < 0) 832 if (ret < 0)
799 goto invalid_key; 833 goto invalid_key;
@@ -805,9 +839,11 @@ try_again:
805 goto invalid_key; 839 goto invalid_key;
806 840
807 /* check the permissions */ 841 /* check the permissions */
808 ret = key_task_permission(key_ref, ctx.cred, perm); 842 if (desired_perm) {
809 if (ret < 0) 843 ret = key_task_permission(key_ref, ctx.cred, desired_perm);
810 goto invalid_key; 844 if (ret < 0)
845 goto invalid_key;
846 }
811 847
812 key->last_used_at = ktime_get_real_seconds(); 848 key->last_used_at = ktime_get_real_seconds();
813 849
@@ -872,13 +908,13 @@ long join_session_keyring(const char *name)
872 if (PTR_ERR(keyring) == -ENOKEY) { 908 if (PTR_ERR(keyring) == -ENOKEY) {
873 /* not found - try and create a new one */ 909 /* not found - try and create a new one */
874 keyring = keyring_alloc( 910 keyring = keyring_alloc(
875 name, old->uid, old->gid, old, 911 name, old->uid, old->gid, old, &joinable_keyring_acl,
876 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK,
877 KEY_ALLOC_IN_QUOTA, NULL, NULL); 912 KEY_ALLOC_IN_QUOTA, NULL, NULL);
878 if (IS_ERR(keyring)) { 913 if (IS_ERR(keyring)) {
879 ret = PTR_ERR(keyring); 914 ret = PTR_ERR(keyring);
880 goto error2; 915 goto error2;
881 } 916 }
917 goto no_perm_test;
882 } else if (IS_ERR(keyring)) { 918 } else if (IS_ERR(keyring)) {
883 ret = PTR_ERR(keyring); 919 ret = PTR_ERR(keyring);
884 goto error2; 920 goto error2;
@@ -887,6 +923,12 @@ long join_session_keyring(const char *name)
887 goto error3; 923 goto error3;
888 } 924 }
889 925
926 ret = key_task_permission(make_key_ref(keyring, false), old,
927 KEY_NEED_JOIN);
928 if (ret < 0)
929 goto error3;
930
931no_perm_test:
890 /* we've got a keyring - now to install it */ 932 /* we've got a keyring - now to install it */
891 ret = install_session_keyring_to_cred(new, keyring); 933 ret = install_session_keyring_to_cred(new, keyring);
892 if (ret < 0) 934 if (ret < 0)
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index aa589d3c90e2..64af697a9126 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -139,8 +139,7 @@ static int call_sbin_request_key(struct key *authkey, void *aux)
139 139
140 cred = get_current_cred(); 140 cred = get_current_cred();
141 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred, 141 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
142 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, 142 NULL, KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL);
143 KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL);
144 put_cred(cred); 143 put_cred(cred);
145 if (IS_ERR(keyring)) { 144 if (IS_ERR(keyring)) {
146 ret = PTR_ERR(keyring); 145 ret = PTR_ERR(keyring);
@@ -371,11 +370,11 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
371 struct key *dest_keyring, 370 struct key *dest_keyring,
372 unsigned long flags, 371 unsigned long flags,
373 struct key_user *user, 372 struct key_user *user,
373 struct key_acl *acl,
374 struct key **_key) 374 struct key **_key)
375{ 375{
376 struct assoc_array_edit *edit = NULL; 376 struct assoc_array_edit *edit = NULL;
377 struct key *key; 377 struct key *key;
378 key_perm_t perm;
379 key_ref_t key_ref; 378 key_ref_t key_ref;
380 int ret; 379 int ret;
381 380
@@ -385,17 +384,9 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
385 *_key = NULL; 384 *_key = NULL;
386 mutex_lock(&user->cons_lock); 385 mutex_lock(&user->cons_lock);
387 386
388 perm = KEY_POS_VIEW | KEY_POS_SEARCH | KEY_POS_LINK | KEY_POS_SETATTR;
389 perm |= KEY_USR_VIEW;
390 if (ctx->index_key.type->read)
391 perm |= KEY_POS_READ;
392 if (ctx->index_key.type == &key_type_keyring ||
393 ctx->index_key.type->update)
394 perm |= KEY_POS_WRITE;
395
396 key = key_alloc(ctx->index_key.type, ctx->index_key.description, 387 key = key_alloc(ctx->index_key.type, ctx->index_key.description,
397 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred, 388 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred,
398 perm, flags, NULL); 389 acl, flags, NULL);
399 if (IS_ERR(key)) 390 if (IS_ERR(key))
400 goto alloc_failed; 391 goto alloc_failed;
401 392
@@ -478,6 +469,7 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx,
478 const char *callout_info, 469 const char *callout_info,
479 size_t callout_len, 470 size_t callout_len,
480 void *aux, 471 void *aux,
472 struct key_acl *acl,
481 struct key *dest_keyring, 473 struct key *dest_keyring,
482 unsigned long flags) 474 unsigned long flags)
483{ 475{
@@ -500,7 +492,7 @@ static struct key *construct_key_and_link(struct keyring_search_context *ctx,
500 goto error_put_dest_keyring; 492 goto error_put_dest_keyring;
501 } 493 }
502 494
503 ret = construct_alloc_key(ctx, dest_keyring, flags, user, &key); 495 ret = construct_alloc_key(ctx, dest_keyring, flags, user, acl, &key);
504 key_user_put(user); 496 key_user_put(user);
505 497
506 if (ret == 0) { 498 if (ret == 0) {
@@ -538,6 +530,7 @@ error:
538 * @callout_info: The data to pass to the instantiation upcall (or NULL). 530 * @callout_info: The data to pass to the instantiation upcall (or NULL).
539 * @callout_len: The length of callout_info. 531 * @callout_len: The length of callout_info.
540 * @aux: Auxiliary data for the upcall. 532 * @aux: Auxiliary data for the upcall.
533 * @acl: The ACL to attach if a new key is created.
541 * @dest_keyring: Where to cache the key. 534 * @dest_keyring: Where to cache the key.
542 * @flags: Flags to key_alloc(). 535 * @flags: Flags to key_alloc().
543 * 536 *
@@ -565,6 +558,7 @@ struct key *request_key_and_link(struct key_type *type,
565 const void *callout_info, 558 const void *callout_info,
566 size_t callout_len, 559 size_t callout_len,
567 void *aux, 560 void *aux,
561 struct key_acl *acl,
568 struct key *dest_keyring, 562 struct key *dest_keyring,
569 unsigned long flags) 563 unsigned long flags)
570{ 564{
@@ -639,7 +633,7 @@ struct key *request_key_and_link(struct key_type *type,
639 goto error_free; 633 goto error_free;
640 634
641 key = construct_key_and_link(&ctx, callout_info, callout_len, 635 key = construct_key_and_link(&ctx, callout_info, callout_len,
642 aux, dest_keyring, flags); 636 aux, acl, dest_keyring, flags);
643 } 637 }
644 638
645error_free: 639error_free:
@@ -682,6 +676,7 @@ EXPORT_SYMBOL(wait_for_key_construction);
682 * @description: The searchable description of the key. 676 * @description: The searchable description of the key.
683 * @domain_tag: The domain in which the key operates. 677 * @domain_tag: The domain in which the key operates.
684 * @callout_info: The data to pass to the instantiation upcall (or NULL). 678 * @callout_info: The data to pass to the instantiation upcall (or NULL).
679 * @acl: The ACL to attach if a new key is created.
685 * 680 *
686 * As for request_key_and_link() except that it does not add the returned key 681 * As for request_key_and_link() except that it does not add the returned key
687 * to a keyring if found, new keys are always allocated in the user's quota, 682 * to a keyring if found, new keys are always allocated in the user's quota,
@@ -694,7 +689,8 @@ EXPORT_SYMBOL(wait_for_key_construction);
694struct key *request_key_tag(struct key_type *type, 689struct key *request_key_tag(struct key_type *type,
695 const char *description, 690 const char *description,
696 struct key_tag *domain_tag, 691 struct key_tag *domain_tag,
697 const char *callout_info) 692 const char *callout_info,
693 struct key_acl *acl)
698{ 694{
699 struct key *key; 695 struct key *key;
700 size_t callout_len = 0; 696 size_t callout_len = 0;
@@ -704,7 +700,7 @@ struct key *request_key_tag(struct key_type *type,
704 callout_len = strlen(callout_info); 700 callout_len = strlen(callout_info);
705 key = request_key_and_link(type, description, domain_tag, 701 key = request_key_and_link(type, description, domain_tag,
706 callout_info, callout_len, 702 callout_info, callout_len,
707 NULL, NULL, KEY_ALLOC_IN_QUOTA); 703 NULL, acl, NULL, KEY_ALLOC_IN_QUOTA);
708 if (!IS_ERR(key)) { 704 if (!IS_ERR(key)) {
709 ret = wait_for_key_construction(key, false); 705 ret = wait_for_key_construction(key, false);
710 if (ret < 0) { 706 if (ret < 0) {
@@ -724,6 +720,7 @@ EXPORT_SYMBOL(request_key_tag);
724 * @callout_info: The data to pass to the instantiation upcall (or NULL). 720 * @callout_info: The data to pass to the instantiation upcall (or NULL).
725 * @callout_len: The length of callout_info. 721 * @callout_len: The length of callout_info.
726 * @aux: Auxiliary data for the upcall. 722 * @aux: Auxiliary data for the upcall.
723 * @acl: The ACL to attach if a new key is created.
727 * 724 *
728 * As for request_key_and_link() except that it does not add the returned key 725 * As for request_key_and_link() except that it does not add the returned key
729 * to a keyring if found and new keys are always allocated in the user's quota. 726 * to a keyring if found and new keys are always allocated in the user's quota.
@@ -736,14 +733,15 @@ struct key *request_key_with_auxdata(struct key_type *type,
736 struct key_tag *domain_tag, 733 struct key_tag *domain_tag,
737 const void *callout_info, 734 const void *callout_info,
738 size_t callout_len, 735 size_t callout_len,
739 void *aux) 736 void *aux,
737 struct key_acl *acl)
740{ 738{
741 struct key *key; 739 struct key *key;
742 int ret; 740 int ret;
743 741
744 key = request_key_and_link(type, description, domain_tag, 742 key = request_key_and_link(type, description, domain_tag,
745 callout_info, callout_len, 743 callout_info, callout_len,
746 aux, NULL, KEY_ALLOC_IN_QUOTA); 744 aux, acl, NULL, KEY_ALLOC_IN_QUOTA);
747 if (!IS_ERR(key)) { 745 if (!IS_ERR(key)) {
748 ret = wait_for_key_construction(key, false); 746 ret = wait_for_key_construction(key, false);
749 if (ret < 0) { 747 if (ret < 0) {
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index f613987e8a63..d9146606f54e 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -28,6 +28,17 @@ static void request_key_auth_revoke(struct key *);
28static void request_key_auth_destroy(struct key *); 28static void request_key_auth_destroy(struct key *);
29static long request_key_auth_read(const struct key *, char __user *, size_t); 29static long request_key_auth_read(const struct key *, char __user *, size_t);
30 30
31static struct key_acl request_key_auth_acl = {
32 .usage = REFCOUNT_INIT(1),
33 .nr_ace = 2,
34 .possessor_viewable = true,
35 .aces = {
36 KEY_POSSESSOR_ACE(KEY_ACE_VIEW | KEY_ACE_READ | KEY_ACE_SEARCH |
37 KEY_ACE_LINK),
38 KEY_OWNER_ACE(KEY_ACE_VIEW),
39 }
40};
41
31/* 42/*
32 * The request-key authorisation key type definition. 43 * The request-key authorisation key type definition.
33 */ 44 */
@@ -214,8 +225,8 @@ struct key *request_key_auth_new(struct key *target, const char *op,
214 225
215 authkey = key_alloc(&key_type_request_key_auth, desc, 226 authkey = key_alloc(&key_type_request_key_auth, desc,
216 cred->fsuid, cred->fsgid, cred, 227 cred->fsuid, cred->fsgid, cred,
217 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | KEY_POS_LINK | 228 &request_key_auth_acl,
218 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL); 229 KEY_ALLOC_NOT_IN_QUOTA, NULL);
219 if (IS_ERR(authkey)) { 230 if (IS_ERR(authkey)) {
220 ret = PTR_ERR(authkey); 231 ret = PTR_ERR(authkey);
221 goto error_free_rka; 232 goto error_free_rka;
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c61787b15f27..b828401dcb70 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6481,6 +6481,7 @@ static int selinux_key_permission(key_ref_t key_ref,
6481{ 6481{
6482 struct key *key; 6482 struct key *key;
6483 struct key_security_struct *ksec; 6483 struct key_security_struct *ksec;
6484 unsigned oldstyle_perm;
6484 u32 sid; 6485 u32 sid;
6485 6486
6486 /* if no specific permissions are requested, we skip the 6487 /* if no specific permissions are requested, we skip the
@@ -6489,13 +6490,26 @@ static int selinux_key_permission(key_ref_t key_ref,
6489 if (perm == 0) 6490 if (perm == 0)
6490 return 0; 6491 return 0;
6491 6492
6493 oldstyle_perm = perm & (KEY_NEED_VIEW | KEY_NEED_READ | KEY_NEED_WRITE |
6494 KEY_NEED_SEARCH | KEY_NEED_LINK);
6495 if (perm & KEY_NEED_SETSEC)
6496 oldstyle_perm |= OLD_KEY_NEED_SETATTR;
6497 if (perm & KEY_NEED_INVAL)
6498 oldstyle_perm |= KEY_NEED_SEARCH;
6499 if (perm & KEY_NEED_REVOKE && !(perm & OLD_KEY_NEED_SETATTR))
6500 oldstyle_perm |= KEY_NEED_WRITE;
6501 if (perm & KEY_NEED_JOIN)
6502 oldstyle_perm |= KEY_NEED_SEARCH;
6503 if (perm & KEY_NEED_CLEAR)
6504 oldstyle_perm |= KEY_NEED_WRITE;
6505
6492 sid = cred_sid(cred); 6506 sid = cred_sid(cred);
6493 6507
6494 key = key_ref_to_ptr(key_ref); 6508 key = key_ref_to_ptr(key_ref);
6495 ksec = key->security; 6509 ksec = key->security;
6496 6510
6497 return avc_has_perm(&selinux_state, 6511 return avc_has_perm(&selinux_state,
6498 sid, ksec->sid, SECCLASS_KEY, perm, NULL); 6512 sid, ksec->sid, SECCLASS_KEY, oldstyle_perm, NULL);
6499} 6513}
6500 6514
6501static int selinux_key_getsecurity(struct key *key, char **_buffer) 6515static int selinux_key_getsecurity(struct key *key, char **_buffer)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 0de725f88bed..6095dc3565a5 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4285,7 +4285,8 @@ static int smack_key_permission(key_ref_t key_ref,
4285#endif 4285#endif
4286 if (perm & (KEY_NEED_READ | KEY_NEED_SEARCH | KEY_NEED_VIEW)) 4286 if (perm & (KEY_NEED_READ | KEY_NEED_SEARCH | KEY_NEED_VIEW))
4287 request |= MAY_READ; 4287 request |= MAY_READ;
4288 if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETATTR)) 4288 if (perm & (KEY_NEED_WRITE | KEY_NEED_LINK | KEY_NEED_SETSEC |
4289 KEY_NEED_INVAL | KEY_NEED_REVOKE | KEY_NEED_CLEAR))
4289 request |= MAY_WRITE; 4290 request |= MAY_WRITE;
4290 rc = smk_access(tkp, keyp->security, request, &ad); 4291 rc = smk_access(tkp, keyp->security, request, &ad);
4291 rc = smk_bu_note("key access", tkp, keyp->security, request, rc); 4292 rc = smk_bu_note("key access", tkp, keyp->security, request, rc);