diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 52 |
1 files changed, 39 insertions, 13 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 98923882ba57..d809cdd6c0f1 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -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: |
@@ -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 | } |
@@ -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 | ||
@@ -2191,7 +2217,7 @@ sys_kill(int pid, int sig) | |||
2191 | info.si_signo = sig; | 2217 | info.si_signo = sig; |
2192 | info.si_errno = 0; | 2218 | info.si_errno = 0; |
2193 | info.si_code = SI_USER; | 2219 | info.si_code = SI_USER; |
2194 | info.si_pid = current->tgid; | 2220 | info.si_pid = task_tgid_vnr(current); |
2195 | info.si_uid = current->uid; | 2221 | info.si_uid = current->uid; |
2196 | 2222 | ||
2197 | return kill_something_info(sig, &info, pid); | 2223 | return kill_something_info(sig, &info, pid); |
@@ -2207,12 +2233,12 @@ static int do_tkill(int tgid, int pid, int sig) | |||
2207 | info.si_signo = sig; | 2233 | info.si_signo = sig; |
2208 | info.si_errno = 0; | 2234 | info.si_errno = 0; |
2209 | info.si_code = SI_TKILL; | 2235 | info.si_code = SI_TKILL; |
2210 | info.si_pid = current->tgid; | 2236 | info.si_pid = task_tgid_vnr(current); |
2211 | info.si_uid = current->uid; | 2237 | info.si_uid = current->uid; |
2212 | 2238 | ||
2213 | read_lock(&tasklist_lock); | 2239 | read_lock(&tasklist_lock); |
2214 | p = find_task_by_pid(pid); | 2240 | p = find_task_by_pid_ns(pid, current->nsproxy->pid_ns); |
2215 | if (p && (tgid <= 0 || p->tgid == tgid)) { | 2241 | if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) { |
2216 | error = check_kill_permission(sig, &info, p); | 2242 | error = check_kill_permission(sig, &info, p); |
2217 | /* | 2243 | /* |
2218 | * The null signal is a permissions and process existence | 2244 | * The null signal is a permissions and process existence |