diff --git a/compiler-rt/lib/scudo/standalone/chunk.h b/compiler-rt/lib/scudo/standalone/chunk.h --- a/compiler-rt/lib/scudo/standalone/chunk.h +++ b/compiler-rt/lib/scudo/standalone/chunk.h @@ -123,9 +123,10 @@ UnpackedHeader *NewUnpackedHeader) { PackedHeader NewPackedHeader = atomic_load_relaxed(getConstAtomicHeader(Ptr)); *NewUnpackedHeader = bit_cast(NewPackedHeader); - if (UNLIKELY(NewUnpackedHeader->Checksum != - computeHeaderChecksum(Cookie, Ptr, NewUnpackedHeader))) - reportHeaderCorruption(const_cast(Ptr)); + u16 checksum = computeHeaderChecksum(Cookie, Ptr, NewUnpackedHeader); + if (UNLIKELY(NewUnpackedHeader->Checksum != checksum)) + reportHeaderCorruption(const_cast(Ptr), NewUnpackedHeader->Checksum, + checksum); } inline void compareExchangeHeader(u32 Cookie, void *Ptr, diff --git a/compiler-rt/lib/scudo/standalone/report.h b/compiler-rt/lib/scudo/standalone/report.h --- a/compiler-rt/lib/scudo/standalone/report.h +++ b/compiler-rt/lib/scudo/standalone/report.h @@ -22,7 +22,8 @@ void NORETURN reportInvalidFlag(const char *FlagType, const char *Value); // Chunk header related errors. -void NORETURN reportHeaderCorruption(void *Ptr); +void NORETURN reportHeaderCorruption(void *Ptr, const u16 ExpectedChecksum, + const u16 ComputedChecksum); void NORETURN reportHeaderRace(void *Ptr); // Sanity checks related error. diff --git a/compiler-rt/lib/scudo/standalone/report.cpp b/compiler-rt/lib/scudo/standalone/report.cpp --- a/compiler-rt/lib/scudo/standalone/report.cpp +++ b/compiler-rt/lib/scudo/standalone/report.cpp @@ -74,9 +74,12 @@ // The checksum of a chunk header is invalid. This could be caused by an // {over,under}write of the header, a pointer that is not an actual chunk. -void NORETURN reportHeaderCorruption(void *Ptr) { +void NORETURN reportHeaderCorruption(void *Ptr, const u16 ExpectedChecksum, + const u16 ComputedChecksum) { ScopedErrorReport Report; - Report.append("corrupted chunk header at address %p\n", Ptr); + Report.append("corrupted chunk header at address %p: expected checksum: 0x%x " + "computed checksum: 0x%x\n", + Ptr, ExpectedChecksum, ComputedChecksum); } // Two threads have attempted to modify a chunk header at the same time. This is diff --git a/compiler-rt/lib/scudo/standalone/tests/report_test.cpp b/compiler-rt/lib/scudo/standalone/tests/report_test.cpp --- a/compiler-rt/lib/scudo/standalone/tests/report_test.cpp +++ b/compiler-rt/lib/scudo/standalone/tests/report_test.cpp @@ -22,7 +22,9 @@ UNUSED void *P = reinterpret_cast(0x42424242U); EXPECT_DEATH(scudo::reportError("TEST123"), "Scudo ERROR.*TEST123"); EXPECT_DEATH(scudo::reportInvalidFlag("ABC", "DEF"), "Scudo ERROR.*ABC.*DEF"); - EXPECT_DEATH(scudo::reportHeaderCorruption(P), "Scudo ERROR.*42424242"); + EXPECT_DEATH(scudo::reportHeaderCorruption(P, 0x123, 0x124), + "Scudo ERROR.*42424242: expected checksum: 0x123 computed " + "checksum: 0x124"); EXPECT_DEATH(scudo::reportHeaderRace(P), "Scudo ERROR.*42424242"); EXPECT_DEATH(scudo::reportSanityCheckError("XYZ"), "Scudo ERROR.*XYZ"); EXPECT_DEATH(scudo::reportAlignmentTooBig(123, 456), "Scudo ERROR.*123.*456");