Merge tag 'pidfd-updates-v5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/braun...
[sfrench/cifs-2.6.git] / kernel / signal.c
index edf8915ddd5432b7c93c201808865a612576dff4..dabe100d209191cb6b15a6f80910e92b28553f11 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/posix-timers.h>
 #include <linux/livepatch.h>
 #include <linux/cgroup.h>
+#include <linux/audit.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/signal.h>
@@ -54,7 +55,6 @@
 #include <asm/unistd.h>
 #include <asm/siginfo.h>
 #include <asm/cacheflush.h>
-#include "audit.h"     /* audit_signal_info() */
 
 /*
  * SLAB caches for signal bits.
@@ -1057,29 +1057,8 @@ static inline bool legacy_queue(struct sigpending *signals, int sig)
        return (sig < SIGRTMIN) && sigismember(&signals->signal, sig);
 }
 
-#ifdef CONFIG_USER_NS
-static inline void userns_fixup_signal_uid(struct kernel_siginfo *info, struct task_struct *t)
-{
-       if (current_user_ns() == task_cred_xxx(t, user_ns))
-               return;
-
-       if (SI_FROMKERNEL(info))
-               return;
-
-       rcu_read_lock();
-       info->si_uid = from_kuid_munged(task_cred_xxx(t, user_ns),
-                                       make_kuid(current_user_ns(), info->si_uid));
-       rcu_read_unlock();
-}
-#else
-static inline void userns_fixup_signal_uid(struct kernel_siginfo *info, struct task_struct *t)
-{
-       return;
-}
-#endif
-
 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;
@@ -1089,8 +1068,7 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc
        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;
@@ -1135,7 +1113,11 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc
                        q->info.si_code = SI_USER;
                        q->info.si_pid = task_tgid_nr_ns(current,
                                                        task_active_pid_ns(t));
-                       q->info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
+                       rcu_read_lock();
+                       q->info.si_uid =
+                               from_kuid_munged(task_cred_xxx(t, user_ns),
+                                                current_uid());
+                       rcu_read_unlock();
                        break;
                case (unsigned long) SEND_SIG_PRIV:
                        clear_siginfo(&q->info);
@@ -1147,30 +1129,24 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc
                        break;
                default:
                        copy_siginfo(&q->info, info);
-                       if (from_ancestor_ns)
-                               q->info.si_pid = 0;
                        break;
                }
-
-               userns_fixup_signal_uid(&q->info, t);
-
-       } else if (!is_si_special(info)) {
-               if (sig >= SIGRTMIN && info->si_code != SI_USER) {
-                       /*
-                        * Queue overflow, abort.  We may abort if the
-                        * signal was rt and sent by user using something
-                        * other than kill().
-                        */
-                       result = TRACE_SIGNAL_OVERFLOW_FAIL;
-                       ret = -EAGAIN;
-                       goto ret;
-               } else {
-                       /*
-                        * This is a silent loss of information.  We still
-                        * send the signal, but the *info bits are lost.
-                        */
-                       result = TRACE_SIGNAL_LOSE_INFO;
-               }
+       } else if (!is_si_special(info) &&
+                  sig >= SIGRTMIN && info->si_code != SI_USER) {
+               /*
+                * Queue overflow, abort.  We may abort if the
+                * signal was rt and sent by user using something
+                * other than kill().
+                */
+               result = TRACE_SIGNAL_OVERFLOW_FAIL;
+               ret = -EAGAIN;
+               goto ret;
+       } else {
+               /*
+                * This is a silent loss of information.  We still
+                * send the signal, but the *info bits are lost.
+                */
+               result = TRACE_SIGNAL_LOSE_INFO;
        }
 
 out_set:
@@ -1197,17 +1173,62 @@ ret:
        return ret;
 }
 
