| From 64037afe014e241e1c642952a703b6031d17d5a5 Mon Sep 17 00:00:00 2001 |
| From: Reid Kleckner <rnk@google.com> |
| Date: Thu, 10 Feb 2022 13:40:28 -0800 |
| Subject: [PATCH] [CodeView] Avoid integer overflow while parsing long version |
| strings |
| |
| This came up on a funny vendor-provided version string that didn't have |
| a standard dotted quad of numbers. |
| --- |
| llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 3 +- |
| .../COFF/compiler-version-overflow.ll | 36 +++++++++++++++++++ |
| 2 files changed, 38 insertions(+), 1 deletion(-) |
| create mode 100644 llvm/test/DebugInfo/COFF/compiler-version-overflow.ll |
| |
| diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp |
| index 52c74713551..6cc30ebe5ce 100644 |
| --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp |
| +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp |
| @@ -826,6 +826,8 @@ static Version parseVersion(StringRef Name) { |
| if (isdigit(C)) { |
| V.Part[N] *= 10; |
| V.Part[N] += C - '0'; |
| + V.Part[N] = |
| + std::min<int>(V.Part[N], std::numeric_limits<uint16_t>::max()); |
| } else if (C == '.') { |
| ++N; |
| if (N >= 4) |
| @@ -867,7 +869,6 @@ void CodeViewDebug::emitCompilerInformation() { |
| Version FrontVer = parseVersion(CompilerVersion); |
| OS.AddComment("Frontend version"); |
| for (int N : FrontVer.Part) { |
| - N = std::min<int>(N, std::numeric_limits<uint16_t>::max()); |
| OS.emitInt16(N); |
| } |
| |
| diff --git a/llvm/test/DebugInfo/COFF/compiler-version-overflow.ll b/llvm/test/DebugInfo/COFF/compiler-version-overflow.ll |
| new file mode 100644 |
| index 00000000000..538ba699ae6 |
| --- /dev/null |
| +++ b/llvm/test/DebugInfo/COFF/compiler-version-overflow.ll |
| @@ -0,0 +1,36 @@ |
| +; RUN: llc -filetype=obj -mtriple i686-pc-windows-msvc %s -o %t.o |
| +; RUN: llvm-pdbutil dump %t.o -symbols | FileCheck %s |
| + |
| +; CHECK: {{.*}} | S_COMPILE3 [size = {{.*}}] |
| +; CHECK-NEXT: machine = intel pentium 3, Ver = clang version 999999999999.9999999999.9999999.99999999 , language = c++ |
| +; CHECK-NEXT: frontend = 65535.65535.65535.65535, backend = 15000.0.0.0 |
| +; CHECK-NEXT: flags = none |
| + |
| + |
| +; ModuleID = 'D:\src\scopes\foo.cpp' |
| +source_filename = "D:\5Csrc\5Cscopes\5Cfoo.cpp" |
| +target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" |
| +target triple = "i686-pc-windows-msvc19.0.23918" |
| + |
| +define i32 @"?foo@@YAHXZ"() !dbg !10 { |
| +entry: |
| + ret i32 42, !dbg !14 |
| +} |
| + |
| +!llvm.dbg.cu = !{!0} |
| +!llvm.module.flags = !{!7, !8} |
| +!llvm.ident = !{!9} |
| + |
| +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 999999999999.9999999999.9999999.99999999 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) |
| +; One .debug$S section should contain an S_COMPILE3 record that identifies the |
| +; source language and the version of the compiler based on the DICompileUnit. |
| +!1 = !DIFile(filename: "D:\5Csrc\5Cscopes\5Cfoo.cpp", directory: "D:\5Csrc\5Cscopes\5Cclang") |
| +!2 = !{} |
| +!7 = !{i32 2, !"CodeView", i32 1} |
| +!8 = !{i32 2, !"Debug Info Version", i32 3} |
| +!9 = !{!"clang version 4.0.0 "} |
| +!10 = distinct !DISubprogram(name: "foo", linkageName: "\01?foo@@YAHXZ", scope: !1, file: !1, line: 1, type: !11, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, retainedNodes: !2) |
| +!11 = !DISubroutineType(types: !12) |
| +!12 = !{!13} |
| +!13 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) |
| +!14 = !DILocation(line: 2, scope: !10) |
| -- |
| 2.35.1.473.g83b2b277ed-goog |
| |