ubsan: move cc-option tests into Kconfig
[linux-2.6-microblaze.git] / kernel / signal.c
index ef8f2a2..c371706 100644 (file)
@@ -984,7 +984,7 @@ static inline bool wants_signal(int sig, struct task_struct *p)
        if (task_is_stopped_or_traced(p))
                return false;
 
-       return task_curr(p) || !signal_pending(p);
+       return task_curr(p) || !task_sigpending(p);
 }
 
 static void complete_signal(int sig, struct task_struct *p, enum pid_type type)
@@ -2524,12 +2524,46 @@ static int ptrace_signal(int signr, kernel_siginfo_t *info)
        return signr;
 }
 
+static void hide_si_addr_tag_bits(struct ksignal *ksig)
+{
+       switch (siginfo_layout(ksig->sig, ksig->info.si_code)) {
+       case SIL_FAULT:
+       case SIL_FAULT_MCEERR:
+       case SIL_FAULT_BNDERR:
+       case SIL_FAULT_PKUERR:
+               ksig->info.si_addr = arch_untagged_si_addr(
+                       ksig->info.si_addr, ksig->sig, ksig->info.si_code);
+               break;
+       case SIL_KILL:
+       case SIL_TIMER:
+       case SIL_POLL:
+       case SIL_CHLD:
+       case SIL_RT:
+       case SIL_SYS:
+               break;
+       }
+}
+
 bool get_signal(struct ksignal *ksig)
 {
        struct sighand_struct *sighand = current->sighand;
        struct signal_struct *signal = current->signal;
        int signr;
 
+       /*
+        * For non-generic architectures, check for TIF_NOTIFY_SIGNAL so
+        * that the arch handlers don't all have to do it. If we get here
+        * without TIF_SIGPENDING, just exit after running signal work.
+        */
+#ifdef TIF_NOTIFY_SIGNAL
+       if (!IS_ENABLED(CONFIG_GENERIC_ENTRY)) {
+               if (test_thread_flag(TIF_NOTIFY_SIGNAL))
+                       tracehook_notify_signal();
+               if (!task_sigpending(current))
+                       return false;
+       }
+#endif
+
        if (unlikely(uprobe_deny_signal()))
                return false;
 
@@ -2761,6 +2795,10 @@ relock:
        spin_unlock_irq(&sighand->siglock);
 
        ksig->sig = signr;
+
+       if (!(ksig->ka.sa.sa_flags & SA_EXPOSE_TAGBITS))
+               hide_si_addr_tag_bits(ksig);
+
        return ksig->sig > 0;
 }
 
@@ -2823,7 +2861,7 @@ static void retarget_shared_pending(struct task_struct *tsk, sigset_t *which)
                /* Remove the signals this thread can handle. */
                sigandsets(&retarget, &retarget, &t->blocked);
 
-               if (!signal_pending(t))
+               if (!task_sigpending(t))
                        signal_wake_up(t, 0);
 
                if (sigisemptyset(&retarget))
@@ -2857,7 +2895,7 @@ void exit_signals(struct task_struct *tsk)
 
        cgroup_threadgroup_change_end(tsk);
 
-       if (!signal_pending(tsk))
+       if (!task_sigpending(tsk))
                goto out;
 
        unblocked = tsk->blocked;
@@ -2901,7 +2939,7 @@ long do_no_restart_syscall(struct restart_block *param)
 
 static void __set_task_blocked(struct task_struct *tsk, const sigset_t *newset)
 {
-       if (signal_pending(tsk) && !thread_group_empty(tsk)) {
+       if (task_sigpending(tsk) && !thread_group_empty(tsk)) {
                sigset_t newblocked;
                /* A set of now blocked but previously unblocked signals. */
                sigandnsets(&newblocked, newset, &current->blocked);
@@ -3985,6 +4023,22 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
        if (oact)
                *oact = *k;
 
+       /*
+        * Make sure that we never accidentally claim to support SA_UNSUPPORTED,
+        * e.g. by having an architecture use the bit in their uapi.
+        */
+       BUILD_BUG_ON(UAPI_SA_FLAGS & SA_UNSUPPORTED);
+
+       /*
+        * Clear unknown flag bits in order to allow userspace to detect missing
+        * support for flag bits and to allow the kernel to use non-uapi bits
+        * internally.
+        */
+       if (act)
+               act->sa.sa_flags &= UAPI_SA_FLAGS;
+       if (oact)
+               oact->sa.sa_flags &= UAPI_SA_FLAGS;
+
        sigaction_compat_abi(act, oact);
 
        if (act) {