Merge "Always set a avb salt for hermetic build" am: fff48d788f

Original change: https://android-review.googlesource.com/c/platform/build/+/2613794

Change-Id: I3feffd1c65f8e92e7c6a6c6e0481e206b28ec8dd
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Treehugger Robot 2023-06-06 19:07:16 +00:00 committed by Automerger Merge Worker
commit 4c357806a3
4 changed files with 61 additions and 38 deletions

View file

@ -68,6 +68,7 @@ import sparse_img
from concurrent.futures import ThreadPoolExecutor
from apex_utils import GetApexInfoFromTargetFiles
from common import ZipDelete, PARTITIONS_WITH_CARE_MAP, ExternalError, RunAndCheckOutput, IsSparseImage, MakeTempFile, ZipWrite
from build_image import FIXED_FILE_TIMESTAMP
if sys.hexversion < 0x02070000:
print("Python 2.7 or newer is required.", file=sys.stderr)
@ -81,12 +82,6 @@ OPTIONS.rebuild_recovery = False
OPTIONS.replace_updated_files_list = []
OPTIONS.is_signing = False
# Use a fixed timestamp (01/01/2009 00:00:00 UTC) for files when packaging
# images. (b/24377993, b/80600931)
FIXED_FILE_TIMESTAMP = int((
datetime.datetime(2009, 1, 1, 0, 0, 0, 0, None) -
datetime.datetime.utcfromtimestamp(0)).total_seconds())
def ParseAvbFooter(img_path) -> avbtool.AvbFooter:
with open(img_path, 'rb') as fp:
@ -594,15 +589,6 @@ def CreateImage(input_dir, info_dict, what, output_file, block_list=None):
if block_list:
image_props["block_list"] = block_list.name
# Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and
# build fingerprint). Also use the legacy build id, because the vbmeta digest
# isn't available at this point.
build_info = common.BuildInfo(info_dict, use_legacy_id=True)
uuid_seed = what + "-" + build_info.GetPartitionFingerprint(what)
image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed))
hash_seed = "hash_seed-" + uuid_seed
image_props["hash_seed"] = str(uuid.uuid5(uuid.NAMESPACE_URL, hash_seed))
build_image.BuildImage(
os.path.join(input_dir, what.upper()), image_props, output_file.name)
@ -1144,14 +1130,18 @@ def AddImagesToTargetFiles(filename):
item for item in vbmeta_partitions
if item not in vbmeta_vendor.split()]
vbmeta_partitions.append("vbmeta_vendor")
custom_avb_partitions = OPTIONS.info_dict.get("avb_custom_vbmeta_images_partition_list", "").strip().split()
custom_avb_partitions = OPTIONS.info_dict.get(
"avb_custom_vbmeta_images_partition_list", "").strip().split()
if custom_avb_partitions:
for avb_part in custom_avb_partitions:
partition_name = "vbmeta_" + avb_part
included_partitions = OPTIONS.info_dict.get("avb_vbmeta_{}".format(avb_part), "").strip().split()
assert included_partitions, "Custom vbmeta partition {0} missing avb_vbmeta_{0} prop".format(avb_part)
included_partitions = OPTIONS.info_dict.get(
"avb_vbmeta_{}".format(avb_part), "").strip().split()
assert included_partitions, "Custom vbmeta partition {0} missing avb_vbmeta_{0} prop".format(
avb_part)
banner(partition_name)
logger.info("VBMeta partition {} needs {}".format(partition_name, included_partitions))
logger.info("VBMeta partition {} needs {}".format(
partition_name, included_partitions))
partitions[partition_name] = AddVBMeta(
output_zip, partitions, partition_name, included_partitions)
vbmeta_partitions = [
@ -1159,7 +1149,6 @@ def AddImagesToTargetFiles(filename):
if item not in included_partitions]
vbmeta_partitions.append(partition_name)
if OPTIONS.info_dict.get("avb_building_vbmeta_image") == "true":
banner("vbmeta")
AddVBMeta(output_zip, partitions, "vbmeta", vbmeta_partitions)

View file

