aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyring.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2011-03-11 12:57:23 -0500
committerJames Morris <jmorris@namei.org>2011-03-16 20:59:32 -0400
commit78b7280cce23293f7570ad52c1ffe1485c6d9669 (patch)
treef3051c5fe69cb41e88f9470dead8534dda3e94e0 /security/keys/keyring.c
parentc151694b2c48d956ac8c8c59c6927f89cc29ef70 (diff)
KEYS: Improve /proc/keys
Improve /proc/keys by: (1) Don't attempt to summarise the payload of a negated key. It won't have one. To this end, a helper function - key_is_instantiated() has been added that allows the caller to find out whether the key is positively instantiated (as opposed to being uninstantiated or negatively instantiated). (2) Do show keys that are negative, expired or revoked rather than hiding them. This requires an override flag (no_state_check) to be passed to search_my_process_keyrings() and keyring_search_aux() to suppress this check. Without this, keys that are possessed by the caller, but only grant permissions to the caller if possessed are skipped as the possession check fails. Keys that are visible due to user, group or other checks are visible with or without this patch. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/keys/keyring.c')
-rw-r--r--security/keys/keyring.c37
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}
483EXPORT_SYMBOL(keyring_search); 494EXPORT_SYMBOL(keyring_search);
484 495