+static inline bool has_si_pid_and_uid(struct kernel_siginfo *info)
+{
+       bool ret = false;
+       switch (siginfo_layout(info->si_signo, info->si_code)) {
+       case SIL_KILL:
+       case SIL_CHLD:
+       case SIL_RT:
+               ret = true;
+               break;
+       case SIL_TIMER:
+       case SIL_POLL:
+       case SIL_FAULT:
+       case SIL_FAULT_MCEERR:
+       case SIL_FAULT_BNDERR:
+       case SIL_FAULT_PKUERR:
+       case SIL_SYS:
+               ret = false;
+               break;
+       }
+       return ret;
+}
+
 static int send_signal(int sig, struct kernel_siginfo *info, struct task_struct *t,
                        enum pid_type type)
 {
-       int from_ancestor_ns = 0;
+       /* Should SIGKILL or SIGSTOP be received by a pid namespace init? */
+       bool force = false;
 
-#ifdef CONFIG_PID_NS
-       from_ancestor_ns = si_fromuser(info) &&
-                          !task_pid_nr_ns(current, task_active_pid_ns(t));
-#endif
+       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();
+               t_user_ns = task_cred_xxx(t, user_ns);
+               if (current_user_ns() != t_user_ns) {
+                       kuid_t uid = make_kuid(current_user_ns(), info->si_uid);
+                       info->si_uid = from_kuid_munged(t_user_ns, uid);
+               }
+               rcu_read_unlock();
 
-       return __send_signal(sig, info, t, type, from_ancestor_ns);
+               /* 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, force);
 }
 
 static void print_fatal_signal(int signr)
@@ -1274,12 +1295,13 @@ int do_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p
  * We don't want to have recursive SIGSEGV's etc, for example,
  * that is why we also clear SIGNAL_UNKILLABLE.
  */
-int
-force_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *t)
+static int
+force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t)
 {
        unsigned long int flags;
        int ret, blocked, ignored;
        struct k_sigaction *action;
+       int sig = info->si_signo;
 
        spin_lock_irqsave(&t->sighand->siglock, flags);
        action = &t->sighand->action[sig-1];
@@ -1304,6 +1326,11 @@ force_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *t)
        return ret;
 }
 
+int force_sig_info(struct kernel_siginfo *info)
+{
+       return force_sig_info_to_task(info, current);
+}
+
 /*
  * Nuke all other threads in the group.
  */
@@ -1440,13 +1467,44 @@ static inline bool kill_as_cred_perm(const struct cred *cred,
               uid_eq(cred->uid, pcred->uid);
 }
 
