]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blobdiff - kernel/signal.c
tracing: probeevent: Unify fetch_insn processing common part
[mirror_ubuntu-jammy-kernel.git] / kernel / signal.c
index 6e92adddd6670c07899e55dc8b50e6d1d256a5ab..5843c541fda9c30bb8e4165facc07a3df114f57b 100644 (file)
@@ -85,7 +85,7 @@ static bool sig_task_ignored(struct task_struct *t, int sig, bool force)
        return sig_handler_ignored(handler, sig);
 }
 
-static int sig_ignored(struct task_struct *t, int sig, bool force)
+static bool sig_ignored(struct task_struct *t, int sig, bool force)
 {
        /*
         * Blocked signals are never ignored, since the
@@ -93,7 +93,7 @@ static int sig_ignored(struct task_struct *t, int sig, bool force)
         * unblocked.
         */
        if (sigismember(&t->blocked, sig) || sigismember(&t->real_blocked, sig))
-               return 0;
+               return false;
 
        /*
         * Tracers may want to know about even ignored signal unless it
@@ -101,7 +101,7 @@ static int sig_ignored(struct task_struct *t, int sig, bool force)
         * by SIGNAL_UNKILLABLE task.
         */
        if (t->ptrace && sig != SIGKILL)
-               return 0;
+               return false;
 
        return sig_task_ignored(t, sig, force);
 }
@@ -110,7 +110,7 @@ static int sig_ignored(struct task_struct *t, int sig, bool force)
  * Re-calculate pending state from the set of locally pending
  * signals, globally pending signals, and blocked signals.
  */
-static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
+static inline bool has_pending_signals(sigset_t *signal, sigset_t *blocked)
 {
        unsigned long ready;
        long i;
@@ -138,20 +138,21 @@ static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked)
 
 #define PENDING(p,b) has_pending_signals(&(p)->signal, (b))
 
-static int recalc_sigpending_tsk(struct task_struct *t)
+static bool recalc_sigpending_tsk(struct task_struct *t)
 {
        if ((t->jobctl & JOBCTL_PENDING_MASK) ||
            PENDING(&t->pending, &t->blocked) ||
            PENDING(&t->signal->shared_pending, &t->blocked)) {
                set_tsk_thread_flag(t, TIF_SIGPENDING);
-               return 1;
+               return true;
        }
+
        /*
         * We must never clear the flag in another thread, or in current
         * when it's possible the current syscall is returning -ERESTART*.
         * So we don't clear it here, and only callers who know they should do.
         */
-       return 0;
+       return false;
 }
 
 /*
@@ -172,6 +173,17 @@ void recalc_sigpending(void)
 
 }
 
+void calculate_sigpending(void)
+{
+       /* Have any signals or users of TIF_SIGPENDING been delayed
+        * until after fork?
+        */
+       spin_lock_irq(&current->sighand->siglock);
+       set_tsk_thread_flag(current, TIF_SIGPENDING);
+       recalc_sigpending();
+       spin_unlock_irq(&current->sighand->siglock);
+}
+
 /* Given the mask, find the first available signal that should be serviced. */
 
 #define SYNCHRONOUS_MASK \
@@ -362,6 +374,20 @@ static bool task_participate_group_stop(struct task_struct *task)
        return false;
 }
 
+void task_join_group_stop(struct task_struct *task)
+{
+       /* Have the new thread join an on-going signal group stop */
+       unsigned long jobctl = current->jobctl;
+       if (jobctl & JOBCTL_STOP_PENDING) {
+               struct signal_struct *sig = current->signal;
+               unsigned long signr = jobctl & JOBCTL_STOP_SIGMASK;
+               unsigned long gstop = JOBCTL_STOP_PENDING | JOBCTL_STOP_CONSUME;
+               if (task_set_jobctl_pending(task, signr | gstop)) {
+                       sig->group_stop_count++;
+               }
+       }
+}
+
 /*
  * allocate a new signal queue record
  * - this may be called without locks if and only if t == current, otherwise an
@@ -504,13 +530,15 @@ flush_signal_handlers(struct task_struct *t, int force_default)
        }
 }
 
-int unhandled_signal(struct task_struct *tsk, int sig)
+bool unhandled_signal(struct task_struct *tsk, int sig)
 {
        void __user *handler = tsk->sighand->action[sig-1].sa.sa_handler;
        if (is_global_init(tsk))
-               return 1;
+               return true;
+
        if (handler != SIG_IGN && handler != SIG_DFL)
-               return 0;
+               return false;
+
        /* if ptraced, let the tracer determine */
        return !tsk->ptrace;
 }
