[llvm] 06e68f0 - [AddressSanitizer] Copy type metadata to prevent miscompilation

Dominic Chen via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 28 10:57:28 PDT 2020


Author: Dominic Chen
Date: 2020-09-28T13:56:05-04:00
New Revision: 06e68f05dafb96ea5395d2fed669fccdcd07f61f

URL: https://github.com/llvm/llvm-project/commit/06e68f05dafb96ea5395d2fed669fccdcd07f61f
DIFF: https://github.com/llvm/llvm-project/commit/06e68f05dafb96ea5395d2fed669fccdcd07f61f.diff

LOG: [AddressSanitizer] Copy type metadata to prevent miscompilation

When ASan and e.g. Dead Virtual Function Elimination are enabled, the
latter will rely on type metadata to determine if certain virtual calls can be
removed. However, ASan currently does not copy type metadata, which can cause
virtual function calls to be incorrectly removed.

Differential Revision: https://reviews.llvm.org/D88368

Added: 
    

Modified: 
    llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
    llvm/test/Instrumentation/AddressSanitizer/debug_info.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 802f6759265c..fd5eaada2feb 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2349,12 +2349,9 @@ bool ModuleAddressSanitizer::InstrumentGlobals(IRBuilder<> &IRB, Module &M,
         NewGlobal->setSection("__TEXT,__asan_cstring,regular");
     }
 
-    // Transfer the debug info.  The payload starts at offset zero so we can
-    // copy the debug info over as is.
-    SmallVector<DIGlobalVariableExpression *, 1> GVs;
-    G->getDebugInfo(GVs);
-    for (auto *GV : GVs)
-      NewGlobal->addDebugInfo(GV);
+    // Transfer the debug info and type metadata.  The payload starts at offset
+    // zero so we can copy the metadata over as is.
+    NewGlobal->copyMetadata(G, 0);
 
     Value *Indices2[2];
     Indices2[0] = IRB.getInt32(0);

diff  --git a/llvm/test/Instrumentation/AddressSanitizer/debug_info.ll b/llvm/test/Instrumentation/AddressSanitizer/debug_info.ll
index ce0126a08c19..1064ce5fc4ba 100644
--- a/llvm/test/Instrumentation/AddressSanitizer/debug_info.ll
+++ b/llvm/test/Instrumentation/AddressSanitizer/debug_info.ll
@@ -1,24 +1,27 @@
 ; RUN: opt < %s -asan -asan-module -enable-new-pm=0 -asan-use-after-return=0 -S | FileCheck %s
 ; RUN: opt < %s -passes='asan-pipeline' -asan-use-after-return=0 -S | FileCheck %s
 
-; Checks that llvm.dbg.declare instructions are updated 
+; Checks that llvm.dbg.declare instructions are updated
 ; accordingly as we merge allocas.
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
-define i32 @_Z3zzzi(i32 %p) nounwind uwtable sanitize_address !dbg !5 {
+ at G = global [32 x i8] zeroinitializer, align 32, !dbg !0, !type !6
+; CHECK: @G = global { [32 x i8], [32 x i8] } zeroinitializer{{(, comdat)?}}, align 32, !dbg !0, !type [[TYPE:![0-9]+]]
+
+define i32 @_Z3zzzi(i32 %p) nounwind uwtable sanitize_address !dbg !12 {
 entry:
   %p.addr = alloca i32, align 4
   %r = alloca i32, align 4
   store volatile i32 %p, i32* %p.addr, align 4
-  call void @llvm.dbg.declare(metadata i32* %p.addr, metadata !10, metadata !DIExpression()), !dbg !11
-  call void @llvm.dbg.declare(metadata i32* %r, metadata !12, metadata !DIExpression()), !dbg !14
-  %0 = load i32, i32* %p.addr, align 4, !dbg !14
-  %add = add nsw i32 %0, 1, !dbg !14
-  store volatile i32 %add, i32* %r, align 4, !dbg !14
-  %1 = load i32, i32* %r, align 4, !dbg !15
-  ret i32 %1, !dbg !15
+  call void @llvm.dbg.declare(metadata i32* %p.addr, metadata !17, metadata !DIExpression()), !dbg !18
+  call void @llvm.dbg.declare(metadata i32* %r, metadata !19, metadata !DIExpression()), !dbg !21
+  %0 = load i32, i32* %p.addr, align 4, !dbg !21
+  %add = add nsw i32 %0, 1, !dbg !21
+  store volatile i32 %add, i32* %r, align 4, !dbg !21
+  %1 = load i32, i32* %r, align 4, !dbg !22
+  ret i32 %1, !dbg !22
 }
 
 ;   CHECK: define i32 @_Z3zzzi
@@ -31,19 +34,28 @@ entry:
 
 declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
 
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!17}
+!llvm.dbg.cu = !{!7}
+!llvm.module.flags = !{!24}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "G", type: !2, isLocal: false, isDefinition: true)
+!2 = !DICompositeType(tag: DW_TAG_array_type, baseType: !3, size: 256, elements: !4)
+!3 = !DIBasicType(name: "unsigned char", size: 8, encoding: DW_ATE_unsigned_char)
+!4 = !{!5}
+!5 = !DISubrange(count: 32)
+!6 = !{i64 0, !"G"}
+; CHECK: [[TYPE]] = !{i64 0, !"G"}
 
