Fix a bug in computing streaming property of payload.bin

When computing the data offset of an entry in zip file, we used length
of extra field from central directory. That is correct most of the time
but wrong if the extra field in central directory has different length
than the one in local file directory. Since python's zipfile doesn't
provide an API to access local file header, we need to parse local file
header ourselves and extract length of extra field.

An incorrect offset will cause magic mismatch error from update_engine,
as update_engine expects to find uncompressed payload at the recorded
offset.

Test: th, partner verification
Bug: 191443484

Change-Id: Id670cd79b0bd65adffaaa5224ae4f8065d66b358
This commit is contained in:
Kelvin Zhang
2021-06-22 09:51:34 -04:00
parent 7b763f0d46
commit 25ab998d82
4 changed files with 95 additions and 15 deletions

View File

@@ -241,7 +241,7 @@ import care_map_pb2
import common
import ota_utils
from ota_utils import (UNZIP_PATTERN, FinalizeMetadata, GetPackageMetadata,
PropertyFiles, SECURITY_PATCH_LEVEL_PROP_NAME)
PropertyFiles, SECURITY_PATCH_LEVEL_PROP_NAME, GetZipEntryOffset)
import target_files_diff
from check_target_files_vintf import CheckVintfIfTrebleEnabled
from non_ab_ota import GenerateNonAbOtaPackage
@@ -603,20 +603,20 @@ class AbOtaPropertyFiles(StreamingPropertyFiles):
payload, till the end of 'medatada_signature_message'.
"""
payload_info = input_zip.getinfo('payload.bin')
payload_offset = payload_info.header_offset
payload_offset += zipfile.sizeFileHeader
payload_offset += len(payload_info.extra) + len(payload_info.filename)
payload_size = payload_info.file_size
(payload_offset, payload_size) = GetZipEntryOffset(input_zip, payload_info)
with input_zip.open('payload.bin') as payload_fp:
header_bin = payload_fp.read(24)
# Read the underlying raw zipfile at specified offset
payload_fp = input_zip.fp
payload_fp.seek(payload_offset)
header_bin = payload_fp.read(24)
# network byte order (big-endian)
header = struct.unpack("!IQQL", header_bin)
# 'CrAU'
magic = header[0]
assert magic == 0x43724155, "Invalid magic: {:x}".format(magic)
assert magic == 0x43724155, "Invalid magic: {:x}, computed offset {}" \
.format(magic, payload_offset)
manifest_size = header[2]
metadata_signature_size = header[3]