diff options
author | David Howells <dhowells@redhat.com> | 2008-11-13 18:39:19 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-11-13 18:39:19 -0500 |
commit | c69e8d9c01db2adc503464993c358901c9af9de4 (patch) | |
tree | bed94aaa9aeb7a7834d1c880f72b62a11a752c78 /security/keys/permission.c | |
parent | 86a264abe542cfececb4df129bc45a0338d8cdb9 (diff) |
CRED: Use RCU to access another task's creds and to release a task's own creds
Use RCU to access another task's creds and to release a task's own creds.
This means that it will be possible for the credentials of a task to be
replaced without another task (a) requiring a full lock to read them, and (b)
seeing deallocated memory.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: James Morris <jmorris@namei.org>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/keys/permission.c')
-rw-r--r-- | security/keys/permission.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/security/keys/permission.c b/security/keys/permission.c index baf3d5f31e71..13c36164f284 100644 --- a/security/keys/permission.c +++ b/security/keys/permission.c | |||
@@ -22,13 +22,16 @@ int key_task_permission(const key_ref_t key_ref, | |||
22 | struct task_struct *context, | 22 | struct task_struct *context, |
23 | key_perm_t perm) | 23 | key_perm_t perm) |
24 | { | 24 | { |
25 | struct cred *cred = context->cred; | 25 | const struct cred *cred; |
26 | struct key *key; | 26 | struct key *key; |
27 | key_perm_t kperm; | 27 | key_perm_t kperm; |
28 | int ret; | 28 | int ret; |
29 | 29 | ||
30 | key = key_ref_to_ptr(key_ref); | 30 | key = key_ref_to_ptr(key_ref); |
31 | 31 | ||
32 | rcu_read_lock(); | ||
33 | cred = __task_cred(context); | ||
34 | |||
32 | /* use the second 8-bits of permissions for keys the caller owns */ | 35 | /* use the second 8-bits of permissions for keys the caller owns */ |
33 | if (key->uid == cred->fsuid) { | 36 | if (key->uid == cred->fsuid) { |
34 | kperm = key->perm >> 16; | 37 | kperm = key->perm >> 16; |
@@ -43,10 +46,7 @@ int key_task_permission(const key_ref_t key_ref, | |||
43 | goto use_these_perms; | 46 | goto use_these_perms; |
44 | } | 47 | } |
45 | 48 | ||
46 | spin_lock(&cred->lock); | ||
47 | ret = groups_search(cred->group_info, key->gid); | 49 | ret = groups_search(cred->group_info, key->gid); |
48 | spin_unlock(&cred->lock); | ||
49 | |||
50 | if (ret) { | 50 | if (ret) { |
51 | kperm = key->perm >> 8; | 51 | kperm = key->perm >> 8; |
52 | goto use_these_perms; | 52 | goto use_these_perms; |
@@ -57,6 +57,8 @@ int key_task_permission(const key_ref_t key_ref, | |||
57 | kperm = key->perm; | 57 | kperm = key->perm; |
58 | 58 | ||
59 | use_these_perms: | 59 | use_these_perms: |
60 | rcu_read_lock(); | ||
61 | |||
60 | /* use the top 8-bits of permissions for keys the caller possesses | 62 | /* use the top 8-bits of permissions for keys the caller possesses |
61 | * - possessor permissions are additive with other permissions | 63 | * - possessor permissions are additive with other permissions |
62 | */ | 64 | */ |