Subject: [PATCH] Generalize killing all processes to work in process groups, and to work From: Eric W. Biederman Date: 1129507113 -0600 externall from the process group. --- kernel/signal.c | 71 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 files changed, 57 insertions(+), 14 deletions(-) 46d02452455338e61ece83d77172cfc8a0ac16a6 diff --git a/kernel/signal.c b/kernel/signal.c index 5b89b8f..8228f81 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1145,6 +1145,51 @@ int group_send_sig_info(int sig, struct } /* + * kill_pspace_info() sends a signal to all processes in a process id space. + * This is what kill(-1, sig) does. + */ + +int __kill_pspace_info(int sig, struct siginfo *info, pid_t pspaceid) +{ + struct task_struct *p = NULL; + struct pspace *pspace; + pid_t min, max; + int retval = 0, count = 0; + + p = find_task_by_pid_type(PIDTYPE_TGID, pspaceid); + if (!p || (p->tgid != (p->pspace->offset + 1))) + return -ESRCH; + + pspace = p->pspace; + min = pspace->offset; + max = pspace->offset + pspace->max; + + for_each_process(p) { + if ((p->pid != current->pspace->offset + 1) && (p->tgid != current->tgid) && + (p->pid > min) && (p->pid < max)) + { + int err = group_send_sig_info(sig, info, p); + ++count; + if (err != -EPERM) + retval = err; + } + } + return count ? retval : -ESRCH; +} + +int +kill_pspace_info(int sig, struct siginfo *info, pid_t pspaceid) +{ + int retval; + + read_lock(&tasklist_lock); + retval = __kill_pspace_info(sig, info, pspaceid); + read_unlock(&tasklist_lock); + + return retval; +} + +/* * kill_pg_info() sends a signal to a process group: this is what the tty * control characters do (^C, ^Z etc) */ @@ -1200,29 +1245,27 @@ kill_proc_info(int sig, struct siginfo * * * POSIX specifies that kill(-1,sig) is unspecified, but what we have * is probably wrong. Should make it like BSD or SYSV. + * + * This has been extended to treak all process spaces just like kill(-1, sig) */ static int kill_something_info(int sig, struct siginfo *info, int pid) { if (!pid) { return kill_pg_info(sig, info, process_group(current)); - } else if (pid == -1) { - int retval = 0, count = 0; - struct task_struct * p; + } else if (pid < 0) { + struct task_struct *p; + int retval; + pid = pid_from_user(-pid); read_lock(&tasklist_lock); - for_each_process(p) { - if (p->pid > 1 && p->tgid != current->tgid && pid_visible(p)) { - int err = group_send_sig_info(sig, info, p); - ++count; - if (err != -EPERM) - retval = err; - } - } + p = find_task_by_pid_type(PIDTYPE_TGID, pid); + if (likely(!p || (p->tgid != (p->pspace->offset + 1)))) + retval = __kill_pg_info(sig, info, pid); + else + retval = __kill_pspace_info(sig, info, pid); read_unlock(&tasklist_lock); - return count ? retval : -ESRCH; - } else if (pid < 0) { - return kill_pg_info(sig, info, pid_from_user(-pid)); + return retval; } else { return kill_proc_info(sig, info, pid_from_user(pid)); } -- 1.0.GIT