@ -23,24 +23,34 @@ Usage: build_image input_directory properties_file output_image \\
"""
from __future__ import print_function
import datetime
import glob
import logging
import os
import os.path
import re
import shlex
import shutil
import sys
import uuid
import common
import verity_utils
logger = logging.getLogger(__name__)
OPTIONS = common.OPTIONS
BLOCK_SIZE = common.BLOCK_SIZE
BYTES_IN_MB = 1024 * 1024
# Use a fixed timestamp (01/01/2009 00:00:00 UTC) for files when packaging
# images. (b/24377993, b/80600931)
FIXED_FILE_TIMESTAMP = int((
datetime.datetime(2009, 1, 1, 0, 0, 0, 0, None) -
datetime.datetime.utcfromtimestamp(0)).total_seconds())
class BuildImageError(Exception):
"""An Exception raised during image building."""
@ -487,6 +497,20 @@ def RunErofsFsck(out_file):
raise
def SetUUIDIfNotExist(image_props):
# Use repeatable ext4 FS UUID and hash_seed UUID (based on partition name and
# build fingerprint). Also use the legacy build id, because the vbmeta digest
# isn't available at this point.
what = image_props["mount_point"]
fingerprint = image_props.get("fingerprint", "")
uuid_seed = what + "-" + fingerprint
logger.info("Using fingerprint %s for partition %s", fingerprint, what)
image_props["uuid"] = str(uuid.uuid5(uuid.NAMESPACE_URL, uuid_seed))
hash_seed = "hash_seed-" + uuid_seed
image_props["hash_seed"] = str(uuid.uuid5(uuid.NAMESPACE_URL, hash_seed))
def BuildImage(in_dir, prop_dict, out_file, target_out=None):
"""Builds an image for the files under in_dir and writes it to out_file.
@ -504,6 +528,7 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None):
BuildImageError: On build image failures.
"""
in_dir, fs_config = SetUpInDirAndFsConfig(in_dir, prop_dict)
SetUUIDIfNotExist(prop_dict)
build_command = []
fs_type = prop_dict.get("fs_type", "")
@ -635,6 +660,19 @@ def BuildImage(in_dir, prop_dict, out_file, target_out=None):
verity_image_builder.Build(out_file)
def TryParseFingerprint(glob_dict: dict):
for (key, val) in glob_dict.items():
if not key.endswith("_add_hashtree_footer_args") and not key.endswith("_add_hash_footer_args"):
continue
for arg in shlex.split(val):
m = re.match(r"^com\.android\.build\.\w+\.fingerprint:", arg)
if m is None:
continue
fingerprint = arg[len(m.group()):]
glob_dict["fingerprint"] = fingerprint
return
def ImagePropFromGlobalDict(glob_dict, mount_point):
"""Build an image property dictionary from the global dictionary.
@ -643,7 +681,9 @@ def ImagePropFromGlobalDict(glob_dict, mount_point):
mount_point: such as "system", "data" etc.
"""
d = {}
TryParseFingerprint(glob_dict)
d["timestamp"] = FIXED_FILE_TIMESTAMP
if "build.prop" in glob_dict:
timestamp = glob_dict["build.prop"].GetProp("ro.build.date.utc")
if timestamp:
@ -680,6 +720,7 @@ def ImagePropFromGlobalDict(glob_dict, mount_point):
"avb_enable",
"avb_avbtool",
"use_dynamic_partition_size",
"fingerprint",
)
for p in common_props:
copy_prop(p, p)
@ -870,10 +911,9 @@ def BuildVBMeta(in_dir, glob_dict, output_path):
if item not in vbmeta_vendor.split()]
vbmeta_partitions.append("vbmeta_vendor")
partitions = {part: os.path.join(in_dir, part + ".img")
for part in vbmeta_partitions}
partitions = {part:path for (part, path) in partitions.items() if os.path.exists(path)}
partitions = {part: path for (part, path) in partitions.items() if os.path.exists(path)}
common.BuildVBMeta(output_path, partitions, name, vbmeta_partitions)

View file

@ -928,20 +928,7 @@ def LoadInfoDict(input_file, repacking=False):
input_file, partition, ramdisk_format=ramdisk_format)
d["build.prop"] = d["system.build.prop"]
# Set up the salt (based on fingerprint) that will be used when adding AVB
# hash / hashtree footers.
if d.get("avb_enable") == "true":
build_info = BuildInfo(d, use_legacy_id=True)
for partition in PARTITIONS_WITH_BUILD_PROP:
fingerprint = build_info.GetPartitionFingerprint(partition)
if fingerprint:
d["avb_{}_salt".format(partition)] = sha256(
fingerprint.encode()).hexdigest()
# Set up the salt for partitions without build.prop
if build_info.fingerprint:
d["avb_salt"] = sha256(build_info.fingerprint.encode()).hexdigest()
# Set the vbmeta digest if exists
try:
d["vbmeta_digest"] = read_helper("META/vbmeta_digest.txt").rstrip()

View file

@ -31,6 +31,7 @@ import sys
import common
import sparse_img
from rangelib import RangeSet
from hashlib import sha256
logger = logging.getLogger(__name__)
@ -42,6 +43,7 @@ FIXED_SALT = "aee087a5be3b982978c923f566a94613496b417f2af592639bc80d141e34dfe7"
MAX_VBMETA_SIZE = 64 * 1024
MAX_FOOTER_SIZE = 4096
class BuildVerityImageError(Exception):
"""An Exception raised during verity image building."""
@ -64,6 +66,11 @@ def CreateVerityImageBuilder(prop_dict):
# partition_size could be None at this point, if using dynamic partitions.
if partition_size:
partition_size = int(partition_size)
# Set up the salt (based on fingerprint) that will be used when adding AVB
# hash / hashtree footers.
salt = prop_dict.get("avb_salt")
if salt is None:
salt = sha256(prop_dict.get("fingerprint", "").encode()).hexdigest()
# Verified Boot 2.0
if (prop_dict.get("avb_hash_enable") == "true" or
@ -81,7 +88,7 @@ def CreateVerityImageBuilder(prop_dict):
prop_dict["avb_avbtool"],
key_path,
algorithm,
prop_dict.get("avb_salt"),
salt,
prop_dict["avb_add_hash_footer_args"])
# Image uses hashtree footer.
@ -92,7 +99,7 @@ def CreateVerityImageBuilder(prop_dict):
prop_dict["avb_avbtool"],
key_path,
algorithm,
prop_dict.get("avb_salt"),
salt,
prop_dict["avb_add_hashtree_footer_args"])
return None
@ -279,7 +286,7 @@ class VerifiedBootVersion2VerityImageBuilder(VerityImageBuilder):
def CreateCustomImageBuilder(info_dict, partition_name, partition_size,
key_path, algorithm, signing_args):
key_path, algorithm, signing_args):
builder = None
if info_dict.get("avb_enable") == "true":
builder = VerifiedBootVersion2VerityImageBuilder(