@@ -684,14 +712,14 @@ void signal_wake_up_state(struct task_struct *t, unsigned int state)
  *
  * All callers must be holding the siglock.
  */
-static int flush_sigqueue_mask(sigset_t *mask, struct sigpending *s)
+static void flush_sigqueue_mask(sigset_t *mask, struct sigpending *s)
 {
        struct sigqueue *q, *n;
        sigset_t m;
 
        sigandsets(&m, mask, &s->signal);
        if (sigisemptyset(&m))
-               return 0;
+               return;
 
        sigandnsets(&s->signal, &s->signal, mask);
        list_for_each_entry_safe(q, n, &s->list, list) {
@@ -700,7 +728,6 @@ static int flush_sigqueue_mask(sigset_t *mask, struct sigpending *s)
                        __sigqueue_free(q);
                }
        }
-       return 1;
 }
 
 static inline int is_si_special(const struct siginfo *info)
@@ -877,20 +904,24 @@ static bool prepare_signal(int sig, struct task_struct *p, bool force)
  * as soon as they're available, so putting the signal on the shared queue
  * will be equivalent to sending it to one such thread.
  */
-static inline int wants_signal(int sig, struct task_struct *p)
+static inline bool wants_signal(int sig, struct task_struct *p)
 {
        if (sigismember(&p->blocked, sig))
-               return 0;
+               return false;
+
        if (p->flags & PF_EXITING)
-               return 0;
+               return false;
+
        if (sig == SIGKILL)
-               return 1;
+               return true;
+
        if (task_is_stopped_or_traced(p))
-               return 0;
+               return false;
+
        return task_curr(p) || !signal_pending(p);
 }
 
-static void complete_signal(int sig, struct task_struct *p, int group)
+static void complete_signal(int sig, struct task_struct *p, enum pid_type type)
 {
        struct signal_struct *signal = p->signal;
        struct task_struct *t;
@@ -903,7 +934,7 @@ static void complete_signal(int sig, struct task_struct *p, int group)
         */
        if (wants_signal(sig, p))
                t = p;
-       else if (!group || thread_group_empty(p))
+       else if ((type == PIDTYPE_PID) || thread_group_empty(p))
                /*
                 * There is just one thread and it does not need to be woken.
                 * It will dequeue unblocked signals before it runs again.
@@ -966,7 +997,7 @@ static void complete_signal(int sig, struct task_struct *p, int group)
        return;
 }
 
-static inline int legacy_queue(struct sigpending *signals, int sig)
+static inline bool legacy_queue(struct sigpending *signals, int sig)
 {
        return (sig < SIGRTMIN) && sigismember(&signals->signal, sig);
 }
@@ -993,7 +1024,7 @@ static inline void userns_fixup_signal_uid(struct siginfo *info, struct task_str
 #endif
 
 static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
-                       int group, int from_ancestor_ns)
+                       enum pid_type type, int from_ancestor_ns)
 {
        struct sigpending *pending;
        struct sigqueue *q;
@@ -1007,7 +1038,7 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
                        from_ancestor_ns || (info == SEND_SIG_FORCED)))
                goto ret;
 
-       pending = group ? &t->signal->shared_pending : &t->pending;
+       pending = (type != PIDTYPE_PID) ? &t->signal->shared_pending : &t->pending;
        /*
         * Short-circuit ignored signals and support queuing
         * exactly one non-rt signal, so that we can get more
@@ -1091,14 +1122,29 @@ static int __send_signal(int sig, struct siginfo *info, struct task_struct *t,
 out_set:
        signalfd_notify(t, sig);
        sigaddset(&pending->signal, sig);
-       complete_signal(sig, t, group);
+
+       /* Let multiprocess signals appear after on-going forks */
+       if (type > PIDTYPE_TGID) {
+               struct multiprocess_signals *delayed;
+               hlist_for_each_entry(delayed, &t->signal->multiprocess, node) {
+                       sigset_t *signal = &delayed->signal;
+                       /* Can't queue both a stop and a continue signal */
+                       if (sig == SIGCONT)
+                               sigdelsetmask(signal, SIG_KERNEL_STOP_MASK);
+                       else if (sig_kernel_stop(sig))
+                               sigdelset(signal, SIGCONT);
+                       sigaddset(signal, sig);
+               }
+       }
+
+       complete_signal(sig, t, type);
 ret:
-       trace_signal_generate(sig, info, t, group, result);
+       trace_signal_generate(sig, info, t, type != PIDTYPE_PID, result);
        return ret;
 }
 
 static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
