forked from Minki/linux
KEYS: load key flags and expiry time atomically in key_validate()
In key_validate(), load the flags and expiry time once atomically, since these can change concurrently if key_validate() is called without the key semaphore held. And we don't want to get inconsistent results if a variable is referenced multiple times. For example, key->expiry was referenced in both 'if (key->expiry)' and in 'if (now.tv_sec >= key->expiry)', making it theoretically possible to see a spurious EKEYEXPIRED while the expiration time was being removed, i.e. set to 0. Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: David Howells <dhowells@redhat.com>
This commit is contained in:
parent
60ff5b2f54
commit
1823d475a5
@ -88,7 +88,8 @@ EXPORT_SYMBOL(key_task_permission);
|
||||
*/
|
||||
int key_validate(const struct key *key)
|
||||
{
|
||||
unsigned long flags = key->flags;
|
||||
unsigned long flags = READ_ONCE(key->flags);
|
||||
time_t expiry = READ_ONCE(key->expiry);
|
||||
|
||||
if (flags & (1 << KEY_FLAG_INVALIDATED))
|
||||
return -ENOKEY;
|
||||
@ -99,9 +100,9 @@ int key_validate(const struct key *key)
|
||||
return -EKEYREVOKED;
|
||||
|
||||
/* check it hasn't expired */
|
||||
if (key->expiry) {
|
||||
if (expiry) {
|
||||
struct timespec now = current_kernel_time();
|
||||
if (now.tv_sec >= key->expiry)
|
||||
if (now.tv_sec >= expiry)
|
||||
return -EKEYEXPIRED;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user