diff --git a/protocol/payload_info.c b/protocol/payload_info.c index 3f2eb41..8f6e8f3 100644 --- a/protocol/payload_info.c +++ b/protocol/payload_info.c @@ -62,7 +62,19 @@ bool libhoth_payload_info(const uint8_t* image, size_t len, memset(payload_info->image_hash, 0, sizeof(payload_info->image_hash)); return false; } else { + // Check for integer overflow + if (descr->descriptor_area_size <= + sizeof(struct image_descriptor) + sizeof(struct hash_sha256)) { + return false; + } + uint32_t region_size = descr->region_count * sizeof(struct image_region); + // Check for overread + if (region_size > + (descr->descriptor_area_size - sizeof(struct image_descriptor) - sizeof(struct hash_sha256))) { + return false; + } + struct hash_sha256* hash = (struct hash_sha256*)((uint8_t*)&descr->image_regions + region_size); memcpy(payload_info->image_hash, hash->hash, sizeof(hash->hash)); diff --git a/protocol/payload_info_test.cc b/protocol/payload_info_test.cc index 7cd8a35..fb14f89 100644 --- a/protocol/payload_info_test.cc +++ b/protocol/payload_info_test.cc @@ -138,4 +138,13 @@ TEST(PayloadInfotest, payload_info_non_SHA256_hash_type) { EXPECT_FALSE(libhoth_payload_info(image, statbuf.st_size, &info)); (void)munmap(image, statbuf.st_size); -} \ No newline at end of file +} + +TEST(PayloadInfoTest, PayloadInfoFuzzRegression) { + std::string data = std::string( + "_IMGDSC_\035_\to\245\245IM\007\001\000\000GDS\360\360\360\360\360C_\to\245\245\267\267\342\342\342\342\342\342\342\267\267\267\267\267\267\267\267\245\245\245\245\245\245\245\251\345\034%\035\252\000\241\254\332\314\374\r\242\205\342\246\247\327Z\241\364\000\250\002\246\205\260I\002\023\255\201\277\247\247\006C\235\234\245\245\245\245\245\245\245\245\245\245\245\245\200\200\200\000\300^\000\246\270\356\027\265\035\000\245\245\245\245\245\003\003\003\245\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\000\035\035\034\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035~~~~\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035\035", + 279); + struct payload_info info; + EXPECT_FALSE(libhoth_payload_info(reinterpret_cast(data.data()), + data.size(), &info)); +}