• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

system/core


Commit MetaInfo

Revisão1fcd51255a8eb1bf2e114ab9fcda73ecc0ac05b4 (tree)
Hora2019-05-31 04:08:42
AutorTom Cherry <tomcherry@goog...>
CommiterKeun young Park

Mensagem de Log

init: dump stack when aborting

Dump init stacks when aborting either due to LOG(FATAL) or in
userdebug/eng builds due to signals, including signals from
sanitizers.

Doesn't work for static first stage init yet, b/133450393 tracks
that.

Also, ensure that LOG(FATAL) in child processes calls abort() in all
stages of init, not just 2nd stage init.

Bug: 131747478
Test: abort init in various ways and see stacks
Test: hang or crash in backtrace handler and see child reboot
Change-Id: Ib53b5d3e7e814244203f875de016ada9900dfce8
Merged-In: Ib53b5d3e7e814244203f875de016ada9900dfce8
(cherry picked from commit 59656fb37769b3c0de927c20f8e9f5855a0f7ac3)

Mudança Sumário

Diff

--- a/init/Android.bp
+++ b/init/Android.bp
@@ -68,6 +68,7 @@ cc_defaults {
6868 "libpropertyinfoparser",
6969 ],
7070 shared_libs: [
71+ "libbacktrace",
7172 "libbase",
7273 "libbinder",
7374 "libbootloader_message",
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -105,6 +105,10 @@ LOCAL_STATIC_LIBRARIES := \
105105 libcap \
106106 libgsi \
107107 libcom.android.sysprop.apex \
108+ liblzma \
109+ libdexfile_support \
110+ libunwindstack \
111+ libbacktrace \
108112
109113 LOCAL_SANITIZE := signed-integer-overflow
110114 # First stage init is weird: it may start without stdout/stderr, and no /proc.
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -33,7 +33,6 @@
3333 #include <android-base/chrono_utils.h>
3434 #include <android-base/file.h>
3535 #include <android-base/logging.h>
36-#include <cutils/android_reboot.h>
3736 #include <private/android_filesystem_config.h>
3837
3938 #include "debug_ramdisk.h"
@@ -168,13 +167,10 @@ int FirstStageMain(int argc, char** argv) {
168167 "mode=0755,uid=0,gid=0"));
169168 #undef CHECKCALL
170169
170+ SetStdioToDevNull(argv);
171171 // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
172172 // talk to the outside world...
173- // We need to set up stdin/stdout/stderr for child processes forked from first
174- // stage init as part of the mount process. This closes /dev/console if the
175- // kernel had previously opened it.
176- auto reboot_bootloader = [](const char*) { RebootSystem(ANDROID_RB_RESTART2, "bootloader"); };
177- InitKernelLogging(argv, reboot_bootloader);
173+ InitKernelLogging(argv);
178174
179175 if (!errors.empty()) {
180176 for (const auto& [error_string, error_errno] : errors) {
--- a/init/host_init_stubs.h
+++ b/init/host_init_stubs.h
@@ -44,6 +44,11 @@ extern uint32_t (*property_set)(const std::string& name, const std::string& valu
4444 uint32_t HandlePropertySet(const std::string& name, const std::string& value,
4545 const std::string& source_context, const ucred& cr, std::string* error);
4646
47+// reboot_utils.h
48+inline void __attribute__((noreturn)) InitFatalReboot() {
49+ abort();
50+}
51+
4752 // selinux.h
4853 int SelinuxGetVendorAndroidVersion();
4954 void SelabelInitialize();
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -38,7 +38,6 @@
3838 #include <android-base/properties.h>
3939 #include <android-base/stringprintf.h>
4040 #include <android-base/strings.h>
41-#include <cutils/android_reboot.h>
4241 #include <fs_avb/fs_avb.h>
4342 #include <fs_mgr_vendor_overlay.h>
4443 #include <keyutils.h>
@@ -601,17 +600,6 @@ void HandleKeychord(const std::vector<int>& keycodes) {
601600 }
602601 }
603602
604-static void InitAborter(const char* abort_message) {
605- // When init forks, it continues to use this aborter for LOG(FATAL), but we want children to
606- // simply abort instead of trying to reboot the system.
607- if (getpid() != 1) {
608- android::base::DefaultAborter(abort_message);
609- return;
610- }
611-
612- RebootSystem(ANDROID_RB_RESTART2, "bootloader");
613-}
614-
615603 static void GlobalSeccomp() {
616604 import_kernel_cmdline(false, [](const std::string& key, const std::string& value,
617605 bool in_qemu) {
@@ -632,8 +620,8 @@ int SecondStageMain(int argc, char** argv) {
632620 InstallRebootSignalHandlers();
633621 }
634622
635- // We need to set up stdin/stdout/stderr again now that we're running in init's context.
636- InitKernelLogging(argv, InitAborter);
623+ SetStdioToDevNull(argv);
624+ InitKernelLogging(argv);
637625 LOG(INFO) << "init second stage started!";
638626
639627 // Set init and its forked children's oom_adj.
--- a/init/reboot_utils.cpp
+++ b/init/reboot_utils.cpp
@@ -19,8 +19,13 @@
1919 #include <sys/syscall.h>
2020 #include <unistd.h>
2121
22-#include <android-base/logging.h>
23-#include <cutils/android_reboot.h>
22+#include <string>
23+
24+#include "android-base/file.h"
25+#include "android-base/logging.h"
26+#include "android-base/strings.h"
27+#include "backtrace/Backtrace.h"
28+#include "cutils/android_reboot.h"
2429
2530 #include "capabilities.h"
2631
@@ -75,6 +80,32 @@ void __attribute__((noreturn)) RebootSystem(unsigned int cmd, const std::string&
7580 abort();
7681 }
7782
83+void __attribute__((noreturn)) InitFatalReboot() {
84+ auto pid = fork();
85+
86+ if (pid == -1) {
87+ // Couldn't fork, don't even try to backtrace, just reboot.
88+ RebootSystem(ANDROID_RB_RESTART2, "bootloader");
89+ } else if (pid == 0) {
90+ // Fork a child for safety, since we always want to shut down if something goes wrong, but
91+ // its worth trying to get the backtrace, even in the signal handler, since typically it
92+ // does work despite not being async-signal-safe.
93+ sleep(5);
94+ RebootSystem(ANDROID_RB_RESTART2, "bootloader");
95+ }
96+
97+ // In the parent, let's try to get a backtrace then shutdown.
98+ std::unique_ptr<Backtrace> backtrace(
99+ Backtrace::Create(BACKTRACE_CURRENT_PROCESS, BACKTRACE_CURRENT_THREAD));
100+ if (!backtrace->Unwind(0)) {
101+ LOG(ERROR) << __FUNCTION__ << ": Failed to unwind callstack.";
102+ }
103+ for (size_t i = 0; i < backtrace->NumFrames(); i++) {
104+ LOG(ERROR) << backtrace->FormatFrameData(i);
105+ }
106+ RebootSystem(ANDROID_RB_RESTART2, "bootloader");
107+}
108+
78109 void InstallRebootSignalHandlers() {
79110 // Instead of panic'ing the kernel as is the default behavior when init crashes,
80111 // we prefer to reboot to bootloader on development builds, as this will prevent
@@ -94,7 +125,7 @@ void InstallRebootSignalHandlers() {
94125 // RebootSystem uses syscall() which isn't actually async-signal-safe, but our only option
95126 // and probably good enough given this is already an error case and only enabled for
96127 // development builds.
97- RebootSystem(ANDROID_RB_RESTART2, "bootloader");
128+ InitFatalReboot();
98129 };
99130 action.sa_flags = SA_RESTART;
100131 sigaction(SIGABRT, &action, nullptr);
--- a/init/reboot_utils.h
+++ b/init/reboot_utils.h
@@ -26,6 +26,7 @@ namespace init {
2626 bool IsRebootCapable();
2727 // This is a wrapper around the actual reboot calls.
2828 void __attribute__((noreturn)) RebootSystem(unsigned int cmd, const std::string& reboot_target);
29+void __attribute__((noreturn)) InitFatalReboot();
2930 void InstallRebootSignalHandlers();
3031
3132 } // namespace init
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -60,7 +60,6 @@
6060 #include <android-base/logging.h>
6161 #include <android-base/parseint.h>
6262 #include <android-base/unique_fd.h>
63-#include <cutils/android_reboot.h>
6463 #include <fs_avb/fs_avb.h>
6564 #include <selinux/android.h>
6665
@@ -518,9 +517,7 @@ int SelinuxGetVendorAndroidVersion() {
518517
519518 // This function initializes SELinux then execs init to run in the init SELinux context.
520519 int SetupSelinux(char** argv) {
521- android::base::InitLogging(argv, &android::base::KernelLogger, [](const char*) {
522- RebootSystem(ANDROID_RB_RESTART2, "bootloader");
523- });
520+ InitKernelLogging(argv);
524521
525522 if (REBOOT_BOOTLOADER_ON_PANIC) {
526523 InstallRebootSignalHandlers();
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -40,6 +40,7 @@
4040 #include <selinux/android.h>
4141
4242 #if defined(__ANDROID__)
43+#include "reboot_utils.h"
4344 #include "selinux.h"
4445 #else
4546 #include "host_init_stubs.h"
@@ -425,20 +426,49 @@ bool IsLegalPropertyName(const std::string& name) {
425426 return true;
426427 }
427428
428-void InitKernelLogging(char** argv, std::function<void(const char*)> abort_function) {
429+static void InitAborter(const char* abort_message) {
430+ // When init forks, it continues to use this aborter for LOG(FATAL), but we want children to
431+ // simply abort instead of trying to reboot the system.
432+ if (getpid() != 1) {
433+ android::base::DefaultAborter(abort_message);
434+ return;
435+ }
436+
437+ InitFatalReboot();
438+}
439+
440+// The kernel opens /dev/console and uses that fd for stdin/stdout/stderr if there is a serial
441+// console enabled and no initramfs, otherwise it does not provide any fds for stdin/stdout/stderr.
442+// SetStdioToDevNull() is used to close these existing fds if they exist and replace them with
443+// /dev/null regardless.
444+//
445+// In the case that these fds are provided by the kernel, the exec of second stage init causes an
446+// SELinux denial as it does not have access to /dev/console. In the case that they are not
447+// provided, exec of any further process is potentially dangerous as the first fd's opened by that
448+// process will take the stdin/stdout/stderr fileno's, which can cause issues if printf(), etc is
449+// then used by that process.
450+//
451+// Lastly, simply calling SetStdioToDevNull() in first stage init is not enough, since first
452+// stage init still runs in kernel context, future child processes will not have permissions to
453+// access any fds that it opens, including the one opened below for /dev/null. Therefore,
454+// SetStdioToDevNull() must be called again in second stage init.
455+void SetStdioToDevNull(char** argv) {
429456 // Make stdin/stdout/stderr all point to /dev/null.
430457 int fd = open("/dev/null", O_RDWR);
431458 if (fd == -1) {
432459 int saved_errno = errno;
433- android::base::InitLogging(argv, &android::base::KernelLogger, std::move(abort_function));
460+ android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
434461 errno = saved_errno;
435462 PLOG(FATAL) << "Couldn't open /dev/null";
436463 }
437- dup2(fd, 0);
438- dup2(fd, 1);
439- dup2(fd, 2);
440- if (fd > 2) close(fd);
441- android::base::InitLogging(argv, &android::base::KernelLogger, std::move(abort_function));
464+ dup2(fd, STDIN_FILENO);
465+ dup2(fd, STDOUT_FILENO);
466+ dup2(fd, STDERR_FILENO);
467+ if (fd > STDERR_FILENO) close(fd);
468+}
469+
470+void InitKernelLogging(char** argv) {
471+ android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
442472 }
443473
444474 bool IsRecoveryMode() {
--- a/init/util.h
+++ b/init/util.h
@@ -63,7 +63,8 @@ bool is_android_dt_value_expected(const std::string& sub_path, const std::string
6363
6464 bool IsLegalPropertyName(const std::string& name);
6565
66-void InitKernelLogging(char** argv, std::function<void(const char*)> abort_function);
66+void SetStdioToDevNull(char** argv);
67+void InitKernelLogging(char** argv);
6768 bool IsRecoveryMode();
6869 } // namespace init
6970 } // namespace android