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 /fs/ioprio.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 'fs/ioprio.c')
-rw-r--r-- | fs/ioprio.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/ioprio.c b/fs/ioprio.c index 5112554fd210..3569e0ad86a2 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c | |||
@@ -31,10 +31,16 @@ static int set_task_ioprio(struct task_struct *task, int ioprio) | |||
31 | { | 31 | { |
32 | int err; | 32 | int err; |
33 | struct io_context *ioc; | 33 | struct io_context *ioc; |
34 | const struct cred *cred = current_cred(), *tcred; | ||
34 | 35 | ||
35 | if (task->cred->uid != current_euid() && | 36 | rcu_read_lock(); |
36 | task->cred->uid != current_uid() && !capable(CAP_SYS_NICE)) | 37 | tcred = __task_cred(task); |
38 | if (tcred->uid != cred->euid && | ||
39 | tcred->uid != cred->uid && !capable(CAP_SYS_NICE)) { | ||
40 | rcu_read_unlock(); | ||
37 | return -EPERM; | 41 | return -EPERM; |
42 | } | ||
43 | rcu_read_unlock(); | ||
38 | 44 | ||
39 | err = security_task_setioprio(task, ioprio); | 45 | err = security_task_setioprio(task, ioprio); |
40 | if (err) | 46 | if (err) |
@@ -131,7 +137,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) | |||
131 | break; | 137 | break; |
132 | 138 | ||
133 | do_each_thread(g, p) { | 139 | do_each_thread(g, p) { |
134 | if (p->cred->uid != who) | 140 | if (__task_cred(p)->uid != who) |
135 | continue; | 141 | continue; |
136 | ret = set_task_ioprio(p, ioprio); | 142 | ret = set_task_ioprio(p, ioprio); |
137 | if (ret) | 143 | if (ret) |
@@ -224,7 +230,7 @@ asmlinkage long sys_ioprio_get(int which, int who) | |||
224 | break; | 230 | break; |
225 | 231 | ||
226 | do_each_thread(g, p) { | 232 | do_each_thread(g, p) { |
227 | if (p->cred->uid != user->uid) | 233 | if (__task_cred(p)->uid != user->uid) |
228 | continue; | 234 | continue; |
229 | tmpio = get_task_ioprio(p); | 235 | tmpio = get_task_ioprio(p); |
230 | if (tmpio < 0) | 236 | if (tmpio < 0) |