forked from openkylin/platform_build
Restrict the verification in block-based incremental OTAs
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
This commit is contained in:
parent
3c242c5ddb
commit
daebaa6ed3
|
@ -1024,20 +1024,22 @@ 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
|
||||||
|
|
||||||
|
if version is None:
|
||||||
version = 1
|
version = 1
|
||||||
if OPTIONS.info_dict:
|
if OPTIONS.info_dict:
|
||||||
version = max(
|
version = max(
|
||||||
int(i) for i in
|
int(i) for i in
|
||||||
OPTIONS.info_dict.get("blockimgdiff_versions", "1").split(","))
|
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=version)
|
version=self.version)
|
||||||
tmpdir = tempfile.mkdtemp()
|
tmpdir = tempfile.mkdtemp()
|
||||||
OPTIONS.tempfiles.append(tmpdir)
|
OPTIONS.tempfiles.append(tmpdir)
|
||||||
self.path = os.path.join(tmpdir, partition)
|
self.path = os.path.join(tmpdir, partition)
|
||||||
|
@ -1066,6 +1068,13 @@ class BlockDifference:
|
||||||
(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..." % (self.partition,))
|
script.Print("Verified %s image..." % (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'
|
script.AppendExtra(('else\n'
|
||||||
' (range_sha1("%s", "%s") == "%s") ||\n'
|
' (range_sha1("%s", "%s") == "%s") ||\n'
|
||||||
' abort("%s partition has unexpected contents");\n'
|
' abort("%s partition has unexpected contents");\n'
|
||||||
|
|
|
@ -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,7 +819,18 @@ 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:
|
||||||
|
# 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)
|
script.AssertSomeFingerprint(source_fp, target_fp)
|
||||||
|
else:
|
||||||
|
if blockimgdiff_version <= 2:
|
||||||
|
script.AssertSomeThumbprint(
|
||||||
|
GetBuildProp("ro.build.thumbprint", OPTIONS.source_info_dict))
|
||||||
else:
|
else:
|
||||||
script.AssertSomeThumbprint(
|
script.AssertSomeThumbprint(
|
||||||
GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
|
GetBuildProp("ro.build.thumbprint", OPTIONS.target_info_dict),
|
||||||
|
|
Loading…
Reference in New Issue