Add security patch level to update manifest
When installing a full OTA, the target build might have a newer
timestamp but older SPL. In these caess, update_engine will fail to
recognize the SPL downgrade and skip data wipe, causing /data decryption
to fail on next reboot. To fix this issue, add a SPL field to update
manifest. update_engine will check this field on OTA install and
schedule data wipe as needed.
Test: install OTA with newer timestamp but older SPL, make sure data wipe is scheduled
Bug: 242812845
Change-Id: I9d1dd73b46323939bbf990e29da5cc0ba79f86e2
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index fc8858f..47eb353 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -28,10 +28,12 @@
#include <utility>
#include <vector>
+#include <android-base/properties.h>
#include <base/files/file_util.h>
#include <base/format_macros.h>
#include <base/metrics/histogram_macros.h>
#include <base/strings/string_number_conversions.h>
+#include <base/strings/stringprintf.h>
#include <base/time/time.h>
#include <brillo/data_encoding.h>
#include <bsdiff/bspatch.h>
@@ -44,24 +46,15 @@
#include "update_engine/common/error_code_utils.h"
#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/prefs_interface.h"
-#include "update_engine/common/subprocess.h"
#include "update_engine/common/terminator.h"
#include "update_engine/common/utils.h"
-#include "update_engine/payload_consumer/bzip_extent_writer.h"
-#include "update_engine/payload_consumer/cached_file_descriptor.h"
-#include "update_engine/payload_consumer/certificate_parser_interface.h"
-#include "update_engine/payload_consumer/extent_reader.h"
-#include "update_engine/payload_consumer/extent_writer.h"
#include "update_engine/payload_consumer/partition_update_generator_interface.h"
#include "update_engine/payload_consumer/partition_writer.h"
#if USE_FEC
#include "update_engine/payload_consumer/fec_file_descriptor.h"
#endif // USE_FEC
-#include "update_engine/payload_consumer/file_descriptor_utils.h"
-#include "update_engine/payload_consumer/mount_history.h"
#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/payload_consumer/payload_verifier.h"
-#include "update_engine/payload_consumer/xz_extent_writer.h"
using google::protobuf::RepeatedPtrField;
using std::min;
@@ -398,6 +391,23 @@
base::TimeDelta::FromMinutes(5), \
20);
+void DeltaPerformer::CheckSPLDowngrade() {
+ const auto new_spl = manifest_.security_patch_level();
+ const auto current_spl =
+ android::base::GetProperty("ro.build.version.security_patch", "");
+ if (current_spl.empty()) {
+ LOG(ERROR) << "Failed to get ro.build.version.security_patch, unable to "
+ "determine if this OTA is a SPL downgrade.";
+ return;
+ }
+ if (new_spl < current_spl) {
+ install_plan_->powerwash_required = true;
+ LOG(INFO) << "Target build SPL " << new_spl
+ << " is older than current build's SPL " << current_spl
+ << ", this OTA is an SPL downgrade. Data wipe will be required";
+ }
+}
+
// Wrapper around write. Returns true if all requested bytes
// were written, or false on any error, regardless of progress
// and stores an action exit code in |error|.
@@ -444,6 +454,8 @@
block_size_ = manifest_.block_size();
+ CheckSPLDowngrade();
+
// This populates |partitions_| and the |install_plan.partitions| with the
// list of partitions from the manifest.
if (!ParseManifestPartitions(error))
diff --git a/payload_consumer/delta_performer.h b/payload_consumer/delta_performer.h
index dd71467..633c533 100644
--- a/payload_consumer/delta_performer.h
+++ b/payload_consumer/delta_performer.h
@@ -32,10 +32,9 @@
#include "update_engine/common/hash_calculator.h"
#include "update_engine/common/platform_constants.h"
-#include "update_engine/payload_consumer/file_descriptor.h"
#include "update_engine/payload_consumer/file_writer.h"
#include "update_engine/payload_consumer/install_plan.h"
-#include "update_engine/payload_consumer/partition_writer.h"
+#include "update_engine/payload_consumer/partition_writer_interface.h"
#include "update_engine/payload_consumer/payload_metadata.h"
#include "update_engine/payload_consumer/payload_verifier.h"
#include "update_engine/update_metadata.pb.h"
@@ -88,7 +87,7 @@
// FileWriter's Write implementation where caller doesn't care about
// error codes.
bool Write(const void* bytes, size_t count) override {
- ErrorCode error;
+ ErrorCode error{};
return Write(bytes, count, &error);
}
@@ -315,6 +314,8 @@
// Check if partition `part_name` is a dynamic partition.
bool IsDynamicPartition(const std::string& part_name, uint32_t slot);
+ void CheckSPLDowngrade();
+
// Update Engine preference store.
PrefsInterface* prefs_;
diff --git a/payload_consumer/partition_writer_unittest.cc b/payload_consumer/partition_writer_unittest.cc
index 331a061..4910594 100644
--- a/payload_consumer/partition_writer_unittest.cc
+++ b/payload_consumer/partition_writer_unittest.cc
@@ -26,16 +26,15 @@
#include "update_engine/common/hash_calculator.h"
#include "update_engine/common/test_utils.h"
#include "update_engine/common/utils.h"
-#include "update_engine/payload_consumer/delta_performer.h"
-#include "update_engine/payload_consumer/extent_reader.h"
#include "update_engine/payload_consumer/extent_writer.h"
#include "update_engine/payload_consumer/fake_file_descriptor.h"
#include "update_engine/payload_consumer/file_descriptor.h"
#include "update_engine/payload_consumer/install_plan.h"
+#include "update_engine/payload_consumer/partition_writer.h"
+#include "update_engine/payload_consumer/payload_constants.h"
#include "update_engine/payload_generator/annotated_operation.h"
#include "update_engine/payload_generator/delta_diff_generator.h"
#include "update_engine/payload_generator/extent_ranges.h"
-#include "update_engine/payload_generator/payload_file.h"
#include "update_engine/payload_generator/payload_generation_config.h"
#include "update_engine/update_metadata.pb.h"