History

Merge branch 'fixes-v4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull key handling fixes from James Morris: "This includes a fix for the capabilities code from Colin King, and a set of further fixes for the keys subsystem. From David: - Fix a bunch of places where kernel drivers may access revoked user-type keys and don't do it correctly. - Fix some ecryptfs bits. - Fix big_key to require CONFIG_CRYPTO. - Fix a couple of bugs in the asymmetric key type. - Fix a race between updating and finding negative keys. - Prevent add_key() from updating uninstantiated keys. - Make loading of key flags and expiry time atomic when not holding locks" * 'fixes-v4.14-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security: commoncap: move assignment of fs_ns to avoid null pointer dereference pkcs7: Prevent NULL pointer dereference, since sinfo is not always set. KEYS: load key flags and expiry time atomically in proc_keys_show() KEYS: Load key expiry time atomically in keyring_search_iterator() KEYS: load key flags and expiry time atomically in key_validate() KEYS: don't let add_key() update an uninstantiated key KEYS: Fix race between updating and finding a negative key KEYS: checking the input id parameters before finding asymmetric key KEYS: Fix the wrong index when checking the existence of second id security/keys: BIG_KEY requires CONFIG_CRYPTO ecryptfs: fix dereference of NULL user_key_payload fscrypt: fix dereference of NULL user_key_payload lib/digsig: fix dereference of NULL user_key_payload FS-Cache: fix dereference of NULL user_key_payload KEYS: encrypted: fix dereference of NULL user_key_payload

Linus Torvalds committed 9 years ago

Commit 03b652e2 parents ce43f4f 76ba89c24 files · +170 −81Browse files

Unified · Split

24 files
  1. crypto/asymmetric_keys/asymmetric_type.c +3 −1
  2. crypto/asymmetric_keys/pkcs7_parser.c +3 −0
  3. fs/crypto/keyinfo.c +5 −0
  4. fs/ecryptfs/ecryptfs_kernel.h +17 −7
  5. fs/ecryptfs/keystore.c +8 −1
  6. fs/fscache/object-list.c +7 −0
  7. include/linux/key.h +30 −17
  8. lib/digsig.c +6 −0
  9. net/dns_resolver/dns_key.c +1 −1
  10. security/commoncap.c +2 −1
  11. security/keys/Kconfig +1 −0
  12. security/keys/big_key.c +2 −2
  13. security/keys/encrypted-keys/encrypted.c +8 −1
  14. security/keys/gc.c +4 −4
  15. security/keys/key.c +30 −11
  16. security/keys/keyctl.c +4 −5
  17. security/keys/keyring.c +8 −6
  18. security/keys/permission.c +4 −3
  19. security/keys/proc.c +19 −12
  20. security/keys/process_keys.c +1 −1
  21. security/keys/request_key.c +3 −4
  22. security/keys/request_key_auth.c +1 −1
  23. security/keys/trusted.c +1 −1
  24. security/keys/user_defined.c +2 −2
