diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index e4f059cd9867..12006308c7eb 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -256,7 +256,7 @@ flush_signal_handlers(struct task_struct *t, int force_default) | |||
256 | 256 | ||
257 | int unhandled_signal(struct task_struct *tsk, int sig) | 257 | int unhandled_signal(struct task_struct *tsk, int sig) |
258 | { | 258 | { |
259 | if (is_init(tsk)) | 259 | if (is_global_init(tsk)) |
260 | return 1; | 260 | return 1; |
261 | if (tsk->ptrace & PT_PTRACED) | 261 | if (tsk->ptrace & PT_PTRACED) |
262 | return 0; | 262 | return 0; |
@@ -536,7 +536,7 @@ static int check_kill_permission(int sig, struct siginfo *info, | |||
536 | return error; | 536 | return error; |
537 | error = -EPERM; | 537 | error = -EPERM; |
538 | if (((sig != SIGCONT) || | 538 | if (((sig != SIGCONT) || |
539 | (process_session(current) != process_session(t))) | 539 | (task_session_nr(current) != task_session_nr(t))) |
540 | && (current->euid ^ t->suid) && (current->euid ^ t->uid) | 540 | && (current->euid ^ t->suid) && (current->euid ^ t->uid) |
541 | && (current->uid ^ t->suid) && (current->uid ^ t->uid) | 541 | && (current->uid ^ t->suid) && (current->uid ^ t->uid) |
542 | && !capable(CAP_KILL)) | 542 | && !capable(CAP_KILL)) |
@@ -694,7 +694,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t, | |||
694 | q->info.si_signo = sig; | 694 | q->info.si_signo = sig; |
695 | q->info.si_errno = 0; | 695 | q->info.si_errno = 0; |
696 | q->info.si_code = SI_USER; | 696 | q->info.si_code = SI_USER; |
697 | q->info.si_pid = current->pid; | 697 | q->info.si_pid = task_pid_vnr(current); |
698 | q->info.si_uid = current->uid; | 698 | q->info.si_uid = current->uid; |
699 | break; | 699 | break; |
700 | case (unsigned long) SEND_SIG_PRIV: | 700 | case (unsigned long) SEND_SIG_PRIV: |
@@ -730,7 +730,7 @@ int print_fatal_signals; | |||
730 | static void print_fatal_signal(struct pt_regs *regs, int signr) | 730 | static void print_fatal_signal(struct pt_regs *regs, int signr) |
731 | { | 731 | { |
732 | printk("%s/%d: potentially unexpected fatal signal %d.\n", | 732 | printk("%s/%d: potentially unexpected fatal signal %d.\n", |
733 | current->comm, current->pid, signr); | 733 | current->comm, task_pid_nr(current), signr); |
734 | 734 | ||
735 | #ifdef __i386__ | 735 | #ifdef __i386__ |
736 | printk("code at %08lx: ", regs->eip); | 736 | printk("code at %08lx: ", regs->eip); |
@@ -1089,7 +1089,7 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid) | |||
1089 | { | 1089 | { |
1090 | int error; | 1090 | int error; |
1091 | rcu_read_lock(); | 1091 | rcu_read_lock(); |
1092 | error = kill_pid_info(sig, info, find_pid(pid)); | 1092 | error = kill_pid_info(sig, info, find_vpid(pid)); |
1093 | rcu_read_unlock(); | 1093 | rcu_read_unlock(); |
1094 | return error; | 1094 | return error; |
1095 | } | 1095 | } |
@@ -1150,7 +1150,7 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) | |||
1150 | 1150 | ||
1151 | read_lock(&tasklist_lock); | 1151 | read_lock(&tasklist_lock); |
1152 | for_each_process(p) { | 1152 | for_each_process(p) { |
1153 | if (p->pid > 1 && p->tgid != current->tgid) { | 1153 | if (p->pid > 1 && !same_thread_group(p, current)) { |
1154 | int err = group_send_sig_info(sig, info, p); | 1154 | int err = group_send_sig_info(sig, info, p); |
1155 | ++count; | 1155 | ++count; |
1156 | if (err != -EPERM) | 1156 | if (err != -EPERM) |
@@ -1160,9 +1160,9 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) | |||
1160 | read_unlock(&tasklist_lock); | 1160 | read_unlock(&tasklist_lock); |
1161 | ret = count ? retval : -ESRCH; | 1161 | ret = count ? retval : -ESRCH; |
1162 | } else if (pid < 0) { | 1162 | } else if (pid < 0) { |
1163 | ret = kill_pgrp_info(sig, info, find_pid(-pid)); | 1163 | ret = kill_pgrp_info(sig, info, find_vpid(-pid)); |
1164 | } else { | 1164 | } else { |
1165 | ret = kill_pid_info(sig, info, find_pid(pid)); | 1165 | ret = kill_pid_info(sig, info, find_vpid(pid)); |
1166 | } | 1166 | } |
1167 | rcu_read_unlock(); | 1167 | rcu_read_unlock(); |
1168 | return ret; | 1168 | return ret; |
@@ -1266,7 +1266,12 @@ EXPORT_SYMBOL(kill_pid); | |||
1266 | int | 1266 | int |
1267 | kill_proc(pid_t pid, int sig, int priv) | 1267 | kill_proc(pid_t pid, int sig, int priv) |
1268 | { | 1268 | { |
1269 | return kill_proc_info(sig, __si_special(priv), pid); | 1269 | int ret; |
1270 | |||
1271 | rcu_read_lock(); | ||
1272 | ret = kill_pid_info(sig, __si_special(priv), find_pid(pid)); | ||
1273 | rcu_read_unlock(); | ||
1274 | return ret; | ||
1270 | } | 1275 | } |
1271 | 1276 | ||
1272 | /* | 1277 | /* |
@@ -1443,7 +1448,22 @@ void do_notify_parent(struct task_struct *tsk, int sig) | |||
1443 | 1448 | ||
1444 | info.si_signo = sig; | 1449 | info.si_signo = sig; |
1445 | info.si_errno = 0; | 1450 | info.si_errno = 0; |
1446 | info.si_pid = tsk->pid; | 1451 | /* |
1452 | * we are under tasklist_lock here so our parent is tied to | ||
1453 | * us and cannot exit and release its namespace. | ||
1454 | * | ||
1455 | * the only it can is to switch its nsproxy with sys_unshare, | ||
1456 | * bu uncharing pid namespaces is not allowed, so we'll always | ||
1457 | * see relevant namespace | ||
1458 | * | ||
1459 | * write_lock() currently calls preempt_disable() which is the | ||
1460 | * same as rcu_read_lock(), but according to Oleg, this is not | ||
1461 | * correct to rely on this | ||
1462 | */ | ||
1463 | rcu_read_lock(); | ||
1464 | info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns); | ||
1465 | rcu_read_unlock(); | ||
1466 | |||
1447 | info.si_uid = tsk->uid; | 1467 | info.si_uid = tsk->uid; |
1448 | 1468 | ||
1449 | /* FIXME: find out whether or not this is supposed to be c*time. */ | 1469 | /* FIXME: find out whether or not this is supposed to be c*time. */ |
@@ -1508,7 +1528,13 @@ static void do_notify_parent_cldstop(struct task_struct *tsk, int why) | |||
1508 | 1528 | ||
1509 | info.si_signo = SIGCHLD; | 1529 | info.si_signo = SIGCHLD; |
1510 | info.si_errno = 0; | 1530 | info.si_errno = 0; |
1511 | info.si_pid = tsk->pid; | 1531 | /* |
1532 | * see comment in do_notify_parent() abot the following 3 lines | ||
1533 | */ | ||
1534 | rcu_read_lock(); | ||
1535 | info.si_pid = task_pid_nr_ns(tsk, tsk->parent->nsproxy->pid_ns); | ||
1536 | rcu_read_unlock(); | ||
1537 | |||
1512 | info.si_uid = tsk->uid; | 1538 | info.si_uid = tsk->uid; |
1513 | 1539 | ||
1514 | /* FIXME: find out whether or not this is supposed to be c*time. */ | 1540 | /* FIXME: find out whether or not this is supposed to be c*time. */ |
@@ -1634,7 +1660,7 @@ void ptrace_notify(int exit_code) | |||
1634 | memset(&info, 0, sizeof info); | 1660 | memset(&info, 0, sizeof info); |
1635 | info.si_signo = SIGTRAP; | 1661 | info.si_signo = SIGTRAP; |
1636 | info.si_code = exit_code; | 1662 | info.si_code = exit_code; |
1637 | info.si_pid = current->pid; | 1663 | info.si_pid = task_pid_vnr(current); |
1638 | info.si_uid = current->uid; | 1664 | info.si_uid = current->uid; |
1639 | 1665 | ||
1640 | /* Let the debugger run. */ | 1666 | /* Let the debugger run. */ |
@@ -1804,7 +1830,7 @@ relock: | |||
1804 | info->si_signo = signr; | 1830 | info->si_signo = signr; |
1805 | info->si_errno = 0; | 1831 | info->si_errno = 0; |
1806 | info->si_code = SI_USER; | 1832 | info->si_code = SI_USER; |
1807 | info->si_pid = current->parent->pid; | 1833 | info->si_pid = task_pid_vnr(current->parent); |
1808 | info->si_uid = current->parent->uid; | 1834 | info->si_uid = current->parent->uid; |
1809 | } | 1835 | } |
1810 | 1836 | ||
@@ -1835,11 +1861,9 @@ relock: | |||
1835 | continue; | 1861 | continue; |
1836 | 1862 | ||
1837 | /* | 1863 | /* |
1838 | * Init of a pid space gets no signals it doesn't want from | 1864 | * Global init gets no signals it doesn't want. |
1839 | * within that pid space. It can of course get signals from | ||
1840 | * its parent pid space. | ||
1841 | */ | 1865 | */ |
1842 | if (current == child_reaper(current)) | 1866 | if (is_global_init(current)) |
1843 | continue; | 1867 | continue; |
1844 | 1868 | ||
1845 | if (sig_kernel_stop(signr)) { | 1869 | if (sig_kernel_stop(signr)) { |
@@ -2193,7 +2217,7 @@ sys_kill(int pid, int sig) | |||
2193 | info.si_signo = sig; | 2217 | info.si_signo = sig; |
2194 | info.si_errno = 0; | 2218 | info.si_errno = 0; |
2195 | info.si_code = SI_USER; | 2219 | info.si_code = SI_USER; |
2196 | info.si_pid = current->tgid; | 2220 | info.si_pid = task_tgid_vnr(current); |
2197 | info.si_uid = current->uid; | 2221 | info.si_uid = current->uid; |
2198 | 2222 | ||
2199 | return kill_something_info(sig, &info, pid); | 2223 | return kill_something_info(sig, &info, pid); |
@@ -2209,12 +2233,12 @@ static int do_tkill(int tgid, int pid, int sig) | |||
2209 | info.si_signo = sig; | 2233 | info.si_signo = sig; |
2210 | info.si_errno = 0; | 2234 | info.si_errno = 0; |
2211 | info.si_code = SI_TKILL; | 2235 | info.si_code = SI_TKILL; |
2212 | info.si_pid = current->tgid; | 2236 | info.si_pid = task_tgid_vnr(current); |
2213 | info.si_uid = current->uid; | 2237 | info.si_uid = current->uid; |
2214 | 2238 | ||
2215 | read_lock(&tasklist_lock); | 2239 | read_lock(&tasklist_lock); |
2216 | p = find_task_by_pid(pid); | 2240 | p = find_task_by_vpid(pid); |
2217 | if (p && (tgid <= 0 || p->tgid == tgid)) { | 2241 | if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) { |
2218 | error = check_kill_permission(sig, &info, p); | 2242 | error = check_kill_permission(sig, &info, p); |
2219 | /* | 2243 | /* |
2220 | * The null signal is a permissions and process existence | 2244 | * The null signal is a permissions and process existence |