aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-10-19 02:40:14 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-19 14:53:40 -0400
commitb488893a390edfe027bae7a46e9af8083e740668 (patch)
treec469a7f99ad01005a73011c029eb5e5d15454559 /kernel/signal.c
parent3eb07c8c8adb6f0572baba844ba2d9e501654316 (diff)
pid namespaces: changes to show virtual ids to user
This is the largest patch in the set. Make all (I hope) the places where the pid is shown to or get from user operate on the virtual pids. The idea is: - all in-kernel data structures must store either struct pid itself or the pid's global nr, obtained with pid_nr() call; - when seeking the task from kernel code with the stored id one should use find_task_by_pid() call that works with global pids; - when showing pid's numerical value to the user the virtual one should be used, but however when one shows task's pid outside this task's namespace the global one is to be used; - when getting the pid from userspace one need to consider this as the virtual one and use appropriate task/pid-searching functions. [akpm@linux-foundation.org: build fix] [akpm@linux-foundation.org: nuther build fix] [akpm@linux-foundation.org: yet nuther build fix] [akpm@linux-foundation.org: remove unneeded casts] Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Alexey Dobriyan <adobriyan@openvz.org> Cc: Sukadev Bhattiprolu <sukadev@us.ibm.com> Cc: Oleg Nesterov <oleg@tv-sign.ru> Cc: Paul Menage <menage@google.com> Cc: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c52
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);
1266int 1266int
1267kill_proc(pid_t pid, int sig, int priv) 1267kill_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