diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -527,8 +527,24 @@ OS << "Binary IDs: \n"; const uint8_t *BI = BinaryIdsStart; - while (BI < BinaryIdsStart + BinaryIdsSize) { - uint64_t BinaryIdLen = swap(*reinterpret_cast(BI)); + const uint8_t *BIEnd = BinaryIdsStart + BinaryIdsSize; + while (BI < BIEnd) { + uint64_t BinaryIdLen = 0; + auto Remaining = BIEnd - BI; + + // If we do not have enough to read a uint64_t, then this remaining data + // must be zero-padding. If it's not padded, then the data must be corrupted + // somehow. In case of misalignment, we can use memcpy() for safe reads. + if (Remaining < sizeof(BinaryIdLen)) { + memcpy(&BinaryIDLen, BI, Remaining); + if (!BinaryIdLen) + return success(); + return make_error(instrprof_error::malformed); + } + + memcpy(&BinaryIdLen, BI, sizeof(BinaryIDLen)); + BinaryIdLen = swap(BinaryIdLen); + // Increment by binary id length data type size. BI += sizeof(BinaryIdLen); if (BI > (const uint8_t *)DataBuffer->getBufferEnd())