Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 30bf4b75 authored by Tom Cherry's avatar Tom Cherry Committed by Gerrit Code Review
Browse files

Merge "init: fix signal handling and LOG(FATAL) in child processes"

parents 32d2eae8 1ca83249
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -358,7 +358,7 @@ static void set_usb_controller() {
    }
}

static void install_reboot_signal_handlers() {
static void InstallRebootSignalHandlers() {
    // Instead of panic'ing the kernel as is the default behavior when init crashes,
    // we prefer to reboot to bootloader on development builds, as this will prevent
    // boot looping bad configurations and allow both developers and test farms to easily
@@ -366,7 +366,13 @@ static void install_reboot_signal_handlers() {
    struct sigaction action;
    memset(&action, 0, sizeof(action));
    sigfillset(&action.sa_mask);
    action.sa_handler = [](int) {
    action.sa_handler = [](int signal) {
        // These signal handlers are also caught for processes forked from init, however we do not
        // want them to trigger reboot, so we directly call _exit() for children processes here.
        if (getpid() != 1) {
            _exit(signal);
        }

        // Calling DoReboot() or LOG(FATAL) is not a good option as this is a signal handler.
        // RebootSystem uses syscall() which isn't actually async-signal-safe, but our only option
        // and probably good enough given this is already an error case and only enabled for
@@ -396,7 +402,7 @@ int main(int argc, char** argv) {
    }

    if (REBOOT_BOOTLOADER_ON_PANIC) {
        install_reboot_signal_handlers();
        InstallRebootSignalHandlers();
    }

    bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);
+11 −3
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include <fcntl.h>
#include <linux/audit.h>
#include <string.h>
#include <unistd.h>

#include <android-base/logging.h>
#include <cutils/android_reboot.h>
@@ -29,7 +30,14 @@
namespace android {
namespace init {

static void RebootAborter(const char* abort_message) {
static void InitAborter(const char* abort_message) {
    // When init forks, it continues to use this aborter for LOG(FATAL), but we want children to
    // simply abort instead of trying to reboot the system.
    if (getpid() != 1) {
        android::base::DefaultAborter(abort_message);
        return;
    }

    // DoReboot() does a lot to try to shutdown the system cleanly.  If something happens to call
    // LOG(FATAL) in the shutdown path, we want to catch this and immediately use the syscall to
    // reboot instead of recursing here.
@@ -49,7 +57,7 @@ void InitKernelLogging(char* argv[]) {
    int fd = open("/sys/fs/selinux/null", O_RDWR);
    if (fd == -1) {
        int saved_errno = errno;
        android::base::InitLogging(argv, &android::base::KernelLogger, RebootAborter);
        android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
        errno = saved_errno;
        PLOG(FATAL) << "Couldn't open /sys/fs/selinux/null";
    }
@@ -58,7 +66,7 @@ void InitKernelLogging(char* argv[]) {
    dup2(fd, 2);
    if (fd > 2) close(fd);

    android::base::InitLogging(argv, &android::base::KernelLogger, RebootAborter);
    android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
}

int selinux_klog_callback(int type, const char *fmt, ...) {