crypto/asymmetric_keys/asymmetric_type.c+3−1
@@ -57,6 +57,8 @@ struct key *find_asymmetric_key(struct key *keyring, · 56 unmodified lines
5757 char *req, *p;
5858 int len;
5959
60+ BUG_ON(!id_0 && !id_1);
61+
6062 if (id_0) {
6163 lookup = id_0->data;
6264 len = id_0->len;
@@ -105,7 +107,7 @@ struct key *find_asymmetric_key(struct key *keyring, · 42 unmodified lines
105107 if (id_0 && id_1) {
106108 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
107109
108− if (!kids->id[0]) {
110+ if (!kids->id[1]) {
109111 pr_debug("First ID matches, but second is missing\n");
110112 goto reject;
111113 }
crypto/asymmetric_keys/pkcs7_parser.c+3−0
@@ -88,6 +88,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg) · 87 unmodified lines
8888 bool want = false;
8989
9090 sinfo = msg->signed_infos;
91+ if (!sinfo)
92+ goto inconsistent;
93+
9194 if (sinfo->authattrs) {
9295 want = true;
9396 msg->have_authattrs = true;
fs/crypto/keyinfo.c+5−0
@@ -109,6 +109,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info, · 108 unmodified lines
109109 goto out;
110110 }
111111 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+ }
112117 if (ukp->datalen != sizeof(struct fscrypt_key)) {
113118 res = -EINVAL;
114119 goto out;
fs/ecryptfs/ecryptfs_kernel.h+17−7
@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context { · 83 unmodified lines
8484 static inline struct ecryptfs_auth_tok *
8585 ecryptfs_get_encrypted_key_payload_data(struct key *key)
8686 {
87− if (key->type == &key_type_encrypted)
88− return (struct ecryptfs_auth_tok *)
89− (&((struct encrypted_key_payload *)key->payload.data[0])->payload_data);
90− else
87+ struct encrypted_key_payload *payload;
88+
89+ if (key->type != &key_type_encrypted)
9190 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;
9297 }
9398
9499 static inline struct key *ecryptfs_get_encrypted_key(char *sig)
@@ -114,12 +119,17 @@ static inline struct ecryptfs_auth_tok * · 19 unmodified lines
114119 ecryptfs_get_key_payload_data(struct key *key)
115120 {
116121 struct ecryptfs_auth_tok *auth_tok;
122+ struct user_key_payload *ukp;
117123
118124 auth_tok = ecryptfs_get_encrypted_key_payload_data(key);
119− if (!auth_tok)
120− return (struct ecryptfs_auth_tok *)user_key_payload_locked(key)->data;
121− else
125+ if (auth_tok)
122126 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;
123133 }
124134
125135 #define ECRYPTFS_MAX_KEYSET_SIZE 1024
fs/ecryptfs/keystore.c+8−1
@@ -459,7 +459,8 @@ out: · 458 unmodified lines
459459 * @auth_tok_key: key containing the authentication token
460460 * @auth_tok: authentication token
461461 *
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.
463464 */
464465 static int
465466 ecryptfs_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, · 2 unmodified lines
468469 int rc = 0;
469470
470471 (*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+
471478 if (ecryptfs_verify_version((*auth_tok)->version)) {
472479 printk(KERN_ERR "Data structure version mismatch. Userspace "
473480 "tools must match eCryptfs kernel module with major "
fs/fscache/object-list.c+7−0
@@ -331,6 +331,13 @@ static void fscache_objlist_config(struct fscache_objlist_data *data) · 330 unmodified lines
331331 rcu_read_lock();
332332
333333 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+
334341 buf = confkey->data;
335342
336343 for (len = confkey->datalen - 1; len >= 0; len--) {
include/linux/key.h+30−17
@@ -138,6 +138,11 @@ struct key_restriction { · 137 unmodified lines
138138 struct key_type *keytype;
139139 };
140140
141+enum key_state {
142+ KEY_IS_UNINSTANTIATED,
143+ KEY_IS_POSITIVE, /* Positively instantiated */
144+};
145+
141146 /*****************************************************************************/
142147 /*
143148 * authentication token / access credential / keyring
@@ -169,6 +174,7 @@ struct key { · 25 unmodified lines
169174 * - may not match RCU dereferenced payload
170175 * - payload should contain own length
171176 */
177+ short state; /* Key state (+) or rejection error (-) */
172178
173179 #ifdef KEY_DEBUGGING
174180 unsigned magic;
@@ -176,18 +182,16 @@ struct key { · 1 unmodified line
176182 #endif
177183
178184 unsigned long flags; /* status flags (change with bitops) */
179−#define KEY_FLAG_INSTANTIATED 0 /* set if key has been instantiated */
180−#define KEY_FLAG_DEAD 1 /* set if key type has been deleted */
181−#define KEY_FLAG_REVOKED 2 /* set if key had been revoked */
182−#define KEY_FLAG_IN_QUOTA 3 /* set if key consumes quota */
183−#define KEY_FLAG_USER_CONSTRUCT 4 /* set if key is being constructed in userspace */
184−#define KEY_FLAG_NEGATIVE 5 /* set if key is negative */
185−#define KEY_FLAG_ROOT_CAN_CLEAR 6 /* set if key can be cleared by root without permission */
186−#define KEY_FLAG_INVALIDATED 7 /* set if key has been invalidated */
187−#define KEY_FLAG_BUILTIN 8 /* set if key is built in to the kernel */
188−#define KEY_FLAG_ROOT_CAN_INVAL 9 /* set if key can be invalidated by root without permission */
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 */
185+#define KEY_FLAG_DEAD 0 /* set if key type has been deleted */
186+#define KEY_FLAG_REVOKED 1 /* set if key had been revoked */
187+#define KEY_FLAG_IN_QUOTA 2 /* set if key consumes quota */
188+#define KEY_FLAG_USER_CONSTRUCT 3 /* 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 */
190+#define KEY_FLAG_INVALIDATED 5 /* set if key has been invalidated */
191+#define KEY_FLAG_BUILTIN 6 /* set if key is built in to the kernel */
192+#define KEY_FLAG_ROOT_CAN_INVAL 7 /* set if key can be invalidated by root without permission */
193+#define KEY_FLAG_KEEP 8 /* set if key should not be removed */
194+#define KEY_FLAG_UID_KEYRING 9 /* set if key is a user or user session keyring */
191195
192196 /* the key type and key description string
193197 * - the desc is used to match a key against search criteria
@@ -213,7 +217,6 @@ struct key { · 19 unmodified lines
213217 struct list_head name_link;
214218 struct assoc_array keys;
215219 };
216− int reject_error;
217220 };
218221
219222 /* 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); · 133 unmodified lines
353356 #define KEY_NEED_SETATTR 0x20 /* Require permission to change attributes */
354357 #define KEY_NEED_ALL 0x3f /* All the above permissions */
355358
359+static 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+
356365 /**
357− * key_is_instantiated - Determine if a key has been positively instantiated
366+ * key_is_positive - Determine if a key has been positively instantiated
358367 * @key: The key to check.
359368 *
360369 * Return true if the specified key has been positively instantiated, false
361370 * otherwise.
362371 */
363−static inline bool key_is_instantiated(const struct key *key)
372+static inline bool key_is_positive(const struct key *key)
373+{
374+ return key_read_state(key) == KEY_IS_POSITIVE;
375+}
376+
377+static inline bool key_is_negative(const struct key *key)
364378 {
365− return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) &&
366− !test_bit(KEY_FLAG_NEGATIVE, &key->flags);
379+ return key_read_state(key) < 0;
367380 }
368381
369382 #define dereference_key_rcu(KEY) \
lib/digsig.c+6−0
@@ -87,6 +87,12 @@ static int digsig_verify_rsa(struct key *key, · 86 unmodified lines
8787 down_read(&key->sem);
8888 ukp = user_key_payload_locked(key);
8989
90+ if (!ukp) {
91+ /* key was revoked before we acquired its semaphore */
92+ err = -EKEYREVOKED;
93+ goto err1;
94+ }
95+
9096 if (ukp->datalen < sizeof(*pkh))
9197 goto err1;
9298
net/dns_resolver/dns_key.c+1−1
@@ -224,7 +224,7 @@ static int dns_resolver_match_preparse(struct key_match_data *match_data) · 223 unmodified lines
224224 static void dns_resolver_describe(const struct key *key, struct seq_file *m)
225225 {
226226 seq_puts(m, key->description);
227− if (key_is_instantiated(key)) {
227+ if (key_is_positive(key)) {
228228 int err = PTR_ERR(key->payload.data[dns_key_error]);
229229
230230 if (err)
security/commoncap.c+2−1
@@ -585,13 +585,14 @@ int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data · 584 unmodified lines
585585 struct vfs_ns_cap_data data, *nscaps = &data;
586586 struct vfs_cap_data *caps = (struct vfs_cap_data *) &data;
587587 kuid_t rootkuid;
588− struct user_namespace *fs_ns = inode->i_sb->s_user_ns;
588+ struct user_namespace *fs_ns;
589589
590590 memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data));
591591
592592 if (!inode)
593593 return -ENODATA;
594594
595+ fs_ns = inode->i_sb->s_user_ns;
595596 size = __vfs_getxattr((struct dentry *)dentry, inode,
596597 XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ);
597598 if (size == -ENODATA || size == -EOPNOTSUPP)
security/keys/Kconfig+1−0
@@ -45,6 +45,7 @@ config BIG_KEYS · 44 unmodified lines
4545 bool "Large payload keys"
4646 depends on KEYS
4747 depends on TMPFS
48+ select CRYPTO
4849 select CRYPTO_AES
4950 select CRYPTO_GCM
5051 help
security/keys/big_key.c+2−2
@@ -247,7 +247,7 @@ void big_key_revoke(struct key *key) · 246 unmodified lines
247247
248248 /* clear the quota */
249249 key_payload_reserve(key, 0);
250− if (key_is_instantiated(key) &&
250+ if (key_is_positive(key) &&
251251 (size_t)key->payload.data[big_key_len] > BIG_KEY_FILE_THRESHOLD)
252252 vfs_truncate(path, 0);
253253 }
@@ -279,7 +279,7 @@ void big_key_describe(const struct key *key, struct seq_file *m) · 25 unmodified lines
279279
280280 seq_puts(m, key->description);
281281
282− if (key_is_instantiated(key))
282+ if (key_is_positive(key))
283283 seq_printf(m, ": %zu [%s]",
284284 datalen,
285285 datalen > BIG_KEY_FILE_THRESHOLD ? "file" : "buff");
security/keys/encrypted-keys/encrypted.c+8−1
@@ -309,6 +309,13 @@ static struct key *request_user_key(const char *master_desc, const u8 **master_k · 308 unmodified lines
309309
310310 down_read(&ukey->sem);
311311 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+ }
312319 *master_key = upayload->data;
313320 *master_keylen = upayload->datalen;
314321 error:
@@ -847,7 +854,7 @@ static int encrypted_update(struct key *key, struct key_preparsed_payload *prep) · 532 unmodified lines
847854 size_t datalen = prep->datalen;
848855 int ret = 0;
849856
850− if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
857+ if (key_is_negative(key))
851858 return -ENOKEY;
852859 if (datalen <= 0 || datalen > 32767 || !prep->data)
853860 return -EINVAL;
security/keys/gc.c+4−4
@@ -129,15 +129,15 @@ static noinline void key_gc_unused_keys(struct list_head *keys) · 128 unmodified lines
129129 while (!list_empty(keys)) {
130130 struct key *key =
131131 list_entry(keys->next, struct key, graveyard_link);
132+ short state = key->state;
133+
132134 list_del(&key->graveyard_link);
133135
134136 kdebug("- %u", key->serial);
135137 key_check(key);
136138
137139 /* Throw away the key data if the key is instantiated */
138− if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags) &&
139− !test_bit(KEY_FLAG_NEGATIVE, &key->flags) &&
140− key->type->destroy)
140+ if (state == KEY_IS_POSITIVE && key->type->destroy)
141141 key->type->destroy(key);
142142
143143 security_key_free(key);
@@ -151,7 +151,7 @@ static noinline void key_gc_unused_keys(struct list_head *keys) · 7 unmodified lines
151151 }
152152
153153 atomic_dec(&key->user->nkeys);
154− if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
154+ if (state != KEY_IS_UNINSTANTIATED)
155155 atomic_dec(&key->user->nikeys);
156156
157157 key_user_put(key->user);
security/keys/key.c+30−11
@@ -401,6 +401,18 @@ int key_payload_reserve(struct key *key, size_t datalen) · 400 unmodified lines
401401 }
402402 EXPORT_SYMBOL(key_payload_reserve);
403403
404+/*
405+ * Change the key state to being instantiated.
406+ */
407+static 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+
404416 /*
405417 * Instantiate a key and link it into the target keyring atomically. Must be
406418 * called with the target keyring's semaphore writelocked. The target key's
@@ -424,14 +436,14 @@ static int __key_instantiate_and_link(struct key *key, · 17 unmodified lines
424436 mutex_lock(&key_construction_mutex);
425437
426438 /* can't instantiate twice */
427− if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
439+ if (key->state == KEY_IS_UNINSTANTIATED) {
428440 /* instantiate the key */
429441 ret = key->type->instantiate(key, prep);
430442
431443 if (ret == 0) {
432444 /* mark the key as being instantiated */
433445 atomic_inc(&key->user->nikeys);
434− set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
446+ mark_key_instantiated(key, 0);
435447
436448 if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
437449 awaken = 1;
@@ -577,13 +589,10 @@ int key_reject_and_link(struct key *key, · 139 unmodified lines
577589 mutex_lock(&key_construction_mutex);
578590
579591 /* can't instantiate twice */
580− if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
592+ if (key->state == KEY_IS_UNINSTANTIATED) {
581593 /* mark the key as being negatively instantiated */
582594 atomic_inc(&key->user->nikeys);
583− key->reject_error = -error;
584− smp_wmb();
585− set_bit(KEY_FLAG_NEGATIVE, &key->flags);
586− set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
595+ mark_key_instantiated(key, -error);
587596 now = current_kernel_time();
588597 key->expiry = now.tv_sec + timeout;
589598 key_schedule_gc(key->expiry + key_gc_delay);
@@ -752,8 +761,8 @@ static inline key_ref_t __key_update(key_ref_t key_ref, · 162 unmodified lines
752761
753762 ret = key->type->update(key, prep);
754763 if (ret == 0)
755− /* updating a negative key instantiates it */
756− clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
764+ /* Updating a negative key positively instantiates it */
765+ mark_key_instantiated(key, 0);
757766
758767 up_write(&key->sem);
759768
@@ -936,6 +945,16 @@ error: · 176 unmodified lines
936945 */
937946 __key_link_end(keyring, &index_key, edit);
938947
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+
939958 key_ref = __key_update(key_ref, &prep);
940959 goto error_free_prep;
941960 }
@@ -986,8 +1005,8 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen) · 44 unmodified lines
9861005
9871006 ret = key->type->update(key, &prep);
9881007 if (ret == 0)
989− /* updating a negative key instantiates it */
990− clear_bit(KEY_FLAG_NEGATIVE, &key->flags);
1008+ /* Updating a negative key positively instantiates it */
1009+ mark_key_instantiated(key, 0);
9911010
9921011 up_write(&key->sem);
9931012
security/keys/keyctl.c+4−5
@@ -766,10 +766,9 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) · 765 unmodified lines
766766
767767 key = key_ref_to_ptr(key_ref);
768768
769− if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
770− ret = -ENOKEY;
771− goto error2;
772− }
769+ ret = key_read_state(key);
770+ if (ret < 0)
771+ goto error2; /* Negatively instantiated */
773772
774773 /* see if we can read it directly */
775774 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) · 125 unmodified lines
901900 atomic_dec(&key->user->nkeys);
902901 atomic_inc(&newowner->nkeys);
903902
904− if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) {
903+ if (key->state != KEY_IS_UNINSTANTIATED) {
905904 atomic_dec(&key->user->nikeys);
906905 atomic_inc(&newowner->nikeys);
907906 }
security/keys/keyring.c+8−6
@@ -414,7 +414,7 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) · 413 unmodified lines
414414 else
415415 seq_puts(m, "[anon]");
416416
417− if (key_is_instantiated(keyring)) {
417+ if (key_is_positive(keyring)) {
418418 if (keyring->keys.nr_leaves_on_tree != 0)
419419 seq_printf(m, ": %lu", keyring->keys.nr_leaves_on_tree);
420420 else
@@ -553,7 +553,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) · 132 unmodified lines
553553 {
554554 struct keyring_search_context *ctx = iterator_data;
555555 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);
557558
558559 kenter("{%d}", key->serial);
559560
@@ -565,6 +566,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) · 5 unmodified lines
565566
566567 /* skip invalidated, revoked and expired keys */
567568 if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) {
569+ time_t expiry = READ_ONCE(key->expiry);
570+
568571 if (kflags & ((1 << KEY_FLAG_INVALIDATED) |
569572 (1 << KEY_FLAG_REVOKED))) {
570573 ctx->result = ERR_PTR(-EKEYREVOKED);
@@ -572,7 +575,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data) · 1 unmodified line
572575 goto skipped;
573576 }
574577
575− if (key->expiry && ctx->now.tv_sec >= key->expiry) {
578+ if (expiry && ctx->now.tv_sec >= expiry) {
576579 if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED))
577580 ctx->result = ERR_PTR(-EKEYEXPIRED);
578581 kleave(" = %d [expire]", ctx->skipped_ret);
@@ -597,9 +600,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) · 18 unmodified lines
597600
598601 if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) {
599602 /* we set a different error code if we pass a negative key */
600− if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
601− smp_rmb();
602− ctx->result = ERR_PTR(key->reject_error);
603+ if (state < 0) {
604+ ctx->result = ERR_PTR(state);
603605 kleave(" = %d [neg]", ctx->skipped_ret);
604606 goto skipped;
605607 }
security/keys/permission.c+4−3
@@ -88,7 +88,8 @@ EXPORT_SYMBOL(key_task_permission); · 87 unmodified lines
8888 */
8989 int key_validate(const struct key *key)
9090 {
91− unsigned long flags = key->flags;
91+ unsigned long flags = READ_ONCE(key->flags);
92+ time_t expiry = READ_ONCE(key->expiry);
9293
9394 if (flags & (1 << KEY_FLAG_INVALIDATED))
9495 return -ENOKEY;
@@ -99,9 +100,9 @@ int key_validate(const struct key *key) · 4 unmodified lines
99100 return -EKEYREVOKED;
100101
101102 /* check it hasn't expired */
102− if (key->expiry) {
103+ if (expiry) {
103104 struct timespec now = current_kernel_time();
104− if (now.tv_sec >= key->expiry)
105+ if (now.tv_sec >= expiry)
105106 return -EKEYEXPIRED;
106107 }
107108
security/keys/proc.c+19−12
@@ -179,9 +179,12 @@ static int proc_keys_show(struct seq_file *m, void *v) · 178 unmodified lines
179179 struct rb_node *_p = v;
180180 struct key *key = rb_entry(_p, struct key, serial_node);
181181 struct timespec now;
182+ time_t expiry;
182183 unsigned long timo;
184+ unsigned long flags;
183185 key_ref_t key_ref, skey_ref;
184186 char xbuf[16];
187+ short state;
185188 int rc;
186189
187190 struct keyring_search_context ctx = {
@@ -217,12 +220,13 @@ static int proc_keys_show(struct seq_file *m, void *v) · 29 unmodified lines
217220 rcu_read_lock();
218221
219222 /* come up with a suitable timeout value */
220− if (key->expiry == 0) {
223+ expiry = READ_ONCE(key->expiry);
224+ if (expiry == 0) {
221225 memcpy(xbuf, "perm", 5);
222− } else if (now.tv_sec >= key->expiry) {
226+ } else if (now.tv_sec >= expiry) {
223227 memcpy(xbuf, "expd", 5);
224228 } else {
225− timo = key->expiry - now.tv_sec;
229+ timo = expiry - now.tv_sec;
226230
227231 if (timo < 60)
228232 sprintf(xbuf, "%lus", timo);
@@ -236,18 +240,21 @@ static int proc_keys_show(struct seq_file *m, void *v) · 7 unmodified lines
236240 sprintf(xbuf, "%luw", timo / (60*60*24*7));
237241 }
238242
239−#define showflag(KEY, LETTER, FLAG) \
240− (test_bit(FLAG, &(KEY)->flags) ? LETTER : '-')
243+ state = key_read_state(key);
241244
245+#define showflag(FLAGS, LETTER, FLAG) \
246+ ((FLAGS & (1 << FLAG)) ? LETTER : '-')
247+
248+ flags = READ_ONCE(key->flags);
242249 seq_printf(m, "%08x %c%c%c%c%c%c%c %5d %4s %08x %5d %5d %-9.9s ",
243250 key->serial,
244− showflag(key, 'I', KEY_FLAG_INSTANTIATED),
245− showflag(key, 'R', KEY_FLAG_REVOKED),
246− showflag(key, 'D', KEY_FLAG_DEAD),
247− showflag(key, 'Q', KEY_FLAG_IN_QUOTA),
248− showflag(key, 'U', KEY_FLAG_USER_CONSTRUCT),
249− showflag(key, 'N', KEY_FLAG_NEGATIVE),
250− showflag(key, 'i', KEY_FLAG_INVALIDATED),
251+ state != KEY_IS_UNINSTANTIATED ? 'I' : '-',
252+ showflag(flags, 'R', KEY_FLAG_REVOKED),
253+ showflag(flags, 'D', KEY_FLAG_DEAD),
254+ showflag(flags, 'Q', KEY_FLAG_IN_QUOTA),
255+ showflag(flags, 'U', KEY_FLAG_USER_CONSTRUCT),
256+ state < 0 ? 'N' : '-',
257+ showflag(flags, 'i', KEY_FLAG_INVALIDATED),
251258 refcount_read(&key->usage),
252259 xbuf,
253260 key->perm,
security/keys/process_keys.c+1−1
@@ -730,7 +730,7 @@ try_again: · 729 unmodified lines
730730
731731 ret = -EIO;
732732 if (!(lflags & KEY_LOOKUP_PARTIAL) &&
733− !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
733+ key_read_state(key) == KEY_IS_UNINSTANTIATED)
734734 goto invalid_key;
735735
736736 /* check the permissions */
security/keys/request_key.c+3−4
@@ -595,10 +595,9 @@ int wait_for_key_construction(struct key *key, bool intr) · 594 unmodified lines
595595 intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
596596 if (ret)
597597 return -ERESTARTSYS;
598− if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) {
599− smp_rmb();
600− return key->reject_error;
601− }
598+ ret = key_read_state(key);
599+ if (ret < 0)
600+ return ret;
602601 return key_validate(key);
603602 }
604603 EXPORT_SYMBOL(wait_for_key_construction);
security/keys/request_key_auth.c+1−1
@@ -73,7 +73,7 @@ static void request_key_auth_describe(const struct key *key, · 72 unmodified lines
7373
7474 seq_puts(m, "key:");
7575 seq_puts(m, key->description);
76− if (key_is_instantiated(key))
76+ if (key_is_positive(key))
7777 seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
7878 }
7979
security/keys/trusted.c+1−1
@@ -1066,7 +1066,7 @@ static int trusted_update(struct key *key, struct key_preparsed_payload *prep) · 1065 unmodified lines
10661066 char *datablob;
10671067 int ret = 0;
10681068
1069− if (test_bit(KEY_FLAG_NEGATIVE, &key->flags))
1069+ if (key_is_negative(key))
10701070 return -ENOKEY;
10711071 p = key->payload.data[0];
10721072 if (!p->migratable)
security/keys/user_defined.c+2−2
@@ -114,7 +114,7 @@ int user_update(struct key *key, struct key_preparsed_payload *prep) · 113 unmodified lines
114114
115115 /* attach the new data, displacing the old */
116116 key->expiry = prep->expiry;
117− if (!test_bit(KEY_FLAG_NEGATIVE, &key->flags))
117+ if (key_is_positive(key))
118118 zap = dereference_key_locked(key);
119119 rcu_assign_keypointer(key, prep->payload.data[0]);
120120 prep->payload.data[0] = NULL;
@@ -162,7 +162,7 @@ EXPORT_SYMBOL_GPL(user_destroy); · 41 unmodified lines
162162 void user_describe(const struct key *key, struct seq_file *m)
163163 {
164164 seq_puts(m, key->description);
165− if (key_is_instantiated(key))
165+ if (key_is_positive(key))
166166 seq_printf(m, ": %u", key->datalen);
167167 }
168168