Subject: [PATCH] Additional pspace work for all syscalls that call find_task_by_pid From: Eric W. Biederman Date: 1129890786 -0600 --- fs/ioprio.c | 9 +++++++-- kernel/cpuset.c | 1 + kernel/posix-cpu-timers.c | 9 +++++---- kernel/posix-timers.c | 3 ++- kernel/sched.c | 2 +- kernel/signal.c | 1 + kernel/sys.c | 11 ++++++++++- 7 files changed, 27 insertions(+), 9 deletions(-) 581920aa9769ab10bde92a5dc7105011e0bebe38 diff --git a/fs/ioprio.c b/fs/ioprio.c index d1c1f2b..21e4cfe 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c @@ -22,6 +22,7 @@ #include #include #include +#include static int set_task_ioprio(struct task_struct *task, int ioprio) { @@ -76,13 +77,15 @@ asmlinkage long sys_ioprio_set(int which if (!who) p = current; else - p = find_task_by_pid(who); + p = find_task_by_pid(pid_from_user(who)); if (p) ret = set_task_ioprio(p, ioprio); break; case IOPRIO_WHO_PGRP: if (!who) who = process_group(current); + else + who = pid_from_user(who); do_each_task_pid(who, PIDTYPE_PGID, p) { ret = set_task_ioprio(p, ioprio); if (ret) @@ -129,13 +132,15 @@ asmlinkage long sys_ioprio_get(int which if (!who) p = current; else - p = find_task_by_pid(who); + p = find_task_by_pid(pid_from_user(who)); if (p) ret = p->ioprio; break; case IOPRIO_WHO_PGRP: if (!who) who = process_group(current); + else + who = pid_from_user(who); do_each_task_pid(who, PIDTYPE_PGID, p) { if (ret == -ESRCH) ret = p->ioprio; diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 28176d0..35f009c 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c @@ -791,6 +791,7 @@ static int attach_task(struct cpuset *cs if (pid) { read_lock(&tasklist_lock); + pid = pid_from_user(pid); tsk = find_task_by_pid(pid); if (!tsk) { read_unlock(&tasklist_lock); diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index ad85d3f..ac239c7 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c @@ -3,6 +3,7 @@ */ #include +#include #include #include #include @@ -20,7 +21,7 @@ static int check_clock(clockid_t which_c return 0; read_lock(&tasklist_lock); - p = find_task_by_pid(pid); + p = find_task_by_pid(pid_from_user(pid)); if (!p || (CPUCLOCK_PERTHREAD(which_clock) ? p->tgid != current->tgid : p->tgid != pid)) { error = -EINVAL; @@ -303,7 +304,7 @@ int posix_cpu_clock_get(clockid_t which_ */ struct task_struct *p; read_lock(&tasklist_lock); - p = find_task_by_pid(pid); + p = find_task_by_pid(pid_from_user(pid)); if (p) { if (CPUCLOCK_PERTHREAD(which_clock)) { if (p->tgid == current->tgid) { @@ -347,7 +348,7 @@ int posix_cpu_timer_create(struct k_itim if (pid == 0) { p = current; } else { - p = find_task_by_pid(pid); + p = find_task_by_pid(pid_from_user(pid)); if (p && p->tgid != current->tgid) p = NULL; } @@ -355,7 +356,7 @@ int posix_cpu_timer_create(struct k_itim if (pid == 0) { p = current->group_leader; } else { - p = find_task_by_pid(pid); + p = find_task_by_pid(pid_from_user(pid)); if (p && p->tgid != pid) p = NULL; } diff --git a/kernel/posix-timers.c b/kernel/posix-timers.c index b7b532a..2258a68 100644 --- a/kernel/posix-timers.c +++ b/kernel/posix-timers.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -518,7 +519,7 @@ static inline struct task_struct * good_ struct task_struct *rtn = current->group_leader; if ((event->sigev_notify & SIGEV_THREAD_ID ) && - (!(rtn = find_task_by_pid(event->sigev_notify_thread_id)) || + (!(rtn = find_task_by_pid(pid_from_user(event->sigev_notify_thread_id))) || rtn->tgid != current->tgid || (event->sigev_notify & ~SIGEV_THREAD_ID) != SIGEV_SIGNAL)) return NULL; diff --git a/kernel/sched.c b/kernel/sched.c index db0f769..0b7c257 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3583,7 +3583,7 @@ task_t *idle_task(int cpu) */ static inline task_t *find_process_by_pid(pid_t pid) { - return pid ? find_task_by_pid(pid) : current; + return pid ? find_task_by_pid(pid_from_user(pid)) : current; } /* Actually do priority change: must hold rq lock. */ diff --git a/kernel/signal.c b/kernel/signal.c index e3ff724..6378175 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2400,6 +2400,7 @@ asmlinkage long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo) { siginfo_t info; + pid = pid_from_user(pid); if (copy_from_user(&info, uinfo, sizeof(siginfo_t))) return -EFAULT; diff --git a/kernel/sys.c b/kernel/sys.c index 5f4a13b..fb2e896 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -268,6 +268,8 @@ asmlinkage long sys_setpriority(int whic case PRIO_PROCESS: if (!who) who = current->pid; + else + who = pid_from_user(who); p = find_task_by_pid(who); if (p) error = set_one_prio(p, niceval, error); @@ -275,6 +277,8 @@ asmlinkage long sys_setpriority(int whic case PRIO_PGRP: if (!who) who = process_group(current); + else + who = pid_from_user(who); do_each_task_pid(who, PIDTYPE_PGID, p) { error = set_one_prio(p, niceval, error); } while_each_task_pid(who, PIDTYPE_PGID, p); @@ -321,6 +325,8 @@ asmlinkage long sys_getpriority(int whic case PRIO_PROCESS: if (!who) who = current->pid; + else + who = pid_from_user(who); p = find_task_by_pid(who); if (p) { niceval = 20 - task_nice(p); @@ -331,6 +337,8 @@ asmlinkage long sys_getpriority(int whic case PRIO_PGRP: if (!who) who = process_group(current); + else + who = pid_from_user(who); do_each_task_pid(who, PIDTYPE_PGID, p) { niceval = 20 - task_nice(p); if (niceval > retval) @@ -1182,11 +1190,12 @@ asmlinkage long sys_getsid(pid_t pid) int retval; struct task_struct *p; + pid = pid_from_user(pid); read_lock(&tasklist_lock); p = find_task_by_pid(pid); retval = -ESRCH; - if(p) { + if (p) { retval = security_task_getsid(p); if (!retval) retval = p->signal->session; -- 1.0.GIT