From 8fc9902bbb0d48c75fe33627641f14c9c3e09e25 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sun, 21 Apr 2019 16:58:25 +0000 Subject: llvm-undname: Fix stack overflow on almost-valid If a unsigned with all 4 bytes non-0 was passed to outputHex(), there were two off-by-ones in it: - Both MaxPos and Pos left space for the final \0, which left the buffer one byte to small. Set MaxPos to 16 instead of 15 to fix. - The `assert(Pos >= 0);` was after a `Pos--`, move it up one line. Since valid Unicode codepoints are <= 0x10ffff, this could never really happen in practice. Found by oss-fuzz. llvm-svn: 358856 --- llvm/lib/Demangle/MicrosoftDemangle.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'llvm/lib/Demangle') diff --git a/llvm/lib/Demangle/MicrosoftDemangle.cpp b/llvm/lib/Demangle/MicrosoftDemangle.cpp index b421f2a7f93..01a742a874e 100644 --- a/llvm/lib/Demangle/MicrosoftDemangle.cpp +++ b/llvm/lib/Demangle/MicrosoftDemangle.cpp @@ -1071,17 +1071,17 @@ static void outputHex(OutputStream &OS, unsigned C) { char TempBuffer[17]; ::memset(TempBuffer, 0, sizeof(TempBuffer)); - constexpr int MaxPos = 15; + constexpr int MaxPos = sizeof(TempBuffer) - 1; - int Pos = MaxPos - 1; + int Pos = MaxPos - 1; // TempBuffer[MaxPos] is the terminating \0. while (C != 0) { for (int I = 0; I < 2; ++I) { writeHexDigit(&TempBuffer[Pos--], C % 16); C /= 16; } TempBuffer[Pos--] = 'x'; - TempBuffer[Pos--] = '\\'; assert(Pos >= 0); + TempBuffer[Pos--] = '\\'; } OS << StringView(&TempBuffer[Pos + 1]); } -- cgit v1.2.3