aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:19 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:19 -0500
commitc69e8d9c01db2adc503464993c358901c9af9de4 (patch)
treebed94aaa9aeb7a7834d1c880f72b62a11a752c78 /kernel/cgroup.c
parent86a264abe542cfececb4df129bc45a0338d8cdb9 (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 'kernel/cgroup.c')
-rw-r--r--kernel/cgroup.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index e210526e6401..a512a75a5560 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1279,7 +1279,7 @@ int cgroup_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
1279static int attach_task_by_pid(struct cgroup *cgrp, u64 pid) 1279static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
1280{ 1280{
1281 struct task_struct *tsk; 1281 struct task_struct *tsk;
1282 uid_t euid; 1282 const struct cred *cred = current_cred(), *tcred;
1283 int ret; 1283 int ret;
1284 1284
1285 if (pid) { 1285 if (pid) {
@@ -1289,16 +1289,16 @@ static int attach_task_by_pid(struct cgroup *cgrp, u64 pid)
1289 rcu_read_unlock(); 1289 rcu_read_unlock();
1290 return -ESRCH; 1290 return -ESRCH;
1291 } 1291 }
1292 get_task_struct(tsk);
1293 rcu_read_unlock();
1294 1292
1295 euid = current_euid(); 1293 tcred = __task_cred(tsk);
1296 if (euid && 1294 if (cred->euid &&
1297 euid != tsk->cred->uid && 1295 cred->euid != tcred->uid &&
1298 euid != tsk->cred->suid) { 1296 cred->euid != tcred->suid) {
1299 put_task_struct(tsk); 1297 rcu_read_unlock();
1300 return -EACCES; 1298 return -EACCES;
1301 } 1299 }
1300 get_task_struct(tsk);
1301 rcu_read_unlock();
1302 } else { 1302 } else {
1303 tsk = current; 1303 tsk = current;
1304 get_task_struct(tsk); 1304 get_task_struct(tsk);