}
static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struct *t,
- enum pid_type type, int from_ancestor_ns)
+ enum pid_type type, bool force)
{
struct sigpending *pending;
struct sigqueue *q;
assert_spin_locked(&t->sighand->siglock);
result = TRACE_SIGNAL_IGNORED;
- if (!prepare_signal(sig, t,
- from_ancestor_ns || (info == SEND_SIG_PRIV)))
+ if (!prepare_signal(sig, t, force))
goto ret;
pending = (type != PIDTYPE_PID) ? &t->signal->shared_pending : &t->pending;
static int send_signal(int sig, struct kernel_siginfo *info, struct task_struct *t,
enum pid_type type)
{
- int from_ancestor_ns = 0;
-
-#ifdef CONFIG_PID_NS
- from_ancestor_ns = si_fromuser(info) &&
- !task_pid_nr_ns(current, task_active_pid_ns(t));
-#endif
- if (!is_si_special(info) && has_si_pid_and_uid(info)) {
+ /* Should SIGKILL or SIGSTOP be received by a pid namespace init? */
+ bool force = false;
+
+ if (info == SEND_SIG_NOINFO) {
+ /* Force if sent from an ancestor pid namespace */
+ force = !task_pid_nr_ns(current, task_active_pid_ns(t));
+ } else if (info == SEND_SIG_PRIV) {
+ /* Don't ignore kernel generated signals */
+ force = true;
+ } else if (has_si_pid_and_uid(info)) {
+ /* SIGKILL and SIGSTOP is special or has ids */
struct user_namespace *t_user_ns;
rcu_read_lock();
}
rcu_read_unlock();
- if (!task_pid_nr_ns(current, task_active_pid_ns(t)))
+ /* A kernel generated signal? */
+ force = (info->si_code == SI_KERNEL);
+
+ /* From an ancestor pid namespace? */
+ if (!task_pid_nr_ns(current, task_active_pid_ns(t))) {
info->si_pid = 0;
+ force = true;
+ }
}
- return __send_signal(sig, info, t, type, from_ancestor_ns);
+ return __send_signal(sig, info, t, type, force);
}
static void print_fatal_signal(int signr)
if (sig) {
if (lock_task_sighand(p, &flags)) {
- ret = __send_signal(sig, &info, p, PIDTYPE_TGID, 0);
+ ret = __send_signal(sig, &info, p, PIDTYPE_TGID, false);
unlock_task_sighand(p, &flags);
} else
ret = -ESRCH;