OSDN Git Service

Restrict the verification in block-based incremental OTAs
authorTao Bao <tbao@google.com>
Thu, 12 Mar 2015 19:32:37 +0000 (12:32 -0700)
committerTao Bao <tbao@google.com>
Thu, 12 Mar 2015 20:47:04 +0000 (13:47 -0700)
BlockImageDiff has three versions. Only the incremental OTAs generated
with the latest version (3) can be re-applied to the system that's
already on the target build. Otherwise, operations like move will make
unconditional changes and damage the system. During the verification
phase, abort the OTA update if BlockImageDiff is less than 3 and it
doesn't match the checksum of the source build.

Change-Id: I3a776495b69e1d174fcb01b10e40c0e912914fd8

tools/releasetools/common.py
tools/releasetools/ota_from_target_files

index 8941f89..a596c26 100644 (file)
@@ -1024,20 +1024,22 @@ def ComputeDifferences(diffs):
 
 
 class BlockDifference:
-  def __init__(self, partition, tgt, src=None, check_first_block=False):
+  def __init__(self, partition, tgt, src=None, check_first_block=False, version=None):
     self.tgt = tgt
     self.src = src
     self.partition = partition
     self.check_first_block = check_first_block
 
-    version = 1
-    if OPTIONS.info_dict:
-      version = max(
-          int(i) for i in
-          OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
+    if version is None:
+      version = 1
+      if OPTIONS.info_dict:
+        version = max(
+            int(i) for i in
+            OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
+    self.version = version
 
     b = blockimgdiff.BlockImageDiff(tgt, src, threads=OPTIONS.worker_threads,
-                                    version=version)
+                                    version=self.version)
     tmpdir = tempfile.mkdtemp()
     OPTIONS.tempfiles.append(tmpdir)
     self.path = os.path.join(tmpdir, partition)
@@ -1066,12 +1068,19 @@ class BlockDifference:
                          (self.device, self.src.care_map.to_string_raw(),
                           self.src.TotalSha1()))
       script.Print("Verified %s image..." % (self.partition,))
-      script.AppendExtra(('else\n'
-                          '  (range_sha1("%s", "%s") == "%s") ||\n'
-                          '  abort("%s partition has unexpected contents");\n'
-                          'endif;') %
-                         (self.device, self.tgt.care_map.to_string_raw(),
-                          self.tgt.TotalSha1(), self.partition))
+      # Abort the OTA update if it doesn't support resumable OTA (i.e. version<3)
+      # and the checksum doesn't match the one in the source partition.
+      if self.version < 3:
+        script.AppendExtra(('else\n'
+                            '  abort("%s partition has unexpected contents");\n'
+                            'endif;') % (self.partition))
+      else:
+        script.AppendExtra(('else\n'
+                            '  (range_sha1("%s", "%s") == "%s") ||\n'
+                            '  abort("%s partition has unexpected contents");\n'
+                            'endif;') %
+                           (self.device, self.tgt.care_map.to_string_raw(),
+                            self.tgt.TotalSha1(), self.partition))
 
   def _WriteUpdate(self, script, output_zip):
     partition = self.partition
index 945f11a..25309a4 100755 (executable)
@@ -740,8 +740,16 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
 
   system_src = GetImage("system", OPTIONS.source_tmp, OPTIONS.source_info_dict)
   system_tgt = GetImage("system", OPTIONS.target_tmp, OPTIONS.target_info_dict)
+
+  blockimgdiff_version = 1
+  if OPTIONS.info_dict:
+    blockimgdiff_version = max(
+        int(i) for i in
+        OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
+
   system_diff = common.BlockDifference("system", system_tgt, system_src,
-                                       check_first_block=True)
+                                       check_first_block=True,
+                                       version=blockimgdiff_version)
 
   if HasVendorPartition(target_zip):
     if not HasVendorPartition(source_zip):
@@ -749,7 +757,8 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
     vendor_src = GetImage("vendor", OPTIONS.source_tmp, OPTIONS.source_info_dict)
     vendor_tgt = GetImage("vendor", OPTIONS.target_tmp, OPTIONS.target_info_dict)
     vendor_diff = common.BlockDifference("vendor", vendor_tgt, vendor_src,
-                                         check_first_block=True)
+                                         check_first_block=True,
+                                         version=blockimgdiff_version)
   else:
     vendor_diff = None
 
@@ -810,11 +819,22 @@ else if get_stage("%(bcb_dev)s") != "3/3" then
   device_specific.IncrementalOTA_VerifyBegin()
 
   if oem_props is None:
-    script.AssertSomeFingerprint(source_fp, target_fp)
+    # When blockimgdiff version is less than 3 (non-resumable block-based OTA),
+    # patching on a device that's already on the target build will damage the
+    # system. Because operations like move don't check the block state, they
+    # always apply the changes unconditionally.
+    if blockimgdiff_version <= 2:
+      script.AssertSomeFingerprint(source_fp)
+    else:
+      script.AssertSomeFingerprint(source_fp, target_fp)
   else:
-    script.AssertSomeThumbprint(
-        GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
-        GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
+    if blockimgdiff_version <= 2:
+      script.AssertSomeThumbprint(
+          GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
+    else:
+      script.AssertSomeThumbprint(
+          GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
+          GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
 
   if updating_boot:
     boot_type, boot_device = common.GetTypeAndDevice("/boot", OPTIONS.info_dict)