History

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()

Linus Torvalds committed 16 years ago

Commit 10e54532 parents 3cd312c d4581a22 files · +16 −11Browse files

Unified · Split

2 files
  1. kernel/signal.c +14 −11
  2. kernel/sys.c +2 −0
kernel/signal.c+14−11
@@ -218,13 +218,13 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t flags, int override_rlimi · 217 unmodified lines
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 us221 * Protect access to @t credentials. This can go away when all
222 * because changing it requires RCU be used, and if t != current, the222 * 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, · 948 unmodified lines
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, · 9 unmodified lines
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);
kernel/sys.c+2−0
@@ -162,6 +162,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) · 161 unmodified lines
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) · 31 unmodified lines
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}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t