diff options
author | David Howells <dhowells@redhat.com> | 2008-11-14 10:39:19 +1100 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-11-14 10:39:19 +1100 |
commit | c69e8d9c01db2adc503464993c358901c9af9de4 (patch) | |
tree | bed94aaa9aeb7a7834d1c880f72b62a11a752c78 /fs/ioprio.c | |
parent | 86a264abe542cfececb4df129bc45a0338d8cdb9 (diff) | |
download | blackbird-op-linux-c69e8d9c01db2adc503464993c358901c9af9de4.tar.gz blackbird-op-linux-c69e8d9c01db2adc503464993c358901c9af9de4.zip |
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) { int err; struct io_context *ioc; + const struct cred *cred = current_cred(), *tcred; - if (task->cred->uid != current_euid() && - task->cred->uid != current_uid() && !capable(CAP_SYS_NICE)) + rcu_read_lock(); + tcred = __task_cred(task); + if (tcred->uid != cred->euid && + tcred->uid != cred->uid && !capable(CAP_SYS_NICE)) { + rcu_read_unlock(); return -EPERM; + } + rcu_read_unlock(); err = security_task_setioprio(task, ioprio); if (err) @@ -131,7 +137,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) break; do_each_thread(g, p) { - if (p->cred->uid != who) + if (__task_cred(p)->uid != who) continue; ret = set_task_ioprio(p, ioprio); if (ret) @@ -224,7 +230,7 @@ asmlinkage long sys_ioprio_get(int which, int who) break; do_each_thread(g, p) { - if (p->cred->uid != user->uid) + if (__task_cred(p)->uid != user->uid) continue; tmpio = get_task_ioprio(p); if (tmpio < 0) |