-/* like kill_pid_info(), but doesn't use uid/euid of "current" */
-int kill_pid_info_as_cred(int sig, struct kernel_siginfo *info, struct pid *pid,
-                        const struct cred *cred)
+/*
+ * The usb asyncio usage of siginfo is wrong.  The glibc support
+ * for asyncio which uses SI_ASYNCIO assumes the layout is SIL_RT.
+ * AKA after the generic fields:
+ *     kernel_pid_t    si_pid;
+ *     kernel_uid32_t  si_uid;
+ *     sigval_t        si_value;
+ *
+ * Unfortunately when usb generates SI_ASYNCIO it assumes the layout
+ * after the generic fields is:
+ *     void __user     *si_addr;
+ *
+ * This is a practical problem when there is a 64bit big endian kernel
+ * and a 32bit userspace.  As the 32bit address will encoded in the low
+ * 32bits of the pointer.  Those low 32bits will be stored at higher
+ * address than appear in a 32 bit pointer.  So userspace will not
+ * see the address it was expecting for it's completions.
+ *
+ * There is nothing in the encoding that can allow
+ * copy_siginfo_to_user32 to detect this confusion of formats, so
+ * handle this by requiring the caller of kill_pid_usb_asyncio to
+ * notice when this situration takes place and to store the 32bit
+ * pointer in sival_int, instead of sival_addr of the sigval_t addr
+ * parameter.
+ */
+int kill_pid_usb_asyncio(int sig, int errno, sigval_t addr,
+                        struct pid *pid, const struct cred *cred)
 {
-       int ret = -EINVAL;
+       struct kernel_siginfo info;
        struct task_struct *p;
        unsigned long flags;
+       int ret = -EINVAL;
+
+       clear_siginfo(&info);
+       info.si_signo = sig;
+       info.si_errno = errno;
+       info.si_code = SI_ASYNCIO;
+       *((sigval_t *)&info.si_pid) = addr;
 
        if (!valid_signal(sig))
                return ret;
@@ -1457,17 +1515,17 @@ int kill_pid_info_as_cred(int sig, struct kernel_siginfo *info, struct pid *pid,
                ret = -ESRCH;
                goto out_unlock;
        }
-       if (si_fromuser(info) && !kill_as_cred_perm(cred, p)) {
+       if (!kill_as_cred_perm(cred, p)) {
                ret = -EPERM;
                goto out_unlock;
        }
-       ret = security_task_kill(p, info, sig, cred);
+       ret = security_task_kill(p, &info, sig, cred);
        if (ret)
                goto out_unlock;
 
        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;
@@ -1476,7 +1534,7 @@ out_unlock:
        rcu_read_unlock();
        return ret;
 }
-EXPORT_SYMBOL_GPL(kill_pid_info_as_cred);
+EXPORT_SYMBOL_GPL(kill_pid_usb_asyncio);
 
 /*
  * kill_something_info() interprets pid in interesting ways just like kill(2).
@@ -1552,9 +1610,17 @@ send_sig(int sig, struct task_struct *p, int priv)
 }
 EXPORT_SYMBOL(send_sig);
 
-void force_sig(int sig, struct task_struct *p)
+void force_sig(int sig)
 {
-       force_sig_info(sig, SEND_SIG_PRIV, p);
+       struct kernel_siginfo info;
+
+       clear_siginfo(&info);
+       info.si_signo = sig;
+       info.si_errno = 0;
+       info.si_code = SI_KERNEL;
+       info.si_pid = 0;
+       info.si_uid = 0;
+       force_sig_info(&info);
 }
 EXPORT_SYMBOL(force_sig);
 
@@ -1564,18 +1630,20 @@ EXPORT_SYMBOL(force_sig);
  * the problem was already a SIGSEGV, we'll want to
  * make sure we don't even try to deliver the signal..
  */
-void force_sigsegv(int sig, struct task_struct *p)
+void force_sigsegv(int sig)
 {
+       struct task_struct *p = current;
+
        if (sig == SIGSEGV) {
                unsigned long flags;
                spin_lock_irqsave(&p->sighand->siglock, flags);
                p->sighand->action[sig - 1].sa.sa_handler = SIG_DFL;
                spin_unlock_irqrestore(&p->sighand->siglock, flags);
        }
-       force_sig(SIGSEGV, p);
+       force_sig(SIGSEGV);
 }
 
-int force_sig_fault(int sig, int code, void __user *addr
+int force_sig_fault_to_task(int sig, int code, void __user *addr
        ___ARCH_SI_TRAPNO(int trapno)
        ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
        , struct task_struct *t)
@@ -1595,7 +1663,16 @@ int force_sig_fault(int sig, int code, void __user *addr
        info.si_flags = flags;
        info.si_isr = isr;
 #endif
-       return force_sig_info(info.si_signo, &info, t);
+       return force_sig_info_to_task(&info, t);
+}
+
+int force_sig_fault(int sig, int code, void __user *addr
+       ___ARCH_SI_TRAPNO(int trapno)
+       ___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr))
+{
+       return force_sig_fault_to_task(sig, code, addr
+                                      ___ARCH_SI_TRAPNO(trapno)
+                                      ___ARCH_SI_IA64(imm, flags, isr), current);
 }
 
 int send_sig_fault(int sig, int code, void __user *addr
@@ -1621,7 +1698,7 @@ int send_sig_fault(int sig, int code, void __user *addr
        return send_sig_info(info.si_signo, &info, t);
 }
 
-int force_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *t)
+int force_sig_mceerr(int code, void __user *addr, short lsb)
 {
        struct kernel_siginfo info;
 
@@ -1632,7 +1709,7 @@ int force_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct
        info.si_code = code;
        info.si_addr = addr;
        info.si_addr_lsb = lsb;
-       return force_sig_info(info.si_signo, &info, t);
+       return force_sig_info(&info);
 }
 
 int send_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *t)
