Enforce handling of expected payload versions only.

We have always shipped version 1 payloads, but have never checked the
version number. This change enforces that, so we refuse to process
any other version number.

The new error code kErrorCodeUnsupportedPayloadVersion is added to
report bad payload versions if they are received.

BUG=chromium:312526
TEST=Unittests.

Change-Id: I25c9f7e73c37274527bc7cc9ba9e3d9f4734326c
Reviewed-on: https://chromium-review.googlesource.com/174940
Commit-Queue: Don Garrett <dgarrett@chromium.org>
Tested-by: Don Garrett <dgarrett@chromium.org>
Reviewed-by: Alex Deymo <deymo@chromium.org>
diff --git a/delta_performer.cc b/delta_performer.cc
index c20614d..69ffbc1 100644
--- a/delta_performer.cc
+++ b/delta_performer.cc
@@ -39,6 +39,8 @@
 
 const uint64_t DeltaPerformer::kDeltaVersionSize = 8;
 const uint64_t DeltaPerformer::kDeltaManifestSizeSize = 8;
+const uint64_t DeltaPerformer::kSupportedMajorPayloadVersion = 1;
+
 const char DeltaPerformer::kUpdatePayloadPublicKeyPath[] =
     "/usr/share/update_engine/update-payload-key.pub.pem";
 const unsigned DeltaPerformer::kProgressLogMaxChunks = 10;
@@ -247,6 +249,11 @@
 
 }  // namespace {}
 
+uint64_t DeltaPerformer::GetVersionOffset() {
+ // Manifest size is stored right after the magic string and the version.
+ return strlen(kDeltaMagic);
+}
+
 uint64_t DeltaPerformer::GetManifestSizeOffset() {
  // Manifest size is stored right after the magic string and the version.
  return strlen(kDeltaMagic) + kDeltaVersionSize;
@@ -279,8 +286,22 @@
     return kMetadataParseError;
   }
 
-  // TODO(jaysri): Compare the version number and skip unknown manifest
-  // versions. We don't check the version at all today.
+  // Extract the payload version from the metadata.
+  uint64_t major_payload_version;
+  COMPILE_ASSERT(sizeof(major_payload_version) == kDeltaVersionSize,
+                 major_payload_version_size_mismatch);
+  memcpy(&major_payload_version,
+         &payload[GetVersionOffset()],
+         kDeltaVersionSize);
+  // switch big endian to host
+  major_payload_version = be64toh(major_payload_version);
+
+  if (major_payload_version != kSupportedMajorPayloadVersion) {
+    LOG(ERROR) << "Bad payload format -- unsupported payload version: "
+               << major_payload_version;
+    *error = kErrorCodeUnsupportedMajorPayloadVersion;
+    return kMetadataParseError;
+  }
 
   // Next, parse the manifest size.
   uint64_t manifest_size;