/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <sys/reboot.h>

#include "crash-handler.h"
#include "exit-status.h"
#include "macro.h"
#include "main.h"
#include "missing_syscall.h"
#include "process-util.h"
#include "raw-clone.h"
#include "rlimit-util.h"
#include "signal-util.h"
#include "terminal-util.h"
#include "virt.h"

_noreturn_ void freeze_or_exit_or_reboot(void) {

        /* If we are running in a container, let's prefer exiting, after all we can propagate an exit code to
         * the container manager, and thus inform it that something went wrong. */
        if (detect_container() > 0) {
                log_emergency("Exiting PID 1...");
                _exit(EXIT_EXCEPTION);
        }

        if (arg_crash_reboot) {
                log_notice("Rebooting in 10s...");
                (void) sleep(10);

                log_notice("Rebooting now...");
                (void) reboot(RB_AUTOBOOT);
                log_emergency_errno(errno, "Failed to reboot: %m");
        }

        log_emergency("Freezing execution.");
        sync();
        freeze();
}

_noreturn_ static void crash(int sig, siginfo_t *siginfo, void *context) {
        struct sigaction sa;
        pid_t pid;

        /* NB: 💣 💣 💣 This is a signal handler, most likely executed in a situation where we have corrupted
         * memory. Thus: please avoid any libc memory allocation here, or any functions that internally use
         * memory allocation, as we cannot rely on memory allocation still working at this point! (Note that
         * memory allocation is not async-signal-safe anyway — see signal-safety(7) for details —, and thus
         * is not permissible in signal handlers.) */

        if (getpid_cached() != 1)
                /* Pass this on immediately, if this is not PID 1 */
                propagate_signal(sig, siginfo);
        else if (!arg_dump_core)
                log_emergency("Caught <%s>, not dumping core.", signal_to_string(sig));
        else {
                sa = (struct sigaction) {
                        .sa_handler = nop_signal_handler,
                        .sa_flags = SA_NOCLDSTOP|SA_RESTART,
                };

                /* We want to wait for the core process, hence let's enable SIGCHLD */
                (void) sigaction(SIGCHLD, &sa, NULL);

                pid = raw_clone(SIGCHLD);
                if (pid < 0)
                        log_emergency_errno(errno, "Caught <%s>, cannot fork for core dump: %m", signal_to_string(sig));
                else if (pid == 0) {
                        /* Enable default signal handler for core dump */

                        sa = (struct sigaction) {
                                .sa_handler = SIG_DFL,
                        };
                        (void) sigaction(sig, &sa, NULL);

                        /* Don't limit the coredump size */
                        (void) setrlimit(RLIMIT_CORE, &RLIMIT_MAKE_CONST(RLIM_INFINITY));

                        /* Just to be sure... */
                        (void) chdir("/");

                        /* Raise the signal again */
                        propagate_signal(sig, siginfo);
                        assert_not_reached();
                        _exit(EXIT_EXCEPTION);
                } else {
                        siginfo_t status;
                        int r;

                        if (siginfo) {
                                if (siginfo->si_pid == 0)
                                        log_emergency("Caught <%s> from unknown sender process.", signal_to_string(sig));
                                else if (siginfo->si_pid == 1)
                                        log_emergency("Caught <%s> from our own process.", signal_to_string(sig));
                                else
                                        log_emergency("Caught <%s> from PID "PID_FMT".", signal_to_string(sig), siginfo->si_pid);
                        }

                        /* Order things nicely. */
                        r = wait_for_terminate(pid, &status);
                        if (r < 0)
                                log_emergency_errno(r, "Caught <%s>, waitpid() failed: %m", signal_to_string(sig));
                        else if (status.si_code != CLD_DUMPED) {
                                const char *s = status.si_code == CLD_EXITED
                                        ? exit_status_to_string(status.si_status, EXIT_STATUS_LIBC)
                                        : signal_to_string(status.si_status);

                                log_emergency("Caught <%s>, core dump failed (child "PID_FMT", code=%s, status=%i/%s).",
                                              signal_to_string(sig),
                                              pid,
                                              sigchld_code_to_string(status.si_code),
                                              status.si_status, strna(s));
                        } else
                                log_emergency("Caught <%s>, dumped core as pid "PID_FMT".",
                                              signal_to_string(sig), pid);
                }
        }

        if (arg_crash_chvt >= 0)
                (void) chvt(arg_crash_chvt);

        sa = (struct sigaction) {
                .sa_handler = SIG_IGN,
                .sa_flags = SA_NOCLDSTOP|SA_NOCLDWAIT|SA_RESTART,
        };

        /* Let the kernel reap children for us */
        (void) sigaction(SIGCHLD, &sa, NULL);

        if (arg_crash_shell) {
                log_notice("Executing crash shell in 10s...");
                (void) sleep(10);

                pid = raw_clone(SIGCHLD);
                if (pid < 0)
                        log_emergency_errno(errno, "Failed to fork off crash shell: %m");
                else if (pid == 0) {
                        (void) setsid();
                        (void) make_console_stdio();
                        (void) rlimit_nofile_safe();
                        (void) execle("/bin/sh", "/bin/sh", NULL, environ);

                        log_emergency_errno(errno, "execle() failed: %m");
                        _exit(EXIT_EXCEPTION);
                } else {
                        log_info("Spawned crash shell as PID "PID_FMT".", pid);
                        (void) wait_for_terminate(pid, NULL);
                }
        }

        freeze_or_exit_or_reboot();
}

void install_crash_handler(void) {
        static const struct sigaction sa = {
                .sa_sigaction = crash,
                .sa_flags = SA_NODEFER | SA_SIGINFO, /* So that we can raise the signal again from the signal handler */
        };
        int r;

        /* We ignore the return value here, since, we don't mind if we cannot set up a crash handler */
        r = sigaction_many(&sa, SIGNALS_CRASH_HANDLER);
        if (r < 0)
                log_debug_errno(r, "I had trouble setting up the crash handler, ignoring: %m");
}
