aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-19 12:47:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-19 12:47:34 -0500
commit10e5453ffa0d04a2eda3cda3f55b88cb9c04595f (patch)
treedef247dc399549bc1359fe9d1faa49c621f8890d
parent3cd312c3e887b4bee2d94668a481b3d19c07732c (diff)
parentd4581a239a40319205762b76c01eb6363f277efa (diff)
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()
-rw-r--r--kernel/signal.c25
-rw-r--r--kernel/sys.c2
2 files changed, 16 insertions, 11 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 1814e68e4de3..d09692b40376 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -218,13 +218,13 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi
218 struct user_struct *user; 218 struct user_struct *user;
219 219
220 /* 220 /*
221 * We won't get problems with the target's UID changing under us 221 * Protect access to @t credentials. This can go away when all
222 * because changing it requires RCU be used, and if t != current, the 222 * callers hold rcu read lock.
223 * caller must be holding the RCU readlock (by way of a spinlock) and
224 * we use RCU protection here
225 */ 223 */
224 rcu_read_lock();
226 user = get_uid(__task_cred(t)->user); 225 user = get_uid(__task_cred(t)->user);
227 atomic_inc(&user->sigpending); 226 atomic_inc(&user->sigpending);
227 rcu_read_unlock();
228 228
229 if (override_rlimit || 229 if (override_rlimit ||
230 atomic_read(&user->sigpending) <= 230 atomic_read(&user->sigpending) <=
@@ -1179,11 +1179,12 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
1179 int ret = -EINVAL; 1179 int ret = -EINVAL;
1180 struct task_struct *p; 1180 struct task_struct *p;
1181 const struct cred *pcred; 1181 const struct cred *pcred;
1182 unsigned long flags;
1182 1183
1183 if (!valid_signal(sig)) 1184 if (!valid_signal(sig))
1184 return ret; 1185 return ret;
1185 1186
1186 read_lock(&tasklist_lock); 1187 rcu_read_lock();
1187 p = pid_task(pid, PIDTYPE_PID); 1188 p = pid_task(pid, PIDTYPE_PID);
1188 if (!p) { 1189 if (!p) {
1189 ret = -ESRCH; 1190 ret = -ESRCH;
@@ -1199,14 +1200,16 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
1199 ret = security_task_kill(p, info, sig, secid); 1200 ret = security_task_kill(p, info, sig, secid);
1200 if (ret) 1201 if (ret)
1201 goto out_unlock; 1202 goto out_unlock;
1202 if (sig && p->sighand) { 1203
1203 unsigned long flags; 1204 if (sig) {
1204 spin_lock_irqsave(&p->sighand->siglock, flags); 1205 if (lock_task_sighand(p, &flags)) {
1205 ret = __send_signal(sig, info, p, 1, 0); 1206 ret = __send_signal(sig, info, p, 1, 0);
1206 spin_unlock_irqrestore(&p->sighand->siglock, flags); 1207 unlock_task_sighand(p, &flags);
1208 } else
1209 ret = -ESRCH;
1207 } 1210 }
1208out_unlock: 1211out_unlock:
1209 read_unlock(&tasklist_lock); 1212 rcu_read_unlock();
1210 return ret; 1213 return ret;
1211} 1214}
1212EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); 1215EXPORT_SYMBOL_GPL(kill_pid_info_as_uid);
diff --git a/kernel/sys.c b/kernel/sys.c
index 20ccfb5da6af..26a6b73a6b85 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -162,6 +162,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
162 if (niceval > 19) 162 if (niceval > 19)
163 niceval = 19; 163 niceval = 19;
164 164
165 rcu_read_lock();
165 read_lock(&tasklist_lock); 166 read_lock(&tasklist_lock);
166 switch (which) { 167 switch (which) {
167 case PRIO_PROCESS: 168 case PRIO_PROCESS:
@@ -199,6 +200,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
199 } 200 }
200out_unlock: 201out_unlock:
201 read_unlock(&tasklist_lock); 202 read_unlock(&tasklist_lock);
203 rcu_read_unlock();
202out: 204out:
203 return error; 205 return error;
204} 206}