summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-04-06 11:14:24 -0400
committerDavid Howells <dhowells@redhat.com>2016-04-11 17:37:37 -0400
commit5ac7eace2d00eab5ae0e9fdee63e38aee6001f7c (patch)
tree59e124fb6daa1dd81aef5f7d660a31cc55dab539
parentbda850cd214e90b1be0cc25bc48c4f6ac53eb543 (diff)
KEYS: Add a facility to restrict new links into a keyring
Add a facility whereby proposed new links to be added to a keyring can be vetted, permitting them to be rejected if necessary. This can be used to block public keys from which the signature cannot be verified or for which the signature verification fails. It could also be used to provide blacklisting. This affects operations like add_key(), KEYCTL_LINK and KEYCTL_INSTANTIATE. To this end: (1) A function pointer is added to the key struct that, if set, points to the vetting function. This is called as: int (*restrict_link)(struct key *keyring, const struct key_type *key_type, unsigned long key_flags, const union key_payload *key_payload), where 'keyring' will be the keyring being added to, key_type and key_payload will describe the key being added and key_flags[*] can be AND'ed with KEY_FLAG_TRUSTED. [*] This parameter will be removed in a later patch when KEY_FLAG_TRUSTED is removed. The function should return 0 to allow the link to take place or an error (typically -ENOKEY, -ENOPKG or -EKEYREJECTED) to reject the link. The pointer should not be set directly, but rather should be set through keyring_alloc(). Note that if called during add_key(), preparse is called before this method, but a key isn't actually allocated until after this function is called. (2) KEY_ALLOC_BYPASS_RESTRICTION is added. This can be passed to key_create_or_update() or key_instantiate_and_link() to bypass the restriction check. (3) KEY_FLAG_TRUSTED_ONLY is removed. The entire contents of a keyring with this restriction emplaced can be considered 'trustworthy' by virtue of being in the keyring when that keyring is consulted. (4) key_alloc() and keyring_alloc() take an extra argument that will be used to set restrict_link in the new key. This ensures that the pointer is set before the key is published, thus preventing a window of unrestrictedness. Normally this argument will be NULL. (5) As a temporary affair, keyring_restrict_trusted_only() is added. It should be passed to keyring_alloc() as the extra argument instead of setting KEY_FLAG_TRUSTED_ONLY on a keyring. This will be replaced in a later patch with functions that look in the appropriate places for authoritative keys. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
-rw-r--r--Documentation/security/keys.txt22
-rw-r--r--certs/system_keyring.c8
-rw-r--r--fs/cifs/cifsacl.c2
-rw-r--r--fs/nfs/nfs4idmap.c2
-rw-r--r--include/linux/key.h53
-rw-r--r--net/dns_resolver/dns_key.c2
-rw-r--r--net/rxrpc/ar-key.c4
-rw-r--r--security/integrity/digsig.c7
-rw-r--r--security/integrity/ima/ima_mok.c8
-rw-r--r--security/keys/key.c43
-rw-r--r--security/keys/keyring.c73
-rw-r--r--security/keys/persistent.c4
-rw-r--r--security/keys/process_keys.c16
-rw-r--r--security/keys/request_key.c4
-rw-r--r--security/keys/request_key_auth.c2
15 files changed, 198 insertions, 52 deletions
diff --git a/Documentation/security/keys.txt b/Documentation/security/keys.txt
index 8c183873b2b7..a6a50b359025 100644
--- a/Documentation/security/keys.txt
+++ b/Documentation/security/keys.txt
@@ -999,6 +999,10 @@ payload contents" for more information.
999 struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 999 struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
1000 const struct cred *cred, 1000 const struct cred *cred,
1001 key_perm_t perm, 1001 key_perm_t perm,
1002 int (*restrict_link)(struct key *,
1003 const struct key_type *,
1004 unsigned long,
1005 const union key_payload *),
1002 unsigned long flags, 1006 unsigned long flags,
1003 struct key *dest); 1007 struct key *dest);
1004 1008
@@ -1010,6 +1014,24 @@ payload contents" for more information.
1010 KEY_ALLOC_NOT_IN_QUOTA in flags if the keyring shouldn't be accounted 1014 KEY_ALLOC_NOT_IN_QUOTA in flags if the keyring shouldn't be accounted
1011 towards the user's quota). Error ENOMEM can also be returned. 1015 towards the user's quota). Error ENOMEM can also be returned.
1012 1016
1017 If restrict_link not NULL, it should point to a function that will be
1018 called each time an attempt is made to link a key into the new keyring.
1019 This function is called to check whether a key may be added into the keying
1020 or not. Callers of key_create_or_update() within the kernel can pass
1021 KEY_ALLOC_BYPASS_RESTRICTION to suppress the check. An example of using
1022 this is to manage rings of cryptographic keys that are set up when the
1023 kernel boots where userspace is also permitted to add keys - provided they
1024 can be verified by a key the kernel already has.
1025
1026 When called, the restriction function will be passed the keyring being
1027 added to, the key flags value and the type and payload of the key being
1028 added. Note that when a new key is being created, this is called between
1029 payload preparsing and actual key creation. The function should return 0
1030 to allow the link or an error to reject it.
1031
1032 A convenience function, restrict_link_reject, exists to always return
1033 -EPERM to in this case.
1034
1013 1035
1014(*) To check the validity of a key, this function can be called: 1036(*) To check the validity of a key, this function can be called:
1015 1037
diff --git a/certs/system_keyring.c b/certs/system_keyring.c
index dc18869ff680..417d65882870 100644
--- a/certs/system_keyring.c
+++ b/certs/system_keyring.c
@@ -36,11 +36,10 @@ static __init int system_trusted_keyring_init(void)
36 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 36 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
37 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 37 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
38 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH), 38 KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH),
39 KEY_ALLOC_NOT_IN_QUOTA, NULL); 39 KEY_ALLOC_NOT_IN_QUOTA,
40 keyring_restrict_trusted_only, NULL);
40 if (IS_ERR(system_trusted_keyring)) 41 if (IS_ERR(system_trusted_keyring))
41 panic("Can't allocate system trusted keyring\n"); 42 panic("Can't allocate system trusted keyring\n");
42
43 set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags);
44 return 0; 43 return 0;
45} 44}
46 45
@@ -85,7 +84,8 @@ static __init int load_system_certificate_list(void)
85 KEY_USR_VIEW | KEY_USR_READ), 84 KEY_USR_VIEW | KEY_USR_READ),
86 KEY_ALLOC_NOT_IN_QUOTA | 85 KEY_ALLOC_NOT_IN_QUOTA |
87 KEY_ALLOC_TRUSTED | 86 KEY_ALLOC_TRUSTED |
88 KEY_ALLOC_BUILT_IN); 87 KEY_ALLOC_BUILT_IN |
88 KEY_ALLOC_BYPASS_RESTRICTION);
89 if (IS_ERR(key)) { 89 if (IS_ERR(key)) {
90 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", 90 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n",
91 PTR_ERR(key)); 91 PTR_ERR(key));
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 3f93125916bf..71e8a56e9479 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -360,7 +360,7 @@ init_cifs_idmap(void)
360 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 360 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
361 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 361 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
362 KEY_USR_VIEW | KEY_USR_READ, 362 KEY_USR_VIEW | KEY_USR_READ,
363 KEY_ALLOC_NOT_IN_QUOTA, NULL); 363 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
364 if (IS_ERR(keyring)) { 364 if (IS_ERR(keyring)) {
365 ret = PTR_ERR(keyring); 365 ret = PTR_ERR(keyring);
366 goto failed_put_cred; 366 goto failed_put_cred;
diff --git a/fs/nfs/nfs4idmap.c b/fs/nfs/nfs4idmap.c
index 5ba22c6b0ffa..c444285bb1b1 100644
--- a/fs/nfs/nfs4idmap.c
+++ b/fs/nfs/nfs4idmap.c
@@ -201,7 +201,7 @@ int nfs_idmap_init(void)
201 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 201 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
202 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 202 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
203 KEY_USR_VIEW | KEY_USR_READ, 203 KEY_USR_VIEW | KEY_USR_READ,
204 KEY_ALLOC_NOT_IN_QUOTA, NULL); 204 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
205 if (IS_ERR(keyring)) { 205 if (IS_ERR(keyring)) {
206 ret = PTR_ERR(keyring); 206 ret = PTR_ERR(keyring);
207 goto failed_put_cred; 207 goto failed_put_cred;
diff --git a/include/linux/key.h b/include/linux/key.h
index 5f5b1129dc92..83b603639d2e 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -174,10 +174,9 @@ struct key {
174#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */ 174#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */
175#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ 175#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */
176#define KEY_FLAG_TRUSTED 8 /* set if key is trusted */ 176#define KEY_FLAG_TRUSTED 8 /* set if key is trusted */
177#define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ 177#define KEY_FLAG_BUILTIN 9 /* set if key is built in to the kernel */
178#define KEY_FLAG_BUILTIN 10 /* set if key is builtin */ 178#define KEY_FLAG_ROOT_CAN_INVAL 10 /* set if key can be invalidated by root without permission */
179#define KEY_FLAG_ROOT_CAN_INVAL 11 /* set if key can be invalidated by root without permission */ 179#define KEY_FLAG_KEEP 11 /* set if key should not be removed */
180#define KEY_FLAG_KEEP 12 /* set if key should not be removed */
181 180
182 /* the key type and key description string 181 /* the key type and key description string
183 * - the desc is used to match a key against search criteria 182 * - the desc is used to match a key against search criteria
@@ -205,6 +204,21 @@ struct key {
205 }; 204 };
206 int reject_error; 205 int reject_error;
207 }; 206 };
207
208 /* This is set on a keyring to restrict the addition of a link to a key
209 * to it. If this method isn't provided then it is assumed that the
210 * keyring is open to any addition. It is ignored for non-keyring
211 * keys.
212 *
213 * This is intended for use with rings of trusted keys whereby addition
214 * to the keyring needs to be controlled. KEY_ALLOC_BYPASS_RESTRICTION
215 * overrides this, allowing the kernel to add extra keys without
216 * restriction.
217 */
218 int (*restrict_link)(struct key *keyring,
219 const struct key_type *type,
220 unsigned long flags,
221 const union key_payload *payload);
208}; 222};
209 223
210extern struct key *key_alloc(struct key_type *type, 224extern struct key *key_alloc(struct key_type *type,
@@ -212,14 +226,19 @@ extern struct key *key_alloc(struct key_type *type,
212 kuid_t uid, kgid_t gid, 226 kuid_t uid, kgid_t gid,
213 const struct cred *cred, 227 const struct cred *cred,
214 key_perm_t perm, 228 key_perm_t perm,
215 unsigned long flags); 229 unsigned long flags,
230 int (*restrict_link)(struct key *,
231 const struct key_type *,
232 unsigned long,
233 const union key_payload *));
216 234
217 235
218#define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */ 236#define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */
219#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */ 237#define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */
220#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ 238#define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */
221#define KEY_ALLOC_TRUSTED 0x0004 /* Key should be flagged as trusted */ 239#define KEY_ALLOC_TRUSTED 0x0004 /* Key should be flagged as trusted */
222#define KEY_ALLOC_BUILT_IN 0x0008 /* Key is built into kernel */ 240#define KEY_ALLOC_BUILT_IN 0x0008 /* Key is built into kernel */
241#define KEY_ALLOC_BYPASS_RESTRICTION 0x0010 /* Override the check on restricted keyrings */
223 242
224extern void key_revoke(struct key *key); 243extern void key_revoke(struct key *key);
225extern void key_invalidate(struct key *key); 244extern void key_invalidate(struct key *key);
@@ -288,8 +307,22 @@ extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid
288 const struct cred *cred, 307 const struct cred *cred,
289 key_perm_t perm, 308 key_perm_t perm,
290 unsigned long flags, 309 unsigned long flags,
310 int (*restrict_link)(struct key *,
311 const struct key_type *,
312 unsigned long,
313 const union key_payload *),
291 struct key *dest); 314 struct key *dest);
292 315
316extern int keyring_restrict_trusted_only(struct key *keyring,
317 const struct key_type *type,
318 unsigned long,
319 const union key_payload *payload);
320
321extern int restrict_link_reject(struct key *keyring,
322 const struct key_type *type,
323 unsigned long flags,
324 const union key_payload *payload);
325
293extern int keyring_clear(struct key *keyring); 326extern int keyring_clear(struct key *keyring);
294 327
295extern key_ref_t keyring_search(key_ref_t keyring, 328extern key_ref_t keyring_search(key_ref_t keyring,
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index c79b85eb4d4c..8737412c7b27 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -281,7 +281,7 @@ static int __init init_dns_resolver(void)
281 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 281 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
282 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 282 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
283 KEY_USR_VIEW | KEY_USR_READ, 283 KEY_USR_VIEW | KEY_USR_READ,
284 KEY_ALLOC_NOT_IN_QUOTA, NULL); 284 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
285 if (IS_ERR(keyring)) { 285 if (IS_ERR(keyring)) {
286 ret = PTR_ERR(keyring); 286 ret = PTR_ERR(keyring);
287 goto failed_put_cred; 287 goto failed_put_cred;
diff --git a/net/rxrpc/ar-key.c b/net/rxrpc/ar-key.c
index 3fb492eedeb9..1021b4c0bdd2 100644
--- a/net/rxrpc/ar-key.c
+++ b/net/rxrpc/ar-key.c
@@ -965,7 +965,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
965 965
966 key = key_alloc(&key_type_rxrpc, "x", 966 key = key_alloc(&key_type_rxrpc, "x",
967 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0, 967 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 0,
968 KEY_ALLOC_NOT_IN_QUOTA); 968 KEY_ALLOC_NOT_IN_QUOTA, NULL);
969 if (IS_ERR(key)) { 969 if (IS_ERR(key)) {
970 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key)); 970 _leave(" = -ENOMEM [alloc %ld]", PTR_ERR(key));
971 return -ENOMEM; 971 return -ENOMEM;
@@ -1012,7 +1012,7 @@ struct key *rxrpc_get_null_key(const char *keyname)
1012 1012
1013 key = key_alloc(&key_type_rxrpc, keyname, 1013 key = key_alloc(&key_type_rxrpc, keyname,
1014 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, 1014 GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred,
1015 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA); 1015 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA, NULL);
1016 if (IS_ERR(key)) 1016 if (IS_ERR(key))
1017 return key; 1017 return key;
1018 1018
diff --git a/security/integrity/digsig.c b/security/integrity/digsig.c
index 8ef15118cc78..659566c2200b 100644
--- a/security/integrity/digsig.c
+++ b/security/integrity/digsig.c
@@ -83,10 +83,9 @@ int __init integrity_init_keyring(const unsigned int id)
83 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 83 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
84 KEY_USR_VIEW | KEY_USR_READ | 84 KEY_USR_VIEW | KEY_USR_READ |
85 KEY_USR_WRITE | KEY_USR_SEARCH), 85 KEY_USR_WRITE | KEY_USR_SEARCH),
86 KEY_ALLOC_NOT_IN_QUOTA, NULL); 86 KEY_ALLOC_NOT_IN_QUOTA,
87 if (!IS_ERR(keyring[id])) 87 NULL, NULL);
88 set_bit(KEY_FLAG_TRUSTED_ONLY, &keyring[id]->flags); 88 if (IS_ERR(keyring[id])) {
89 else {
90 err = PTR_ERR(keyring[id]); 89 err = PTR_ERR(keyring[id]);
91 pr_info("Can't allocate %s keyring (%d)\n", 90 pr_info("Can't allocate %s keyring (%d)\n",
92 keyring_name[id], err); 91 keyring_name[id], err);
diff --git a/security/integrity/ima/ima_mok.c b/security/integrity/ima/ima_mok.c
index 676885e4320e..ef91248cb934 100644
--- a/security/integrity/ima/ima_mok.c
+++ b/security/integrity/ima/ima_mok.c
@@ -35,20 +35,20 @@ __init int ima_mok_init(void)
35 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 35 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
36 KEY_USR_VIEW | KEY_USR_READ | 36 KEY_USR_VIEW | KEY_USR_READ |
37 KEY_USR_WRITE | KEY_USR_SEARCH, 37 KEY_USR_WRITE | KEY_USR_SEARCH,
38 KEY_ALLOC_NOT_IN_QUOTA, NULL); 38 KEY_ALLOC_NOT_IN_QUOTA,
39 keyring_restrict_trusted_only, NULL);
39 40
40 ima_blacklist_keyring = keyring_alloc(".ima_blacklist", 41 ima_blacklist_keyring = keyring_alloc(".ima_blacklist",
41 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(), 42 KUIDT_INIT(0), KGIDT_INIT(0), current_cred(),
42 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 43 (KEY_POS_ALL & ~KEY_POS_SETATTR) |
43 KEY_USR_VIEW | KEY_USR_READ | 44 KEY_USR_VIEW | KEY_USR_READ |
44 KEY_USR_WRITE | KEY_USR_SEARCH, 45 KEY_USR_WRITE | KEY_USR_SEARCH,
45 KEY_ALLOC_NOT_IN_QUOTA, NULL); 46 KEY_ALLOC_NOT_IN_QUOTA,
47 keyring_restrict_trusted_only, NULL);
46 48
47 if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring)) 49 if (IS_ERR(ima_mok_keyring) || IS_ERR(ima_blacklist_keyring))
48 panic("Can't allocate IMA MOK or blacklist keyrings."); 50 panic("Can't allocate IMA MOK or blacklist keyrings.");
49 set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_mok_keyring->flags);
50 51
51 set_bit(KEY_FLAG_TRUSTED_ONLY, &ima_blacklist_keyring->flags);
52 set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags); 52 set_bit(KEY_FLAG_KEEP, &ima_blacklist_keyring->flags);
53 return 0; 53 return 0;
54} 54}
diff --git a/security/keys/key.c b/security/keys/key.c
index b28755131687..deb881754e03 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -201,6 +201,7 @@ serial_exists:
201 * @cred: The credentials specifying UID namespace. 201 * @cred: The credentials specifying UID namespace.
202 * @perm: The permissions mask of the new key. 202 * @perm: The permissions mask of the new key.
203 * @flags: Flags specifying quota properties. 203 * @flags: Flags specifying quota properties.
204 * @restrict_link: Optional link restriction method for new keyrings.
204 * 205 *
205 * Allocate a key of the specified type with the attributes given. The key is 206 * Allocate a key of the specified type with the attributes given. The key is
206 * returned in an uninstantiated state and the caller needs to instantiate the 207 * returned in an uninstantiated state and the caller needs to instantiate the
@@ -223,7 +224,11 @@ serial_exists:
223 */ 224 */
224struct key *key_alloc(struct key_type *type, const char *desc, 225struct key *key_alloc(struct key_type *type, const char *desc,
225 kuid_t uid, kgid_t gid, const struct cred *cred, 226 kuid_t uid, kgid_t gid, const struct cred *cred,
226 key_perm_t perm, unsigned long flags) 227 key_perm_t perm, unsigned long flags,
228 int (*restrict_link)(struct key *,
229 const struct key_type *,
230 unsigned long,
231 const union key_payload *))
227{ 232{
228 struct key_user *user = NULL; 233 struct key_user *user = NULL;
229 struct key *key; 234 struct key *key;
@@ -291,6 +296,7 @@ struct key *key_alloc(struct key_type *type, const char *desc,
291 key->uid = uid; 296 key->uid = uid;
292 key->gid = gid; 297 key->gid = gid;
293 key->perm = perm; 298 key->perm = perm;
299 key->restrict_link = restrict_link;
294 300
295 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) 301 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA))
296 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 302 key->flags |= 1 << KEY_FLAG_IN_QUOTA;
@@ -496,6 +502,12 @@ int key_instantiate_and_link(struct key *key,
496 } 502 }
497 503
498 if (keyring) { 504 if (keyring) {
505 if (keyring->restrict_link) {
506 ret = keyring->restrict_link(keyring, key->type,
507 key->flags, &prep.payload);
508 if (ret < 0)
509 goto error;
510 }
499 ret = __key_link_begin(keyring, &key->index_key, &edit); 511 ret = __key_link_begin(keyring, &key->index_key, &edit);
500 if (ret < 0) 512 if (ret < 0)
501 goto error; 513 goto error;
@@ -551,8 +563,12 @@ int key_reject_and_link(struct key *key,
551 awaken = 0; 563 awaken = 0;
552 ret = -EBUSY; 564 ret = -EBUSY;
553 565
554 if (keyring) 566 if (keyring) {
567 if (keyring->restrict_link)
568 return -EPERM;
569
555 link_ret = __key_link_begin(keyring, &key->index_key, &edit); 570 link_ret = __key_link_begin(keyring, &key->index_key, &edit);
571 }
556 572
557 mutex_lock(&key_construction_mutex); 573 mutex_lock(&key_construction_mutex);
558 574
@@ -793,6 +809,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
793 struct key *keyring, *key = NULL; 809 struct key *keyring, *key = NULL;
794 key_ref_t key_ref; 810 key_ref_t key_ref;
795 int ret; 811 int ret;
812 int (*restrict_link)(struct key *,
813 const struct key_type *,
814 unsigned long,
815 const union key_payload *) = NULL;
796 816
797 /* look up the key type to see if it's one of the registered kernel 817 /* look up the key type to see if it's one of the registered kernel
798 * types */ 818 * types */
@@ -811,6 +831,10 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
811 831
812 key_check(keyring); 832 key_check(keyring);
813 833
834 key_ref = ERR_PTR(-EPERM);
835 if (!(flags & KEY_ALLOC_BYPASS_RESTRICTION))
836 restrict_link = keyring->restrict_link;
837
814 key_ref = ERR_PTR(-ENOTDIR); 838 key_ref = ERR_PTR(-ENOTDIR);
815 if (keyring->type != &key_type_keyring) 839 if (keyring->type != &key_type_keyring)
816 goto error_put_type; 840 goto error_put_type;
@@ -835,10 +859,15 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
835 } 859 }
836 index_key.desc_len = strlen(index_key.description); 860 index_key.desc_len = strlen(index_key.description);
837 861
838 key_ref = ERR_PTR(-EPERM); 862 if (restrict_link) {
839 if (!prep.trusted && test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags)) 863 unsigned long kflags = prep.trusted ? KEY_FLAG_TRUSTED : 0;
840 goto error_free_prep; 864 ret = restrict_link(keyring,
841 flags |= prep.trusted ? KEY_ALLOC_TRUSTED : 0; 865 index_key.type, kflags, &prep.payload);
866 if (ret < 0) {
867 key_ref = ERR_PTR(ret);
868 goto error_free_prep;
869 }
870 }
842 871
843 ret = __key_link_begin(keyring, &index_key, &edit); 872 ret = __key_link_begin(keyring, &index_key, &edit);
844 if (ret < 0) { 873 if (ret < 0) {
@@ -879,7 +908,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
879 908
880 /* allocate a new key */ 909 /* allocate a new key */
881 key = key_alloc(index_key.type, index_key.description, 910 key = key_alloc(index_key.type, index_key.description,
882 cred->fsuid, cred->fsgid, cred, perm, flags); 911 cred->fsuid, cred->fsgid, cred, perm, flags, NULL);
883 if (IS_ERR(key)) { 912 if (IS_ERR(key)) {
884 key_ref = ERR_CAST(key); 913 key_ref = ERR_CAST(key);
885 goto error_link_end; 914 goto error_link_end;
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index f931ccfeefb0..d2d1f3378008 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -491,13 +491,18 @@ static long keyring_read(const struct key *keyring,
491 */ 491 */
492struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid, 492struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
493 const struct cred *cred, key_perm_t perm, 493 const struct cred *cred, key_perm_t perm,
494 unsigned long flags, struct key *dest) 494 unsigned long flags,
495 int (*restrict_link)(struct key *,
496 const struct key_type *,
497 unsigned long,
498 const union key_payload *),
499 struct key *dest)
495{ 500{
496 struct key *keyring; 501 struct key *keyring;
497 int ret; 502 int ret;
498 503
499 keyring = key_alloc(&key_type_keyring, description, 504 keyring = key_alloc(&key_type_keyring, description,
500 uid, gid, cred, perm, flags); 505 uid, gid, cred, perm, flags, restrict_link);
501 if (!IS_ERR(keyring)) { 506 if (!IS_ERR(keyring)) {
502 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL); 507 ret = key_instantiate_and_link(keyring, NULL, 0, dest, NULL);
503 if (ret < 0) { 508 if (ret < 0) {
@@ -510,6 +515,51 @@ struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
510} 515}
511EXPORT_SYMBOL(keyring_alloc); 516EXPORT_SYMBOL(keyring_alloc);
512 517
518/**
519 * keyring_restrict_trusted_only - Restrict additions to a keyring to trusted keys only
520 * @keyring: The keyring being added to.
521 * @type: The type of key being added.
522 * @flags: The key flags.
523 * @payload: The payload of the key intended to be added.
524 *
525 * Reject the addition of any links to a keyring that point to keys that aren't
526 * marked as being trusted. It can be overridden by passing
527 * KEY_ALLOC_BYPASS_RESTRICTION to key_instantiate_and_link() when adding a key
528 * to a keyring.
529 *
530 * This is meant to be passed as the restrict_link parameter to
531 * keyring_alloc().
532 */
533int keyring_restrict_trusted_only(struct key *keyring,
534 const struct key_type *type,
535 unsigned long flags,
536 const union key_payload *payload)
537{
538 return flags & KEY_FLAG_TRUSTED ? 0 : -EPERM;
539}
540
541/**
542 * restrict_link_reject - Give -EPERM to restrict link
543 * @keyring: The keyring being added to.
544 * @type: The type of key being added.
545 * @flags: The key flags.
546 * @payload: The payload of the key intended to be added.
547 *
548 * Reject the addition of any links to a keyring. It can be overridden by
549 * passing KEY_ALLOC_BYPASS_RESTRICTION to key_instantiate_and_link() when
550 * adding a key to a keyring.
551 *
552 * This is meant to be passed as the restrict_link parameter to
553 * keyring_alloc().
554 */
555int restrict_link_reject(struct key *keyring,
556 const struct key_type *type,
557 unsigned long flags,
558 const union key_payload *payload)
559{
560 return -EPERM;
561}
562
513/* 563/*
514 * By default, we keys found by getting an exact match on their descriptions. 564 * By default, we keys found by getting an exact match on their descriptions.
515 */ 565 */
@@ -1191,6 +1241,17 @@ void __key_link_end(struct key *keyring,
1191 up_write(&keyring->sem); 1241 up_write(&keyring->sem);
1192} 1242}
1193 1243
1244/*
1245 * Check addition of keys to restricted keyrings.
1246 */
1247static int __key_link_check_restriction(struct key *keyring, struct key *key)
1248{
1249 if (!keyring->restrict_link)
1250 return 0;
1251 return keyring->restrict_link(keyring,
1252 key->type, key->flags, &key->payload);
1253}
1254
1194/** 1255/**
1195 * key_link - Link a key to a keyring 1256 * key_link - Link a key to a keyring
1196 * @keyring: The keyring to make the link in. 1257 * @keyring: The keyring to make the link in.
@@ -1221,14 +1282,12 @@ int key_link(struct key *keyring, struct key *key)
1221 key_check(keyring); 1282 key_check(keyring);
1222 key_check(key); 1283 key_check(key);
1223 1284
1224 if (test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags) &&
1225 !test_bit(KEY_FLAG_TRUSTED, &key->flags))
1226 return -EPERM;
1227
1228 ret = __key_link_begin(keyring, &key->index_key, &edit); 1285 ret = __key_link_begin(keyring, &key->index_key, &edit);
1229 if (ret == 0) { 1286 if (ret == 0) {
1230 kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage)); 1287 kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage));
1231 ret = __key_link_check_live_key(keyring, key); 1288 ret = __key_link_check_restriction(keyring, key);
1289 if (ret == 0)
1290 ret = __key_link_check_live_key(keyring, key);
1232 if (ret == 0) 1291 if (ret == 0)
1233 __key_link(key, &edit); 1292 __key_link(key, &edit);
1234 __key_link_end(keyring, &key->index_key, edit); 1293 __key_link_end(keyring, &key->index_key, edit);
diff --git a/security/keys/persistent.c b/security/keys/persistent.c
index c9fae5ea89fe..2ef45b319dd9 100644
--- a/security/keys/persistent.c
+++ b/security/keys/persistent.c
@@ -26,7 +26,7 @@ static int key_create_persistent_register(struct user_namespace *ns)
26 current_cred(), 26 current_cred(),
27 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 27 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
28 KEY_USR_VIEW | KEY_USR_READ), 28 KEY_USR_VIEW | KEY_USR_READ),
29 KEY_ALLOC_NOT_IN_QUOTA, NULL); 29 KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL);
30 if (IS_ERR(reg)) 30 if (IS_ERR(reg))
31 return PTR_ERR(reg); 31 return PTR_ERR(reg);
32 32
@@ -60,7 +60,7 @@ static key_ref_t key_create_persistent(struct user_namespace *ns, kuid_t uid,
60 uid, INVALID_GID, current_cred(), 60 uid, INVALID_GID, current_cred(),
61 ((KEY_POS_ALL & ~KEY_POS_SETATTR) | 61 ((KEY_POS_ALL & ~KEY_POS_SETATTR) |
62 KEY_USR_VIEW | KEY_USR_READ), 62 KEY_USR_VIEW | KEY_USR_READ),
63 KEY_ALLOC_NOT_IN_QUOTA, 63 KEY_ALLOC_NOT_IN_QUOTA, NULL,
64 ns->persistent_keyring_register); 64 ns->persistent_keyring_register);
65 if (IS_ERR(persistent)) 65 if (IS_ERR(persistent))
66 return ERR_CAST(persistent); 66 return ERR_CAST(persistent);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index e6d50172872f..40a885239782 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -76,7 +76,8 @@ int install_user_keyrings(void)
76 if (IS_ERR(uid_keyring)) { 76 if (IS_ERR(uid_keyring)) {
77 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID, 77 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
78 cred, user_keyring_perm, 78 cred, user_keyring_perm,
79 KEY_ALLOC_IN_QUOTA, NULL); 79 KEY_ALLOC_IN_QUOTA,
80 NULL, NULL);
80 if (IS_ERR(uid_keyring)) { 81 if (IS_ERR(uid_keyring)) {
81 ret = PTR_ERR(uid_keyring); 82 ret = PTR_ERR(uid_keyring);
82 goto error; 83 goto error;
@@ -92,7 +93,8 @@ int install_user_keyrings(void)
92 session_keyring = 93 session_keyring =
93 keyring_alloc(buf, user->uid, INVALID_GID, 94 keyring_alloc(buf, user->uid, INVALID_GID,
94 cred, user_keyring_perm, 95 cred, user_keyring_perm,
95 KEY_ALLOC_IN_QUOTA, NULL); 96 KEY_ALLOC_IN_QUOTA,
97 NULL, NULL);
96 if (IS_ERR(session_keyring)) { 98 if (IS_ERR(session_keyring)) {
97 ret = PTR_ERR(session_keyring); 99 ret = PTR_ERR(session_keyring);
98 goto error_release; 100 goto error_release;
@@ -134,7 +136,8 @@ int install_thread_keyring_to_cred(struct cred *new)
134 136
135 keyring = keyring_alloc("_tid", new->uid, new->gid, new, 137 keyring = keyring_alloc("_tid", new->uid, new->gid, new,
136 KEY_POS_ALL | KEY_USR_VIEW, 138 KEY_POS_ALL | KEY_USR_VIEW,
137 KEY_ALLOC_QUOTA_OVERRUN, NULL); 139 KEY_ALLOC_QUOTA_OVERRUN,
140 NULL, NULL);
138 if (IS_ERR(keyring)) 141 if (IS_ERR(keyring))
139 return PTR_ERR(keyring); 142 return PTR_ERR(keyring);
140 143
@@ -180,7 +183,8 @@ int install_process_keyring_to_cred(struct cred *new)
180 183
181 keyring = keyring_alloc("_pid", new->uid, new->gid, new, 184 keyring = keyring_alloc("_pid", new->uid, new->gid, new,
182 KEY_POS_ALL | KEY_USR_VIEW, 185 KEY_POS_ALL | KEY_USR_VIEW,
183 KEY_ALLOC_QUOTA_OVERRUN, NULL); 186 KEY_ALLOC_QUOTA_OVERRUN,
187 NULL, NULL);
184 if (IS_ERR(keyring)) 188 if (IS_ERR(keyring))
185 return PTR_ERR(keyring); 189 return PTR_ERR(keyring);
186 190
@@ -231,7 +235,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
231 235
232 keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred, 236 keyring = keyring_alloc("_ses", cred->uid, cred->gid, cred,
233 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, 237 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
234 flags, NULL); 238 flags, NULL, NULL);
235 if (IS_ERR(keyring)) 239 if (IS_ERR(keyring))
236 return PTR_ERR(keyring); 240 return PTR_ERR(keyring);
237 } else { 241 } else {
@@ -785,7 +789,7 @@ long join_session_keyring(const char *name)
785 keyring = keyring_alloc( 789 keyring = keyring_alloc(
786 name, old->uid, old->gid, old, 790 name, old->uid, old->gid, old,
787 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK, 791 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ | KEY_USR_LINK,
788 KEY_ALLOC_IN_QUOTA, NULL); 792 KEY_ALLOC_IN_QUOTA, NULL, NULL);
789 if (IS_ERR(keyring)) { 793 if (IS_ERR(keyring)) {
790 ret = PTR_ERR(keyring); 794 ret = PTR_ERR(keyring);
791 goto error2; 795 goto error2;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index c7a117c9a8f3..a29e3554751e 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -116,7 +116,7 @@ static int call_sbin_request_key(struct key_construction *cons,
116 cred = get_current_cred(); 116 cred = get_current_cred();
117 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred, 117 keyring = keyring_alloc(desc, cred->fsuid, cred->fsgid, cred,
118 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ, 118 KEY_POS_ALL | KEY_USR_VIEW | KEY_USR_READ,
119 KEY_ALLOC_QUOTA_OVERRUN, NULL); 119 KEY_ALLOC_QUOTA_OVERRUN, NULL, NULL);
120 put_cred(cred); 120 put_cred(cred);
121 if (IS_ERR(keyring)) { 121 if (IS_ERR(keyring)) {
122 ret = PTR_ERR(keyring); 122 ret = PTR_ERR(keyring);
@@ -355,7 +355,7 @@ static int construct_alloc_key(struct keyring_search_context *ctx,
355 355
356 key = key_alloc(ctx->index_key.type, ctx->index_key.description, 356 key = key_alloc(ctx->index_key.type, ctx->index_key.description,
357 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred, 357 ctx->cred->fsuid, ctx->cred->fsgid, ctx->cred,
358 perm, flags); 358 perm, flags, NULL);
359 if (IS_ERR(key)) 359 if (IS_ERR(key))
360 goto alloc_failed; 360 goto alloc_failed;
361 361
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 4f0f112fe276..9db8b4a82787 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -202,7 +202,7 @@ struct key *request_key_auth_new(struct key *target, const void *callout_info,
202 authkey = key_alloc(&key_type_request_key_auth, desc, 202 authkey = key_alloc(&key_type_request_key_auth, desc,
203 cred->fsuid, cred->fsgid, cred, 203 cred->fsuid, cred->fsgid, cred,
204 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH | 204 KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
205 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA); 205 KEY_USR_VIEW, KEY_ALLOC_NOT_IN_QUOTA, NULL);
206 if (IS_ERR(authkey)) { 206 if (IS_ERR(authkey)) {
207 ret = PTR_ERR(authkey); 207 ret = PTR_ERR(authkey);
208 goto error_alloc; 208 goto error_alloc;