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
218218 struct user_struct *user;
219219
220220 /*
221− * We won't get problems with the target's UID changing under us
222− * because changing it requires RCU be used, and if t != current, the
223− * caller must be holding the RCU readlock (by way of a spinlock) and
224− * we use RCU protection here
221+ * Protect access to @t credentials. This can go away when all
222+ * callers hold rcu read lock.
225223 */
224+ rcu_read_lock();
226225 user = get_uid(__task_cred(t)->user);
227226 atomic_inc(&user->sigpending);
227+ rcu_read_unlock();
228228
229229 if (override_rlimit ||
230230 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
11791179 int ret = -EINVAL;
11801180 struct task_struct *p;
11811181 const struct cred *pcred;
1182+ unsigned long flags;
11821183
11831184 if (!valid_signal(sig))
11841185 return ret;
11851186
1186− read_lock(&tasklist_lock);
1187+ rcu_read_lock();
11871188 p = pid_task(pid, PIDTYPE_PID);
11881189 if (!p) {
11891190 ret = -ESRCH;
@@ -1199,14 +1200,16 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid, · 9 unmodified lines
11991200 ret = security_task_kill(p, info, sig, secid);
12001201 if (ret)
12011202 goto out_unlock;
1202− if (sig && p->sighand) {
1203− unsigned long flags;
1204− spin_lock_irqsave(&p->sighand->siglock, flags);
1205− ret = __send_signal(sig, info, p, 1, 0);
1206− spin_unlock_irqrestore(&p->sighand->siglock, flags);
1203+
1204+ if (sig) {
1205+ if (lock_task_sighand(p, &flags)) {
1206+ ret = __send_signal(sig, info, p, 1, 0);
1207+ unlock_task_sighand(p, &flags);
1208+ } else
1209+ ret = -ESRCH;
12071210 }
12081211 out_unlock:
1209− read_unlock(&tasklist_lock);
1212+ rcu_read_unlock();
12101213 return ret;
12111214 }
12121215 EXPORT_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
162162 if (niceval > 19)
163163 niceval = 19;
164164
165+ rcu_read_lock();
165166 read_lock(&tasklist_lock);
166167 switch (which) {
167168 case PRIO_PROCESS:
@@ -199,6 +200,7 @@ SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval) · 31 unmodified lines
199200 }
200201 out_unlock:
201202 read_unlock(&tasklist_lock);
203+ rcu_read_unlock();
202204 out:
203205 return error;
204206 }

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