forked from openkylin/platform_build
AVB: decouple vbmeta.img from recovery.img for non-A/B devices
For following cases: Case 1: A/B devices: no change Case 2: non-A/B devices, with unsigned recovery image: not allowed anymore by mandating BOARD_AVB_RECOVERY_KEY_PATH Case 3: non-A/B devices, with signed recovery image: vbmeta.img should not include ChainPartitionDescriptor of recovery.img, otherwise device can not even boot into normal mode if recovery partition is damaged This CL will cause a build break if BOARD_AVB_RECOVERY_KEY_PATH is not set for non-A/B targets with recovery.img The following is an example to fix the build break by specifying AVB signing configs for the recovery.img. BOARD_AVB_RECOVERY_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_RECOVERY_ALGORITHM := SHA256_RSA2048 BOARD_AVB_RECOVERY_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_RECOVERY_ROLLBACK_INDEX_LOCATION := 2 Also note that libavb in bootloader needs an update to include this commit Iaa886037edb18c2ff6c60fa2a7f883ab7303ba1a, to support verifying recovery.img independently (not through vbmeta.img). Bug: 130351427 Test (Case 3): normal mode: avb_slot_verify(flags=AVB_SLOT_VERIFY_FLAGS_NONE) recovery mode: avb_slot_verify(flags=AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION) Test: PYTHONPATH=build/make/tools/releasetools \ python -m unittest test_validate_target_files Test: Use a lunch'd target. `atest --host releasetools_test releasetools_py3_test` Test: validate_target_files.py with Case-3 target files Change-Id: I2a73252b385fa463b4abd444923a8acc473df0b4
This commit is contained in:
parent
818df7b0d0
commit
1aeef725a7
|
@ -3289,6 +3289,17 @@ ifneq ($(words $(sort $(INTERNAL_AVB_PARTITIONS_IN_CHAINED_VBMETA_IMAGES))),$(wo
|
|||
$(error BOARD_AVB_VBMETA_SYSTEM and BOARD_AVB_VBMETA_VENDOR cannot have duplicates)
|
||||
endif
|
||||
|
||||
# When building a standalone recovery image for non-A/B devices, recovery image must be self-signed
|
||||
# to be verified independently, and cannot be chained into vbmeta.img. See the link below for
|
||||
# details.
|
||||
ifneq ($(AB_OTA_UPDATER),true)
|
||||
ifneq ($(INSTALLED_RECOVERYIMAGE_TARGET),)
|
||||
$(if $(BOARD_AVB_RECOVERY_KEY_PATH),,\
|
||||
$(error BOARD_AVB_RECOVERY_KEY_PATH must be defined for non-A/B devices. \
|
||||
See https://android.googlesource.com/platform/external/avb/+/master/README.md#booting-into-recovery))
|
||||
endif
|
||||
endif
|
||||
|
||||
# Appends os version and security patch level as a AVB property descriptor
|
||||
|
||||
BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS += \
|
||||
|
@ -3358,8 +3369,11 @@ $(eval _signing_args := INTERNAL_AVB_$(PART)_SIGNING_ARGS)
|
|||
$(eval $(_signing_args) := \
|
||||
--algorithm $($(_signing_algorithm)) --key $($(_key_path)))
|
||||
|
||||
$(eval INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
|
||||
--chain_partition $(part):$($(_rollback_index_location)):$(AVB_CHAIN_KEY_DIR)/$(part).avbpubkey)
|
||||
# The recovery partition in non-A/B devices should be verified separately. Skip adding the chain
|
||||
# partition descriptor for recovery partition into vbmeta.img.
|
||||
$(if $(or $(filter true,$(AB_OTA_UPDATER)),$(filter-out recovery,$(part))),\
|
||||
$(eval INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS += \
|
||||
--chain_partition $(part):$($(_rollback_index_location)):$(AVB_CHAIN_KEY_DIR)/$(part).avbpubkey))
|
||||
|
||||
# Set rollback_index via footer args for non-chained vbmeta image. Chained vbmeta image will pick up
|
||||
# the index via a separate flag (e.g. BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX).
|
||||
|
|
|
@ -873,10 +873,20 @@ def GetAvbPartitionArg(partition, image, info_dict=None):
|
|||
|
||||
# Check if chain partition is used.
|
||||
key_path = info_dict.get("avb_" + partition + "_key_path")
|
||||
if key_path:
|
||||
chained_partition_arg = GetAvbChainedPartitionArg(partition, info_dict)
|
||||
return ["--chain_partition", chained_partition_arg]
|
||||
return ["--include_descriptors_from_image", image]
|
||||
if not key_path:
|
||||
return ["--include_descriptors_from_image", image]
|
||||
|
||||
# For a non-A/B device, we don't chain /recovery nor include its descriptor
|
||||
# into vbmeta.img. The recovery image will be configured on an independent
|
||||
# boot chain, to be verified with AVB_SLOT_VERIFY_FLAGS_NO_VBMETA_PARTITION.
|
||||
# See details at
|
||||
# https://android.googlesource.com/platform/external/avb/+/master/README.md#booting-into-recovery.
|
||||
if OPTIONS.info_dict.get("ab_update") != "true" and partition == "recovery":
|
||||
return []
|
||||
|
||||
# Otherwise chain the partition into vbmeta.
|
||||
chained_partition_arg = GetAvbChainedPartitionArg(partition, info_dict)
|
||||
return ["--chain_partition", chained_partition_arg]
|
||||
|
||||
|
||||
def GetAvbChainedPartitionArg(partition, info_dict, key=None):
|
||||
|
|
|
@ -346,20 +346,25 @@ def ValidateVerifiedBootImages(input_tmp, info_dict, options):
|
|||
key = info_dict['avb_vbmeta_key_path']
|
||||
|
||||
# avbtool verifies all the images that have descriptors listed in vbmeta.
|
||||
# Using `--follow_chain_partitions` so it would additionally verify chained
|
||||
# vbmeta partitions (e.g. vbmeta_system).
|
||||
image = os.path.join(input_tmp, 'IMAGES', 'vbmeta.img')
|
||||
cmd = [info_dict['avb_avbtool'], 'verify_image', '--image', image,
|
||||
'--key', key]
|
||||
'--key', key, '--follow_chain_partitions']
|
||||
|
||||
# Append the args for chained partitions if any.
|
||||
for partition in common.AVB_PARTITIONS + common.AVB_VBMETA_PARTITIONS:
|
||||
key_name = 'avb_' + partition + '_key_path'
|
||||
if info_dict.get(key_name) is not None:
|
||||
if info_dict.get('ab_update') != 'true' and partition == 'recovery':
|
||||
continue
|
||||
|
||||
# Use the key file from command line if specified; otherwise fall back
|
||||
# to the one in info dict.
|
||||
key_file = options.get(key_name, info_dict[key_name])
|
||||
chained_partition_arg = common.GetAvbChainedPartitionArg(
|
||||
partition, info_dict, key_file)
|
||||
cmd.extend(["--expected_chain_partition", chained_partition_arg])
|
||||
cmd.extend(['--expected_chain_partition', chained_partition_arg])
|
||||
|
||||
proc = common.Run(cmd)
|
||||
stdoutdata, _ = proc.communicate()
|
||||
|
@ -371,6 +376,22 @@ def ValidateVerifiedBootImages(input_tmp, info_dict, options):
|
|||
'Verified %s with avbtool (key: %s):\n%s', image, key,
|
||||
stdoutdata.rstrip())
|
||||
|
||||
# avbtool verifies recovery image for non-A/B devices.
|
||||
if (info_dict.get('ab_update') != 'true' and
|
||||
info_dict.get('no_recovery') != 'true'):
|
||||
image = os.path.join(input_tmp, 'IMAGES', 'recovery.img')
|
||||
key = info_dict['avb_recovery_key_path']
|
||||
cmd = [info_dict['avb_avbtool'], 'verify_image', '--image', image,
|
||||
'--key', key]
|
||||
proc = common.Run(cmd)
|
||||
stdoutdata, _ = proc.communicate()
|
||||
assert proc.returncode == 0, \
|
||||
'Failed to verify {} with avbtool (key: {}):\n{}'.format(
|
||||
image, key, stdoutdata)
|
||||
logging.info(
|
||||
'Verified %s with avbtool (key: %s):\n%s', image, key,
|
||||
stdoutdata.rstrip())
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
|
|
Loading…
Reference in New Issue