Skip to content

Commit c736c8b

Browse files
kousuclaude
andcommitted
Update AVB hash header to match repacked contents.
This follows topjohnwu#9830 by recomputing the AVB hash. Apparently few (no?) devices actually respect this hash in the wild at the moment, but it's good to be prepared. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 81a674f commit c736c8b

1 file changed

Lines changed: 50 additions & 2 deletions

File tree

native/src/boot/bootimg.cpp

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,8 +1026,7 @@ void repack(Utf8CStr src_img, Utf8CStr out_img, bool skip_comp) {
10261026
vbmeta->flags = __builtin_bswap32(3);
10271027
}
10281028

1029-
// Sync hash descriptor image_size with the new AOSP portion size.
1030-
// Without this, some bootloaders (e.g. Motorola) reject images.
1029+
// Patch hash descriptor
10311030
for (auto &desc : vbmeta->descriptors()) {
10321031
if (__builtin_bswap64(desc.tag) != AVB_DESCRIPTOR_TAG_HASH)
10331032
continue;
@@ -1046,7 +1045,56 @@ void repack(Utf8CStr src_img, Utf8CStr out_img, bool skip_comp) {
10461045
}
10471046

10481047
auto &hd = reinterpret_cast<AvbHashDescriptor &>(desc);
1048+
1049+
// Update image_size
10491050
hd.image_size = __builtin_bswap64(aosp_img_size);
1051+
1052+
// Recompute hash
1053+
auto *algo = reinterpret_cast<char *>(hd.hash_algorithm);
1054+
bool is_sha1 = memcmp(hd.hash_algorithm, "sha1", 5) == 0;
1055+
bool is_sha256 = memcmp(hd.hash_algorithm, "sha256", 7) == 0;
1056+
1057+
uint32_t name_len = __builtin_bswap32(hd.partition_name_len);
1058+
uint32_t salt_len = __builtin_bswap32(hd.salt_len);
1059+
uint32_t digest_len = __builtin_bswap32(hd.digest_len);
1060+
1061+
// Get pointers to the (flexibly sized) payloads, checking each against desc_end
1062+
uint8_t *desc_end = reinterpret_cast<uint8_t *>(&desc) + sizeof(AvbDescriptor) + __builtin_bswap64(desc.num_bytes);
1063+
1064+
uint8_t *name = reinterpret_cast<uint8_t *>(&hd + 1);
1065+
if (name > desc_end) {
1066+
fprintf(stderr, "AVB hash descriptor overflows bounds\n");
1067+
break;
1068+
}
1069+
if ((size_t)(desc_end - name) < name_len) {
1070+
fprintf(stderr, "AVB hash descriptor name of %u bytes overflows bounds\n", name_len);
1071+
break;
1072+
}
1073+
1074+
uint8_t *salt = name + name_len;
1075+
if ((size_t)(desc_end - salt) < salt_len) {
1076+
fprintf(stderr, "AVB hash descriptor salt of %u bytes overflows bounds\n", salt_len);
1077+
break;
1078+
}
1079+
1080+
uint8_t *digest = salt + salt_len;
1081+
if ((size_t)(desc_end - digest) < digest_len) {
1082+
fprintf(stderr, "AVB hash descriptor digest of %u bytes overflows bounds\n", digest_len);
1083+
break;
1084+
}
1085+
1086+
if (is_sha1 || is_sha256) {
1087+
digest_len = is_sha1 ? 20 : 32;
1088+
hd.digest_len = __builtin_bswap32(digest_len);
1089+
1090+
auto ctx = get_sha(is_sha1);
1091+
ctx->update(byte_view(salt, salt_len));
1092+
ctx->update(byte_view(out.data(), aosp_img_size));
1093+
ctx->finalize_into(byte_data(digest, digest_len));
1094+
} else {
1095+
fprintf(stderr, "Unsupported AVB hash algorithm: %.32s — zeroing digest\n", algo);
1096+
memset(digest, 0, desc_end - digest);
1097+
}
10501098
break;
10511099
}
10521100
}

0 commit comments

Comments
 (0)