-                       int group)
+                       enum pid_type type)
 {
        int from_ancestor_ns = 0;
 
@@ -1107,7 +1153,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
                           !task_pid_nr_ns(current, task_active_pid_ns(t));
 #endif
 
-       return __send_signal(sig, info, t, group, from_ancestor_ns);
+       return __send_signal(sig, info, t, type, from_ancestor_ns);
 }
 
 static void print_fatal_signal(int signr)
@@ -1146,23 +1192,23 @@ __setup("print-fatal-signals=", setup_print_fatal_signals);
 int
 __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
 {
-       return send_signal(sig, info, p, 1);
+       return send_signal(sig, info, p, PIDTYPE_TGID);
 }
 
 static int
 specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
 {
-       return send_signal(sig, info, t, 0);
+       return send_signal(sig, info, t, PIDTYPE_PID);
 }
 
 int do_send_sig_info(int sig, struct siginfo *info, struct task_struct *p,
-                       bool group)
+                       enum pid_type type)
 {
        unsigned long flags;
        int ret = -ESRCH;
 
        if (lock_task_sighand(p, &flags)) {
-               ret = send_signal(sig, info, p, group);
+               ret = send_signal(sig, info, p, type);
                unlock_task_sighand(p, &flags);
        }
 
@@ -1269,7 +1315,8 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk,
 /*
  * send signal info to all the members of a group
  */
-int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
+int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p,
+                       enum pid_type type)
 {
        int ret;
 
@@ -1278,7 +1325,7 @@ int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
        rcu_read_unlock();
 
        if (!ret && sig)
-               ret = do_send_sig_info(sig, info, p, true);
+               ret = do_send_sig_info(sig, info, p, type);
 
        return ret;
 }
@@ -1296,7 +1343,7 @@ int __kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp)
        success = 0;
        retval = -ESRCH;
        do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
-               int err = group_send_sig_info(sig, info, p);
+               int err = group_send_sig_info(sig, info, p, PIDTYPE_PGID);
                success |= !err;
                retval = err;
        } while_each_pid_task(pgrp, PIDTYPE_PGID, p);
@@ -1312,7 +1359,7 @@ int kill_pid_info(int sig, struct siginfo *info, struct pid *pid)
                rcu_read_lock();
                p = pid_task(pid, PIDTYPE_PID);
                if (p)
-                       error = group_send_sig_info(sig, info, p);
+                       error = group_send_sig_info(sig, info, p, PIDTYPE_TGID);
                rcu_read_unlock();
                if (likely(!p || error != -ESRCH))
                        return error;