-!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 (trunk 169314)", isOptimized: true, emissionKind: FullDebug, file: !16, enums: !1, retainedTypes: !1, globals: !1)
-!1 = !{}
-!5 = distinct !DISubprogram(name: "zzz", linkageName: "_Z3zzzi", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 1, file: !16, scope: !6, type: !7, retainedNodes: !1)
-!6 = !DIFile(filename: "a.cc", directory: "/usr/local/google/llvm_cmake_clang/tmp/debuginfo")
-!7 = !DISubroutineType(types: !8)
-!8 = !{!9, !9}
-!9 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
-!10 = !DILocalVariable(name: "p", line: 1, arg: 1, scope: !5, file: !6, type: !9)
-!11 = !DILocation(line: 1, scope: !5)
-!12 = !DILocalVariable(name: "r", line: 2, scope: !13, file: !6, type: !9)
+!7 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 (trunk 169314)", isOptimized: true, emissionKind: FullDebug, file: !23, enums: !8, retainedTypes: !8, globals: !8)
+!8 = !{}
+!12 = distinct !DISubprogram(name: "zzz", linkageName: "_Z3zzzi", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !7, scopeLine: 1, file: !23, scope: !13, type: !14, retainedNodes: !8)
+!13 = !DIFile(filename: "a.cc", directory: "/usr/local/google/llvm_cmake_clang/tmp/debuginfo")
+!14 = !DISubroutineType(types: !15)
+!15 = !{!16, !16}
+!16 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
+!17 = !DILocalVariable(name: "p", line: 1, arg: 1, scope: !12, file: !13, type: !16)
+!18 = !DILocation(line: 1, scope: !12)
+!19 = !DILocalVariable(name: "r", line: 2, scope: !20, file: !13, type: !16)
 
 ; Verify that debug descriptors for argument and local variable will be replaced
 ; with descriptors that end with OpDeref (encoded as 2).
@@ -54,8 +66,8 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
 ;   CHECK-NOT: !DILocalVariable(tag: DW_TAG_auto_variable
 
 
-!13 = distinct !DILexicalBlock(line: 1, column: 0, file: !16, scope: !5)
-!14 = !DILocation(line: 2, scope: !13)
-!15 = !DILocation(line: 3, scope: !13)
-!16 = !DIFile(filename: "a.cc", directory: "/usr/local/google/llvm_cmake_clang/tmp/debuginfo")
-!17 = !{i32 1, !"Debug Info Version", i32 3}
+!20 = distinct !DILexicalBlock(line: 1, column: 0, file: !23, scope: !12)
+!21 = !DILocation(line: 2, scope: !20)
+!22 = !DILocation(line: 3, scope: !20)
+!23 = !DIFile(filename: "a.cc", directory: "/usr/local/google/llvm_cmake_clang/tmp/debuginfo")
+!24 = !{i32 1, !"Debug Info Version", i32 3}


        


More information about the llvm-commits mailing list