Merge "Restrict the verification in block-based incremental OTAs"

This commit is contained in:
Tao Bao 2015-03-14 05:01:33 +00:00 committed by Gerrit Code Review
commit 18b27966a6
2 changed files with 48 additions and 21 deletions

View File

@ -1024,17 +1024,19 @@ def ComputeDifferences(diffs):
class BlockDifference: 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.tgt = tgt
self.src = src self.src = src
self.partition = partition self.partition = partition
self.check_first_block = check_first_block self.check_first_block = check_first_block
self.version = 1 if version is None:
if OPTIONS.info_dict: version = 1
self.version = max( if OPTIONS.info_dict:
int(i) for i in version = max(
OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(",")) 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, b = blockimgdiff.BlockImageDiff(tgt, src, threads=OPTIONS.worker_threads,
version=self.version) version=self.version)
@ -1069,17 +1071,25 @@ class BlockDifference:
script.AppendExtra('if range_sha1("%s", "%s") == "%s" then' % script.AppendExtra('if range_sha1("%s", "%s") == "%s" then' %
(self.device, self.src.care_map.to_string_raw(), (self.device, self.src.care_map.to_string_raw(),
self.src.TotalSha1())) self.src.TotalSha1()))
script.Print("Verified %s image..." % (partition,)) script.Print('Verified %s image...' % (partition,))
script.AppendExtra('else'); script.AppendExtra('else');
# When generating incrementals for the system and vendor partitions,
# explicitly check the first block (which contains the superblock) of
# the partition to see if it's what we expect. If this check fails,
# give an explicit log message about the partition having been
# remounted R/W (the most likely explanation) and the need to flash to
# get OTAs working again.
if self.check_first_block: if self.check_first_block:
self._CheckFirstBlock(script) self._CheckFirstBlock(script)
script.AppendExtra(('(range_sha1("%s", "%s") == "%s") ||\n' # Abort the OTA update. Note that the incremental OTA cannot be applied
' abort("%s partition has unexpected contents");\n' # even if it may match the checksum of the target partition.
'endif;') % # a) If version < 3, operations like move and erase will make changes
(self.device, self.tgt.care_map.to_string_raw(), # unconditionally and damage the partition.
self.tgt.TotalSha1(), self.partition)) # b) If version >= 3, it won't even reach here.
script.AppendExtra(('abort("%s partition has unexpected contents");\n'
'endif;') % (partition,))
def _WriteUpdate(self, script, output_zip): def _WriteUpdate(self, script, output_zip):
partition = self.partition partition = self.partition
@ -1109,14 +1119,11 @@ class BlockDifference:
def _CheckFirstBlock(self, script): def _CheckFirstBlock(self, script):
r = RangeSet((0, 1)) r = RangeSet((0, 1))
srchash = self._HashBlocks(self.src, r); srchash = self._HashBlocks(self.src, r);
tgthash = self._HashBlocks(self.tgt, r);
script.AppendExtra(('(range_sha1("%s", "%s") == "%s") || ' script.AppendExtra(('(range_sha1("%s", "%s") == "%s") || '
'(range_sha1("%s", "%s") == "%s") || '
'abort("%s has been remounted R/W; ' 'abort("%s has been remounted R/W; '
'reflash device to reenable OTA updates");') 'reflash device to reenable OTA updates");')
% (self.device, r.to_string_raw(), srchash, % (self.device, r.to_string_raw(), srchash,
self.device, r.to_string_raw(), tgthash,
self.device)) self.device))
DataImage = blockimgdiff.DataImage DataImage = blockimgdiff.DataImage

View File

@ -740,8 +740,16 @@ def WriteBlockIncrementalOTAPackage(target_zip, source_zip, output_zip):
system_src = GetImage("system", OPTIONS.source_tmp, OPTIONS.source_info_dict) system_src = GetImage("system", OPTIONS.source_tmp, OPTIONS.source_info_dict)
system_tgt = GetImage("system", OPTIONS.target_tmp, OPTIONS.target_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, 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 HasVendorPartition(target_zip):
if not HasVendorPartition(source_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_src = GetImage("vendor", OPTIONS.source_tmp, OPTIONS.source_info_dict)
vendor_tgt = GetImage("vendor", OPTIONS.target_tmp, OPTIONS.target_info_dict) vendor_tgt = GetImage("vendor", OPTIONS.target_tmp, OPTIONS.target_info_dict)
vendor_diff = common.BlockDifference("vendor", vendor_tgt, vendor_src, vendor_diff = common.BlockDifference("vendor", vendor_tgt, vendor_src,
check_first_block=True) check_first_block=True,
version=blockimgdiff_version)
else: else:
vendor_diff = None vendor_diff = None
@ -810,11 +819,22 @@ else if get_stage("%(bcb_dev)s") != "3/3" then
device_specific.IncrementalOTA_VerifyBegin() device_specific.IncrementalOTA_VerifyBegin()
if oem_props is None: 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: else:
script.AssertSomeThumbprint( if blockimgdiff_version <= 2:
GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict), script.AssertSomeThumbprint(
GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict)) 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: if updating_boot:
boot_type, boot_device = common.GetTypeAndDevice("/boot", OPTIONS.info_dict) boot_type, boot_device = common.GetTypeAndDevice("/boot", OPTIONS.info_dict)