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

Unverified Commit e5a5717d authored by Michael Bestas's avatar Michael Bestas
Browse files

Merge tag 'android-16.0.0_r3' into staging/lineage-23.0_merge-android-16.0.0_r3

Android 16.0.0 Release 3 (BP3A.250905.014)

# -----BEGIN PGP SIGNATURE-----
#
# iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCaRO/HQAKCRDorT+BmrEO
# eDdjAJ9uKTosjsyJa14wdWkVB1AxXiE1hgCaA4EF7u1pAleYwFH/M/hdUWeLIKk=
# =SavO
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed Nov 12 00:56:29 2025 EET
# gpg:                using DSA key 4340D13570EF945E83810964E8AD3F819AB10E78
# gpg: Good signature from "The Android Open Source Project <initial-contribution@android.com>" [ultimate]

# By David Anderson (17) and others
# Via Android (Google) Code Review (135) and others
* tag 'android-16.0.0_r3': (189 commits)
  Revert "Ensure to kill all processes and reap them before unmounting"
  Ensure to kill all processes and reap them before unmounting
  Remove override_creds flag
  fastboot: Delay resparsing until flash_buf() is called.
  libsparse: Propagate errors when writing skip chunks.
  fastboot: Convert sparse_file usage to RAII.
  fastbootd: Remove an erroneous partition size check.
  Use libbase STRINGIFY().
  liblp: Add flock() for accessing partitions
  prefetch: use latest version of rand crate
  [owners] Remove rayhdez@google.com from libstats/OWNERS
  fix log comment
  remove unused includes
  Set task profiles for read ahead thread
  prefetch: Handle large folios correctly
  Install vintf dependencies using Soong
  libsnapshot: Print current slot during rollback
  init: Avoid unnecessarily setting sys.use_memfd to false
  Clean up debuggerd tests.
  Check the amount of dirty pages to flush out
  ...

 Conflicts:
	init/first_stage_mount.cpp
	init/property_service.cpp
	init/service_parser.cpp
	libmodprobe/include/modprobe/modprobe.h

Change-Id: I8a67e889bcf8537b828c4e02edbbec0ddd541aa0
parents 914a773a 4deec405
Loading
Loading
Loading
Loading
+36 −3
Original line number Diff line number Diff line
@@ -67,9 +67,6 @@ cc_binary {
    name: "bootstat",
    defaults: ["bootstat_defaults"],
    static_libs: ["libbootstat"],
    shared_libs: [
        "libstatslog"
    ],
    init_rc: ["bootstat.rc"],
    product_variables: {
        debuggable: {
@@ -77,6 +74,15 @@ cc_binary {
        },
    },
    srcs: ["bootstat.cpp"],
    generated_sources: [
        "statslog_bootstats.cpp",
    ],
    generated_headers: [
        "statslog_bootstats.h",
    ],
    shared_libs: [
        "libstatssocket",
    ],
}

// Native tests
@@ -98,3 +104,30 @@ cc_test {
        unit_test: true,
    },
}

// StatsD atom logging
//------------------------------------------------------------------------------
genrule {
    name: "statslog_bootstats.h",
    tools: ["stats-log-api-gen"],
    cmd: "$(location stats-log-api-gen)" +
        " --header $(genDir)/statslog_bootstats.h" +
        " --module bootstats" +
        " --namespace android,util,bootstats",
    out: [
        "statslog_bootstats.h",
    ],
}

genrule {
    name: "statslog_bootstats.cpp",
    tools: ["stats-log-api-gen"],
    cmd: "$(location stats-log-api-gen)" +
        " --cpp $(genDir)/statslog_bootstats.cpp" +
        " --module bootstats" +
        " --namespace android,util,bootstats" +
        " --importHeader statslog_bootstats.h",
    out: [
        "statslog_bootstats.cpp",
    ],
}
+78 −68
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@
#include <android/log.h>
#include <cutils/android_reboot.h>
#include <cutils/properties.h>
#include <statslog.h>
#include <statslog_bootstats.h>

#include "boot_event_record_store.h"

