diff options
author | David Howells <dhowells@redhat.com> | 2010-06-11 17:31:10 +0100 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 15:34:27 +1000 |
commit | 927942aabbbe506bf9bc70a16dc5460ecc64c148 (patch) | |
tree | 2c53ccb405bd4afb03ff9f7acab892fafc7e9b0f /security/keys/proc.c | |
parent | 9156235b3427d6f01c5c95022f72f381f07583f5 (diff) | |
download | linux-927942aabbbe506bf9bc70a16dc5460ecc64c148.tar.gz linux-927942aabbbe506bf9bc70a16dc5460ecc64c148.tar.bz2 linux-927942aabbbe506bf9bc70a16dc5460ecc64c148.zip |
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 <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/keys/proc.c')
-rw-r--r-- | security/keys/proc.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/security/keys/proc.c b/security/keys/proc.c index 068b66ea2f1b..70373966816e 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c @@ -184,20 +184,36 @@ static void proc_keys_stop(struct seq_file *p, void *v) static int proc_keys_show(struct seq_file *m, void *v) { + const struct cred *cred = current_cred(); struct rb_node *_p = v; struct key *key = rb_entry(_p, struct key, serial_node); struct timespec now; unsigned long timo; + key_ref_t key_ref, skey_ref; char xbuf[12]; int rc; + key_ref = make_key_ref(key, 0); + + /* determine if the key is possessed by this process (a test we can + * skip if the key does not indicate the possessor can view it + */ + if (key->perm & KEY_POS_VIEW) { + skey_ref = search_my_process_keyrings(key->type, key, + lookup_user_key_possessed, + cred); + if (!IS_ERR(skey_ref)) { + key_ref_put(skey_ref); + key_ref = make_key_ref(key, 1); + } + } + /* check whether the current task is allowed to view the key (assuming * non-possession) * - the caller holds a spinlock, and thus the RCU read lock, making our * access to __current_cred() safe */ - rc = key_task_permission(make_key_ref(key, 0), current_cred(), - KEY_VIEW); + rc = key_task_permission(key_ref, cred, KEY_VIEW); if (rc < 0) return 0; |