From 927942aabbbe506bf9bc70a16dc5460ecc64c148 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 11 Jun 2010 17:31:10 +0100 Subject: KEYS: Make /proc/keys check to see if a key is possessed before security check Make /proc/keys check to see if the calling process possesses each key before performing the security check. The possession check can be skipped if the key doesn't have the possessor-view permission bit set. This causes the keys a process possesses to show up in /proc/keys, even if they don't have matching user/group/other view permissions. Signed-off-by: David Howells Signed-off-by: James Morris --- security/keys/process_keys.c | 64 +++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 21 deletions(-) (limited to 'security/keys/process_keys.c') diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 6b8e4ff4cc68..f8e7251ae2c8 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c @@ -309,22 +309,19 @@ void key_fsgid_changed(struct task_struct *tsk) /*****************************************************************************/ /* - * search the process keyrings for the first matching key + * search only my process keyrings for the first matching key * - we use the supplied match function to see if the description (or other * feature of interest) matches * - we return -EAGAIN if we didn't find any matching key * - we return -ENOKEY if we found only negative matching keys */ -key_ref_t search_process_keyrings(struct key_type *type, - const void *description, - key_match_func_t match, - const struct cred *cred) +key_ref_t search_my_process_keyrings(struct key_type *type, + const void *description, + key_match_func_t match, + const struct cred *cred) { - struct request_key_auth *rka; key_ref_t key_ref, ret, err; - might_sleep(); - /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were * searchable, but we failed to find a key or we found a negative key; * otherwise we want to return a sample error (probably -EACCES) if @@ -424,6 +421,36 @@ key_ref_t search_process_keyrings(struct key_type *type, } } + /* no key - decide on the error we're going to go for */ + key_ref = ret ? ret : err; + +found: + return key_ref; +} + +/*****************************************************************************/ +/* + * search the process keyrings for the first matching key + * - we use the supplied match function to see if the description (or other + * feature of interest) matches + * - we return -EAGAIN if we didn't find any matching key + * - we return -ENOKEY if we found only negative matching keys + */ +key_ref_t search_process_keyrings(struct key_type *type, + const void *description, + key_match_func_t match, + const struct cred *cred) +{ + struct request_key_auth *rka; + key_ref_t key_ref, ret = ERR_PTR(-EACCES), err; + + might_sleep(); + + key_ref = search_my_process_keyrings(type, description, match, cred); + if (!IS_ERR(key_ref)) + goto found; + err = key_ref; + /* if this process has an instantiation authorisation key, then we also * search the keyrings of the process mentioned there * - we don't permit access to request_key auth keys via this method @@ -446,24 +473,19 @@ key_ref_t search_process_keyrings(struct key_type *type, if (!IS_ERR(key_ref)) goto found; - switch (PTR_ERR(key_ref)) { - case -EAGAIN: /* no key */ - if (ret) - break; - case -ENOKEY: /* negative key */ - ret = key_ref; - break; - default: - err = key_ref; - break; - } + ret = key_ref; } else { up_read(&cred->request_key_auth->sem); } } /* no key - decide on the error we're going to go for */ - key_ref = ret ? ret : err; + if (err == ERR_PTR(-ENOKEY) || ret == ERR_PTR(-ENOKEY)) + key_ref = ERR_PTR(-ENOKEY); + else if (err == ERR_PTR(-EACCES)) + key_ref = ret; + else + key_ref = err; found: return key_ref; @@ -474,7 +496,7 @@ found: /* * see if the key we're looking at is the target key */ -static int lookup_user_key_possessed(const struct key *key, const void *target) +int lookup_user_key_possessed(const struct key *key, const void *target) { return key == target; -- cgit v1.2.3-59-g8ed1b