Revert "update_engine: Deprecate major version 1"
This partially reverts commit 55c75417e22d5026971276997924a345d9973bbc.
It turns out that we forgot a scenario when we deprecated major version
1. We use update_engine in lab tests (specifically
autoupdate_EndToEndTests on stable channel) to update a DUT to an
old (very old) versions using actual update payloads so we can test that
they can get updated to newer versions. However, deprecating major
version 1 in the update_engine caused trouble because we no longer can
update from a newer version to a version before M72 (to prepare the
device for update test). We need to put this feature back until we find
a better solution for it.
On this CL, we only support major version 1 in the client and only for
test (non-official) images. We don't even bother adding paygen support
for it.
This CL should be reverted once we figured out what to do with
provisioning the autoupdate end to end tests.
BUG=chromium:1043428
TEST=FEATURES=test emerge-reef update_engine
TEST=cros deployed it, then cros flash using an m71 payload, it succeeded.
Change-Id: I1fecbe3ae845b2e419f0999adc53e4732b1f7696
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/2013884
Reviewed-by: Tianjie Xu <xunchang@google.com>
Reviewed-by: Sen Jiang <senj@chromium.org>
Tested-by: Amin Hassani <ahassani@chromium.org>
Commit-Queue: Amin Hassani <ahassani@chromium.org>
diff --git a/payload_consumer/payload_metadata.cc b/payload_consumer/payload_metadata.cc
index b83001a..69ccb46 100644
--- a/payload_consumer/payload_metadata.cc
+++ b/payload_consumer/payload_metadata.cc
@@ -20,6 +20,7 @@
#include <brillo/data_encoding.h>
+#include "update_engine/common/hardware_interface.h"
#include "update_engine/common/hash_calculator.h"
#include "update_engine/common/utils.h"
#include "update_engine/payload_consumer/payload_constants.h"
@@ -36,18 +37,36 @@
const uint64_t PayloadMetadata::kDeltaManifestSizeSize = 8;
const uint64_t PayloadMetadata::kDeltaMetadataSignatureSizeSize = 4;
-uint64_t PayloadMetadata::GetMetadataSignatureSizeOffset() const {
- return kDeltaManifestSizeOffset + kDeltaManifestSizeSize;
+bool PayloadMetadata::GetMetadataSignatureSizeOffset(
+ uint64_t* out_offset) const {
+ if (GetMajorVersion() == kBrilloMajorPayloadVersion) {
+ *out_offset = kDeltaManifestSizeOffset + kDeltaManifestSizeSize;
+ return true;
+ }
+ return false;
}
-uint64_t PayloadMetadata::GetManifestOffset() const {
- // Actual manifest begins right after the metadata signature size field.
- return kDeltaManifestSizeOffset + kDeltaManifestSizeSize +
- kDeltaMetadataSignatureSizeSize;
+bool PayloadMetadata::GetManifestOffset(uint64_t* out_offset) const {
+ // Actual manifest begins right after the manifest size field or
+ // metadata signature size field if major version >= 2.
+ if (major_payload_version_ == kChromeOSMajorPayloadVersion) {
+ *out_offset = kDeltaManifestSizeOffset + kDeltaManifestSizeSize;
+ return true;
+ }
+ if (major_payload_version_ == kBrilloMajorPayloadVersion) {
+ *out_offset = kDeltaManifestSizeOffset + kDeltaManifestSizeSize +
+ kDeltaMetadataSignatureSizeSize;
+ return true;
+ }
+ LOG(ERROR) << "Unknown major payload version: " << major_payload_version_;
+ return false;
}
MetadataParseResult PayloadMetadata::ParsePayloadHeader(
- const brillo::Blob& payload, ErrorCode* error) {
+ const brillo::Blob& payload,
+ HardwareInterface* hardware,
+ ErrorCode* error) {
+ uint64_t manifest_offset;
// Ensure we have data to cover the major payload version.
if (payload.size() < kDeltaManifestSizeOffset)
return MetadataParseResult::kInsufficientData;
@@ -59,11 +78,6 @@
return MetadataParseResult::kError;
}
- uint64_t manifest_offset = GetManifestOffset();
- // Check again with the manifest offset.
- if (payload.size() < manifest_offset)
- return MetadataParseResult::kInsufficientData;
-
// Extract the payload version from the metadata.
static_assert(sizeof(major_payload_version_) == kDeltaVersionSize,
"Major payload version size mismatch");
@@ -73,14 +87,26 @@
// Switch big endian to host.
major_payload_version_ = be64toh(major_payload_version_);
- if (major_payload_version_ < kMinSupportedMajorPayloadVersion ||
- major_payload_version_ > kMaxSupportedMajorPayloadVersion) {
+ // We only want to test major version 1 for test images.
+ if (major_payload_version_ == kChromeOSMajorPayloadVersion
+ ? hardware != nullptr && hardware->IsOfficialBuild()
+ : major_payload_version_ < kMinSupportedMajorPayloadVersion ||
+ major_payload_version_ > kMaxSupportedMajorPayloadVersion) {
LOG(ERROR) << "Bad payload format -- unsupported payload version: "
<< major_payload_version_;
*error = ErrorCode::kUnsupportedMajorPayloadVersion;
return MetadataParseResult::kError;
}
+ // Get the manifest offset now that we have payload version.
+ if (!GetManifestOffset(&manifest_offset)) {
+ *error = ErrorCode::kUnsupportedMajorPayloadVersion;
+ return MetadataParseResult::kError;
+ }
+ // Check again with the manifest offset.
+ if (payload.size() < manifest_offset)
+ return MetadataParseResult::kInsufficientData;
+
// Next, parse the manifest size.
static_assert(sizeof(manifest_size_) == kDeltaManifestSizeSize,
"manifest_size size mismatch");
@@ -97,33 +123,43 @@
return MetadataParseResult::kError;
}
- // Parse the metadata signature size.
- static_assert(
- sizeof(metadata_signature_size_) == kDeltaMetadataSignatureSizeSize,
- "metadata_signature_size size mismatch");
- uint64_t metadata_signature_size_offset = GetMetadataSignatureSizeOffset();
- memcpy(&metadata_signature_size_,
- &payload[metadata_signature_size_offset],
- kDeltaMetadataSignatureSizeSize);
- metadata_signature_size_ = be32toh(metadata_signature_size_);
+ if (GetMajorVersion() == kBrilloMajorPayloadVersion) {
+ // Parse the metadata signature size.
+ static_assert(
+ sizeof(metadata_signature_size_) == kDeltaMetadataSignatureSizeSize,
+ "metadata_signature_size size mismatch");
+ uint64_t metadata_signature_size_offset;
+ if (!GetMetadataSignatureSizeOffset(&metadata_signature_size_offset)) {
+ *error = ErrorCode::kError;
+ return MetadataParseResult::kError;
+ }
+ memcpy(&metadata_signature_size_,
+ &payload[metadata_signature_size_offset],
+ kDeltaMetadataSignatureSizeSize);
+ metadata_signature_size_ = be32toh(metadata_signature_size_);
- if (metadata_size_ + metadata_signature_size_ < metadata_size_) {
- // Overflow detected.
- LOG(ERROR) << "Overflow detected on metadata and signature size.";
- *error = ErrorCode::kDownloadInvalidMetadataSize;
- return MetadataParseResult::kError;
+ if (metadata_size_ + metadata_signature_size_ < metadata_size_) {
+ // Overflow detected.
+ LOG(ERROR) << "Overflow detected on metadata and signature size.";
+ *error = ErrorCode::kDownloadInvalidMetadataSize;
+ return MetadataParseResult::kError;
+ }
}
return MetadataParseResult::kSuccess;
}
-bool PayloadMetadata::ParsePayloadHeader(const brillo::Blob& payload) {
+bool PayloadMetadata::ParsePayloadHeader(const brillo::Blob& payload,
+ HardwareInterface* hardware) {
ErrorCode error;
- return ParsePayloadHeader(payload, &error) == MetadataParseResult::kSuccess;
+ return ParsePayloadHeader(payload, hardware, &error) ==
+ MetadataParseResult::kSuccess;
}
bool PayloadMetadata::GetManifest(const brillo::Blob& payload,
DeltaArchiveManifest* out_manifest) const {
- uint64_t manifest_offset = GetManifestOffset();
+ uint64_t manifest_offset;
+ if (!GetManifestOffset(&manifest_offset))
+ return false;
CHECK_GE(payload.size(), manifest_offset + manifest_size_);
return out_manifest->ParseFromArray(&payload[manifest_offset],
manifest_size_);
@@ -145,7 +181,7 @@
<< metadata_signature;
return ErrorCode::kDownloadMetadataSignatureError;
}
- } else {
+ } else if (major_payload_version_ == kBrilloMajorPayloadVersion) {
metadata_signature_protobuf_blob.assign(
payload.begin() + metadata_size_,
payload.begin() + metadata_size_ + metadata_signature_size_);
@@ -206,7 +242,7 @@
brillo::Blob payload;
TEST_AND_RETURN_FALSE(
utils::ReadFileChunk(payload_path, 0, kMaxPayloadHeaderSize, &payload));
- TEST_AND_RETURN_FALSE(ParsePayloadHeader(payload));
+ TEST_AND_RETURN_FALSE(ParsePayloadHeader(payload, nullptr));
if (manifest != nullptr) {
TEST_AND_RETURN_FALSE(
@@ -217,7 +253,8 @@
TEST_AND_RETURN_FALSE(GetManifest(payload, manifest));
}
- if (metadata_signatures != nullptr) {
+ if (metadata_signatures != nullptr &&
+ GetMajorVersion() >= kBrilloMajorPayloadVersion) {
payload.clear();
TEST_AND_RETURN_FALSE(utils::ReadFileChunk(
payload_path, GetMetadataSize(), GetMetadataSignatureSize(), &payload));