diff options
Diffstat (limited to 'security/keys')
-rw-r--r-- | security/keys/key.c | 3 | ||||
-rw-r--r-- | security/keys/keyring.c | 1 | ||||
-rw-r--r-- | security/keys/request_key.c | 4 |
3 files changed, 6 insertions, 2 deletions
diff --git a/security/keys/key.c b/security/keys/key.c index d331ea9ef380..55d110f0aced 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -557,9 +557,10 @@ int key_reject_and_link(struct key *key, if (!test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) { /* mark the key as being negatively instantiated */ atomic_inc(&key->user->nikeys); + key->type_data.reject_error = -error; + smp_wmb(); set_bit(KEY_FLAG_NEGATIVE, &key->flags); set_bit(KEY_FLAG_INSTANTIATED, &key->flags); - key->type_data.reject_error = -error; now = current_kernel_time(); key->expiry = now.tv_sec + timeout; key_schedule_gc(key->expiry + key_gc_delay); diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 9b6f6e09b50c..8c05ebd7203d 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c @@ -551,6 +551,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data) if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) { /* we set a different error code if we pass a negative key */ if (kflags & (1 << KEY_FLAG_NEGATIVE)) { + smp_rmb(); ctx->result = ERR_PTR(key->type_data.reject_error); kleave(" = %d [neg]", ctx->skipped_ret); goto skipped; diff --git a/security/keys/request_key.c b/security/keys/request_key.c index df94827103d0..381411941cc1 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c @@ -596,8 +596,10 @@ int wait_for_key_construction(struct key *key, bool intr) intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); if (ret < 0) return ret; - if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) + if (test_bit(KEY_FLAG_NEGATIVE, &key->flags)) { + smp_rmb(); return key->type_data.reject_error; + } return key_validate(key); } EXPORT_SYMBOL(wait_for_key_construction); |