[scudo] Modify header corrupption error message (#126812) am: 0a5dfc4690 Original change: https://android-review.googlesource.com/c/platform/external/scudo/+/3491010 Change-Id: Ibcd2e9add789b8c50bea31b98f60fe372ddd16f9 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/standalone/chunk.h b/standalone/chunk.h index 9228df0..a1b8e72 100644 --- a/standalone/chunk.h +++ b/standalone/chunk.h
@@ -125,7 +125,7 @@ *NewUnpackedHeader = bit_cast<UnpackedHeader>(NewPackedHeader); if (UNLIKELY(NewUnpackedHeader->Checksum != computeHeaderChecksum(Cookie, Ptr, NewUnpackedHeader))) - reportHeaderCorruption(const_cast<void *>(Ptr)); + reportHeaderCorruption(NewUnpackedHeader, const_cast<void *>(Ptr)); } inline bool isValid(u32 Cookie, const void *Ptr,
diff --git a/standalone/report.cpp b/standalone/report.cpp index 9cef0ad..14a4066 100644 --- a/standalone/report.cpp +++ b/standalone/report.cpp
@@ -9,6 +9,7 @@ #include "report.h" #include "atomic_helpers.h" +#include "chunk.h" #include "string_utils.h" #include <stdarg.h> @@ -65,9 +66,18 @@ // 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 *Header, void *Ptr) { ScopedErrorReport Report; - Report.append("corrupted chunk header at address %p\n", Ptr); + Report.append("corrupted chunk header at address %p", Ptr); + if (*static_cast<Chunk::PackedHeader *>(Header) == 0U) { + // Header all zero, which could indicate that this might be a pointer that + // has been double freed but the memory has been released to the kernel. + Report.append(": chunk header is zero and might indicate memory corruption " + "or a double free\n", + Ptr); + } else { + Report.append(": most likely due to memory corruption\n", Ptr); + } } // The allocator was compiled with parameters that conflict with field size
diff --git a/standalone/report.h b/standalone/report.h index a510fda..c0214b5 100644 --- a/standalone/report.h +++ b/standalone/report.h
@@ -12,7 +12,6 @@ #include "internal_defs.h" namespace scudo { - // Reports are *fatal* unless stated otherwise. // Generic error, adds newline to end of message. @@ -25,7 +24,7 @@ void NORETURN reportInvalidFlag(const char *FlagType, const char *Value); // Chunk header related errors. -void NORETURN reportHeaderCorruption(void *Ptr); +void NORETURN reportHeaderCorruption(void *Header, void *Ptr); // Sanity checks related error. void NORETURN reportSanityCheckError(const char *Field);
diff --git a/standalone/tests/report_test.cpp b/standalone/tests/report_test.cpp index 6c46243..514837d 100644 --- a/standalone/tests/report_test.cpp +++ b/standalone/tests/report_test.cpp
@@ -8,6 +8,7 @@ #include "tests/scudo_unit_test.h" +#include "chunk.h" #include "report.h" TEST(ScudoReportDeathTest, Check) { @@ -20,9 +21,11 @@ TEST(ScudoReportDeathTest, Generic) { // Potentially unused if EXPECT_DEATH isn't defined. UNUSED void *P = reinterpret_cast<void *>(0x42424242U); + UNUSED scudo::Chunk::PackedHeader Header = {}; 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(&Header, P), + "Scudo ERROR.*42424242"); EXPECT_DEATH(scudo::reportSanityCheckError("XYZ"), "Scudo ERROR.*XYZ"); EXPECT_DEATH(scudo::reportAlignmentTooBig(123, 456), "Scudo ERROR.*123.*456"); EXPECT_DEATH(scudo::reportAllocationSizeTooBig(123, 456, 789), @@ -54,6 +57,19 @@ "Scudo ERROR.*123.*456"); } +TEST(ScudoReportDeathTest, HeaderCorruption) { + UNUSED void *P = reinterpret_cast<void *>(0x42424242U); + UNUSED scudo::Chunk::PackedHeader Header = {}; + EXPECT_DEATH(scudo::reportHeaderCorruption(&Header, P), + "Scudo ERROR.*corrupted chunk header at address 0x.*42424242: " + "chunk header is zero and might indicate memory " + "corruption or a double free"); + Header = 10U; + EXPECT_DEATH(scudo::reportHeaderCorruption(&Header, P), + "Scudo ERROR.*corrupted chunk header at address 0x.*42424242: " + "most likely due to memory corruption"); +} + #if SCUDO_LINUX || SCUDO_TRUSTY || SCUDO_ANDROID #include "report_linux.h"