@@ -1026,13 +1026,68 @@ 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 ;
1033+
1034+ // enforce size limits; protect against adversarial input.
1035+ size_t buf_remaining = out.data () + out.size () - reinterpret_cast <uint8_t *>(&desc);
1036+ if (buf_remaining < __builtin_bswap64 (desc.num_bytes ) || buf_remaining - __builtin_bswap64 (desc.num_bytes ) < sizeof (AvbDescriptor)) {
1037+ // beware: both conditions are necessary because underflow in the subtraction could wrap
1038+ fprintf (stderr, " AVB hash descriptor num_bytes overflows buffer\n " );
1039+ break ;
1040+ }
1041+
1042+ uint8_t *desc_end = reinterpret_cast <uint8_t *>(&desc) + sizeof (AvbDescriptor) + __builtin_bswap64 (desc.num_bytes );
1043+
10341044 auto &hd = reinterpret_cast <AvbHashDescriptor &>(desc);
1045+
1046+ // Update image_size
10351047 hd.image_size = __builtin_bswap64 (aosp_img_size);
1048+
1049+ // Recompute hash
1050+ auto *algo = reinterpret_cast <char *>(hd.hash_algorithm );
1051+ bool is_sha1 = memcmp (hd.hash_algorithm , " sha1" , 5 ) == 0 ;
1052+ bool is_sha256 = memcmp (hd.hash_algorithm , " sha256" , 7 ) == 0 ;
1053+
1054+ uint32_t name_len = __builtin_bswap32 (hd.partition_name_len );
1055+ uint32_t salt_len = __builtin_bswap32 (hd.salt_len );
1056+ uint32_t digest_len = __builtin_bswap32 (hd.digest_len );
1057+
1058+ // Get pointers to the (flexibly sized) payloads, checking each against desc_end
1059+ uint8_t *name = reinterpret_cast <uint8_t *>(&hd + 1 );
1060+ if (name > desc_end) {
1061+ fprintf (stderr, " AVB hash descriptor overflows bounds\n " );
1062+ break ;
1063+ }
1064+ if ((size_t )(desc_end - name) < name_len) {
1065+ fprintf (stderr, " AVB hash descriptor name of %u bytes overflows bounds\n " , name_len);
1066+ break ;
1067+ }
1068+ uint8_t *salt = name + name_len;
1069+ if ((size_t )(desc_end - salt) < salt_len) {
1070+ fprintf (stderr, " AVB hash descriptor salt of %u bytes overflows bounds\n " , salt_len);
1071+ break ;
1072+ }
1073+ uint8_t *digest = salt + salt_len;
1074+ if ((size_t )(desc_end - digest) < digest_len) {
1075+ fprintf (stderr, " AVB hash descriptor digest of %u bytes overflows bounds\n " , digest_len);
1076+ break ;
1077+ }
1078+
1079+ if (is_sha1 || is_sha256) {
1080+ digest_len = is_sha1 ? 20 : 32 ;
1081+ hd.digest_len = __builtin_bswap32 (digest_len);
1082+
1083+ auto ctx = get_sha (is_sha1);
1084+ ctx->update (byte_view (salt, salt_len));
1085+ ctx->update (byte_view (out.data (), aosp_img_size));
1086+ ctx->finalize_into (byte_data (digest, digest_len));
1087+ } else {
1088+ fprintf (stderr, " Unsupported AVB hash algorithm: %.32s — zeroing digest\n " , algo);
1089+ memset (digest, 0 , desc_end - digest);
1090+ }
10361091 break ;
10371092 }
10381093 }
0 commit comments