Merge "Close /dev/fuse FD before calling onClosed" into qt-dev
diff --git a/init/Android.bp b/init/Android.bp
index 69498ac..6be7290 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -68,6 +68,7 @@
         "libpropertyinfoparser",
     ],
     shared_libs: [
+        "libbacktrace",
         "libbase",
         "libbinder",
         "libbootloader_message",
diff --git a/init/Android.mk b/init/Android.mk
index b02c926..c4f7d34 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -105,6 +105,10 @@
     libcap \
     libgsi \
     libcom.android.sysprop.apex \
+    liblzma \
+    libdexfile_support \
+    libunwindstack \
+    libbacktrace \
 
 LOCAL_SANITIZE := signed-integer-overflow
 # First stage init is weird: it may start without stdout/stderr, and no /proc.
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 8b95e38..2b89940 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -33,7 +33,6 @@
 #include <android-base/chrono_utils.h>
 #include <android-base/file.h>
 #include <android-base/logging.h>
-#include <cutils/android_reboot.h>
 #include <private/android_filesystem_config.h>
 
 #include "debug_ramdisk.h"
@@ -168,13 +167,10 @@
                     "mode=0755,uid=0,gid=0"));
 #undef CHECKCALL
 
+    SetStdioToDevNull(argv);
     // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
     // talk to the outside world...
-    // We need to set up stdin/stdout/stderr for child processes forked from first
-    // stage init as part of the mount process.  This closes /dev/console if the
-    // kernel had previously opened it.
-    auto reboot_bootloader = [](const char*) { RebootSystem(ANDROID_RB_RESTART2, "bootloader"); };
-    InitKernelLogging(argv, reboot_bootloader);
+    InitKernelLogging(argv);
 
     if (!errors.empty()) {
         for (const auto& [error_string, error_errno] : errors) {
diff --git a/init/host_init_stubs.h b/init/host_init_stubs.h
index 63ceead..f6e9676 100644
--- a/init/host_init_stubs.h
+++ b/init/host_init_stubs.h
@@ -44,6 +44,12 @@
 uint32_t HandlePropertySet(const std::string& name, const std::string& value,
                            const std::string& source_context, const ucred& cr, std::string* error);
 
+// reboot_utils.h
+inline void SetFatalRebootTarget() {}
+inline void __attribute__((noreturn)) InitFatalReboot() {
+    abort();
+}
+
 // selinux.h
 int SelinuxGetVendorAndroidVersion();
 void SelabelInitialize();
diff --git a/init/init.cpp b/init/init.cpp
index c79e459..6b03bc9 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -38,7 +38,6 @@
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
-#include <cutils/android_reboot.h>
 #include <fs_avb/fs_avb.h>
 #include <fs_mgr_vendor_overlay.h>
 #include <keyutils.h>
@@ -601,17 +600,6 @@
     }
 }
 
