diff options
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r-- | security/keys/keyring.c | 37 |
1 files changed, 24 insertions, 13 deletions
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index cdd2f3f88c88..a06ffab38568 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c | |||
@@ -176,13 +176,15 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m) | |||
176 | else | 176 | else |
177 | seq_puts(m, "[anon]"); | 177 | seq_puts(m, "[anon]"); |
178 | 178 | ||
179 | rcu_read_lock(); | 179 | if (key_is_instantiated(keyring)) { |
180 | klist = rcu_dereference(keyring->payload.subscriptions); | 180 | rcu_read_lock(); |
181 | if (klist) | 181 | klist = rcu_dereference(keyring->payload.subscriptions); |
182 | seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); | 182 | if (klist) |
183 | else | 183 | seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); |
184 | seq_puts(m, ": empty"); | 184 | else |
185 | rcu_read_unlock(); | 185 | seq_puts(m, ": empty"); |
186 | rcu_read_unlock(); | ||
187 | } | ||
186 | } | 188 | } |
187 | 189 | ||
188 | /* | 190 | /* |
@@ -271,6 +273,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, | |||
271 | * @type: The type of key to search for. | 273 | * @type: The type of key to search for. |
272 | * @description: Parameter for @match. | 274 | * @description: Parameter for @match. |
273 | * @match: Function to rule on whether or not a key is the one required. | 275 | * @match: Function to rule on whether or not a key is the one required. |
276 | * @no_state_check: Don't check if a matching key is bad | ||
274 | * | 277 | * |
275 | * Search the supplied keyring tree for a key that matches the criteria given. | 278 | * Search the supplied keyring tree for a key that matches the criteria given. |
276 | * The root keyring and any linked keyrings must grant Search permission to the | 279 | * The root keyring and any linked keyrings must grant Search permission to the |
@@ -303,7 +306,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, | |||
303 | const struct cred *cred, | 306 | const struct cred *cred, |
304 | struct key_type *type, | 307 | struct key_type *type, |
305 | const void *description, | 308 | const void *description, |
306 | key_match_func_t match) | 309 | key_match_func_t match, |
310 | bool no_state_check) | ||
307 | { | 311 | { |
308 | struct { | 312 | struct { |
309 | struct keyring_list *keylist; | 313 | struct keyring_list *keylist; |
@@ -345,6 +349,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref, | |||
345 | kflags = keyring->flags; | 349 | kflags = keyring->flags; |
346 | if (keyring->type == type && match(keyring, description)) { | 350 | if (keyring->type == type && match(keyring, description)) { |
347 | key = keyring; | 351 | key = keyring; |
352 | if (no_state_check) | ||
353 | goto found; | ||
348 | 354 | ||
349 | /* check it isn't negative and hasn't expired or been | 355 | /* check it isn't negative and hasn't expired or been |
350 | * revoked */ | 356 | * revoked */ |
@@ -384,11 +390,13 @@ descend: | |||
384 | continue; | 390 | continue; |
385 | 391 | ||
386 | /* skip revoked keys and expired keys */ | 392 | /* skip revoked keys and expired keys */ |
387 | if (kflags & (1 << KEY_FLAG_REVOKED)) | 393 | if (!no_state_check) { |
388 | continue; | 394 | if (kflags & (1 << KEY_FLAG_REVOKED)) |
395 | continue; | ||
389 | 396 | ||
390 | if (key->expiry && now.tv_sec >= key->expiry) | 397 | if (key->expiry && now.tv_sec >= key->expiry) |
391 | continue; | 398 | continue; |
399 | } | ||
392 | 400 | ||
393 | /* keys that don't match */ | 401 | /* keys that don't match */ |
394 | if (!match(key, description)) | 402 | if (!match(key, description)) |
@@ -399,6 +407,9 @@ descend: | |||
399 | cred, KEY_SEARCH) < 0) | 407 | cred, KEY_SEARCH) < 0) |
400 | continue; | 408 | continue; |
401 | 409 | ||
410 | if (no_state_check) | ||
411 | goto found; | ||
412 | |||
402 | /* we set a different error code if we pass a negative key */ | 413 | /* we set a different error code if we pass a negative key */ |
403 | if (kflags & (1 << KEY_FLAG_NEGATIVE)) { | 414 | if (kflags & (1 << KEY_FLAG_NEGATIVE)) { |
404 | err = key->type_data.reject_error; | 415 | err = key->type_data.reject_error; |
@@ -478,7 +489,7 @@ key_ref_t keyring_search(key_ref_t keyring, | |||
478 | return ERR_PTR(-ENOKEY); | 489 | return ERR_PTR(-ENOKEY); |
479 | 490 | ||
480 | return keyring_search_aux(keyring, current->cred, | 491 | return keyring_search_aux(keyring, current->cred, |
481 | type, description, type->match); | 492 | type, description, type->match, false); |
482 | } | 493 | } |
483 | EXPORT_SYMBOL(keyring_search); | 494 | EXPORT_SYMBOL(keyring_search); |
484 | 495 | ||