mirror of
https://github.com/adulau/aha.git
synced 2024-12-26 18:56:14 +00:00
Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: sys: Fix missing rcu protection for __task_cred() access signals: Fix more rcu assumptions signal: Fix racy access to __task_cred in kill_pid_info_as_uid()
This commit is contained in:
commit
10e5453ffa
2 changed files with 16 additions and 11 deletions
|
@ -218,13 +218,13 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
|
||||||
struct user_struct *user;
|
struct user_struct *user;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We won't get problems with the target's UID changing under us
|
* Protect access to @t credentials. This can go away when all
|
||||||
* because changing it requires RCU be used, and if t != current, the
|
* callers hold rcu read lock.
|
||||||
* caller must be holding the RCU readlock (by way of a spinlock) and
|
|
||||||
* we use RCU protection here
|
|
||||||
*/
|
*/
|
||||||
|
rcu_read_lock();
|
||||||
user = get_uid(__task_cred(t)->user);
|
user = get_uid(__task_cred(t)->user);
|
||||||
atomic_inc(&user->sigpending);
|
atomic_inc(&user->sigpending);
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (override_rlimit ||
|
if (override_rlimit ||
|
||||||
atomic_read(&user->sigpending) <=
|
atomic_read(&user->sigpending) <=
|
||||||
|
@ -1179,11 +1179,12 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
struct task_struct *p;
|
struct task_struct *p;
|
||||||
const struct cred *pcred;
|
const struct cred *pcred;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (!valid_signal(sig))
|
if (!valid_signal(sig))
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
read_lock(&tasklist_lock);
|
rcu_read_lock();
|
||||||
p = pid_task(pid, PIDTYPE_PID);
|
p = pid_task(pid, PIDTYPE_PID);
|
||||||
if (!p) {
|
if (!p) {
|
||||||
ret = -ESRCH;
|
ret = -ESRCH;
|
||||||
|
@ -1199,14 +1200,16 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
|
||||||
ret = security_task_kill(p, info, sig, secid);
|
ret = security_task_kill(p, info, sig, secid);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
if (sig && p->sighand) {
|
|
||||||
unsigned long flags;
|
if (sig) {
|
||||||
spin_lock_irqsave(&p->sighand->siglock, flags);
|
if (lock_task_sighand(p, &flags)) {
|
||||||
ret = __send_signal(sig, info, p, 1, 0);
|
ret = __send_signal(sig, info, p, 1, 0);
|
||||||
spin_unlock_irqrestore(&p->sighand->siglock, flags);
|
unlock_task_sighand(p, &flags);
|
||||||
|
} else
|
||||||
|
ret = -ESRCH;
|
||||||
}
|
}
|
||||||
out_unlock:
|
out_unlock:
|
||||||
read_unlock(&tasklist_lock);
|
rcu_read_unlock();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(kill_pid_info_as_uid);
|
EXPORT_SYMBOL_GPL(kill_pid_info_as_uid);
|
||||||
|
|
|
@ -162,6 +162,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
|
||||||
if (niceval > 19)
|
if (niceval > 19)
|
||||||
niceval = 19;
|
niceval = 19;
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
read_lock(&tasklist_lock);
|
read_lock(&tasklist_lock);
|
||||||
switch (which) {
|
switch (which) {
|
||||||
case PRIO_PROCESS:
|
case PRIO_PROCESS:
|
||||||
|
@ -199,6 +200,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
|
||||||
}
|
}
|
||||||
out_unlock:
|
out_unlock:
|
||||||
read_unlock(&tasklist_lock);
|
read_unlock(&tasklist_lock);
|
||||||
|
rcu_read_unlock();
|
||||||
out:
|
out:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue