diff options
author | David Howells <dhowells@redhat.com> | 2010-06-11 12:31:10 -0400 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2010-08-02 01:34:27 -0400 |
commit | 927942aabbbe506bf9bc70a16dc5460ecc64c148 (patch) | |
tree | 2c53ccb405bd4afb03ff9f7acab892fafc7e9b0f /security/keys/proc.c | |
parent | 9156235b3427d6f01c5c95022f72f381f07583f5 (diff) |
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) | |||
184 | 184 | ||
185 | static int proc_keys_show(struct seq_file *m, void *v) | 185 | static int proc_keys_show(struct seq_file *m, void *v) |
186 | { | 186 | { |
187 | const struct cred *cred = current_cred(); | ||
187 | struct rb_node *_p = v; | 188 | struct rb_node *_p = v; |
188 | struct key *key = rb_entry(_p, struct key, serial_node); | 189 | struct key *key = rb_entry(_p, struct key, serial_node); |
189 | struct timespec now; | 190 | struct timespec now; |
190 | unsigned long timo; | 191 | unsigned long timo; |
192 | key_ref_t key_ref, skey_ref; | ||
191 | char xbuf[12]; | 193 | char xbuf[12]; |
192 | int rc; | 194 | int rc; |
193 | 195 | ||
196 | key_ref = make_key_ref(key, 0); | ||
197 | |||
198 | /* determine if the key is possessed by this process (a test we can | ||
199 | * skip if the key does not indicate the possessor can view it | ||
200 | */ | ||
201 | if (key->perm & KEY_POS_VIEW) { | ||
202 | skey_ref = search_my_process_keyrings(key->type, key, | ||
203 | lookup_user_key_possessed, | ||
204 | cred); | ||
205 | if (!IS_ERR(skey_ref)) { | ||
206 | key_ref_put(skey_ref); | ||
207 | key_ref = make_key_ref(key, 1); | ||
208 | } | ||
209 | } | ||
210 | |||
194 | /* check whether the current task is allowed to view the key (assuming | 211 | /* check whether the current task is allowed to view the key (assuming |
195 | * non-possession) | 212 | * non-possession) |
196 | * - the caller holds a spinlock, and thus the RCU read lock, making our | 213 | * - the caller holds a spinlock, and thus the RCU read lock, making our |
197 | * access to __current_cred() safe | 214 | * access to __current_cred() safe |
198 | */ | 215 | */ |
199 | rc = key_task_permission(make_key_ref(key, 0), current_cred(), | 216 | rc = key_task_permission(key_ref, cred, KEY_VIEW); |
200 | KEY_VIEW); | ||
201 | if (rc < 0) | 217 | if (rc < 0) |
202 | return 0; | 218 | return 0; |
203 | 219 | ||