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