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

Commit 5a1dee01 authored by Tao Bao's avatar Tao Bao
Browse files

update_verifier: Handle legacy care_map.txt gracefully.

update_verifier should be backward compatible to not reject legacy
care_map.txt from old releases, which could otherwise fail to boot into
the new release.

For example, we've changed the care_map format between N and O. An O
update_verifier would fail to work with an N care_map.txt - a) we have
switched update_verifier to read from device mapper in O; b) the last
few blocks that contain metadata can't be read via device mapper. This
could be a result of sideloading an O OTA while the device having a
pending N update.

Bug: 63544345
Test: As follows on sailfish:
 1. Flash the device with this CL;
 2. Put a copy of N care_map.txt at /data/ota_package/. Restore the
    permissions properly ('cache' group);
 3. `adb reboot bootloader`;
 4. `fastboot set_active <current_slot>`
 5. Device boots up into home screen, with a warning in logcat that says
    it has skipped legacy care_map.txt.
Change-Id: I6acc88c9e655a9245e6531f176fef7953953935f
parent 9187f1cc
Loading
Loading
Loading
Loading
+42 −29
Original line number Diff line number Diff line
@@ -175,6 +175,13 @@ static bool read_blocks(const std::string& partition, const std::string& range_s
  return true;
}

// Returns true to indicate a passing verification (or the error should be ignored); Otherwise
// returns false on fatal errors, where we should reject the current boot and trigger a fallback.
// Note that update_verifier should be backward compatible to not reject care_map.txt from old
// releases, which could otherwise fail to boot into the new release. For example, we've changed
// the care_map format between N and O. An O update_verifier would fail to work with N
// care_map.txt. This could be a result of sideloading an O OTA while the device having a pending N
// update.
bool verify_image(const std::string& care_map_name) {
  android::base::unique_fd care_map_fd(TEMP_FAILURE_RETRY(open(care_map_name.c_str(), O_RDONLY)));
  // If the device is flashed before the current boot, it may not have care_map.txt
@@ -203,6 +210,12 @@ bool verify_image(const std::string& care_map_name) {
  }

  for (size_t i = 0; i < lines.size(); i += 2) {
    // We're seeing an N care_map.txt. Skip the verification since it's not compatible with O
    // update_verifier (the last few metadata blocks can't be read via device mapper).
    if (android::base::StartsWith(lines[i], "/dev/block/")) {
      LOG(WARNING) << "Found legacy care_map.txt; skipped.";
      return true;
    }
    if (!read_blocks(lines[i], lines[i+1])) {
      return false;
    }