diff options
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r-- | security/keys/keyctl.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 6261745e4459..639226afd0db 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
@@ -1091,7 +1091,7 @@ error: | |||
1091 | long keyctl_set_timeout(key_serial_t id, unsigned timeout) | 1091 | long keyctl_set_timeout(key_serial_t id, unsigned timeout) |
1092 | { | 1092 | { |
1093 | struct timespec now; | 1093 | struct timespec now; |
1094 | struct key *key; | 1094 | struct key *key, *instkey; |
1095 | key_ref_t key_ref; | 1095 | key_ref_t key_ref; |
1096 | time_t expiry; | 1096 | time_t expiry; |
1097 | long ret; | 1097 | long ret; |
@@ -1099,10 +1099,25 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout) | |||
1099 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, | 1099 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, |
1100 | KEY_SETATTR); | 1100 | KEY_SETATTR); |
1101 | if (IS_ERR(key_ref)) { | 1101 | if (IS_ERR(key_ref)) { |
1102 | /* setting the timeout on a key under construction is permitted | ||
1103 | * if we have the authorisation token handy */ | ||
1104 | if (PTR_ERR(key_ref) == -EACCES) { | ||
1105 | instkey = key_get_instantiation_authkey(id); | ||
1106 | if (!IS_ERR(instkey)) { | ||
1107 | key_put(instkey); | ||
1108 | key_ref = lookup_user_key(id, | ||
1109 | KEY_LOOKUP_PARTIAL, | ||
1110 | 0); | ||
1111 | if (!IS_ERR(key_ref)) | ||
1112 | goto okay; | ||
1113 | } | ||
1114 | } | ||
1115 | |||
1102 | ret = PTR_ERR(key_ref); | 1116 | ret = PTR_ERR(key_ref); |
1103 | goto error; | 1117 | goto error; |
1104 | } | 1118 | } |
1105 | 1119 | ||
1120 | okay: | ||
1106 | key = key_ref_to_ptr(key_ref); | 1121 | key = key_ref_to_ptr(key_ref); |
1107 | 1122 | ||
1108 | /* make the changes with the locks held to prevent races */ | 1123 | /* make the changes with the locks held to prevent races */ |