KEYS: Load key expiry time atomically in keyring_search_iterator()
authorEric Biggers <ebiggers@google.com>
Wed, 27 Sep 2017 19:50:45 +0000 (12:50 -0700)
committerDavid Howells <dhowells@redhat.com>
Wed, 18 Oct 2017 08:12:41 +0000 (09:12 +0100)
Similar to the case for key_validate(), we should load the key ->expiry
once atomically in keyring_search_iterator(), since it can be changed
concurrently with the flags whenever the key semaphore isn't held.

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: David Howells <dhowells@redhat.com>
security/keys/keyring.c

index 06173b0..a7e51f7 100644 (file)
@@ -566,6 +566,8 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
 
        /* skip invalidated, revoked and expired keys */
        if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) {
+               time_t expiry = READ_ONCE(key->expiry);
+
                if (kflags & ((1 << KEY_FLAG_INVALIDATED) |
                              (1 << KEY_FLAG_REVOKED))) {
                        ctx->result = ERR_PTR(-EKEYREVOKED);
@@ -573,7 +575,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
                        goto skipped;
                }
 
-               if (key->expiry && ctx->now.tv_sec >= key->expiry) {
+               if (expiry && ctx->now.tv_sec >= expiry) {
                        if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED))
                                ctx->result = ERR_PTR(-EKEYEXPIRED);
                        kleave(" = %d [expire]", ctx->skipped_ret);