aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c60
1 files changed, 39 insertions, 21 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index e9afe63da24..8e95855ff3c 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -179,6 +179,11 @@ int next_signal(struct sigpending *pending, sigset_t *mask)
179 return sig; 179 return sig;
180} 180}
181 181
182/*
183 * allocate a new signal queue record
184 * - this may be called without locks if and only if t == current, otherwise an
185 * appopriate lock must be held to stop the target task from exiting
186 */
182static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags, 187static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
183 int override_rlimit) 188 int override_rlimit)
184{ 189{
@@ -186,11 +191,12 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
186 struct user_struct *user; 191 struct user_struct *user;
187 192
188 /* 193 /*
189 * In order to avoid problems with "switch_user()", we want to make 194 * We won't get problems with the target's UID changing under us
190 * sure that the compiler doesn't re-load "t->user" 195 * because changing it requires RCU be used, and if t != current, the
196 * caller must be holding the RCU readlock (by way of a spinlock) and
197 * we use RCU protection here
191 */ 198 */
192 user = t->user; 199 user = get_uid(__task_cred(t)->user);
193 barrier();
194 atomic_inc(&user->sigpending); 200 atomic_inc(&user->sigpending);
195 if (override_rlimit || 201 if (override_rlimit ||
196 atomic_read(&user->sigpending) <= 202 atomic_read(&user->sigpending) <=
@@ -198,12 +204,14 @@ static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags,
198 q = kmem_cache_alloc(sigqueue_cachep, flags); 204 q = kmem_cache_alloc(sigqueue_cachep, flags);
199 if (unlikely(q == NULL)) { 205 if (unlikely(q == NULL)) {
200 atomic_dec(&user->sigpending); 206 atomic_dec(&user->sigpending);
207 free_uid(user);
201 } else { 208 } else {
202 INIT_LIST_HEAD(&q->list); 209 INIT_LIST_HEAD(&q->list);
203 q->flags = 0; 210 q->flags = 0;
204 q->user = get_uid(user); 211 q->user = user;
205 } 212 }
206 return(q); 213
214 return q;
207} 215}
208 216
209static void __sigqueue_free(struct sigqueue *q) 217static void __sigqueue_free(struct sigqueue *q)
@@ -564,10 +572,12 @@ static int rm_from_queue(unsigned long mask, struct sigpending *s)
564 572
565/* 573/*
566 * Bad permissions for sending the signal 574 * Bad permissions for sending the signal
575 * - the caller must hold at least the RCU read lock
567 */ 576 */
568static int check_kill_permission(int sig, struct siginfo *info, 577static int check_kill_permission(int sig, struct siginfo *info,
569 struct task_struct *t) 578 struct task_struct *t)
570{ 579{
580 const struct cred *cred = current_cred(), *tcred;
571 struct pid *sid; 581 struct pid *sid;
572 int error; 582 int error;
573 583
@@ -581,8 +591,11 @@ static int check_kill_permission(int sig, struct siginfo *info,
581 if (error) 591 if (error)
582 return error; 592 return error;
583 593
584 if ((current->euid ^ t->suid) && (current->euid ^ t->uid) && 594 tcred = __task_cred(t);
585 (current->uid ^ t->suid) && (current->uid ^ t->uid) && 595 if ((cred->euid ^ tcred->suid) &&
596 (cred->euid ^ tcred->uid) &&
597 (cred->uid ^ tcred->suid) &&
598 (cred->uid ^ tcred->uid) &&
586 !capable(CAP_KILL)) { 599 !capable(CAP_KILL)) {
587 switch (sig) { 600 switch (sig) {
588 case SIGCONT: 601 case SIGCONT:
@@ -846,7 +859,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
846 q->info.si_errno = 0; 859 q->info.si_errno = 0;
847 q->info.si_code = SI_USER; 860 q->info.si_code = SI_USER;
848 q->info.si_pid = task_pid_vnr(current); 861 q->info.si_pid = task_pid_vnr(current);
849 q->info.si_uid = current->uid; 862 q->info.si_uid = current_uid();
850 break; 863 break;
851 case (unsigned long) SEND_SIG_PRIV: 864 case (unsigned long) SEND_SIG_PRIV:
852 q->info.si_signo = sig; 865 q->info.si_signo = sig;
@@ -1010,6 +1023,10 @@ struct sighand_struct *lock_task_sighand(struct task_struct *tsk, unsigned long
1010 return sighand; 1023 return sighand;
1011} 1024}
1012 1025
1026/*
1027 * send signal info to all the members of a group
1028 * - the caller must hold the RCU read lock at least
1029 */
1013int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) 1030int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
1014{ 1031{
1015 unsigned long flags; 1032 unsigned long flags;
@@ -1031,8 +1048,8 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
1031/* 1048/*
1032 * __kill_pgrp_info() sends a signal to a process group: this is what the tty 1049 * __kill_pgrp_info() sends a signal to a process group: this is what the tty
1033 * control characters do (^C, ^Z etc) 1050 * control characters do (^C, ^Z etc)
1051 * - the caller must hold at least a readlock on tasklist_lock
1034 */ 1052 */
1035
1036int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp) 1053int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
1037{ 1054{
1038 struct task_struct *p = NULL; 1055 struct task_struct *p = NULL;
@@ -1088,6 +1105,7 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
1088{ 1105{
1089 int ret = -EINVAL; 1106 int ret = -EINVAL;
1090 struct task_struct *p; 1107 struct task_struct *p;
1108 const struct cred *pcred;
1091 1109
1092 if (!valid_signal(sig)) 1110 if (!valid_signal(sig))
1093 return ret; 1111 return ret;
@@ -1098,9 +1116,11 @@ int kill_pid_info_as_uid(int sig, struct siginfo *info, struct pid *pid,
1098 ret = -ESRCH; 1116 ret = -ESRCH;
1099 goto out_unlock; 1117 goto out_unlock;
1100 } 1118 }
1101 if ((info == SEND_SIG_NOINFO || (!is_si_special(info) && SI_FROMUSER(info))) 1119 pcred = __task_cred(p);
1102 && (euid != p->suid) && (euid != p->uid) 1120 if ((info == SEND_SIG_NOINFO ||
1103 && (uid != p->suid) && (uid != p->uid)) { 1121 (!is_si_special(info) && SI_FROMUSER(info))) &&
1122 euid != pcred->suid && euid != pcred->uid &&
1123 uid != pcred->suid && uid != pcred->uid) {
1104 ret = -EPERM; 1124 ret = -EPERM;
1105 goto out_unlock; 1125 goto out_unlock;
1106 } 1126 }
@@ -1371,10 +1391,9 @@ int do_notify_parent(struct task_struct *tsk, int sig)
1371 */ 1391 */
1372 rcu_read_lock(); 1392 rcu_read_lock();
1373 info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns); 1393 info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
1394 info.si_uid = __task_cred(tsk)->uid;
1374 rcu_read_unlock(); 1395 rcu_read_unlock();
1375 1396
1376 info.si_uid = tsk->uid;
1377
1378 thread_group_cputime(tsk, &cputime); 1397 thread_group_cputime(tsk, &cputime);
1379 info.si_utime = cputime_to_jiffies(cputime.utime); 1398 info.si_utime = cputime_to_jiffies(cputime.utime);
1380 info.si_stime = cputime_to_jiffies(cputime.stime); 1399 info.si_stime = cputime_to_jiffies(cputime.stime);
@@ -1442,10 +1461,9 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why)
1442 */ 1461 */
1443 rcu_read_lock(); 1462 rcu_read_lock();
1444 info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns); 1463 info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns);
1464 info.si_uid = __task_cred(tsk)->uid;
1445 rcu_read_unlock(); 1465 rcu_read_unlock();
1446 1466
1447 info.si_uid = tsk->uid;
1448
1449 info.si_utime = cputime_to_clock_t(tsk->utime); 1467 info.si_utime = cputime_to_clock_t(tsk->utime);
1450 info.si_stime = cputime_to_clock_t(tsk->stime); 1468 info.si_stime = cputime_to_clock_t(tsk->stime);
1451 1469
@@ -1600,7 +1618,7 @@ void ptrace_notify(int exit_code)
1600 info.si_signo = SIGTRAP; 1618 info.si_signo = SIGTRAP;
1601 info.si_code = exit_code; 1619 info.si_code = exit_code;
1602 info.si_pid = task_pid_vnr(current); 1620 info.si_pid = task_pid_vnr(current);
1603 info.si_uid = current->uid; 1621 info.si_uid = current_uid();
1604 1622
1605 /* Let the debugger run. */ 1623 /* Let the debugger run. */
1606 spin_lock_irq(&current->sighand->siglock); 1624 spin_lock_irq(&current->sighand->siglock);
@@ -1712,7 +1730,7 @@ static int ptrace_signal(int signr, siginfo_t *info,
1712 info->si_errno = 0; 1730 info->si_errno = 0;
1713 info->si_code = SI_USER; 1731 info->si_code = SI_USER;
1714 info->si_pid = task_pid_vnr(current->parent); 1732 info->si_pid = task_pid_vnr(current->parent);
1715 info->si_uid = current->parent->uid; 1733 info->si_uid = task_uid(current->parent);
1716 } 1734 }
1717 1735
1718 /* If the (new) signal is now blocked, requeue it. */ 1736 /* If the (new) signal is now blocked, requeue it. */
@@ -2213,7 +2231,7 @@ sys_kill(pid_t pid, int sig)
2213 info.si_errno = 0; 2231 info.si_errno = 0;
2214 info.si_code = SI_USER; 2232 info.si_code = SI_USER;
2215 info.si_pid = task_tgid_vnr(current); 2233 info.si_pid = task_tgid_vnr(current);
2216 info.si_uid = current->uid; 2234 info.si_uid = current_uid();
2217 2235
2218 return kill_something_info(sig, &info, pid); 2236 return kill_something_info(sig, &info, pid);
2219} 2237}
@@ -2230,7 +2248,7 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig)
2230 info.si_errno = 0; 2248 info.si_errno = 0;
2231 info.si_code = SI_TKILL; 2249 info.si_code = SI_TKILL;
2232 info.si_pid = task_tgid_vnr(current); 2250 info.si_pid = task_tgid_vnr(current);
2233 info.si_uid = current->uid; 2251 info.si_uid = current_uid();
2234 2252
2235 rcu_read_lock(); 2253 rcu_read_lock();
2236 p = find_task_by_vpid(pid); 2254 p = find_task_by_vpid(pid);