@@ -62,78 +62,80 @@ struct AtomInfo {
const std::unordered_map<std::string_view, AtomInfo> kBootEventToAtomInfo = {
    // ELAPSED_TIME
    {"ro.boottime.init",
     {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ANDROID_INIT_STAGE_1}},
     {android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ANDROID_INIT_STAGE_1}},
    {"boot_complete",
     {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__BOOT_COMPLETE}},
     {android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__BOOT_COMPLETE}},
    {"boot_complete_no_encryption",
     {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__BOOT_COMPLETE_NO_ENCRYPTION}},
     {android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__BOOT_COMPLETE_NO_ENCRYPTION}},
    {"factory_reset_boot_complete",
     {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FACTORY_RESET_BOOT_COMPLETE}},
     {android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FACTORY_RESET_BOOT_COMPLETE}},
    {"factory_reset_boot_complete_no_encryption",
     {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::
     {android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::bootstats::
          BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__FACTORY_RESET_BOOT_COMPLETE_NO_ENCRYPTION}},
    {"ota_boot_complete",
     {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__OTA_BOOT_COMPLETE}},
     {android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__OTA_BOOT_COMPLETE}},
    {"ota_boot_complete_no_encryption",
     {android::util::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__OTA_BOOT_COMPLETE_NO_ENCRYPTION}},
     {android::util::bootstats::BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
      android::util::bootstats::
          BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__OTA_BOOT_COMPLETE_NO_ENCRYPTION}},
    // DURATION
    {"absolute_boot_time",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__ABSOLUTE_BOOT_TIME}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__ABSOLUTE_BOOT_TIME}},
    {"boottime.bootloader.1BLE",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_FIRST_STAGE_EXEC}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_FIRST_STAGE_EXEC}},
    {"boottime.bootloader.1BLL",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_FIRST_STAGE_LOAD}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_FIRST_STAGE_LOAD}},
    {"boottime.bootloader.KL",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_KERNEL_LOAD}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_KERNEL_LOAD}},
    {"boottime.bootloader.2BLE",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_SECOND_STAGE_EXEC}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_SECOND_STAGE_EXEC}},
    {"boottime.bootloader.2BLL",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_SECOND_STAGE_LOAD}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_SECOND_STAGE_LOAD}},
    {"boottime.bootloader.SW",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_UI_WAIT}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_UI_WAIT}},
    {"boottime.bootloader.total",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_TOTAL}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__BOOTLOADER_TOTAL}},
    {"boottime.init.cold_boot_wait",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__COLDBOOT_WAIT}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__COLDBOOT_WAIT}},
    {"time_since_factory_reset",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__FACTORY_RESET_TIME_SINCE_RESET}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__FACTORY_RESET_TIME_SINCE_RESET}},
    {"ro.boottime.init.first_stage",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__ANDROID_INIT_STAGE_1}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__ANDROID_INIT_STAGE_1}},
    {"ro.boottime.init.selinux",
     {android::util::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::BOOT_TIME_EVENT_DURATION__EVENT__SELINUX_INIT}},
     {android::util::bootstats::BOOT_TIME_EVENT_DURATION_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_DURATION__EVENT__SELINUX_INIT}},
    // UTC_TIME
    {"factory_reset",
     {android::util::BOOT_TIME_EVENT_UTC_TIME_REPORTED,
      android::util::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_RESET_TIME}},
     {android::util::bootstats::BOOT_TIME_EVENT_UTC_TIME_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_RESET_TIME}},
    {"factory_reset_current_time",
     {android::util::BOOT_TIME_EVENT_UTC_TIME_REPORTED,
      android::util::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_CURRENT_TIME}},
     {android::util::bootstats::BOOT_TIME_EVENT_UTC_TIME_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_CURRENT_TIME}},
    {"factory_reset_record_value",
     {android::util::BOOT_TIME_EVENT_UTC_TIME_REPORTED,
      android::util::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_RECORD_VALUE}},
     {android::util::bootstats::BOOT_TIME_EVENT_UTC_TIME_REPORTED,
      android::util::bootstats::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_RECORD_VALUE}},
    // ERROR_CODE
    {"factory_reset_current_time_failure",
     {android::util::BOOT_TIME_EVENT_ERROR_CODE_REPORTED,
      android::util::BOOT_TIME_EVENT_ERROR_CODE__EVENT__FACTORY_RESET_CURRENT_TIME_FAILURE}},
     {android::util::bootstats::BOOT_TIME_EVENT_ERROR_CODE_REPORTED,
      android::util::bootstats::
          BOOT_TIME_EVENT_ERROR_CODE__EVENT__FACTORY_RESET_CURRENT_TIME_FAILURE}},
};