@@ -1372,7 +1419,7 @@ int kill_pid_info_as_cred(int sig, struct siginfo *info, struct pid *pid,
 
        if (sig) {
                if (lock_task_sighand(p, &flags)) {
-                       ret = __send_signal(sig, info, p, 1, 0);
+                       ret = __send_signal(sig, info, p, PIDTYPE_TGID, 0);
                        unlock_task_sighand(p, &flags);
                } else
                        ret = -ESRCH;
@@ -1416,7 +1463,8 @@ static int kill_something_info(int sig, struct siginfo *info, pid_t pid)
                for_each_process(p) {
                        if (task_pid_vnr(p) > 1 &&
                                        !same_thread_group(p, current)) {
-                               int err = group_send_sig_info(sig, info, p);
+                               int err = group_send_sig_info(sig, info, p,
+                                                             PIDTYPE_MAX);
                                ++count;
                                if (err != -EPERM)
                                        retval = err;
@@ -1442,7 +1490,7 @@ int send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
        if (!valid_signal(sig))
                return -EINVAL;
 
-       return do_send_sig_info(sig, info, p, false);
+       return do_send_sig_info(sig, info, p, PIDTYPE_PID);
 }
 
 #define __si_special(priv) \
@@ -1657,17 +1705,20 @@ void sigqueue_free(struct sigqueue *q)
                __sigqueue_free(q);
 }
 
-int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
+int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type)
 {
        int sig = q->info.si_signo;
        struct sigpending *pending;
+       struct task_struct *t;
        unsigned long flags;
        int ret, result;
 
        BUG_ON(!(q->flags & SIGQUEUE_PREALLOC));
 
        ret = -1;
-       if (!likely(lock_task_sighand(t, &flags)))
+       rcu_read_lock();
+       t = pid_task(pid, type);
+       if (!t || !likely(lock_task_sighand(t, &flags)))
                goto ret;
 
        ret = 1; /* the signal is ignored */
@@ -1689,15 +1740,16 @@ int send_sigqueue(struct sigqueue *q, struct task_struct *t, int group)
        q->info.si_overrun = 0;
 
        signalfd_notify(t, sig);
-       pending = group ? &t->signal->shared_pending : &t->pending;
+       pending = (type != PIDTYPE_PID) ? &t->signal->shared_pending : &t->pending;
        list_add_tail(&q->list, &pending->list);
        sigaddset(&pending->signal, sig);
-       complete_signal(sig, t, group);
+       complete_signal(sig, t, type);
        result = TRACE_SIGNAL_DELIVERED;
 out:
-       trace_signal_generate(sig, &q->info, t, group, result);
+       trace_signal_generate(sig, &q->info, t, type != PIDTYPE_PID, result);
        unlock_task_sighand(t, &flags);
 ret:
+       rcu_read_unlock();
        return ret;
 }
 
@@ -1898,10 +1950,10 @@ static inline bool may_ptrace_stop(void)
  * Return non-zero if there is a SIGKILL that should be waking us up.
  * Called with the siglock held.
  */
-static int sigkill_pending(struct task_struct *tsk)
+static bool sigkill_pending(struct task_struct *tsk)
 {
-       return  sigismember(&tsk->pending.signal, SIGKILL) ||
-               sigismember(&tsk->signal->shared_pending.signal, SIGKILL);
+       return sigismember(&tsk->pending.signal, SIGKILL) ||
+              sigismember(&tsk->signal->shared_pending.signal, SIGKILL);
 }
 
 /*
@@ -2281,7 +2333,7 @@ static int ptrace_signal(int signr, siginfo_t *info)
        return signr;
 }
 
-int get_signal(struct ksignal *ksig)
+bool get_signal(struct ksignal *ksig)
 {
        struct sighand_struct *sighand = current->sighand;
        struct signal_struct *signal = current->signal;
@@ -2291,7 +2343,7 @@ int get_signal(struct ksignal *ksig)
                task_work_run();
 
        if (unlikely(uprobe_deny_signal()))
-               return 0;
+               return false;
 
        /*
         * Do this once, we can't return to user-mode if freezing() == T.
@@ -3184,7 +3236,7 @@ do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
                 * probe.  No signal is actually delivered.
                 */
                if (!error && sig) {
-                       error = do_send_sig_info(sig, info, p, false);
+                       error = do_send_sig_info(sig, info, p, PIDTYPE_PID);
                        /*
                         * If lock_task_sighand() failed we pretend the task
                         * dies after receiving the signal. The window is tiny,
@@ -3950,7 +4002,7 @@ void kdb_send_sig(struct task_struct *t, int sig)
                           "the deadlock.\n");
                return;
        }
-       ret = send_signal(sig, SEND_SIG_PRIV, t, false);
+       ret = send_signal(sig, SEND_SIG_PRIV, t, PIDTYPE_PID);
        spin_unlock(&t->sighand->siglock);
        if (ret)
                kdb_printf("Fail to deliver Signal %d to process %d.\n",