-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;
-    }
-
-    RebootSystem(ANDROID_RB_RESTART2, "bootloader");
-}
-
 static void GlobalSeccomp() {
     import_kernel_cmdline(false, [](const std::string& key, const std::string& value,
                                     bool in_qemu) {
@@ -632,8 +620,8 @@
         InstallRebootSignalHandlers();
     }
 
-    // We need to set up stdin/stdout/stderr again now that we're running in init's context.
-    InitKernelLogging(argv, InitAborter);
+    SetStdioToDevNull(argv);
+    InitKernelLogging(argv);
     LOG(INFO) << "init second stage started!";
 
     // Set init and its forked children's oom_adj.
diff --git a/init/reboot_utils.cpp b/init/reboot_utils.cpp
index 9610304..d1a712f 100644
--- a/init/reboot_utils.cpp
+++ b/init/reboot_utils.cpp
@@ -19,14 +19,40 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 
-#include <android-base/logging.h>
-#include <cutils/android_reboot.h>
+#include <string>
+
+#include "android-base/file.h"
+#include "android-base/logging.h"
+#include "android-base/strings.h"
+#include "backtrace/Backtrace.h"
+#include "cutils/android_reboot.h"
 
 #include "capabilities.h"
 
 namespace android {
 namespace init {
 
+static std::string init_fatal_reboot_target = "bootloader";
+
+void SetFatalRebootTarget() {
+    std::string cmdline;
+    android::base::ReadFileToString("/proc/cmdline", &cmdline);
+    cmdline = android::base::Trim(cmdline);
+
+    const char kRebootTargetString[] = "androidboot.init_fatal_reboot_target=";
+    auto start_pos = cmdline.find(kRebootTargetString);
+    if (start_pos == std::string::npos) {
+        return;  // We already default to bootloader if no setting is provided.
+    }
+    start_pos += sizeof(kRebootTargetString) - 1;
+
+    auto end_pos = cmdline.find(' ', start_pos);
+    // if end_pos isn't found, then we've run off the end, but this is okay as this is the last
+    // entry, and -1 is a valid size for string::substr();
+    auto size = end_pos == std::string::npos ? -1 : end_pos - start_pos;
+    init_fatal_reboot_target = cmdline.substr(start_pos, size);
+}
+
 bool IsRebootCapable() {
     if (!CAP_IS_SUPPORTED(CAP_SYS_BOOT)) {
         PLOG(WARNING) << "CAP_SYS_BOOT is not supported";
@@ -75,6 +101,32 @@
     abort();
 }
 
+void __attribute__((noreturn)) InitFatalReboot() {
+    auto pid = fork();
+
+    if (pid == -1) {
+        // Couldn't fork, don't even try to backtrace, just reboot.
+        RebootSystem(ANDROID_RB_RESTART2, init_fatal_reboot_target);
+    } else if (pid == 0) {
+        // Fork a child for safety, since we always want to shut down if something goes wrong, but
+        // its worth trying to get the backtrace, even in the signal handler, since typically it
+        // does work despite not being async-signal-safe.
+        sleep(5);
+        RebootSystem(ANDROID_RB_RESTART2, init_fatal_reboot_target);
+    }
+
+    // In the parent, let's try to get a backtrace then shutdown.
+    std::unique_ptr<Backtrace> backtrace(
+            Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
+    if (!backtrace->Unwind(0)) {
+        LOG(ERROR) << __FUNCTION__ << ": Failed to unwind callstack.";
+    }
+    for (size_t i = 0; i < backtrace->NumFrames(); i++) {
+        LOG(ERROR) << backtrace->FormatFrameData(i);
+    }
+    RebootSystem(ANDROID_RB_RESTART2, init_fatal_reboot_target);
+}
+
 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
@@ -94,7 +146,7 @@
         // 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
         // development builds.
-        RebootSystem(ANDROID_RB_RESTART2, "bootloader");
+        InitFatalReboot();
     };
     action.sa_flags = SA_RESTART;
     sigaction(SIGABRT, &action, nullptr);
diff --git a/init/reboot_utils.h b/init/reboot_utils.h
index 073a16a..3fd969e 100644
--- a/init/reboot_utils.h
+++ b/init/reboot_utils.h
@@ -21,11 +21,13 @@
 namespace android {
 namespace init {
 
+void SetFatalRebootTarget();
 // Determines whether the system is capable of rebooting. This is conservative,
 // so if any of the attempts to determine this fail, it will still return true.
 bool IsRebootCapable();
 // This is a wrapper around the actual reboot calls.
 void __attribute__((noreturn)) RebootSystem(unsigned int cmd, const std::string& reboot_target);
+void __attribute__((noreturn)) InitFatalReboot();
 void InstallRebootSignalHandlers();
 
 }  // namespace init
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 132fc13..86238b4 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -60,7 +60,6 @@
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
 #include <android-base/unique_fd.h>
-#include <cutils/android_reboot.h>
 #include <fs_avb/fs_avb.h>
 #include <selinux/android.h>
 
@@ -518,9 +517,7 @@
 
 // This function initializes SELinux then execs init to run in the init SELinux context.
 int SetupSelinux(char** argv) {
-    android::base::InitLogging(argv, &android::base::KernelLogger, [](const char*) {
-        RebootSystem(ANDROID_RB_RESTART2, "bootloader");
-    });
+    InitKernelLogging(argv);
 
     if (REBOOT_BOOTLOADER_ON_PANIC) {
         InstallRebootSignalHandlers();
diff --git a/init/util.cpp b/init/util.cpp
index 29d7a76..63d2d44 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -40,6 +40,7 @@
 #include <selinux/android.h>
 
 #if defined(__ANDROID__)
+#include "reboot_utils.h"
 #include "selinux.h"
 #else
 #include "host_init_stubs.h"
@@ -425,20 +426,50 @@
     return true;
 }
 
-void InitKernelLogging(char** argv, std::function<void(const char*)> abort_function) {
+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;
+    }
+
+    InitFatalReboot();
+}
+
+// The kernel opens /dev/console and uses that fd for stdin/stdout/stderr if there is a serial
+// console enabled and no initramfs, otherwise it does not provide any fds for stdin/stdout/stderr.
+// SetStdioToDevNull() is used to close these existing fds if they exist and replace them with
+// /dev/null regardless.
+//
+// In the case that these fds are provided by the kernel, the exec of second stage init causes an
+// SELinux denial as it does not have access to /dev/console.  In the case that they are not
+// provided, exec of any further process is potentially dangerous as the first fd's opened by that
+// process will take the stdin/stdout/stderr fileno's, which can cause issues if printf(), etc is
+// then used by that process.
+//
+// Lastly, simply calling SetStdioToDevNull() in first stage init is not enough, since first
+// stage init still runs in kernel context, future child processes will not have permissions to
+// access any fds that it opens, including the one opened below for /dev/null.  Therefore,
+// SetStdioToDevNull() must be called again in second stage init.
+void SetStdioToDevNull(char** argv) {
     // Make stdin/stdout/stderr all point to /dev/null.
     int fd = open("/dev/null", O_RDWR);
     if (fd == -1) {
         int saved_errno = errno;
-        android::base::InitLogging(argv, &android::base::KernelLogger, std::move(abort_function));
+        android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
         errno = saved_errno;
         PLOG(FATAL) << "Couldn't open /dev/null";
     }
-    dup2(fd, 0);
-    dup2(fd, 1);
-    dup2(fd, 2);
-    if (fd > 2) close(fd);
-    android::base::InitLogging(argv, &android::base::KernelLogger, std::move(abort_function));
+    dup2(fd, STDIN_FILENO);
+    dup2(fd, STDOUT_FILENO);
+    dup2(fd, STDERR_FILENO);
+    if (fd > STDERR_FILENO) close(fd);
+}
+
+void InitKernelLogging(char** argv) {
+    SetFatalRebootTarget();
+    android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
 }
 
 bool IsRecoveryMode() {
diff --git a/init/util.h b/init/util.h
index 2232a0f..767620b 100644
--- a/init/util.h
+++ b/init/util.h
@@ -63,7 +63,8 @@
 
 bool IsLegalPropertyName(const std::string& name);
 
-void InitKernelLogging(char** argv, std::function<void(const char*)> abort_function);
+void SetStdioToDevNull(char** argv);
+void InitKernelLogging(char** argv);
 bool IsRecoveryMode();
 }  // namespace init
 }  // namespace android
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index f1ca446..f71d0c3 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -86,6 +86,7 @@
         const bool proxy_read_ready = last_proxy_events_.events & EPOLLIN;
         const bool proxy_write_ready = last_proxy_events_.events & EPOLLOUT;
 
+        last_state_ = state_;
         last_device_events_.events = 0;
         last_proxy_events_.events = 0;