// Scans the boot event record store for record files and logs each boot event
@@ -146,12 +148,12 @@ void LogBootEvents() {
    const auto& name = event.first;
    const auto& info = kBootEventToAtomInfo.find(name);
    if (info != kBootEventToAtomInfo.end()) {
      if (info->second.atom == android::util::BOOT_TIME_EVENT_ERROR_CODE_REPORTED) {
        android::util::stats_write(static_cast<int32_t>(info->second.atom),
      if (info->second.atom == android::util::bootstats::BOOT_TIME_EVENT_ERROR_CODE_REPORTED) {
        android::util::bootstats::stats_write(static_cast<int32_t>(info->second.atom),
                                              static_cast<int32_t>(info->second.event),
                                              static_cast<int32_t>(event.second));
      } else {
        android::util::stats_write(static_cast<int32_t>(info->second.atom),
        android::util::bootstats::stats_write(static_cast<int32_t>(info->second.atom),
                                              static_cast<int32_t>(info->second.event),
                                              static_cast<int64_t>(event.second));
      }
@@ -422,7 +424,7 @@ const std::map<std::string, int32_t> kBootReasonMap = {
    {"reboot,mount_userdata_failed", 190},
    {"reboot,forcedsilent", 191},
    {"reboot,forcednonsilent", 192},
    {"reboot,thermal,tj", 193},
    {"reboot,thermal,tj.*", 193},
    {"reboot,emergency", 194},
    {"reboot,factory", 195},
    {"reboot,fastboot", 196},
@@ -470,6 +472,7 @@ const std::map<std::string, int32_t> kBootReasonMap = {
    {"reboot,fship.*", 238},
    {"reboot,ocp,.*", 239},
    {"reboot,ntc,pmic,sub", 240},
    {"reboot,telemtemp,pmic,main", 241},
};

// Converts a string value representing the reason the system booted to an
@@ -1271,10 +1274,16 @@ void LogBootInfoToStatsd(std::chrono::milliseconds end_time,
                         double time_since_last_boot_sec) {
  auto reason = android::base::GetProperty(bootloader_reboot_reason_property, "<EMPTY>");
  auto system_reason = android::base::GetProperty(system_reboot_reason_property, "<EMPTY>");
  android::util::stats_write(android::util::BOOT_SEQUENCE_REPORTED, reason.c_str(),
                             system_reason.c_str(), end_time.count(), total_duration.count(),
                             (int64_t)bootloader_duration_ms,
                             (int64_t)time_since_last_boot_sec * 1000);
  auto system_reason_parts = android::base::Split(system_reason, ",");
  std::string main_reason, sub_reason, detail;
  main_reason = (system_reason_parts.size() > 0) ? system_reason_parts[0] : "";
  sub_reason = (system_reason_parts.size() > 1) ? system_reason_parts[1] : "";
  detail = (system_reason_parts.size() > 2) ? system_reason_parts[2] : "";
  android::util::bootstats::stats_write(
      android::util::bootstats::BOOT_SEQUENCE_REPORTED, reason.c_str(), system_reason.c_str(),
      end_time.count(), total_duration.count(), (int64_t)bootloader_duration_ms,
      (int64_t)time_since_last_boot_sec * 1000,
      main_reason.c_str(), sub_reason.c_str(), detail.c_str());
}

void SetSystemBootReason() {
@@ -1427,10 +1436,11 @@ void RecordFactoryReset() {
  if (current_time_utc < 0) {
    // UMA does not display negative values in buckets, so convert to positive.
    // Logging via BootEventRecordStore.
    android::util::stats_write(
        static_cast<int32_t>(android::util::BOOT_TIME_EVENT_ERROR_CODE_REPORTED),
    android::util::bootstats::stats_write(
        static_cast<int32_t>(android::util::bootstats::BOOT_TIME_EVENT_ERROR_CODE_REPORTED),
        static_cast<int32_t>(
            android::util::BOOT_TIME_EVENT_ERROR_CODE__EVENT__FACTORY_RESET_CURRENT_TIME_FAILURE),
            android::util::bootstats::
                BOOT_TIME_EVENT_ERROR_CODE__EVENT__FACTORY_RESET_CURRENT_TIME_FAILURE),
        static_cast<int32_t>(std::abs(current_time_utc)));

    // Logging via BootEventRecordStore to see if using android::metricslogger::LogHistogram
@@ -1439,10 +1449,10 @@ void RecordFactoryReset() {
                                           std::abs(current_time_utc));
    return;
  } else {
    android::util::stats_write(
        static_cast<int32_t>(android::util::BOOT_TIME_EVENT_UTC_TIME_REPORTED),
    android::util::bootstats::stats_write(
        static_cast<int32_t>(android::util::bootstats::BOOT_TIME_EVENT_UTC_TIME_REPORTED),
        static_cast<int32_t>(
            android::util::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_CURRENT_TIME),
            android::util::bootstats::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_CURRENT_TIME),
        static_cast<int64_t>(current_time_utc));

    // Logging via BootEventRecordStore to see if using android::metricslogger::LogHistogram
@@ -1463,10 +1473,10 @@ void RecordFactoryReset() {
  // Calculate and record the difference in time between now and the
  // factory_reset time.
  time_t factory_reset_utc = record.second;
  android::util::stats_write(
      static_cast<int32_t>(android::util::BOOT_TIME_EVENT_UTC_TIME_REPORTED),
  android::util::bootstats::stats_write(
      static_cast<int32_t>(android::util::bootstats::BOOT_TIME_EVENT_UTC_TIME_REPORTED),
      static_cast<int32_t>(
          android::util::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_RECORD_VALUE),
          android::util::bootstats::BOOT_TIME_EVENT_UTC_TIME__EVENT__FACTORY_RESET_RECORD_VALUE),
      static_cast<int64_t>(factory_reset_utc));

  // Logging via BootEventRecordStore to see if using android::metricslogger::LogHistogram
+58 −0
Original line number Diff line number Diff line
@@ -581,6 +581,41 @@ prebuilt_etc {
    },
}

prebuilt_etc {
    name: "crash_dump.no_mmap_mprotect_prctl.policy",
    sub_dir: "seccomp_policy",
    filename_from_src: true,
    arch: {
        arm: {
            src: "seccomp_policy/crash_dump.no_mmap_mprotect_prctl.arm.policy",
            required: [
                "crash_dump.policy_no_mmap_mprotect_prctl_other",
            ],
        },
        arm64: {
            src: "seccomp_policy/crash_dump.no_mmap_mprotect_prctl.arm64.policy",
            required: [
                "crash_dump.policy_no_mmap_mprotect_prctl_other",
            ],
        },
        riscv64: {
            src: "seccomp_policy/crash_dump.no_mmap_mprotect_prctl.riscv64.policy",
        },
        x86: {
            src: "seccomp_policy/crash_dump.no_mmap_mprotect_prctl.x86.policy",
            required: [
                "crash_dump.policy_no_mmap_mprotect_prctl_other",
            ],
        },
        x86_64: {
            src: "seccomp_policy/crash_dump.no_mmap_mprotect_prctl.x86_64.policy",
            required: [
                "crash_dump.policy_no_mmap_mprotect_prctl_other",
            ],
        },
    },
}

// This installs the "other" architecture (so 32-bit on 64-bit device).
prebuilt_etc {
    name: "crash_dump.policy_other",
@@ -604,3 +639,26 @@ prebuilt_etc {
        },
    },
}

prebuilt_etc {
    name: "crash_dump.policy_no_mmap_mprotect_prctl_other",
    sub_dir: "seccomp_policy",
    filename_from_src: true,
    arch: {
        arm: {
            src: "seccomp_policy/crash_dump.no_mmap_mprotect_prctl.arm64.policy",
        },
        arm64: {
            src: "seccomp_policy/crash_dump.no_mmap_mprotect_prctl.arm.policy",
        },
        riscv64: {
            enabled: false,
        },
        x86: {
            src: "seccomp_policy/crash_dump.no_mmap_mprotect_prctl.x86_64.policy",
        },
        x86_64: {
            src: "seccomp_policy/crash_dump.no_mmap_mprotect_prctl.x86.policy",
        },
    },
}
+20 −19
Original line number Diff line number Diff line
@@ -302,7 +302,7 @@ static void ParseArgs(int argc, char** argv, pid_t* pseudothread_tid, DebuggerdD
static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
                          std::unique_ptr<unwindstack::Regs>* regs, ProcessInfo* process_info,
                          bool* recoverable_crash) {
  std::aligned_storage<sizeof(CrashInfo) + 1, alignof(CrashInfo)>::type buf;
  std::aligned_storage<sizeof(CrashInfo) + 1, alignof(CrashInfo)>::type buf = {};
  CrashInfo* crash_info = reinterpret_cast<CrashInfo*>(&buf);
  ssize_t rc = TEMP_FAILURE_RETRY(read(fd.get(), &buf, sizeof(buf)));
  *recoverable_crash = false;
@@ -310,19 +310,19 @@ static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
    PLOG(FATAL) << "failed to read target ucontext";
  }
  ssize_t expected_size = 0;
  switch (crash_info->header.version) {
  switch (crash_info->c.version) {
    case 1:
    case 2:
    case 3:
      expected_size = sizeof(CrashInfoHeader) + sizeof(CrashInfoDataStatic);
      expected_size = sizeof(CrashInfoDataCommon);
      break;

    case 4:
      expected_size = sizeof(CrashInfoHeader) + sizeof(CrashInfoDataDynamic);
      expected_size = sizeof(CrashInfo);
      break;

    default:
      LOG(FATAL) << "unexpected CrashInfo version: " << crash_info->header.version;
      LOG(FATAL) << "unexpected CrashInfo version: " << crash_info->c.version;
      break;
  }

@@ -331,24 +331,24 @@ static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
                << expected_size;
  }

  switch (crash_info->header.version) {
  switch (crash_info->c.version) {
    case 4:
      process_info->fdsan_table_address = crash_info->data.d.fdsan_table_address;
      process_info->gwp_asan_state = crash_info->data.d.gwp_asan_state;
      process_info->gwp_asan_metadata = crash_info->data.d.gwp_asan_metadata;
      process_info->scudo_stack_depot = crash_info->data.d.scudo_stack_depot;
      process_info->scudo_stack_depot_size = crash_info->data.d.scudo_stack_depot_size;
      process_info->scudo_region_info = crash_info->data.d.scudo_region_info;
      process_info->scudo_ring_buffer = crash_info->data.d.scudo_ring_buffer;
      process_info->scudo_ring_buffer_size = crash_info->data.d.scudo_ring_buffer_size;
      *recoverable_crash = crash_info->data.d.recoverable_crash;
      process_info->crash_detail_page = crash_info->data.d.crash_detail_page;
      process_info->fdsan_table_address = crash_info->d.fdsan_table_address;
      process_info->gwp_asan_state = crash_info->d.gwp_asan_state;
      process_info->gwp_asan_metadata = crash_info->d.gwp_asan_metadata;
      process_info->scudo_stack_depot = crash_info->d.scudo_stack_depot;
      process_info->scudo_stack_depot_size = crash_info->d.scudo_stack_depot_size;
      process_info->scudo_region_info = crash_info->d.scudo_region_info;
      process_info->scudo_ring_buffer = crash_info->d.scudo_ring_buffer;
      process_info->scudo_ring_buffer_size = crash_info->d.scudo_ring_buffer_size;
      *recoverable_crash = crash_info->d.recoverable_crash;
      process_info->crash_detail_page = crash_info->d.crash_detail_page;
      FALLTHROUGH_INTENDED;
    case 1:
    case 2:
    case 3:
      process_info->abort_msg_address = crash_info->data.s.abort_msg_address;
      *siginfo = crash_info->data.s.siginfo;
      process_info->abort_msg_address = crash_info->c.abort_msg_address;
      *siginfo = crash_info->c.siginfo;
      if (signal_has_si_addr(siginfo)) {
        process_info->has_fault_address = true;
        process_info->maybe_tagged_fault_address = reinterpret_cast<uintptr_t>(siginfo->si_addr);
@@ -356,7 +356,7 @@ static void ReadCrashInfo(unique_fd& fd, siginfo_t* siginfo,
            untag_address(reinterpret_cast<uintptr_t>(siginfo->si_addr));
      }
      regs->reset(unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(),
                                                        &crash_info->data.s.ucontext));
                                                        &crash_info->c.ucontext));
      break;

    default:
@@ -706,6 +706,7 @@ int main(int argc, char** argv) {
        info.siginfo = &siginfo;
        info.signo = info.siginfo->si_signo;

        info.executable_name = get_executable_name(g_target_thread);
        info.command_line = get_command_line(g_target_thread);
      } else {
        info.registers.reset(unwindstack::Regs::RemoteGet(thread));
+41 −6
Original line number Diff line number Diff line
@@ -145,12 +145,24 @@ noinline int crash(int a) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfree-nonheap-object"

noinline void abuse_heap() {
noinline void invalid_free() {
    char buf[16];
    free(buf); // GCC is smart enough to warn about this, but we're doing it deliberately.
    free(buf); // The compiler is smart enough to warn about this, but we're doing it deliberately.
}
#pragma clang diagnostic pop

noinline void heap_buffer_overflow() {
    volatile char* p = reinterpret_cast<volatile char*>(malloc(32));
    p[32] = p[32];
}

noinline void use_after_free() {
    void* allocation = malloc(32);
    volatile char* p = reinterpret_cast<volatile char*>(allocation);
    free(allocation);
    p[0] = p[0];
}

noinline void leak() {
    while (true) {
        void* mapping =
@@ -164,6 +176,16 @@ noinline void sigsegv_non_null() {
    *a = 42;
}

noinline void sigsegv_write() {
  int* a = reinterpret_cast<int*>(0xdeadbeef);
  *a = 10;
}

noinline void sigsegv_read() {
  int* a = reinterpret_cast<int*>(0xdeadbeef);
  int value = *a;
}

noinline void fprintf_null() {
    FILE* sneaky_null = nullptr;
    fprintf(sneaky_null, "oops");
@@ -187,7 +209,10 @@ static int usage() {
    fprintf(stderr, "  stack-overflow        recurse until the stack overflows\n");
    fprintf(stderr, "  nostack               crash with a NULL stack pointer\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "  heap-usage            cause a libc abort by abusing a heap function\n");
    fprintf(stderr, "  heap-buffer-overflow  write past the end of a heap allocation\n");
    fprintf(stderr, "  invalid-free          pass a non-heap pointer to free()\n");
    fprintf(stderr, "  use-after-free        write to a buffer after free()\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "  call-null             cause a crash by calling through a nullptr\n");
    fprintf(stderr, "  leak                  leak memory until we get OOM-killed\n");
    fprintf(stderr, "\n");
@@ -215,6 +240,8 @@ static int usage() {
    fprintf(stderr, "  SIGSEGV               cause a SIGSEGV at address 0x0 (synonym: crash)\n");
    fprintf(stderr, "  SIGSEGV-non-null      cause a SIGSEGV at a non-zero address\n");
    fprintf(stderr, "  SIGSEGV-unmapped      mmap/munmap a region of memory and then attempt to access it\n");
    fprintf(stderr, "  SIGSEGV-read          cause a SIGSEGV reading from a non-zero address\n");
    fprintf(stderr, "  SIGSEGV-write         cause a SIGSEGV writing to a non-zero address\n");
    fprintf(stderr, "  SIGTRAP               cause a SIGTRAP\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "  fprintf-NULL          pass a null pointer to fprintf\n");
@@ -280,6 +307,10 @@ noinline int do_action(const char* arg) {
    // Actions.
    if (!strcasecmp(arg, "SIGSEGV-non-null")) {
      sigsegv_non_null();
    } else if (!strcasecmp(arg, "SIGSEGV-read")) {
      sigsegv_read();
    } else if (!strcasecmp(arg, "SIGSEGV-write")) {
      sigsegv_write();
    } else if (!strcasecmp(arg, "smash-stack")) {
      volatile int len = 128;
      return smash_stack(&len);
@@ -351,8 +382,12 @@ noinline int do_action(const char* arg) {
      return strlen_null();
    } else if (!strcasecmp(arg, "pthread_join-NULL")) {
      return pthread_join(0, nullptr);
    } else if (!strcasecmp(arg, "heap-usage")) {
      abuse_heap();
    } else if (!strcasecmp(arg, "heap-buffer-overflow")) {
      heap_buffer_overflow();
    } else if (!strcasecmp(arg, "invalid-free")) {
      invalid_free();
    } else if (!strcasecmp(arg, "use-after-free")) {
      use_after_free();
    } else if (!strcasecmp(arg, "leak")) {
      leak();
    } else if (!strcasecmp(arg, "SIGSEGV-unmapped")) {
@@ -398,7 +433,7 @@ noinline int do_action(const char* arg) {
        return usage();
    }

    fprintf(stderr, "%s: exiting normally!\n", getprogname());
    fprintf(stderr, "%s: exiting normally (which is unexpected)!\n", getprogname());
    return EXIT_SUCCESS;
}

Loading