Calculate vbmetadigest of inactive slot am: 838793dc39
Original change: https://android-review.googlesource.com/c/platform/system/update_engine/+/1543621
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I83cfc98d87b98f2fb8778525ba43dee2f4c134d1
diff --git a/Android.bp b/Android.bp
index ebe43a9..be37dba 100644
--- a/Android.bp
+++ b/Android.bp
@@ -307,9 +307,12 @@
],
static_libs: [
+ "libavb",
+ "libavb_user",
"gkiprops",
"libpayload_consumer",
"libupdate_engine_boot_control",
+ "PlatformProperties",
],
shared_libs: [
"libandroid_net",
diff --git a/aosp/hardware_android.cc b/aosp/hardware_android.cc
index 6f884d4..0ac82d6 100644
--- a/aosp/hardware_android.cc
+++ b/aosp/hardware_android.cc
@@ -23,16 +23,24 @@
#include <string_view>
#include <android/sysprop/GkiProperties.sysprop.h>
-#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <base/files/file_util.h>
+#include <base/strings/string_number_conversions.h>
+#include <base/strings/string_util.h>
#include <bootloader_message/bootloader_message.h>
+#include <fstab/fstab.h>
+#include <libavb/libavb.h>
+#include <libavb_user/avb_ops_user.h>
#include "update_engine/common/error_code_utils.h"
#include "update_engine/common/hardware.h"
#include "update_engine/common/platform_constants.h"
#include "update_engine/common/utils.h"
+#ifndef __ANDROID_RECOVERY__
+#include <android/sysprop/OtaProperties.sysprop.h>
+#endif
+
using android::base::GetBoolProperty;
using android::base::GetIntProperty;
using android::base::GetProperty;
@@ -68,6 +76,40 @@
return error_code;
}
+void SetVbmetaDigestProp(const std::string& value) {
+#ifndef __ANDROID_RECOVERY__
+ if (!android::sysprop::OtaProperties::other_vbmeta_digest(value)) {
+ LOG(WARNING) << "Failed to set other vbmeta digest to " << value;
+ }
+#endif
+}
+
+std::string CalculateVbmetaDigestForInactiveSlot() {
+ AvbSlotVerifyData* avb_slot_data;
+
+ auto suffix = fs_mgr_get_other_slot_suffix();
+ const char* requested_partitions[] = {nullptr};
+ auto avb_ops = avb_ops_user_new();
+ auto verify_result = avb_slot_verify(avb_ops,
+ requested_partitions,
+ suffix.c_str(),
+ AVB_SLOT_VERIFY_FLAGS_NONE,
+ AVB_HASHTREE_ERROR_MODE_EIO,
+ &avb_slot_data);
+ if (verify_result != AVB_SLOT_VERIFY_RESULT_OK) {
+ LOG(WARNING) << "Failed to verify avb slot data: " << verify_result;
+ return "";
+ }
+
+ uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE];
+ avb_slot_verify_data_calculate_vbmeta_digest(
+ avb_slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest);
+
+ std::string encoded_digest =
+ base::HexEncode(vbmeta_digest, AVB_SHA256_DIGEST_SIZE);
+ return base::ToLowerASCII(encoded_digest);
+}
+
} // namespace
namespace hardware {
@@ -239,6 +281,30 @@
}
}
+void HardwareAndroid::SetVbmetaDigestForInactiveSlot(bool reset) {
+ if constexpr (constants::kIsRecovery) {
+ return;
+ }
+
+ if (android::base::GetProperty("ro.boot.avb_version", "").empty() &&
+ android::base::GetProperty("ro.boot.vbmeta.avb_version", "").empty()) {
+ LOG(INFO) << "Device doesn't use avb, skipping setting vbmeta digest";
+ return;
+ }
+
+ if (reset) {
+ SetVbmetaDigestProp("");
+ return;
+ }
+
+ std::string digest = CalculateVbmetaDigestForInactiveSlot();
+ if (digest.empty()) {
+ LOG(WARNING) << "Failed to calculate the vbmeta digest for the other slot";
+ return;
+ }
+ SetVbmetaDigestProp(digest);
+}
+
string HardwareAndroid::GetVersionForLogging(
const string& partition_name) const {
if (partition_name == "boot") {
diff --git a/aosp/hardware_android.h b/aosp/hardware_android.h
index 5ffd7c5..78f056e 100644
--- a/aosp/hardware_android.h
+++ b/aosp/hardware_android.h
@@ -58,6 +58,7 @@
bool GetFirstActiveOmahaPingSent() const override;
bool SetFirstActiveOmahaPingSent() override;
void SetWarmReset(bool warm_reset) override;
+ void SetVbmetaDigestForInactiveSlot(bool reset) override;
[[nodiscard]] std::string GetVersionForLogging(
const std::string& partition_name) const override;
[[nodiscard]] ErrorCode IsPartitionUpdateValid(
diff --git a/aosp/update_attempter_android.cc b/aosp/update_attempter_android.cc
index eb1ebe0..96bb67c 100644
--- a/aosp/update_attempter_android.cc
+++ b/aosp/update_attempter_android.cc
@@ -374,6 +374,9 @@
// Resets the warm reset property since we won't switch the slot.
hardware_->SetWarmReset(false);
+ // Resets the vbmeta digest.
+ hardware_->SetVbmetaDigestForInactiveSlot(true /* reset */);
+
// Remove update progress for DeltaPerformer and remove snapshots.
if (!boot_control_->GetDynamicPartitionControl()->ResetUpdate(prefs_))
ret_value = false;
diff --git a/common/fake_hardware.h b/common/fake_hardware.h
index 00a212e..29ba607 100644
--- a/common/fake_hardware.h
+++ b/common/fake_hardware.h
@@ -194,6 +194,8 @@
void SetWarmReset(bool warm_reset) override { warm_reset_ = warm_reset; }
+ void SetVbmetaDigestForInactiveSlot(bool reset) override {}
+
// Getters to verify state.
int GetMaxKernelKeyRollforward() const { return kernel_max_rollforward_; }
diff --git a/common/hardware_interface.h b/common/hardware_interface.h
index cad32fc..7460097 100644
--- a/common/hardware_interface.h
+++ b/common/hardware_interface.h
@@ -137,6 +137,10 @@
// needed on the next reboot. Otherwise, clears the flag.
virtual void SetWarmReset(bool warm_reset) = 0;
+ // If not reset, sets the vbmeta digest of the inactive slot as a sysprop.
+ // Otherwise, clears the sysprop.
+ virtual void SetVbmetaDigestForInactiveSlot(bool reset) = 0;
+
// Return the version/timestamp for partition `partition_name`.
// Don't make any assumption about the formatting of returned string.
// Only used for logging/debugging purposes.
diff --git a/cros/hardware_chromeos.cc b/cros/hardware_chromeos.cc
index 14f2497..a57cd78 100644
--- a/cros/hardware_chromeos.cc
+++ b/cros/hardware_chromeos.cc
@@ -349,6 +349,8 @@
void HardwareChromeOS::SetWarmReset(bool warm_reset) {}
+void HardwareChromeOS::SetVbmetaDigestForInactiveSlot(bool reset) {}
+
std::string HardwareChromeOS::GetVersionForLogging(
const std::string& partition_name) const {
// TODO(zhangkelvin) Implement per-partition timestamp for Chrome OS.
diff --git a/cros/hardware_chromeos.h b/cros/hardware_chromeos.h
index de84d78..8a920ef 100644
--- a/cros/hardware_chromeos.h
+++ b/cros/hardware_chromeos.h
@@ -62,6 +62,7 @@
bool GetFirstActiveOmahaPingSent() const override;
bool SetFirstActiveOmahaPingSent() override;
void SetWarmReset(bool warm_reset) override;
+ void SetVbmetaDigestForInactiveSlot(bool reset) override;
std::string GetVersionForLogging(
const std::string& partition_name) const override;
ErrorCode IsPartitionUpdateValid(
diff --git a/payload_consumer/postinstall_runner_action.cc b/payload_consumer/postinstall_runner_action.cc
index dc444c7..58d045b 100644
--- a/payload_consumer/postinstall_runner_action.cc
+++ b/payload_consumer/postinstall_runner_action.cc
@@ -374,6 +374,8 @@
} else {
// Schedules warm reset on next reboot, ignores the error.
hardware_->SetWarmReset(true);
+ // Sets the vbmeta digest for the other slot to boot into.
+ hardware_->SetVbmetaDigestForInactiveSlot(false);
}
} else {
error_code = ErrorCode::kUpdatedButNotActive;