Loading crash_reporter/crash_collector.cc +10 −28 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ const char kDefaultUserName[] = "chronos"; const char kLeaveCoreFile[] = "/root/.leave_core"; const char kLsbRelease[] = "/etc/lsb-release"; const char kShellPath[] = "/bin/sh"; const char kSystemCrashPath[] = "/var/spool/crash"; const char kSystemCrashPath[] = "/data/misc/crash_reporter/crash"; const char kUploadVarPrefix[] = "upload_var_"; const char kUploadFilePrefix[] = "upload_file_"; Loading Loading @@ -148,24 +148,14 @@ FilePath CrashCollector::GetCrashPath(const FilePath &crash_directory, } FilePath CrashCollector::GetCrashDirectoryInfo( uid_t process_euid, uid_t default_user_id, gid_t default_user_group, mode_t *mode, uid_t *directory_owner, gid_t *directory_group) { if (process_euid == default_user_id) { *mode = kUserCrashPathMode; *directory_owner = default_user_id; *directory_group = default_user_group; return FilePath(kFallbackUserCrashPath); } else { *mode = kSystemCrashPathMode; *directory_owner = kRootOwner; *directory_group = kRootGroup; return FilePath(kSystemCrashPath); } } bool CrashCollector::GetUserInfoFromName(const std::string &name, uid_t *uid, Loading @@ -188,9 +178,6 @@ bool CrashCollector::GetUserInfoFromName(const std::string &name, bool CrashCollector::GetCreatedCrashDirectoryByEuid(uid_t euid, FilePath *crash_directory, bool *out_of_capacity) { uid_t default_user_id; gid_t default_user_group; if (out_of_capacity) *out_of_capacity = false; // For testing. Loading @@ -199,20 +186,11 @@ bool CrashCollector::GetCreatedCrashDirectoryByEuid(uid_t euid, return true; } if (!GetUserInfoFromName(kDefaultUserName, &default_user_id, &default_user_group)) { LOG(ERROR) << "Could not find default user info"; return false; } mode_t directory_mode; uid_t directory_owner; gid_t directory_group; *crash_directory = GetCrashDirectoryInfo(euid, default_user_id, default_user_group, &directory_mode, GetCrashDirectoryInfo(&directory_mode, &directory_owner, &directory_group); Loading @@ -238,6 +216,8 @@ bool CrashCollector::GetCreatedCrashDirectoryByEuid(uid_t euid, if (!CheckHasCapacity(*crash_directory)) { if (out_of_capacity) *out_of_capacity = true; LOG(ERROR) << "Directory " << crash_directory->value() << " is out of capacity."; return false; } Loading Loading @@ -309,6 +289,8 @@ bool CrashCollector::GetExecutableBaseNameFromPid(pid_t pid, bool CrashCollector::CheckHasCapacity(const FilePath &crash_directory) { DIR* dir = opendir(crash_directory.value().c_str()); if (!dir) { LOG(WARNING) << "Unable to open crash directory " << crash_directory.value(); return false; } struct dirent ent_buf; Loading crash_reporter/crash_collector.h +3 −6 Original line number Diff line number Diff line Loading @@ -72,10 +72,7 @@ class CrashCollector { forced_crash_directory_ = forced_directory; } base::FilePath GetCrashDirectoryInfo(uid_t process_euid, uid_t default_user_id, gid_t default_user_group, mode_t *mode, base::FilePath GetCrashDirectoryInfo(mode_t *mode, uid_t *directory_owner, gid_t *directory_group); bool GetUserInfoFromName(const std::string &name, Loading crash_reporter/crash_collector_test.cc +0 −48 Original line number Diff line number Diff line Loading @@ -83,54 +83,6 @@ TEST_F(CrashCollectorTest, Sanitize) { EXPECT_EQ("_", collector_.Sanitize(" ")); } TEST_F(CrashCollectorTest, GetCrashDirectoryInfo) { FilePath path; const int kRootUid = 0; const int kRootGid = 0; const int kNtpUid = 5; const int kChronosUid = 1000; const int kChronosGid = 1001; const mode_t kExpectedSystemMode = 01755; const mode_t kExpectedUserMode = 0755; mode_t directory_mode; uid_t directory_owner; gid_t directory_group; path = collector_.GetCrashDirectoryInfo(kRootUid, kChronosUid, kChronosGid, &directory_mode, &directory_owner, &directory_group); EXPECT_EQ("/var/spool/crash", path.value()); EXPECT_EQ(kExpectedSystemMode, directory_mode); EXPECT_EQ(kRootUid, directory_owner); EXPECT_EQ(kRootGid, directory_group); path = collector_.GetCrashDirectoryInfo(kNtpUid, kChronosUid, kChronosGid, &directory_mode, &directory_owner, &directory_group); EXPECT_EQ("/var/spool/crash", path.value()); EXPECT_EQ(kExpectedSystemMode, directory_mode); EXPECT_EQ(kRootUid, directory_owner); EXPECT_EQ(kRootGid, directory_group); path = collector_.GetCrashDirectoryInfo(kChronosUid, kChronosUid, kChronosGid, &directory_mode, &directory_owner, &directory_group); EXPECT_EQ("/var/spool/crash", path.value()); EXPECT_EQ(kExpectedUserMode, directory_mode); EXPECT_EQ(kChronosUid, directory_owner); EXPECT_EQ(kChronosGid, directory_group); } TEST_F(CrashCollectorTest, FormatDumpBasename) { struct tm tm = {0}; tm.tm_sec = 15; Loading crash_reporter/init.crash_reporter.rc 0 → 100644 +19 −0 Original line number Diff line number Diff line on property:crash_reporter.coredump.enabled=1 write /proc/sys/kernel/core_pattern \ "|/system/bin/crash_reporter --user=%P:%s:%u:%e" on property:crash_reporter.coredump.enabled=0 write /proc/sys/kernel/core_pattern "core" on boot # Allow catching multiple unrelated concurrent crashes, but use a finite # number to prevent infinitely recursing on crash handling. write /proc/sys/kernel/core_pipe_limit 4 # Create crash directories. mkdir /data/misc/crash_reporter 0700 root root mkdir /data/local/tmp/crash_reporter 0700 root root service crash_reporter /system/bin/crash_reporter --init class late_start oneshot crash_reporter/user_collector.cc +9 −25 Original line number Diff line number Diff line Loading @@ -24,21 +24,17 @@ #include <base/strings/stringprintf.h> #include <chromeos/process.h> #include <chromeos/syslog_logging.h> #include <cutils/properties.h> static const char kCollectionErrorSignature[] = "crash_reporter-user-collection"; // This procfs file is used to cause kernel core file writing to // instead pipe the core file into a user space process. See // core(5) man page. static const char kCorePatternFile[] = "/proc/sys/kernel/core_pattern"; static const char kCorePipeLimitFile[] = "/proc/sys/kernel/core_pipe_limit"; // Set core_pipe_limit to 4 so that we can catch a few unrelated concurrent // crashes, but finite to avoid infinitely recursing on crash handling. static const char kCorePipeLimit[] = "4"; static const char kCoreToMinidumpConverterPath[] = "/usr/bin/core2md"; static const char kCorePatternProperty[] = "crash_reporter.coredump.enabled"; static const char kCoreToMinidumpConverterPath[] = "/system/bin/core2md"; static const char kStatePrefix[] = "State:\t"; static const char kCoreTempFolder[] = "/data/local/tmp/crash_reporter"; // Define an otherwise invalid value that represents an unknown UID. static const uid_t kUnknownUid = -1; Loading @@ -50,8 +46,6 @@ using base::StringPrintf; UserCollector::UserCollector() : generate_diagnostics_(false), core_pattern_file_(kCorePatternFile), core_pipe_limit_file_(kCorePipeLimitFile), initialized_(false) { } Loading Loading @@ -115,18 +109,8 @@ bool UserCollector::SetUpInternal(bool enabled) { CHECK(initialized_); LOG(INFO) << (enabled ? "Enabling" : "Disabling") << " user crash handling"; if (base::WriteFile(FilePath(core_pipe_limit_file_), kCorePipeLimit, strlen(kCorePipeLimit)) != static_cast<int>(strlen(kCorePipeLimit))) { PLOG(ERROR) << "Unable to write " << core_pipe_limit_file_; return false; } std::string pattern = GetPattern(enabled); if (base::WriteFile(FilePath(core_pattern_file_), pattern.c_str(), pattern.length()) != static_cast<int>(pattern.length())) { PLOG(ERROR) << "Unable to write " << core_pattern_file_; return false; } property_set(kCorePatternProperty, enabled ? "1" : "0"); return true; } Loading Loading @@ -342,7 +326,7 @@ bool UserCollector::GetCreatedCrashDirectory(pid_t pid, uid_t supplied_ruid, bool UserCollector::CopyStdinToCoreFile(const FilePath &core_path) { // Copy off all stdin to a core file. FilePath stdin_path("/dev/fd/0"); FilePath stdin_path("/proc/self/fd/0"); if (base::CopyFile(stdin_path, core_path)) { return true; } Loading Loading @@ -438,7 +422,7 @@ UserCollector::ErrorType UserCollector::ConvertAndEnqueueCrash( // Directory like /tmp/crash_reporter/1234 which contains the // procfs entries and other temporary files used during conversion. FilePath container_dir(StringPrintf("/tmp/crash_reporter/%d", pid)); FilePath container_dir(StringPrintf("%s/%d", kCoreTempFolder, pid)); // Delete a pre-existing directory from crash reporter that may have // been left around for diagnostics from a failed conversion attempt. // If we don't, existing files can cause forking to fail. Loading Loading
crash_reporter/crash_collector.cc +10 −28 Original line number Diff line number Diff line Loading @@ -36,7 +36,7 @@ const char kDefaultUserName[] = "chronos"; const char kLeaveCoreFile[] = "/root/.leave_core"; const char kLsbRelease[] = "/etc/lsb-release"; const char kShellPath[] = "/bin/sh"; const char kSystemCrashPath[] = "/var/spool/crash"; const char kSystemCrashPath[] = "/data/misc/crash_reporter/crash"; const char kUploadVarPrefix[] = "upload_var_"; const char kUploadFilePrefix[] = "upload_file_"; Loading Loading @@ -148,24 +148,14 @@ FilePath CrashCollector::GetCrashPath(const FilePath &crash_directory, } FilePath CrashCollector::GetCrashDirectoryInfo( uid_t process_euid, uid_t default_user_id, gid_t default_user_group, mode_t *mode, uid_t *directory_owner, gid_t *directory_group) { if (process_euid == default_user_id) { *mode = kUserCrashPathMode; *directory_owner = default_user_id; *directory_group = default_user_group; return FilePath(kFallbackUserCrashPath); } else { *mode = kSystemCrashPathMode; *directory_owner = kRootOwner; *directory_group = kRootGroup; return FilePath(kSystemCrashPath); } } bool CrashCollector::GetUserInfoFromName(const std::string &name, uid_t *uid, Loading @@ -188,9 +178,6 @@ bool CrashCollector::GetUserInfoFromName(const std::string &name, bool CrashCollector::GetCreatedCrashDirectoryByEuid(uid_t euid, FilePath *crash_directory, bool *out_of_capacity) { uid_t default_user_id; gid_t default_user_group; if (out_of_capacity) *out_of_capacity = false; // For testing. Loading @@ -199,20 +186,11 @@ bool CrashCollector::GetCreatedCrashDirectoryByEuid(uid_t euid, return true; } if (!GetUserInfoFromName(kDefaultUserName, &default_user_id, &default_user_group)) { LOG(ERROR) << "Could not find default user info"; return false; } mode_t directory_mode; uid_t directory_owner; gid_t directory_group; *crash_directory = GetCrashDirectoryInfo(euid, default_user_id, default_user_group, &directory_mode, GetCrashDirectoryInfo(&directory_mode, &directory_owner, &directory_group); Loading @@ -238,6 +216,8 @@ bool CrashCollector::GetCreatedCrashDirectoryByEuid(uid_t euid, if (!CheckHasCapacity(*crash_directory)) { if (out_of_capacity) *out_of_capacity = true; LOG(ERROR) << "Directory " << crash_directory->value() << " is out of capacity."; return false; } Loading Loading @@ -309,6 +289,8 @@ bool CrashCollector::GetExecutableBaseNameFromPid(pid_t pid, bool CrashCollector::CheckHasCapacity(const FilePath &crash_directory) { DIR* dir = opendir(crash_directory.value().c_str()); if (!dir) { LOG(WARNING) << "Unable to open crash directory " << crash_directory.value(); return false; } struct dirent ent_buf; Loading
crash_reporter/crash_collector.h +3 −6 Original line number Diff line number Diff line Loading @@ -72,10 +72,7 @@ class CrashCollector { forced_crash_directory_ = forced_directory; } base::FilePath GetCrashDirectoryInfo(uid_t process_euid, uid_t default_user_id, gid_t default_user_group, mode_t *mode, base::FilePath GetCrashDirectoryInfo(mode_t *mode, uid_t *directory_owner, gid_t *directory_group); bool GetUserInfoFromName(const std::string &name, Loading
crash_reporter/crash_collector_test.cc +0 −48 Original line number Diff line number Diff line Loading @@ -83,54 +83,6 @@ TEST_F(CrashCollectorTest, Sanitize) { EXPECT_EQ("_", collector_.Sanitize(" ")); } TEST_F(CrashCollectorTest, GetCrashDirectoryInfo) { FilePath path; const int kRootUid = 0; const int kRootGid = 0; const int kNtpUid = 5; const int kChronosUid = 1000; const int kChronosGid = 1001; const mode_t kExpectedSystemMode = 01755; const mode_t kExpectedUserMode = 0755; mode_t directory_mode; uid_t directory_owner; gid_t directory_group; path = collector_.GetCrashDirectoryInfo(kRootUid, kChronosUid, kChronosGid, &directory_mode, &directory_owner, &directory_group); EXPECT_EQ("/var/spool/crash", path.value()); EXPECT_EQ(kExpectedSystemMode, directory_mode); EXPECT_EQ(kRootUid, directory_owner); EXPECT_EQ(kRootGid, directory_group); path = collector_.GetCrashDirectoryInfo(kNtpUid, kChronosUid, kChronosGid, &directory_mode, &directory_owner, &directory_group); EXPECT_EQ("/var/spool/crash", path.value()); EXPECT_EQ(kExpectedSystemMode, directory_mode); EXPECT_EQ(kRootUid, directory_owner); EXPECT_EQ(kRootGid, directory_group); path = collector_.GetCrashDirectoryInfo(kChronosUid, kChronosUid, kChronosGid, &directory_mode, &directory_owner, &directory_group); EXPECT_EQ("/var/spool/crash", path.value()); EXPECT_EQ(kExpectedUserMode, directory_mode); EXPECT_EQ(kChronosUid, directory_owner); EXPECT_EQ(kChronosGid, directory_group); } TEST_F(CrashCollectorTest, FormatDumpBasename) { struct tm tm = {0}; tm.tm_sec = 15; Loading
crash_reporter/init.crash_reporter.rc 0 → 100644 +19 −0 Original line number Diff line number Diff line on property:crash_reporter.coredump.enabled=1 write /proc/sys/kernel/core_pattern \ "|/system/bin/crash_reporter --user=%P:%s:%u:%e" on property:crash_reporter.coredump.enabled=0 write /proc/sys/kernel/core_pattern "core" on boot # Allow catching multiple unrelated concurrent crashes, but use a finite # number to prevent infinitely recursing on crash handling. write /proc/sys/kernel/core_pipe_limit 4 # Create crash directories. mkdir /data/misc/crash_reporter 0700 root root mkdir /data/local/tmp/crash_reporter 0700 root root service crash_reporter /system/bin/crash_reporter --init class late_start oneshot
crash_reporter/user_collector.cc +9 −25 Original line number Diff line number Diff line Loading @@ -24,21 +24,17 @@ #include <base/strings/stringprintf.h> #include <chromeos/process.h> #include <chromeos/syslog_logging.h> #include <cutils/properties.h> static const char kCollectionErrorSignature[] = "crash_reporter-user-collection"; // This procfs file is used to cause kernel core file writing to // instead pipe the core file into a user space process. See // core(5) man page. static const char kCorePatternFile[] = "/proc/sys/kernel/core_pattern"; static const char kCorePipeLimitFile[] = "/proc/sys/kernel/core_pipe_limit"; // Set core_pipe_limit to 4 so that we can catch a few unrelated concurrent // crashes, but finite to avoid infinitely recursing on crash handling. static const char kCorePipeLimit[] = "4"; static const char kCoreToMinidumpConverterPath[] = "/usr/bin/core2md"; static const char kCorePatternProperty[] = "crash_reporter.coredump.enabled"; static const char kCoreToMinidumpConverterPath[] = "/system/bin/core2md"; static const char kStatePrefix[] = "State:\t"; static const char kCoreTempFolder[] = "/data/local/tmp/crash_reporter"; // Define an otherwise invalid value that represents an unknown UID. static const uid_t kUnknownUid = -1; Loading @@ -50,8 +46,6 @@ using base::StringPrintf; UserCollector::UserCollector() : generate_diagnostics_(false), core_pattern_file_(kCorePatternFile), core_pipe_limit_file_(kCorePipeLimitFile), initialized_(false) { } Loading Loading @@ -115,18 +109,8 @@ bool UserCollector::SetUpInternal(bool enabled) { CHECK(initialized_); LOG(INFO) << (enabled ? "Enabling" : "Disabling") << " user crash handling"; if (base::WriteFile(FilePath(core_pipe_limit_file_), kCorePipeLimit, strlen(kCorePipeLimit)) != static_cast<int>(strlen(kCorePipeLimit))) { PLOG(ERROR) << "Unable to write " << core_pipe_limit_file_; return false; } std::string pattern = GetPattern(enabled); if (base::WriteFile(FilePath(core_pattern_file_), pattern.c_str(), pattern.length()) != static_cast<int>(pattern.length())) { PLOG(ERROR) << "Unable to write " << core_pattern_file_; return false; } property_set(kCorePatternProperty, enabled ? "1" : "0"); return true; } Loading Loading @@ -342,7 +326,7 @@ bool UserCollector::GetCreatedCrashDirectory(pid_t pid, uid_t supplied_ruid, bool UserCollector::CopyStdinToCoreFile(const FilePath &core_path) { // Copy off all stdin to a core file. FilePath stdin_path("/dev/fd/0"); FilePath stdin_path("/proc/self/fd/0"); if (base::CopyFile(stdin_path, core_path)) { return true; } Loading Loading @@ -438,7 +422,7 @@ UserCollector::ErrorType UserCollector::ConvertAndEnqueueCrash( // Directory like /tmp/crash_reporter/1234 which contains the // procfs entries and other temporary files used during conversion. FilePath container_dir(StringPrintf("/tmp/crash_reporter/%d", pid)); FilePath container_dir(StringPrintf("%s/%d", kCoreTempFolder, pid)); // Delete a pre-existing directory from crash reporter that may have // been left around for diagnostics from a failed conversion attempt. // If we don't, existing files can cause forking to fail. Loading