Loading debuggerd/libdebuggerd/utility.cpp +45 −1 Original line number Diff line number Diff line Loading @@ -22,16 +22,22 @@ #include <signal.h> #include <string.h> #include <sys/ptrace.h> #include <sys/uio.h> #include <sys/wait.h> #include <unistd.h> #include <string> #include <android-base/logging.h> #include <android-base/properties.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <android-base/unique_fd.h> #include <backtrace/Backtrace.h> #include <log/log.h> using android::base::unique_fd; // Whitelist output desired in the logcat output. bool is_allowed_in_logcat(enum logtype ltype) { if ((ltype == HEADER) Loading @@ -42,6 +48,19 @@ bool is_allowed_in_logcat(enum logtype ltype) { return false; } static bool should_write_to_kmsg() { // Write to kmsg if tombstoned isn't up, and we're able to do so. if (!android::base::GetBoolProperty("ro.debuggable", false)) { return false; } if (android::base::GetProperty("init.svc.tombstoned", "") == "running") { return false; } return true; } __attribute__((__weak__, visibility("default"))) void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { bool write_to_tombstone = (log->tfd != -1); Loading @@ -49,6 +68,7 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { && log->crashed_tid != -1 && log->current_tid != -1 && (log->crashed_tid == log->current_tid); static bool write_to_kmsg = should_write_to_kmsg(); char buf[512]; va_list ap; Loading @@ -70,6 +90,30 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { if (log->amfd_data != nullptr) { *log->amfd_data += buf; } if (write_to_kmsg) { unique_fd kmsg_fd(open("/dev/kmsg_debug", O_WRONLY | O_APPEND | O_CLOEXEC)); if (kmsg_fd.get() >= 0) { // Our output might contain newlines which would otherwise be handled by the android logger. // Split the lines up ourselves before sending to the kernel logger. if (buf[len - 1] == '\n') { buf[len - 1] = '\0'; } std::vector<std::string> fragments = android::base::Split(buf, "\n"); for (const std::string& fragment : fragments) { static constexpr char prefix[] = "<3>DEBUG: "; struct iovec iov[3]; iov[0].iov_base = const_cast<char*>(prefix); iov[0].iov_len = strlen(prefix); iov[1].iov_base = const_cast<char*>(fragment.c_str()); iov[1].iov_len = fragment.length(); iov[2].iov_base = const_cast<char*>("\n"); iov[2].iov_len = 1; TEMP_FAILURE_RETRY(writev(kmsg_fd.get(), iov, 3)); } } } } } Loading Loading @@ -205,7 +249,7 @@ void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* f } void read_with_default(const char* path, char* buf, size_t len, const char* default_value) { android::base::unique_fd fd(open(path, O_RDONLY)); unique_fd fd(open(path, O_RDONLY | O_CLOEXEC)); if (fd != -1) { int rc = TEMP_FAILURE_RETRY(read(fd.get(), buf, len - 1)); if (rc != -1) { Loading init/Android.mk +4 −2 Original line number Diff line number Diff line Loading @@ -8,12 +8,14 @@ ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) init_options += \ -DALLOW_LOCAL_PROP_OVERRIDE=1 \ -DALLOW_PERMISSIVE_SELINUX=1 \ -DREBOOT_BOOTLOADER_ON_PANIC=1 -DREBOOT_BOOTLOADER_ON_PANIC=1 \ -DWORLD_WRITABLE_KMSG=1 else init_options += \ -DALLOW_LOCAL_PROP_OVERRIDE=0 \ -DALLOW_PERMISSIVE_SELINUX=0 \ -DREBOOT_BOOTLOADER_ON_PANIC=0 -DREBOOT_BOOTLOADER_ON_PANIC=0 \ -DWORLD_WRITABLE_KMSG=0 endif ifneq (,$(filter eng,$(TARGET_BUILD_VARIANT))) Loading init/init.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -890,6 +890,9 @@ static void selinux_restore_context() { LOG(INFO) << "Running restorecon..."; restorecon("/dev"); restorecon("/dev/kmsg"); if constexpr (WORLD_WRITABLE_KMSG) { restorecon("/dev/kmsg_debug"); } restorecon("/dev/socket"); restorecon("/dev/random"); restorecon("/dev/urandom"); Loading Loading @@ -1166,7 +1169,13 @@ int main(int argc, char** argv) { setgroups(arraysize(groups), groups); mount("sysfs", "/sys", "sysfs", 0, NULL); mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL); mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)); if constexpr (WORLD_WRITABLE_KMSG) { mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11)); } mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)); mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)); Loading Loading
debuggerd/libdebuggerd/utility.cpp +45 −1 Original line number Diff line number Diff line Loading @@ -22,16 +22,22 @@ #include <signal.h> #include <string.h> #include <sys/ptrace.h> #include <sys/uio.h> #include <sys/wait.h> #include <unistd.h> #include <string> #include <android-base/logging.h> #include <android-base/properties.h> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include <android-base/unique_fd.h> #include <backtrace/Backtrace.h> #include <log/log.h> using android::base::unique_fd; // Whitelist output desired in the logcat output. bool is_allowed_in_logcat(enum logtype ltype) { if ((ltype == HEADER) Loading @@ -42,6 +48,19 @@ bool is_allowed_in_logcat(enum logtype ltype) { return false; } static bool should_write_to_kmsg() { // Write to kmsg if tombstoned isn't up, and we're able to do so. if (!android::base::GetBoolProperty("ro.debuggable", false)) { return false; } if (android::base::GetProperty("init.svc.tombstoned", "") == "running") { return false; } return true; } __attribute__((__weak__, visibility("default"))) void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { bool write_to_tombstone = (log->tfd != -1); Loading @@ -49,6 +68,7 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { && log->crashed_tid != -1 && log->current_tid != -1 && (log->crashed_tid == log->current_tid); static bool write_to_kmsg = should_write_to_kmsg(); char buf[512]; va_list ap; Loading @@ -70,6 +90,30 @@ void _LOG(log_t* log, enum logtype ltype, const char* fmt, ...) { if (log->amfd_data != nullptr) { *log->amfd_data += buf; } if (write_to_kmsg) { unique_fd kmsg_fd(open("/dev/kmsg_debug", O_WRONLY | O_APPEND | O_CLOEXEC)); if (kmsg_fd.get() >= 0) { // Our output might contain newlines which would otherwise be handled by the android logger. // Split the lines up ourselves before sending to the kernel logger. if (buf[len - 1] == '\n') { buf[len - 1] = '\0'; } std::vector<std::string> fragments = android::base::Split(buf, "\n"); for (const std::string& fragment : fragments) { static constexpr char prefix[] = "<3>DEBUG: "; struct iovec iov[3]; iov[0].iov_base = const_cast<char*>(prefix); iov[0].iov_len = strlen(prefix); iov[1].iov_base = const_cast<char*>(fragment.c_str()); iov[1].iov_len = fragment.length(); iov[2].iov_base = const_cast<char*>("\n"); iov[2].iov_len = 1; TEMP_FAILURE_RETRY(writev(kmsg_fd.get(), iov, 3)); } } } } } Loading Loading @@ -205,7 +249,7 @@ void dump_memory(log_t* log, Backtrace* backtrace, uintptr_t addr, const char* f } void read_with_default(const char* path, char* buf, size_t len, const char* default_value) { android::base::unique_fd fd(open(path, O_RDONLY)); unique_fd fd(open(path, O_RDONLY | O_CLOEXEC)); if (fd != -1) { int rc = TEMP_FAILURE_RETRY(read(fd.get(), buf, len - 1)); if (rc != -1) { Loading
init/Android.mk +4 −2 Original line number Diff line number Diff line Loading @@ -8,12 +8,14 @@ ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) init_options += \ -DALLOW_LOCAL_PROP_OVERRIDE=1 \ -DALLOW_PERMISSIVE_SELINUX=1 \ -DREBOOT_BOOTLOADER_ON_PANIC=1 -DREBOOT_BOOTLOADER_ON_PANIC=1 \ -DWORLD_WRITABLE_KMSG=1 else init_options += \ -DALLOW_LOCAL_PROP_OVERRIDE=0 \ -DALLOW_PERMISSIVE_SELINUX=0 \ -DREBOOT_BOOTLOADER_ON_PANIC=0 -DREBOOT_BOOTLOADER_ON_PANIC=0 \ -DWORLD_WRITABLE_KMSG=0 endif ifneq (,$(filter eng,$(TARGET_BUILD_VARIANT))) Loading
init/init.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -890,6 +890,9 @@ static void selinux_restore_context() { LOG(INFO) << "Running restorecon..."; restorecon("/dev"); restorecon("/dev/kmsg"); if constexpr (WORLD_WRITABLE_KMSG) { restorecon("/dev/kmsg_debug"); } restorecon("/dev/socket"); restorecon("/dev/random"); restorecon("/dev/urandom"); Loading Loading @@ -1166,7 +1169,13 @@ int main(int argc, char** argv) { setgroups(arraysize(groups), groups); mount("sysfs", "/sys", "sysfs", 0, NULL); mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL); mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11)); if constexpr (WORLD_WRITABLE_KMSG) { mknod("/dev/kmsg_debug", S_IFCHR | 0622, makedev(1, 11)); } mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8)); mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9)); Loading