summaryrefslogtreecommitdiffstats
path: root/security/keys/proc.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2010-06-11 18:31:10 +0200
committerJames Morris <jmorris@namei.org>2010-08-02 07:34:27 +0200
commit927942aabbbe506bf9bc70a16dc5460ecc64c148 (patch)
tree2c53ccb405bd4afb03ff9f7acab892fafc7e9b0f /security/keys/proc.c
parentKEYS: Authorise keyctl_set_timeout() on a key if we have its authorisation key (diff)
downloadlinux-927942aabbbe506bf9bc70a16dc5460ecc64c148.tar.xz
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.c20
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;