Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KEYS: Add a 'trusted' flag and a 'trusted only' flag

Add KEY_FLAG_TRUSTED to indicate that a key either comes from a trusted source
or had a cryptographic signature chain that led back to a trusted key the
kernel already possessed.

Add KEY_FLAGS_TRUSTED_ONLY to indicate that a keyring will only accept links to
keys marked with KEY_FLAGS_TRUSTED.

Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Kees Cook <keescook@chromium.org>

+19 -1
+1
include/linux/key-type.h
··· 45 45 const void *data; /* Raw data */ 46 46 size_t datalen; /* Raw datalen */ 47 47 size_t quotalen; /* Quota length for proposed payload */ 48 + bool trusted; /* True if key is trusted */ 48 49 }; 49 50 50 51 typedef int (*request_key_actor_t)(struct key_construction *key,
+3
include/linux/key.h
··· 168 168 #define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ 169 169 #define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */ 170 170 #define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ 171 + #define KEY_FLAG_TRUSTED 8 /* set if key is trusted */ 172 + #define KEY_FLAG_TRUSTED_ONLY 9 /* set if keyring only accepts links to trusted keys */ 171 173 172 174 /* the key type and key description string 173 175 * - the desc is used to match a key against search criteria ··· 220 218 #define KEY_ALLOC_IN_QUOTA 0x0000 /* add to quota, reject if would overrun */ 221 219 #define KEY_ALLOC_QUOTA_OVERRUN 0x0001 /* add to quota, permit even if overrun */ 222 220 #define KEY_ALLOC_NOT_IN_QUOTA 0x0002 /* not in quota */ 221 + #define KEY_ALLOC_TRUSTED 0x0004 /* Key should be flagged as trusted */ 223 222 224 223 extern void key_revoke(struct key *key); 225 224 extern void key_invalidate(struct key *key);
+3 -1
kernel/system_keyring.c
··· 40 40 if (IS_ERR(system_trusted_keyring)) 41 41 panic("Can't allocate system trusted keyring\n"); 42 42 43 + set_bit(KEY_FLAG_TRUSTED_ONLY, &system_trusted_keyring->flags); 43 44 return 0; 44 45 } 45 46 ··· 83 82 plen, 84 83 (KEY_POS_ALL & ~KEY_POS_SETATTR) | 85 84 KEY_USR_VIEW, 86 - KEY_ALLOC_NOT_IN_QUOTA); 85 + KEY_ALLOC_NOT_IN_QUOTA | 86 + KEY_ALLOC_TRUSTED); 87 87 if (IS_ERR(key)) { 88 88 pr_err("Problem loading in-kernel X.509 certificate (%ld)\n", 89 89 PTR_ERR(key));
+8
security/keys/key.c
··· 300 300 301 301 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) 302 302 key->flags |= 1 << KEY_FLAG_IN_QUOTA; 303 + if (flags & KEY_ALLOC_TRUSTED) 304 + key->flags |= 1 << KEY_FLAG_TRUSTED; 303 305 304 306 memset(&key->type_data, 0, sizeof(key->type_data)); 305 307 ··· 815 813 prep.data = payload; 816 814 prep.datalen = plen; 817 815 prep.quotalen = index_key.type->def_datalen; 816 + prep.trusted = flags & KEY_ALLOC_TRUSTED; 818 817 if (index_key.type->preparse) { 819 818 ret = index_key.type->preparse(&prep); 820 819 if (ret < 0) { ··· 829 826 goto error_free_prep; 830 827 } 831 828 index_key.desc_len = strlen(index_key.description); 829 + 830 + key_ref = ERR_PTR(-EPERM); 831 + if (!prep.trusted && test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags)) 832 + goto error_free_prep; 833 + flags |= prep.trusted ? KEY_ALLOC_TRUSTED : 0; 832 834 833 835 ret = __key_link_begin(keyring, &index_key, &edit); 834 836 if (ret < 0) {
+4
security/keys/keyring.c
··· 1183 1183 key_check(keyring); 1184 1184 key_check(key); 1185 1185 1186 + if (test_bit(KEY_FLAG_TRUSTED_ONLY, &keyring->flags) && 1187 + !test_bit(KEY_FLAG_TRUSTED, &key->flags)) 1188 + return -EPERM; 1189 + 1186 1190 ret = __key_link_begin(keyring, &key->index_key, &edit); 1187 1191 if (ret == 0) { 1188 1192 kdebug("begun {%d,%d}", keyring->serial, atomic_read(&keyring->usage));