aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2017-10-18 21:28:38 -0400
committerJames Morris <james.l.morris@oracle.com>2017-10-18 21:28:38 -0400
commit494b9ae7abb84e6d88d7587906aff29dd26cf9d0 (patch)
treeaeb24854a715777aaa9d433d57f5e45d05017f73
parent73d3393ada4f70fa3df5639c8d438f2f034c0ecb (diff)
parent68a1fdbbf8bd3378325e45c19e167a165f9ffc3a (diff)
Merge commit 'tags/keys-fixes-20171018' into fixes-v4.14-rc5
-rw-r--r--crypto/asymmetric_keys/asymmetric_type.c4
-rw-r--r--crypto/asymmetric_keys/pkcs7_parser.c3
-rw-r--r--fs/crypto/keyinfo.c5
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h24
-rw-r--r--fs/ecryptfs/keystore.c9
-rw-r--r--fs/fscache/object-list.c7
-rw-r--r--include/linux/key.h47
-rw-r--r--lib/digsig.c6
-rw-r--r--net/dns_resolver/dns_key.c2
-rw-r--r--security/keys/Kconfig1
-rw-r--r--security/keys/big_key.c4
-rw-r--r--security/keys/encrypted-keys/encrypted.c9
-rw-r--r--security/keys/gc.c8
-rw-r--r--security/keys/key.c41
-rw-r--r--security/keys/keyctl.c9
-rw-r--r--security/keys/keyring.c14
-rw-r--r--security/keys/permission.c7
-rw-r--r--security/keys/proc.c31
-rw-r--r--security/keys/process_keys.c2
-rw-r--r--security/keys/request_key.c7
-rw-r--r--security/keys/request_key_auth.c2
-rw-r--r--security/keys/trusted.c2
-rw-r--r--security/keys/user_defined.c4
23 files changed, 168 insertions, 80 deletions
diff --git a/crypto/asymmetric_keys/asymmetric_type.c b/crypto/asymmetric_keys/asymmetric_type.c
index e4b0ed386bc8..39aecad286fe 100644
--- a/crypto/asymmetric_keys/asymmetric_type.c
+++ b/crypto/asymmetric_keys/asymmetric_type.c
@@ -57,6 +57,8 @@ struct key *find_asymmetric_key(struct key *keyring,
57 char *req, *p; 57 char *req, *p;
58 int len; 58 int len;
59 59
60 BUG_ON(!id_0 && !id_1);
61
60 if (id_0) { 62 if (id_0) {
61 lookup = id_0->data; 63 lookup = id_0->data;
62 len = id_0->len; 64 len = id_0->len;
@@ -105,7 +107,7 @@ struct key *find_asymmetric_key(struct key *keyring,
105 if (id_0 && id_1) { 107 if (id_0 && id_1) {
106 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key); 108 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
107 109
108 if (!kids->id[0]) { 110 if (!kids->id[1]) {
109 pr_debug("First ID matches, but second is missing\n"); 111 pr_debug("First ID matches, but second is missing\n");
110 goto reject; 112 goto reject;
111 } 113 }
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
index af4cd8649117..d140d8bb2c96 100644
--- a/crypto/asymmetric_keys/pkcs7_parser.c
+++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -88,6 +88,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg)
88 bool want = false; 88 bool want = false;
89 89
90 sinfo = msg->signed_infos; 90 sinfo = msg->signed_infos;
91 if (!sinfo)
92 goto inconsistent;
93
91 if (sinfo->authattrs) { 94 if (sinfo->authattrs) {
92 want = true; 95 want = true;
93 msg->have_authattrs = true; 96 msg->have_authattrs = true;
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index 018c588c7ac3..8e704d12a1cf 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -109,6 +109,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info,
109 goto out; 109 goto out;
110 } 110 }
111 ukp = user_key_payload_locked(keyring_key); 111 ukp = user_key_payload_locked(keyring_key);
112 if (!ukp) {
113 /* key was revoked before we acquired its semaphore */
114 res = -EKEYREVOKED;
115 goto out;
116 }
112 if (ukp->datalen != sizeof(struct fscrypt_key)) { 117 if (ukp->datalen != sizeof(struct fscrypt_key)) {
113 res = -EINVAL; 118 res = -EINVAL;
114 goto out; 119 goto out;
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 9c351bf757b2..3fbc0ff79699 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context {
84static inline struct ecryptfs_auth_tok * 84static inline struct ecryptfs_auth_tok *
85ecryptfs_get_encrypted_key_payload_data(struct key *key) 85ecryptfs_get_encrypted_key_payload_data(struct key *key)
86{ 86{
87 if (key->type == &key_type_encrypted) 87 struct encrypted_key_payload *payload;
88 return (struct ecryptfs_auth_tok *) 88
89 (&((struct encrypted_key_payload *)key->payload.data[0])->payload_data); 89 if (key->type != &key_type_encrypted)
90 else
91 return NULL; 90 return NULL;
91
92 payload = key->payload.data[0];
93 if (!payload)
94 return ERR_PTR(-EKEYREVOKED);
95
96 return (struct ecryptfs_auth_tok *)payload->payload_data;
92} 97}
93 98
94static inline struct key *ecryptfs_get_encrypted_key(char *sig) 99static inline struct key *ecryptfs_get_encrypted_key(char *sig)
@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok *
114ecryptfs_get_key_payload_data(struct key *key) 119ecryptfs_get_key_payload_data(struct key *key)
115{ 120{
116 struct ecryptfs_auth_tok *auth_tok; 121 struct ecryptfs_auth_tok *auth_tok;
122 struct user_key_payload *ukp;
117 123
118 auth_tok = ecryptfs_get_encrypted_key_payload_data(key); 124 auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
119 if (!auth_tok) 125 if (auth_tok)
120 return (struct ecryptfs_auth_tok *)user_key_payload_locked(key)->data;
121 else
122 return auth_tok; 126 return auth_tok;
127
128 ukp = user_key_payload_locked(key);
129 if (!ukp)
130 return ERR_PTR(-EKEYREVOKED);
131
132 return (struct ecryptfs_auth_tok *)ukp->data;
123} 133}
124 134
125#define ECRYPTFS_MAX_KEYSET_SIZE 1024 135#define ECRYPTFS_MAX_KEYSET_SIZE 1024
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 3cf1546dca82..fa218cd64f74 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -459,7 +459,8 @@ out:
459 * @auth_tok_key: key containing the authentication token 459 * @auth_tok_key: key containing the authentication token
460 * @auth_tok: authentication token 460 * @auth_tok: authentication token
461 * 461 *
462 * Returns zero on valid auth tok; -EINVAL otherwise 462 * Returns zero on valid auth tok; -EINVAL if the payload is invalid; or
463 * -EKEYREVOKED if the key was revoked before we acquired its semaphore.
463 */ 464 */
464static int 465static int
465ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key, 466ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
@@ -468,6 +469,12 @@ ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
468 int rc = 0; 469 int rc = 0;
469 470
470 (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key); 471 (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key);
472 if (IS_ERR(*auth_tok)) {
473 rc = PTR_ERR(*auth_tok);
474 *auth_tok = NULL;
475 goto out;
476 }
477
471 if (ecryptfs_verify_version((*auth_tok)->version)) { 478 if (ecryptfs_verify_version((*auth_tok)->version)) {
472 printk(KERN_ERR "Data structure version mismatch. Userspace " 479 printk(KERN_ERR "Data structure version mismatch. Userspace "
473 "tools must match eCryptfs kernel module with major " 480 "tools must match eCryptfs kernel module with major "
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c
index b5ab06fabc60..0438d4cd91ef 100644
--- a/fs/fscache/object-list.c
+++ b/fs/fscache/object-list.c
@@ -331,6 +331,13 @@ static void fscache_objlist_config(struct fscache_objlist_data *data)
331 rcu_read_lock(); 331 rcu_read_lock();
332 332
333 confkey = user_key_payload_rcu(key); 333 confkey = user_key_payload_rcu(key);
334 if (!confkey) {
335 /* key was revoked */
336 rcu_read_unlock();
337 key_put(key);
338 goto no_config;
339 }
340
334 buf = confkey->data; 341 buf = confkey->data;
335 342
336 for (len = confkey->datalen - 1; len >= 0; len--) { 343 for (len = confkey->datalen - 1; len >= 0; len--) {
diff --git a/include/linux/key.h b/include/linux/key.h
index e315e16b6ff8..8a15cabe928d 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -138,6 +138,11 @@ struct key_restriction {
138 struct key_type *keytype; 138 struct key_type *keytype;
139}; 139};
140 140
141enum key_state {
142 KEY_IS_UNINSTANTIATED,
143 KEY_IS_POSITIVE, /* Positively instantiated */
144};
145
141/*****************************************************************************/ 146/*****************************************************************************/
142/* 147/*
143 * authentication token / access credential / keyring 148 * authentication token / access credential / keyring
@@ -169,6 +174,7 @@ struct key {
169 * - may not match RCU dereferenced payload 174 * - may not match RCU dereferenced payload
170 * - payload should contain own length 175 * - payload should contain own length
171 */ 176 */
177 short state; /* Key state (+) or rejection error (-) */
172 178
173#ifdef KEY_DEBUGGING 179#ifdef KEY_DEBUGGING
174 unsigned magic; 180 unsigned magic;
@@ -176,18 +182,16 @@ struct key {
176#endif 182#endif
177 183
178 unsigned long flags; /* status flags (change with bitops) */ 184 unsigned long flags; /* status flags (change with bitops) */
179#define KEY_FLAG_INSTANTIATED 0 /* set if key has been instantiated */ 185#define KEY_FLAG_DEAD 0 /* set if key type has been deleted */
180#define KEY_FLAG_DEAD 1 /* set if key type has been deleted */ 186#define KEY_FLAG_REVOKED 1 /* set if key had been revoked */
181#define KEY_FLAG_REVOKED 2 /* set if key had been revoked */ 187#define KEY_FLAG_IN_QUOTA 2 /* set if key consumes quota */
182#define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */ 188#define KEY_FLAG_USER_CONSTRUCT 3 /* set if key is being constructed in userspace */
183#define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */ 189#define KEY_FLAG_ROOT_CAN_CLEAR 4 /* set if key can be cleared by root without permission */
184#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */ 190#define KEY_FLAG_INVALIDATED 5 /* set if key has been invalidated */
185#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */ 191#define KEY_FLAG_BUILTIN 6 /* set if key is built in to the kernel */
186#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */ 192#define KEY_FLAG_ROOT_CAN_INVAL 7 /* set if key can be invalidated by root without permission */
187#define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */ 193#define KEY_FLAG_KEEP 8 /* set if key should not be removed */
188#define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */ 194#define KEY_FLAG_UID_KEYRING 9 /* set if key is a user or user session keyring */
189#define KEY_FLAG_KEEP 10 /* set if key should not be removed */
190#define KEY_FLAG_UID_KEYRING 11 /* set if key is a user or user session keyring */
191 195
192 /* the key type and key description string 196 /* the key type and key description string
193 * - the desc is used to match a key against search criteria 197 * - the desc is used to match a key against search criteria
@@ -213,7 +217,6 @@ struct key {
213 struct list_head name_link; 217 struct list_head name_link;
214 struct assoc_array keys; 218 struct assoc_array keys;
215 }; 219 };
216 int reject_error;
217 }; 220 };
218 221
219 /* This is set on a keyring to restrict the addition of a link to a key 222 /* This is set on a keyring to restrict the addition of a link to a key
@@ -353,17 +356,27 @@ extern void key_set_timeout(struct key *, unsigned);
353#define KEY_NEED_SETATTR 0x20 /* Require permission to change attributes */ 356#define KEY_NEED_SETATTR 0x20 /* Require permission to change attributes */
354#define KEY_NEED_ALL 0x3f /* All the above permissions */ 357#define KEY_NEED_ALL 0x3f /* All the above permissions */
355 358
359static inline short key_read_state(const struct key *key)
360{
361 /* Barrier versus mark_key_instantiated(). */
362 return smp_load_acquire(&key->state);
363}
364
356/** 365/**
357 * key_is_instantiated - Determine if a key has been positively instantiated 366 * key_is_positive - Determine if a key has been positively instantiated
358 * @key: The key to check. 367 * @key: The key to check.
359 * 368 *
360 * Return true if the specified key has been positively instantiated, false 369 * Return true if the specified key has been positively instantiated, false
361 * otherwise. 370 * otherwise.
362 */ 371 */
363static inline bool key_is_instantiated(const struct key *key) 372static inline bool key_is_positive(const struct key *key)
373{
374 return key_read_state(key) == KEY_IS_POSITIVE;
375}
376
377static inline bool key_is_negative(const struct key *key)
364{ 378{
365 return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && 379 return key_read_state(key) < 0;
366 !test_bit(KEY_FLAG_NEGATIVE, &key->flags);
367} 380}
368 381
369#define dereference_key_rcu(KEY) \ 382#define dereference_key_rcu(KEY) \
diff --git a/lib/digsig.c b/lib/digsig.c
index 03d7c63837ae..6ba6fcd92dd1 100644
--- a/lib/digsig.c
+++ b/lib/digsig.c
@@ -87,6 +87,12 @@ static int digsig_verify_rsa(struct key *key,
87 down_read(&key->sem); 87 down_read(&key->sem);
88 ukp = user_key_payload_locked(key); 88 ukp = user_key_payload_locked(key);
89 89
90 if (!ukp) {
91 /* key was revoked before we acquired its semaphore */
92 err = -EKEYREVOKED;
93 goto err1;
94 }
95
90 if (ukp->datalen < sizeof(*pkh)) 96 if (ukp->datalen < sizeof(*pkh))
91 goto err1; 97 goto err1;
92 98
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index 8737412c7b27..e1d4d898a007 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -224,7 +224,7 @@ static int dns_resolver_match_preparse(struct key_match_data *match_data)
224static void dns_resolver_describe(const struct key *key, struct seq_file *m) 224static void dns_resolver_describe(const struct key *key, struct seq_file *m)
225{ 225{
226 seq_puts(m, key->description); 226 seq_puts(m, key->description);
227 if (key_is_instantiated(key)) { 227 if (key_is_positive(key)) {
228 int err = PTR_ERR(key->payload.data[dns_key_error]); 228 int err = PTR_ERR(key->payload.data[dns_key_error]);
229 229
230 if (err) 230 if (err)
diff --git a/security/keys/Kconfig b/security/keys/Kconfig
index 91eafada3164..6462e6654ccf 100644
--- a/security/keys/Kconfig
+++ b/security/keys/Kconfig
@@ -45,6 +45,7 @@ config BIG_KEYS
45 bool "Large payload keys" 45 bool "Large payload keys"
46 depends on KEYS 46 depends on KEYS
47 depends on TMPFS 47 depends on TMPFS
48 select CRYPTO
48 select CRYPTO_AES 49 select CRYPTO_AES
49 select CRYPTO_GCM 50 select CRYPTO_GCM
50 help 51 help
diff --git a/security/keys/big_key.c b/security/keys/big_key.c
index e607830b6154..929e14978c42 100644
--- a/security/keys/big_key.c
+++ b/security/keys/big_key.c
@@ -247,7 +247,7 @@ void big_key_revoke(struct key *key)
247 247
248 /* clear the quota */ 248 /* clear the quota */
249 key_payload_reserve(key, 0); 249 key_payload_reserve(key, 0);
250 if (key_is_instantiated(key) && 250 if (key_is_positive(key) &&
251 (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD) 251 (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD)
252 vfs_truncate(path, 0); 252 vfs_truncate(path, 0);
253} 253}
@@ -279,7 +279,7 @@ void big_key_describe(const struct key *key, struct seq_file *m)
279 279
280 seq_puts(m, key->description); 280 seq_puts(m, key->description);
281 281
282 if (key_is_instantiated(key)) 282 if (key_is_positive(key))
283 seq_printf(m, ": %zu [%s]", 283 seq_printf(m, ": %zu [%s]",
284 datalen, 284 datalen,
285 datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff"); 285 datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff");
diff --git a/security/keys/encrypted-keys/encrypted.c b/security/keys/encrypted-keys/encrypted.c
index 69855ba0d3b3..d92cbf9687c3 100644
--- a/security/keys/encrypted-keys/encrypted.c
+++ b/security/keys/encrypted-keys/encrypted.c
@@ -309,6 +309,13 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k
309 309
310 down_read(&ukey->sem); 310 down_read(&ukey->sem);
311 upayload = user_key_payload_locked(ukey); 311 upayload = user_key_payload_locked(ukey);
312 if (!upayload) {
313 /* key was revoked before we acquired its semaphore */
314 up_read(&ukey->sem);
315 key_put(ukey);
316 ukey = ERR_PTR(-EKEYREVOKED);
317 goto error;
318 }
312 *master_key = upayload->data; 319 *master_key = upayload->data;
313 *master_keylen = upayload->datalen; 320 *master_keylen = upayload->datalen;
314error: 321error:
@@ -847,7 +854,7 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
847 size_t datalen = prep->datalen; 854 size_t datalen = prep->datalen;
848 int ret = 0; 855 int ret = 0;
849 856
850 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) 857 if (key_is_negative(key))
851 return -ENOKEY; 858 return -ENOKEY;
852 if (datalen <= 0 || datalen > 32767 || !prep->data) 859 if (datalen <= 0 || datalen > 32767 || !prep->data)
853 return -EINVAL; 860 return -EINVAL;
diff --git a/security/keys/gc.c b/security/keys/gc.c
index 87cb260e4890..f01d48cb3de1 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -129,15 +129,15 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
129 while (!list_empty(keys)) { 129 while (!list_empty(keys)) {
130 struct key *key = 130 struct key *key =
131 list_entry(keys->next, struct key, graveyard_link); 131 list_entry(keys->next, struct key, graveyard_link);
132 short state = key->state;
133
132 list_del(&key->graveyard_link); 134 list_del(&key->graveyard_link);
133 135
134 kdebug("- %u", key->serial); 136 kdebug("- %u", key->serial);
135 key_check(key); 137 key_check(key);
136 138
137 /* Throw away the key data if the key is instantiated */ 139 /* Throw away the key data if the key is instantiated */
138 if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags) && 140 if (state == KEY_IS_POSITIVE && key->type->destroy)
139 !test_bit(KEY_FLAG_NEGATIVE, &key->flags) &&
140 key->type->destroy)
141 key->type->destroy(key); 141 key->type->destroy(key);
142 142
143 security_key_free(key); 143 security_key_free(key);
@@ -151,7 +151,7 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
151 } 151 }
152 152
153 atomic_dec(&key->user->nkeys); 153 atomic_dec(&key->user->nkeys);
154 if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 154 if (state != KEY_IS_UNINSTANTIATED)
155 atomic_dec(&key->user->nikeys); 155 atomic_dec(&key->user->nikeys);
156 156
157 key_user_put(key->user); 157 key_user_put(key->user);
diff --git a/security/keys/key.c b/security/keys/key.c
index eb914a838840..83bf4b4afd49 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -402,6 +402,18 @@ int key_payload_reserve(struct key *key, size_t datalen)
402EXPORT_SYMBOL(key_payload_reserve); 402EXPORT_SYMBOL(key_payload_reserve);
403 403
404/* 404/*
405 * Change the key state to being instantiated.
406 */
407static void mark_key_instantiated(struct key *key, int reject_error)
408{
409 /* Commit the payload before setting the state; barrier versus
410 * key_read_state().
411 */
412 smp_store_release(&key->state,
413 (reject_error < 0) ? reject_error : KEY_IS_POSITIVE);
414}
415
416/*
405 * Instantiate a key and link it into the target keyring atomically. Must be 417 * Instantiate a key and link it into the target keyring atomically. Must be
406 * called with the target keyring's semaphore writelocked. The target key's 418 * called with the target keyring's semaphore writelocked. The target key's
407 * semaphore need not be locked as instantiation is serialised by 419 * semaphore need not be locked as instantiation is serialised by
@@ -424,14 +436,14 @@ static int __key_instantiate_and_link(struct key *key,
424 mutex_lock(&key_construction_mutex); 436 mutex_lock(&key_construction_mutex);
425 437
426 /* can't instantiate twice */ 438 /* can't instantiate twice */
427 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 439 if (key->state == KEY_IS_UNINSTANTIATED) {
428 /* instantiate the key */ 440 /* instantiate the key */
429 ret = key->type->instantiate(key, prep); 441 ret = key->type->instantiate(key, prep);
430 442
431 if (ret == 0) { 443 if (ret == 0) {
432 /* mark the key as being instantiated */ 444 /* mark the key as being instantiated */
433 atomic_inc(&key->user->nikeys); 445 atomic_inc(&key->user->nikeys);
434 set_bit(KEY_FLAG_INSTANTIATED, &key->flags); 446 mark_key_instantiated(key, 0);
435 447
436 if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) 448 if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
437 awaken = 1; 449 awaken = 1;
@@ -577,13 +589,10 @@ int key_reject_and_link(struct key *key,
577 mutex_lock(&key_construction_mutex); 589 mutex_lock(&key_construction_mutex);
578 590
579 /* can't instantiate twice */ 591 /* can't instantiate twice */
580 if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 592 if (key->state == KEY_IS_UNINSTANTIATED) {
581 /* mark the key as being negatively instantiated */ 593 /* mark the key as being negatively instantiated */
582 atomic_inc(&key->user->nikeys); 594 atomic_inc(&key->user->nikeys);
583 key->reject_error = -error; 595 mark_key_instantiated(key, -error);
584 smp_wmb();
585 set_bit(KEY_FLAG_NEGATIVE, &key->flags);
586 set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
587 now = current_kernel_time(); 596 now = current_kernel_time();
588 key->expiry = now.tv_sec + timeout; 597 key->expiry = now.tv_sec + timeout;
589 key_schedule_gc(key->expiry + key_gc_delay); 598 key_schedule_gc(key->expiry + key_gc_delay);
@@ -752,8 +761,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref,
752 761
753 ret = key->type->update(key, prep); 762 ret = key->type->update(key, prep);
754 if (ret == 0) 763 if (ret == 0)
755 /* updating a negative key instantiates it */ 764 /* Updating a negative key positively instantiates it */
756 clear_bit(KEY_FLAG_NEGATIVE, &key->flags); 765 mark_key_instantiated(key, 0);
757 766
758 up_write(&key->sem); 767 up_write(&key->sem);
759 768
@@ -936,6 +945,16 @@ error:
936 */ 945 */
937 __key_link_end(keyring, &index_key, edit); 946 __key_link_end(keyring, &index_key, edit);
938 947
948 key = key_ref_to_ptr(key_ref);
949 if (test_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) {
950 ret = wait_for_key_construction(key, true);
951 if (ret < 0) {
952 key_ref_put(key_ref);
953 key_ref = ERR_PTR(ret);
954 goto error_free_prep;
955 }
956 }
957
939 key_ref = __key_update(key_ref, &prep); 958 key_ref = __key_update(key_ref, &prep);
940 goto error_free_prep; 959 goto error_free_prep;
941} 960}
@@ -986,8 +1005,8 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
986 1005
987 ret = key->type->update(key, &prep); 1006 ret = key->type->update(key, &prep);
988 if (ret == 0) 1007 if (ret == 0)
989 /* updating a negative key instantiates it */ 1008 /* Updating a negative key positively instantiates it */
990 clear_bit(KEY_FLAG_NEGATIVE, &key->flags); 1009 mark_key_instantiated(key, 0);
991 1010
992 up_write(&key->sem); 1011 up_write(&key->sem);
993 1012
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 365ff85d7e27..76d22f726ae4 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -766,10 +766,9 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen)
766 766
767 key = key_ref_to_ptr(key_ref); 767 key = key_ref_to_ptr(key_ref);
768 768
769 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { 769 ret = key_read_state(key);
770 ret = -ENOKEY; 770 if (ret < 0)
771 goto error2; 771 goto error2; /* Negatively instantiated */
772 }
773 772
774 /* see if we can read it directly */ 773 /* see if we can read it directly */
775 ret = key_permission(key_ref, KEY_NEED_READ); 774 ret = key_permission(key_ref, KEY_NEED_READ);
@@ -901,7 +900,7 @@ long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
901 atomic_dec(&key->user->nkeys); 900 atomic_dec(&key->user->nkeys);
902 atomic_inc(&newowner->nkeys); 901 atomic_inc(&newowner->nkeys);
903 902
904 if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { 903 if (key->state != KEY_IS_UNINSTANTIATED) {
905 atomic_dec(&key->user->nikeys); 904 atomic_dec(&key->user->nikeys);
906 atomic_inc(&newowner->nikeys); 905 atomic_inc(&newowner->nikeys);
907 } 906 }
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 4fa82a8a9c0e..a7e51f793867 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -414,7 +414,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
414 else 414 else
415 seq_puts(m, "[anon]"); 415 seq_puts(m, "[anon]");
416 416
417 if (key_is_instantiated(keyring)) { 417 if (key_is_positive(keyring)) {
418 if (keyring->keys.nr_leaves_on_tree != 0) 418 if (keyring->keys.nr_leaves_on_tree != 0)
419 seq_printf(m, ": %lu", keyring->keys.nr_leaves_on_tree); 419 seq_printf(m, ": %lu", keyring->keys.nr_leaves_on_tree);
420 else 420 else
@@ -553,7 +553,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
553{ 553{
554 struct keyring_search_context *ctx = iterator_data; 554 struct keyring_search_context *ctx = iterator_data;
555 const struct key *key = keyring_ptr_to_key(object); 555 const struct key *key = keyring_ptr_to_key(object);
556 unsigned long kflags = key->flags; 556 unsigned long kflags = READ_ONCE(key->flags);
557 short state = READ_ONCE(key->state);
557 558
558 kenter("{%d}", key->serial); 559 kenter("{%d}", key->serial);
559 560
@@ -565,6 +566,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
565 566
566 /* skip invalidated, revoked and expired keys */ 567 /* skip invalidated, revoked and expired keys */
567 if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) { 568 if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) {
569 time_t expiry = READ_ONCE(key->expiry);
570
568 if (kflags & ((1 << KEY_FLAG_INVALIDATED) | 571 if (kflags & ((1 << KEY_FLAG_INVALIDATED) |
569 (1 << KEY_FLAG_REVOKED))) { 572 (1 << KEY_FLAG_REVOKED))) {
570 ctx->result = ERR_PTR(-EKEYREVOKED); 573 ctx->result = ERR_PTR(-EKEYREVOKED);
@@ -572,7 +575,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
572 goto skipped; 575 goto skipped;
573 } 576 }
574 577
575 if (key->expiry && ctx->now.tv_sec >= key->expiry) { 578 if (expiry && ctx->now.tv_sec >= expiry) {
576 if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED)) 579 if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED))
577 ctx->result = ERR_PTR(-EKEYEXPIRED); 580 ctx->result = ERR_PTR(-EKEYEXPIRED);
578 kleave(" = %d [expire]", ctx->skipped_ret); 581 kleave(" = %d [expire]", ctx->skipped_ret);
@@ -597,9 +600,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
597 600
598 if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) { 601 if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) {
599 /* we set a different error code if we pass a negative key */ 602 /* we set a different error code if we pass a negative key */
600 if (kflags & (1 << KEY_FLAG_NEGATIVE)) { 603 if (state < 0) {
601 smp_rmb(); 604 ctx->result = ERR_PTR(state);
602 ctx->result = ERR_PTR(key->reject_error);
603 kleave(" = %d [neg]", ctx->skipped_ret); 605 kleave(" = %d [neg]", ctx->skipped_ret);
604 goto skipped; 606 goto skipped;
605 } 607 }
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 732cc0beffdf..a72b4dd70c8a 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -88,7 +88,8 @@ EXPORT_SYMBOL(key_task_permission);
88 */ 88 */
89int key_validate(const struct key *key) 89int key_validate(const struct key *key)
90{ 90{
91 unsigned long flags = key->flags; 91 unsigned long flags = READ_ONCE(key->flags);
92 time_t expiry = READ_ONCE(key->expiry);
92 93
93 if (flags & (1 << KEY_FLAG_INVALIDATED)) 94 if (flags & (1 << KEY_FLAG_INVALIDATED))
94 return -ENOKEY; 95 return -ENOKEY;
@@ -99,9 +100,9 @@ int key_validate(const struct key *key)
99 return -EKEYREVOKED; 100 return -EKEYREVOKED;
100 101
101 /* check it hasn't expired */ 102 /* check it hasn't expired */
102 if (key->expiry) { 103 if (expiry) {
103 struct timespec now = current_kernel_time(); 104 struct timespec now = current_kernel_time();
104 if (now.tv_sec >= key->expiry) 105 if (now.tv_sec >= expiry)
105 return -EKEYEXPIRED; 106 return -EKEYEXPIRED;
106 } 107 }
107 108
diff --git a/security/keys/proc.c b/security/keys/proc.c
index de834309d100..6d1fcbba1e09 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -179,9 +179,12 @@ static int proc_keys_show(struct seq_file *m, void *v)
179 struct rb_node *_p = v; 179 struct rb_node *_p = v;
180 struct key *key = rb_entry(_p, struct key, serial_node); 180 struct key *key = rb_entry(_p, struct key, serial_node);
181 struct timespec now; 181 struct timespec now;
182 time_t expiry;
182 unsigned long timo; 183 unsigned long timo;
184 unsigned long flags;
183 key_ref_t key_ref, skey_ref; 185 key_ref_t key_ref, skey_ref;
184 char xbuf[16]; 186 char xbuf[16];
187 short state;
185 int rc; 188 int rc;
186 189
187 struct keyring_search_context ctx = { 190 struct keyring_search_context ctx = {
@@ -217,12 +220,13 @@ static int proc_keys_show(struct seq_file *m, void *v)
217 rcu_read_lock(); 220 rcu_read_lock();
218 221
219 /* come up with a suitable timeout value */ 222 /* come up with a suitable timeout value */
220 if (key->expiry == 0) { 223 expiry = READ_ONCE(key->expiry);
224 if (expiry == 0) {
221 memcpy(xbuf, "perm", 5); 225 memcpy(xbuf, "perm", 5);
222 } else if (now.tv_sec >= key->expiry) { 226 } else if (now.tv_sec >= expiry) {
223 memcpy(xbuf, "expd", 5); 227 memcpy(xbuf, "expd", 5);
224 } else { 228 } else {
225 timo = key->expiry - now.tv_sec; 229 timo = expiry - now.tv_sec;
226 230
227 if (timo < 60) 231 if (timo < 60)
228 sprintf(xbuf, "%lus", timo); 232 sprintf(xbuf, "%lus", timo);
@@ -236,18 +240,21 @@ static int proc_keys_show(struct seq_file *m, void *v)
236 sprintf(xbuf, "%luw", timo / (60*60*24*7)); 240 sprintf(xbuf, "%luw", timo / (60*60*24*7));
237 } 241 }
238 242
239#define showflag(KEY, LETTER, FLAG) \ 243 state = key_read_state(key);
240 (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-')
241 244
245#define showflag(FLAGS, LETTER, FLAG) \
246 ((FLAGS & (1 << FLAG)) ? LETTER : '-')
247
248 flags = READ_ONCE(key->flags);
242 seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ", 249 seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ",
243 key->serial, 250 key->serial,
244 showflag(key, 'I', KEY_FLAG_INSTANTIATED), 251 state != KEY_IS_UNINSTANTIATED ? 'I' : '-',
245 showflag(key, 'R', KEY_FLAG_REVOKED), 252 showflag(flags, 'R', KEY_FLAG_REVOKED),
246 showflag(key, 'D', KEY_FLAG_DEAD), 253 showflag(flags, 'D', KEY_FLAG_DEAD),
247 showflag(key, 'Q', KEY_FLAG_IN_QUOTA), 254 showflag(flags, 'Q', KEY_FLAG_IN_QUOTA),
248 showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT), 255 showflag(flags, 'U', KEY_FLAG_USER_CONSTRUCT),
249 showflag(key, 'N', KEY_FLAG_NEGATIVE), 256 state < 0 ? 'N' : '-',
250 showflag(key, 'i', KEY_FLAG_INVALIDATED), 257 showflag(flags, 'i', KEY_FLAG_INVALIDATED),
251 refcount_read(&key->usage), 258 refcount_read(&key->usage),
252 xbuf, 259 xbuf,
253 key->perm, 260 key->perm,
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 293d3598153b..740affd65ee9 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -730,7 +730,7 @@ try_again:
730 730
731 ret = -EIO; 731 ret = -EIO;
732 if (!(lflags & KEY_LOOKUP_PARTIAL) && 732 if (!(lflags & KEY_LOOKUP_PARTIAL) &&
733 !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 733 key_read_state(key) == KEY_IS_UNINSTANTIATED)
734 goto invalid_key; 734 goto invalid_key;
735 735
736 /* check the permissions */ 736 /* check the permissions */
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 63e63a42db3c..e8036cd0ad54 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -595,10 +595,9 @@ int wait_for_key_construction(struct key *key, bool intr)
595 intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); 595 intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
596 if (ret) 596 if (ret)
597 return -ERESTARTSYS; 597 return -ERESTARTSYS;
598 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { 598 ret = key_read_state(key);
599 smp_rmb(); 599 if (ret < 0)
600 return key->reject_error; 600 return ret;
601 }
602 return key_validate(key); 601 return key_validate(key);
603} 602}
604EXPORT_SYMBOL(wait_for_key_construction); 603EXPORT_SYMBOL(wait_for_key_construction);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 6ebf1af8fce9..424e1d90412e 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -73,7 +73,7 @@ static void request_key_auth_describe(const struct key *key,
73 73
74 seq_puts(m, "key:"); 74 seq_puts(m, "key:");
75 seq_puts(m, key->description); 75 seq_puts(m, key->description);
76 if (key_is_instantiated(key)) 76 if (key_is_positive(key))
77 seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); 77 seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
78} 78}
79 79
diff --git a/security/keys/trusted.c b/security/keys/trusted.c
index ddfaebf60fc8..bd85315cbfeb 100644
--- a/security/keys/trusted.c
+++ b/security/keys/trusted.c
@@ -1066,7 +1066,7 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep)
1066 char *datablob; 1066 char *datablob;
1067 int ret = 0; 1067 int ret = 0;
1068 1068
1069 if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) 1069 if (key_is_negative(key))
1070 return -ENOKEY; 1070 return -ENOKEY;
1071 p = key->payload.data[0]; 1071 p = key->payload.data[0];
1072 if (!p->migratable) 1072 if (!p->migratable)
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index 3d8c68eba516..9f558bedba23 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -114,7 +114,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep)
114 114
115 /* attach the new data, displacing the old */ 115 /* attach the new data, displacing the old */
116 key->expiry = prep->expiry; 116 key->expiry = prep->expiry;
117 if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags)) 117 if (key_is_positive(key))
118 zap = dereference_key_locked(key); 118 zap = dereference_key_locked(key);
119 rcu_assign_keypointer(key, prep->payload.data[0]); 119 rcu_assign_keypointer(key, prep->payload.data[0]);
120 prep->payload.data[0] = NULL; 120 prep->payload.data[0] = NULL;
@@ -162,7 +162,7 @@ EXPORT_SYMBOL_GPL(user_destroy);
162void user_describe(const struct key *key, struct seq_file *m) 162void user_describe(const struct key *key, struct seq_file *m)
163{ 163{
164 seq_puts(m, key->description); 164 seq_puts(m, key->description);
165 if (key_is_instantiated(key)) 165 if (key_is_positive(key))
166 seq_printf(m, ": %u", key->datalen); 166 seq_printf(m, ": %u", key->datalen);
167} 167}
168 168