@@ -1661,7 +1738,7 @@ int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper)
        info.si_addr  = addr;
        info.si_lower = lower;
        info.si_upper = upper;
-       return force_sig_info(info.si_signo, &info, current);
+       return force_sig_info(&info);
 }
 
 #ifdef SEGV_PKUERR
@@ -1675,7 +1752,7 @@ int force_sig_pkuerr(void __user *addr, u32 pkey)
        info.si_code  = SEGV_PKUERR;
        info.si_addr  = addr;
        info.si_pkey  = pkey;
-       return force_sig_info(info.si_signo, &info, current);
+       return force_sig_info(&info);
 }
 #endif
 
@@ -1691,7 +1768,7 @@ int force_sig_ptrace_errno_trap(int errno, void __user *addr)
        info.si_errno = errno;
        info.si_code  = TRAP_HWBKPT;
        info.si_addr  = addr;
-       return force_sig_info(info.si_signo, &info, current);
+       return force_sig_info(&info);
 }
 
 int kill_pgrp(struct pid *pid, int sig, int priv)
@@ -1804,6 +1881,14 @@ ret:
        return ret;
 }
 
+static void do_notify_pidfd(struct task_struct *task)
+{
+       struct pid *pid;
+
+       pid = task_pid(task);
+       wake_up_all(&pid->wait_pidfd);
+}
+
 /*
  * Let a parent know about the death of a child.
  * For a stopped/continued status change, use do_notify_parent_cldstop instead.
@@ -1827,6 +1912,9 @@ bool do_notify_parent(struct task_struct *tsk, int sig)
        BUG_ON(!tsk->ptrace &&
               (tsk->group_leader != tsk || !thread_group_empty(tsk)));
 
+       /* Wake up all pidfd waiters */
+       do_notify_pidfd(tsk);
+
        if (sig != SIGCHLD) {
                /*
                 * This is only possible if parent == real_parent.
@@ -2676,7 +2764,7 @@ static void signal_delivered(struct ksignal *ksig, int stepping)
 void signal_setup_done(int failed, struct ksignal *ksig, int stepping)
 {
        if (failed)
-               force_sigsegv(ksig->sig, current);
+               force_sigsegv(ksig->sig);
        else
                signal_delivered(ksig, stepping);
 }
@@ -4477,6 +4565,28 @@ static inline void siginfo_buildtime_checks(void)
        CHECK_OFFSET(si_syscall);
        CHECK_OFFSET(si_arch);
 #undef CHECK_OFFSET
+
+       /* usb asyncio */
+       BUILD_BUG_ON(offsetof(struct siginfo, si_pid) !=
+                    offsetof(struct siginfo, si_addr));
+       if (sizeof(int) == sizeof(void __user *)) {
+               BUILD_BUG_ON(sizeof_field(struct siginfo, si_pid) !=
+                            sizeof(void __user *));
+       } else {
+               BUILD_BUG_ON((sizeof_field(struct siginfo, si_pid) +
+                             sizeof_field(struct siginfo, si_uid)) !=
+                            sizeof(void __user *));
+               BUILD_BUG_ON(offsetofend(struct siginfo, si_pid) !=
+                            offsetof(struct siginfo, si_uid));
+       }
+#ifdef CONFIG_COMPAT
+       BUILD_BUG_ON(offsetof(struct compat_siginfo, si_pid) !=
+                    offsetof(struct compat_siginfo, si_addr));
+       BUILD_BUG_ON(sizeof_field(struct compat_siginfo, si_pid) !=
+                    sizeof(compat_uptr_t));
+       BUILD_BUG_ON(sizeof_field(struct compat_siginfo, si_pid) !=
+                    sizeof_field(struct siginfo, si_pid));
+#endif
 }
 
 void __init signals_init(void)