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
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, · 42 unmodified lines
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 }
crypto/asymmetric_keys/pkcs7_parser.c+3−0
@@ -88,6 +88,9 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg) · 87 unmodified lines
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;
fs/crypto/keyinfo.c+5−0
@@ -109,6 +109,11 @@ static int validate_user_key(struct fscrypt_info *crypt_info, · 108 unmodified lines
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;
fs/ecryptfs/ecryptfs_kernel.h+17−7
@@ -84,11 +84,16 @@ struct ecryptfs_page_crypt_context { · 83 unmodified lines
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 * · 19 unmodified lines
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 1024135#define ECRYPTFS_MAX_KEYSET_SIZE 1024
fs/ecryptfs/keystore.c+8−1
@@ -459,7 +459,8 @@ out: · 458 unmodified lines
459 * @auth_tok_key: key containing the authentication token459 * @auth_tok_key: key containing the authentication token
460 * @auth_tok: authentication token460 * @auth_tok: authentication token
461 *461 *
462 * Returns zero on valid auth tok; -EINVAL otherwise462 * 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 int465static 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, · 2 unmodified lines
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 "
fs/fscache/object-list.c+7−0
@@ -331,6 +331,13 @@ static void fscache_objlist_config(struct fscache_objlist_data *data) · 330 unmodified lines
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--) {
include/linux/key.h+30−17
@@ -138,6 +138,11 @@ struct key_restriction { · 137 unmodified lines
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 / keyring148 * authentication token / access credential / keyring
@@ -169,6 +174,7 @@ struct key { · 25 unmodified lines
169 * - may not match RCU dereferenced payload174 * - may not match RCU dereferenced payload
170 * - payload should contain own length175 * - payload should contain own length
171 */176 */
177 short state; /* Key state (+) or rejection error (-) */
172 178
173#ifdef KEY_DEBUGGING179#ifdef KEY_DEBUGGING
174 unsigned magic;180 unsigned magic;
@@ -176,18 +182,16 @@ struct key { · 1 unmodified line
176#endif182#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 string196 /* the key type and key description string
193 * - the desc is used to match a key against search criteria197 * - the desc is used to match a key against search criteria
@@ -213,7 +217,6 @@ struct key { · 19 unmodified lines
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 key222 /* 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
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 instantiated366 * 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, false369 * 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) \
lib/digsig.c+6−0
@@ -87,6 +87,12 @@ static int digsig_verify_rsa(struct key *key, · 86 unmodified lines
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
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
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)
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
585 struct vfs_ns_cap_data data, *nscaps = &data;585 struct vfs_ns_cap_data data, *nscaps = &data;
586 struct vfs_cap_data *caps = (struct vfs_cap_data *) &data;586 struct vfs_cap_data *caps = (struct vfs_cap_data *) &data;
587 kuid_t rootkuid;587 kuid_t rootkuid;
588 struct user_namespace *fs_ns = inode->i_sb->s_user_ns;588 struct user_namespace *fs_ns;
589 589
590 memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data));590 memset(cpu_caps, 0, sizeof(struct cpu_vfs_cap_data));
591 591
592 if (!inode)592 if (!inode)
593 return -ENODATA;593 return -ENODATA;
594 594
595 fs_ns = inode->i_sb->s_user_ns;
595 size = __vfs_getxattr((struct dentry *)dentry, inode,596 size = __vfs_getxattr((struct dentry *)dentry, inode,
596 XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ);597 XATTR_NAME_CAPS, &data, XATTR_CAPS_SZ);
597 if (size == -ENODATA || size == -EOPNOTSUPP)598 if (size == -ENODATA || size == -EOPNOTSUPP)
security/keys/Kconfig+1−0
@@ -45,6 +45,7 @@ config BIG_KEYS · 44 unmodified lines
45 bool "Large payload keys"45 bool "Large payload keys"
46 depends on KEYS46 depends on KEYS
47 depends on TMPFS47 depends on TMPFS
48 select CRYPTO
48 select CRYPTO_AES49 select CRYPTO_AES
49 select CRYPTO_GCM50 select CRYPTO_GCM
50 help51 help
security/keys/big_key.c+2−2
@@ -247,7 +247,7 @@ void big_key_revoke(struct key *key) · 246 unmodified lines
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) · 25 unmodified lines
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");
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
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) · 532 unmodified lines
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;
security/keys/gc.c+4−4
@@ -129,15 +129,15 @@ static noinline void key_gc_unused_keys(struct list_head *keys) · 128 unmodified lines
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) · 7 unmodified lines
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);
security/keys/key.c+30−11
@@ -401,6 +401,18 @@ int key_payload_reserve(struct key *key, size_t datalen) · 400 unmodified lines
401}401}
402EXPORT_SYMBOL(key_payload_reserve);402EXPORT_SYMBOL(key_payload_reserve);
403 403
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
404/*416/*
405 * Instantiate a key and link it into the target keyring atomically. Must be417 * 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's418 * 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
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, · 139 unmodified lines
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, · 162 unmodified lines
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: · 176 unmodified lines
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) · 44 unmodified lines
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
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
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) · 125 unmodified lines
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 }
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
414 else414 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 else420 else
@@ -553,7 +553,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data) · 132 unmodified lines
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) · 5 unmodified lines
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) · 1 unmodified line
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) · 18 unmodified lines
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 }
security/keys/permission.c+4−3
@@ -88,7 +88,8 @@ EXPORT_SYMBOL(key_task_permission); · 87 unmodified lines
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) · 4 unmodified lines
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
security/keys/proc.c+19−12
@@ -179,9 +179,12 @@ static int proc_keys_show(struct seq_file *m, void *v) · 178 unmodified lines
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) · 29 unmodified lines
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) · 7 unmodified lines
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,
security/keys/process_keys.c+1−1
@@ -730,7 +730,7 @@ try_again: · 729 unmodified lines
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 */
security/keys/request_key.c+3−4
@@ -595,10 +595,9 @@ int wait_for_key_construction(struct key *key, bool intr) · 594 unmodified lines
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);
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
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
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
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)
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
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); · 41 unmodified lines
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