diff options
-rw-r--r-- | bootctl/Android.bp | 2 | ||||
-rw-r--r-- | bootctl/bootctl.cpp | 183 | ||||
-rw-r--r-- | cppreopts/fstab.postinstall | 3 | ||||
-rw-r--r-- | mtectrl/mtectrl.cc | 56 | ||||
-rw-r--r-- | mtectrl/mtectrl.rc | 5 | ||||
-rw-r--r-- | simpleperf/cmd_report_sample.cpp | 5 |
6 files changed, 136 insertions, 118 deletions
diff --git a/bootctl/Android.bp b/bootctl/Android.bp index f63871cf..106ff863 100644 --- a/bootctl/Android.bp +++ b/bootctl/Android.bp @@ -30,6 +30,8 @@ cc_binary { "android.hardware.boot@1.0", "android.hardware.boot@1.1", "android.hardware.boot@1.2", + "android.hardware.boot-V1-ndk", + "libboot_control_client", "libhidlbase", "libutils", ], diff --git a/bootctl/bootctl.cpp b/bootctl/bootctl.cpp index 8ead010d..1bf91815 100644 --- a/bootctl/bootctl.cpp +++ b/bootctl/bootctl.cpp @@ -17,27 +17,19 @@ #include <optional> #include <sstream> +#include <BootControlClient.h> #include <android/hardware/boot/1.2/IBootControl.h> #include <sysexits.h> using android::sp; -using android::hardware::hidl_string; -using android::hardware::Return; +using aidl::android::hardware::boot::MergeStatus; -using android::hardware::boot::V1_0::BoolResult; -using android::hardware::boot::V1_0::CommandResult; -using android::hardware::boot::V1_0::Slot; -using android::hardware::boot::V1_1::IBootControl; -using android::hardware::boot::V1_1::MergeStatus; +using android::hal::BootControlClient; +using android::hal::BootControlVersion; +using android::hal::CommandResult; -namespace V1_0 = android::hardware::boot::V1_0; -namespace V1_1 = android::hardware::boot::V1_1; -namespace V1_2 = android::hardware::boot::V1_2; - -enum BootCtlVersion { BOOTCTL_V1_0, BOOTCTL_V1_1, BOOTCTL_V1_2 }; - -static void usage(FILE* where, BootCtlVersion bootVersion, int /* argc */, char* argv[]) { +static void usage(FILE* where, BootControlVersion bootVersion, int /* argc */, char* argv[]) { fprintf(where, "%s - command-line wrapper for the boot HAL.\n" "\n" @@ -56,7 +48,7 @@ static void usage(FILE* where, BootCtlVersion bootVersion, int /* argc */, char* " is-slot-marked-successful SLOT - Returns 0 only if SLOT is marked GOOD.\n" " get-suffix SLOT - Prints suffix for SLOT.\n", argv[0], argv[0]); - if (bootVersion >= BOOTCTL_V1_1) { + if (bootVersion >= BootControlVersion::BOOTCTL_V1_1) { fprintf(where, " set-snapshot-merge-status STAT - Sets whether a snapshot-merge of any dynamic\n" " partition is in progress. Valid STAT values\n" @@ -69,32 +61,39 @@ static void usage(FILE* where, BootCtlVersion bootVersion, int /* argc */, char* "SLOT parameter is the zero-based slot-number.\n"); } -static int do_hal_info(const sp<V1_0::IBootControl> module) { - module->interfaceDescriptor([&](const auto& descriptor) { - fprintf(stdout, "HAL Version: %s\n", descriptor.c_str()); - }); +static constexpr auto ToString(BootControlVersion ver) { + switch (ver) { + case BootControlVersion::BOOTCTL_V1_0: + return "android.hardware.boot@1.0::IBootControl"; + case BootControlVersion::BOOTCTL_V1_1: + return "android.hardware.boot@1.1::IBootControl"; + case BootControlVersion::BOOTCTL_V1_2: + return "android.hardware.boot@1.2::IBootControl"; + case BootControlVersion::BOOTCTL_AIDL: + return "android.hardware.boot@aidl::IBootControl"; + } +} + +static int do_hal_info(const BootControlClient* module) { + fprintf(stdout, "HAL Version: %s\n", ToString(module->GetVersion())); return EX_OK; } -static int do_get_number_slots(sp<V1_0::IBootControl> module) { - uint32_t numSlots = module->getNumberSlots(); +static int do_get_number_slots(BootControlClient* module) { + auto numSlots = module->GetNumSlots(); fprintf(stdout, "%u\n", numSlots); return EX_OK; } -static int do_get_current_slot(sp<V1_0::IBootControl> module) { - Slot curSlot = module->getCurrentSlot(); +static int do_get_current_slot(BootControlClient* module) { + auto curSlot = module->GetCurrentSlot(); fprintf(stdout, "%u\n", curSlot); return EX_OK; } -static std::function<void(CommandResult)> generate_callback(CommandResult* crp) { - return [=](CommandResult cr) { *crp = cr; }; -} - -static int handle_return(const Return<void>& ret, CommandResult cr, const char* errStr) { - if (!ret.isOk()) { - fprintf(stderr, errStr, ret.description().c_str()); +static int handle_return(CommandResult cr, const char* errStr) { + if (!cr.IsOk()) { + fprintf(stderr, errStr, cr.errMsg.c_str()); return EX_SOFTWARE; } else if (!cr.success) { fprintf(stderr, errStr, cr.errMsg.c_str()); @@ -103,51 +102,48 @@ static int handle_return(const Return<void>& ret, CommandResult cr, const char* return EX_OK; } -static int do_mark_boot_successful(sp<V1_0::IBootControl> module) { - CommandResult cr; - Return<void> ret = module->markBootSuccessful(generate_callback(&cr)); - return handle_return(ret, cr, "Error marking as having booted successfully: %s\n"); +static int do_mark_boot_successful(BootControlClient* module) { + auto ret = module->MarkBootSuccessful(); + return handle_return(ret, "Error marking as having booted successfully: %s\n"); } -static int do_get_active_boot_slot(sp<V1_2::IBootControl> module) { - uint32_t slot = module->getActiveBootSlot(); +static int do_get_active_boot_slot(BootControlClient* module) { + uint32_t slot = module->GetActiveBootSlot(); fprintf(stdout, "%u\n", slot); return EX_OK; } -static int do_set_active_boot_slot(sp<V1_0::IBootControl> module, Slot slot_number) { - CommandResult cr; - Return<void> ret = module->setActiveBootSlot(slot_number, generate_callback(&cr)); - return handle_return(ret, cr, "Error setting active boot slot: %s\n"); +static int do_set_active_boot_slot(BootControlClient* module, int32_t slot_number) { + const auto cr = module->SetActiveBootSlot(slot_number); + return handle_return(cr, "Error setting active boot slot: %s\n"); } -static int do_set_slot_as_unbootable(sp<V1_0::IBootControl> module, Slot slot_number) { - CommandResult cr; - Return<void> ret = module->setSlotAsUnbootable(slot_number, generate_callback(&cr)); - return handle_return(ret, cr, "Error setting slot as unbootable: %s\n"); +static int do_set_slot_as_unbootable(BootControlClient* module, int32_t slot_number) { + const auto cr = module->MarkSlotUnbootable(slot_number); + return handle_return(cr, "Error setting slot as unbootable: %s\n"); } -static int handle_return(const Return<BoolResult>& ret, const char* errStr) { - if (!ret.isOk()) { - fprintf(stderr, errStr, ret.description().c_str()); +static int handle_return(const std::optional<bool>& ret, const char* errStr) { + if (!ret.has_value()) { + fprintf(stderr, errStr, ""); return EX_SOFTWARE; - } else if (ret == BoolResult::INVALID_SLOT) { - fprintf(stderr, errStr, "Invalid slot"); - return EX_SOFTWARE; - } else if (ret == BoolResult::TRUE) { + } + if (ret.value()) { + printf("%d\n", ret.value()); return EX_OK; } + printf("%d\n", ret.value()); return EX_SOFTWARE; } -static int do_is_slot_bootable(sp<V1_0::IBootControl> module, Slot slot_number) { - Return<BoolResult> ret = module->isSlotBootable(slot_number); - return handle_return(ret, "Error calling isSlotBootable(): %s\n"); +static int do_is_slot_bootable(BootControlClient* module, int32_t slot_number) { + const auto ret = module->IsSlotBootable(slot_number); + return handle_return(ret, "Error calling isSlotBootable()\n"); } -static int do_is_slot_marked_successful(sp<V1_0::IBootControl> module, Slot slot_number) { - Return<BoolResult> ret = module->isSlotMarkedSuccessful(slot_number); - return handle_return(ret, "Error calling isSlotMarkedSuccessful(): %s\n"); +static int do_is_slot_marked_successful(BootControlClient* module, int32_t slot_number) { + const auto ret = module->IsSlotMarkedSuccessful(slot_number); + return handle_return(ret, "Error calling isSlotMarkedSuccessful()\n"); } std::optional<MergeStatus> stringToMergeStatus(const std::string& status) { @@ -159,7 +155,7 @@ std::optional<MergeStatus> stringToMergeStatus(const std::string& status) { return {}; } -static int do_set_snapshot_merge_status(sp<V1_1::IBootControl> module, BootCtlVersion bootVersion, +static int do_set_snapshot_merge_status(BootControlClient* module, BootControlVersion bootVersion, int argc, char* argv[]) { if (argc != 3) { usage(stderr, bootVersion, argc, argv); @@ -174,10 +170,8 @@ static int do_set_snapshot_merge_status(sp<V1_1::IBootControl> module, BootCtlVe return -1; } - if (!module->setSnapshotMergeStatus(status.value())) { - return EX_SOFTWARE; - } - return EX_OK; + const auto ret = module->SetSnapshotMergeStatus(status.value()); + return handle_return(ret, "Failed to set snapshot merge status: %s\n"); } std::ostream& operator<<(std::ostream& os, MergeStatus state) { @@ -197,7 +191,7 @@ std::ostream& operator<<(std::ostream& os, MergeStatus state) { } } -static int do_get_snapshot_merge_status(sp<V1_1::IBootControl> module) { +static int do_get_snapshot_merge_status(BootControlClient* module) { MergeStatus ret = module->getSnapshotMergeStatus(); std::stringstream ss; ss << ret; @@ -205,19 +199,17 @@ static int do_get_snapshot_merge_status(sp<V1_1::IBootControl> module) { return EX_OK; } -static int do_get_suffix(sp<V1_0::IBootControl> module, Slot slot_number) { - std::function<void(hidl_string)> cb = [](hidl_string suffix) { - fprintf(stdout, "%s\n", suffix.c_str()); - }; - Return<void> ret = module->getSuffix(slot_number, cb); - if (!ret.isOk()) { - fprintf(stderr, "Error calling getSuffix(): %s\n", ret.description().c_str()); +static int do_get_suffix(BootControlClient* module, int32_t slot_number) { + const auto ret = module->GetSuffix(slot_number); + if (ret.empty()) { + fprintf(stderr, "Error calling getSuffix()\n"); return EX_SOFTWARE; } + printf("%s\n", ret.c_str()); return EX_OK; } -static uint32_t parse_slot(BootCtlVersion bootVersion, int pos, int argc, char* argv[]) { +static uint32_t parse_slot(BootControlVersion bootVersion, int pos, int argc, char* argv[]) { if (pos > argc - 1) { usage(stderr, bootVersion, argc, argv); exit(EX_USAGE); @@ -234,25 +226,12 @@ static uint32_t parse_slot(BootCtlVersion bootVersion, int pos, int argc, char* } int main(int argc, char* argv[]) { - sp<V1_0::IBootControl> v1_0_module; - sp<V1_1::IBootControl> v1_1_module; - sp<V1_2::IBootControl> v1_2_module; - BootCtlVersion bootVersion = BOOTCTL_V1_0; - - v1_0_module = V1_0::IBootControl::getService(); - if (v1_0_module == nullptr) { - fprintf(stderr, "Error getting bootctrl v1.0 module.\n"); + const auto client = android::hal::BootControlClient::WaitForService(); + if (client == nullptr) { + fprintf(stderr, "Failed to get bootctl module.\n"); return EX_SOFTWARE; } - v1_1_module = V1_1::IBootControl::castFrom(v1_0_module); - if (v1_1_module != nullptr) { - bootVersion = BOOTCTL_V1_1; - } - - v1_2_module = V1_2::IBootControl::castFrom(v1_0_module); - if (v1_2_module != nullptr) { - bootVersion = BOOTCTL_V1_2; - } + const auto bootVersion = client->GetVersion(); if (argc < 2) { usage(stderr, bootVersion, argc, argv); @@ -261,46 +240,46 @@ int main(int argc, char* argv[]) { // Functions present from version 1.0 if (strcmp(argv[1], "hal-info") == 0) { - return do_hal_info(v1_0_module); + return do_hal_info(client.get()); } else if (strcmp(argv[1], "get-number-slots") == 0) { - return do_get_number_slots(v1_0_module); + return do_get_number_slots(client.get()); } else if (strcmp(argv[1], "get-current-slot") == 0) { - return do_get_current_slot(v1_0_module); + return do_get_current_slot(client.get()); } else if (strcmp(argv[1], "mark-boot-successful") == 0) { - return do_mark_boot_successful(v1_0_module); + return do_mark_boot_successful(client.get()); } else if (strcmp(argv[1], "set-active-boot-slot") == 0) { - return do_set_active_boot_slot(v1_0_module, parse_slot(bootVersion, 2, argc, argv)); + return do_set_active_boot_slot(client.get(), parse_slot(bootVersion, 2, argc, argv)); } else if (strcmp(argv[1], "set-slot-as-unbootable") == 0) { - return do_set_slot_as_unbootable(v1_0_module, parse_slot(bootVersion, 2, argc, argv)); + return do_set_slot_as_unbootable(client.get(), parse_slot(bootVersion, 2, argc, argv)); } else if (strcmp(argv[1], "is-slot-bootable") == 0) { - return do_is_slot_bootable(v1_0_module, parse_slot(bootVersion, 2, argc, argv)); + return do_is_slot_bootable(client.get(), parse_slot(bootVersion, 2, argc, argv)); } else if (strcmp(argv[1], "is-slot-marked-successful") == 0) { - return do_is_slot_marked_successful(v1_0_module, parse_slot(bootVersion, 2, argc, argv)); + return do_is_slot_marked_successful(client.get(), parse_slot(bootVersion, 2, argc, argv)); } else if (strcmp(argv[1], "get-suffix") == 0) { - return do_get_suffix(v1_0_module, parse_slot(bootVersion, 2, argc, argv)); + return do_get_suffix(client.get(), parse_slot(bootVersion, 2, argc, argv)); } // Functions present from version 1.1 if (strcmp(argv[1], "set-snapshot-merge-status") == 0 || strcmp(argv[1], "get-snapshot-merge-status") == 0) { - if (v1_1_module == nullptr) { + if (bootVersion < BootControlVersion::BOOTCTL_V1_1) { fprintf(stderr, "Error getting bootctrl v1.1 module.\n"); return EX_SOFTWARE; } if (strcmp(argv[1], "set-snapshot-merge-status") == 0) { - return do_set_snapshot_merge_status(v1_1_module, bootVersion, argc, argv); + return do_set_snapshot_merge_status(client.get(), bootVersion, argc, argv); } else if (strcmp(argv[1], "get-snapshot-merge-status") == 0) { - return do_get_snapshot_merge_status(v1_1_module); + return do_get_snapshot_merge_status(client.get()); } } if (strcmp(argv[1], "get-active-boot-slot") == 0) { - if (v1_2_module == nullptr) { + if (bootVersion < BootControlVersion::BOOTCTL_V1_2) { fprintf(stderr, "Error getting bootctrl v1.2 module.\n"); return EX_SOFTWARE; } - return do_get_active_boot_slot(v1_2_module); + return do_get_active_boot_slot(client.get()); } // Parameter not matched, print usage diff --git a/cppreopts/fstab.postinstall b/cppreopts/fstab.postinstall index c77c9083..6802bb37 100644 --- a/cppreopts/fstab.postinstall +++ b/cppreopts/fstab.postinstall @@ -20,4 +20,7 @@ system /postinstall ext4 ro,nosuid,nodev,noexec slotselect_other,logical system /postinstall erofs ro,nosuid,nodev,noexec slotselect_other,logical /dev/block/by-name/system /postinstall ext4 ro,nosuid,nodev,noexec slotselect_other +/dev/block/by-name/system /postinstall erofs ro,nosuid,nodev,noexec slotselect_other +/dev/block/mapper/system /postinstall ext4 ro,nosuid,nodev,noexec slotselect_other +/dev/block/mapper/system /postinstall erofs ro,nosuid,nodev,noexec slotselect_other diff --git a/mtectrl/mtectrl.cc b/mtectrl/mtectrl.cc index 118c71c7..eefc1588 100644 --- a/mtectrl/mtectrl.cc +++ b/mtectrl/mtectrl.cc @@ -21,15 +21,16 @@ #include <iostream> int main(int argc, char** argv) { - if (argc != 2) { - std::cerr - << "Usage: " << argv[0] - << " none|memtag|memtag-once|memtag-kernel|memtag-kernel-once[,...]\n"; - return 1; - } + if (argc != 2 && argc != 3) { + std::cerr << "Usage: " << argv[0] + << " none|memtag|memtag-once|memtag-kernel|memtag-kernel-once[,.." + ".] [default|force_on|force_off]\n"; + return 1; + } std::string value = argv[1]; misc_memtag_message m = {.version = MISC_MEMTAG_MESSAGE_VERSION, .magic = MISC_MEMTAG_MAGIC_HEADER}; + bool valid_value = true; for (const auto& field : android::base::Split(value, ",")) { if (field == "memtag") { m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG; @@ -42,17 +43,48 @@ int main(int argc, char** argv) { } else if (field == "memtag-off") { m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_OFF; } else if (field != "none") { - LOG(ERROR) << "Unknown value for arm64.memtag.bootctl: " << field; - return 1; + LOG(ERROR) << "Unknown value for mode: " << field; + valid_value = false; + m = {.version = MISC_MEMTAG_MESSAGE_VERSION, .magic = MISC_MEMTAG_MAGIC_HEADER}; + break; } } + bool valid_override = true; + std::string override_value; + if (argc == 3) { + override_value = argv[2]; + } + if (override_value == "force_off") { + // If the force_off override is active, only allow MEMTAG_MODE_MEMTAG_ONCE. + m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_OFF; + m.memtag_mode &= ~MISC_MEMTAG_MODE_MEMTAG; + } else if (override_value == "force_on") { + m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG; + m.memtag_mode &= ~MISC_MEMTAG_MODE_MEMTAG_OFF; + } else if (!override_value.empty() && override_value != "default") { + LOG(ERROR) << "Unknown value for override: " << override_value; + valid_override = false; + } + if (!valid_value && !valid_override) { + return 1; + } std::string err; if (!WriteMiscMemtagMessage(m, &err)) { - LOG(ERROR) << "Failed to apply arm64.memtag.bootctl: " << value << ". " - << err; + LOG(ERROR) << "Failed to apply mode: " << value << ", override: " << override_value << err; return 1; } else { - LOG(INFO) << "Applied arm64.memtag.bootctl: " << value; - return 0; + const char* parse_error = ""; + const char* verb = "Applied"; + if (!valid_value) { + parse_error = " (invalid mode)"; + verb = "Partially applied"; + } else if (!valid_override) { + // else if because we bail out if both are false above. + parse_error = " (invalid override)"; + verb = "Partially applied"; + } + LOG(INFO) << verb << " mode: " << value << ", " + << "override: " << override_value << parse_error; + return !valid_value || !valid_override; } } diff --git a/mtectrl/mtectrl.rc b/mtectrl/mtectrl.rc index de042376..05bdaa23 100644 --- a/mtectrl/mtectrl.rc +++ b/mtectrl/mtectrl.rc @@ -13,4 +13,7 @@ # limitations under the License. on property:arm64.memtag.bootctl=* - exec -- /system/bin/mtectrl ${arm64.memtag.bootctl} + exec -- /system/bin/mtectrl ${arm64.memtag.bootctl:-none} ${persist.device_config.memory_safety_native.bootloader_override:-default} + +on property:persist.device_config.memory_safety_native.bootloader_override=* + exec -- /system/bin/mtectrl ${arm64.memtag.bootctl:-none} ${persist.device_config.memory_safety_native.bootloader_override:-default} diff --git a/simpleperf/cmd_report_sample.cpp b/simpleperf/cmd_report_sample.cpp index dc2a3d44..dfaf5a3f 100644 --- a/simpleperf/cmd_report_sample.cpp +++ b/simpleperf/cmd_report_sample.cpp @@ -372,8 +372,7 @@ bool ReportSampleCommand::DumpProtobufReport(const std::string& filename) { // files[file_id] is the number of symbols in the file. std::vector<uint32_t> files; uint32_t max_message_size = 64 * (1 << 20); - uint32_t warning_message_size = 512 * (1 << 20); - coded_is.SetTotalBytesLimit(max_message_size, warning_message_size); + coded_is.SetTotalBytesLimit(max_message_size); while (true) { uint32_t size; if (!coded_is.ReadLittleEndian32(&size)) { @@ -386,7 +385,7 @@ bool ReportSampleCommand::DumpProtobufReport(const std::string& filename) { // Handle files having large symbol table. if (size > max_message_size) { max_message_size = size; - coded_is.SetTotalBytesLimit(max_message_size, warning_message_size); + coded_is.SetTotalBytesLimit(max_message_size); } auto limit = coded_is.PushLimit(size); proto::Record proto_record; |