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 e9afe63da24b..8e95855ff3cf 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 | */ | ||
182 | static struct sigqueue *__sigqueue_alloc(struct task_struct *t, gfp_t flags, | 187 | static 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 | ||
209 | static void __sigqueue_free(struct sigqueue *q) | 217 | static 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 | */ |
568 | static int check_kill_permission(int sig, struct siginfo *info, | 577 | static 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 | */ | ||
1013 | int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p) | 1030 | int 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 | |||
1036 | int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp) | 1053 | int __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(¤t->sighand->siglock); | 1624 | spin_lock_irq(¤t->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); |