diff options
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r-- | security/keys/keyctl.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 6261745e445..b2b0998d6ab 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -505,13 +505,11 @@ okay: ret = snprintf(tmpbuf, PAGE_SIZE - 1, "%s;%d;%d;%08x;%s", - key_ref_to_ptr(key_ref)->type->name, - key_ref_to_ptr(key_ref)->uid, - key_ref_to_ptr(key_ref)->gid, - key_ref_to_ptr(key_ref)->perm, - key_ref_to_ptr(key_ref)->description ? - key_ref_to_ptr(key_ref)->description : "" - ); + key->type->name, + key->uid, + key->gid, + key->perm, + key->description ?: ""); /* include a NUL char at the end of the data */ if (ret > PAGE_SIZE - 1) @@ -1091,7 +1089,7 @@ error: long keyctl_set_timeout(key_serial_t id, unsigned timeout) { struct timespec now; - struct key *key; + struct key *key, *instkey; key_ref_t key_ref; time_t expiry; long ret; @@ -1099,10 +1097,25 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout) key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, KEY_SETATTR); if (IS_ERR(key_ref)) { + /* setting the timeout on a key under construction is permitted + * if we have the authorisation token handy */ + if (PTR_ERR(key_ref) == -EACCES) { + instkey = key_get_instantiation_authkey(id); + if (!IS_ERR(instkey)) { + key_put(instkey); + key_ref = lookup_user_key(id, + KEY_LOOKUP_PARTIAL, + 0); + if (!IS_ERR(key_ref)) + goto okay; + } + } + ret = PTR_ERR(key_ref); goto error; } +okay: key = key_ref_to_ptr(key_ref); /* make the changes with the locks held to prevent races */ |