hctim updated this revision to Diff 435257.
hctim marked 3 inline comments as done.
hctim added a comment.

Update.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126929/new/

https://reviews.llvm.org/D126929

Files:
  clang/lib/CodeGen/SanitizerMetadata.cpp
  clang/lib/CodeGen/SanitizerMetadata.h
  clang/test/CodeGen/Inputs/sanitizer-special-case-list-globals.txt
  clang/test/CodeGen/asan-globals.cpp
  clang/test/CodeGen/sanitize-init-order.cpp
  clang/test/CodeGen/sanitizer-special-case-list-globals.c

Index: clang/test/CodeGen/sanitizer-special-case-list-globals.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/sanitizer-special-case-list-globals.c
@@ -0,0 +1,55 @@
+// Verify that ignorelist sections correctly select sanitizers to apply
+// ignorelist entries to.
+
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm %s -o -\
+// RUN: -fsanitize-ignorelist=%S/Inputs/sanitizer-special-case-list-globals.txt \
+// RUN: | FileCheck %s --check-prefix=ASAN
+
+// Note: HWASan effectively reorders globals (it puts the unsanitized ones
+// first), which is hard to check for, as 'CHECK-DAG' doesn't play terribly
+// nicely with 'CHECK-NOT'. This is why the 'always_ignored' and
+// 'hwasan_ignored' comes first in this file.
+// RUN: %clang_cc1 -fsanitize=hwaddress -emit-llvm %s -o -\
+// RUN: -fsanitize-ignorelist=%S/Inputs/sanitizer-special-case-list-globals.txt \
+// RUN: | FileCheck %s --check-prefix=HWASAN
+
+// TODO(hctim): Move over to memtag-globals when it's implemented. For now
+// though, it's fine, the frontend still annotates based on any memtag sanitizer
+// being used.
+// RUN: %clang_cc1 -fsanitize=memtag-heap -triple=aarch64-linux-android31 -emit-llvm %s -o -\
+// RUN: -fsanitize-ignorelist=%S/Inputs/sanitizer-special-case-list-globals.txt \
+// RUN: | FileCheck %s --check-prefix=MEMTAG
+
+// ASAN:   @always_ignored = global {{.*}}, no_sanitize_address
+// HWASAN: @always_ignored = global {{.*}}, no_sanitize_hwaddress
+// MEMTAG: @always_ignored = global {{.*}}, no_sanitize_memtag
+unsigned always_ignored;
+
+// ASAN:       @hwasan_ignored = global
+// ASAN-NOT:   no_sanitize_address
+// HWASAN:     @hwasan_ignored = global {{.*}}, no_sanitize_hwaddress
+// MEMTAG:     @hwasan_ignored = global
+// MEMTAG-NOT: no_sanitize_memtag
+unsigned hwasan_ignored;
+
+// ASAN:       @asan_ignored = global {{.*}}, no_sanitize_address
+// HWASAN:     @asan_ignored.hwasan = {{.*}} global
+// HWASAN-NOT: no_sanitize_hwaddress
+// MEMTAG:     @asan_ignored = global
+// MEMTAG-NOT: no_sanitize_memtag
+unsigned asan_ignored;
+
+// ASAN:       @memtag_ignored = global
+// ASAN-NOT:   no_sanitize_address
+// HWASAN:     @memtag_ignored.hwasan = {{.*}} global
+// HWASAN-NOT: no_sanitize_hwaddress
+// MEMTAG:     @memtag_ignored = global {{.*}}, no_sanitize_memtag
+unsigned memtag_ignored;
+
+// ASAN:       @never_ignored = global
+// ASAN-NOT:   no_sanitize_address
+// HWASAN:     @never_ignored.hwasan = {{.*}} global
+// HWASAN-NOT: no_sanitize_hwaddress
+// MEMTAG:     @never_ignored = global
+// MEMTAG-NOT: no_sanitize_memtag
+unsigned never_ignored;
Index: clang/test/CodeGen/sanitize-init-order.cpp
===================================================================
--- clang/test/CodeGen/sanitize-init-order.cpp
+++ clang/test/CodeGen/sanitize-init-order.cpp
@@ -36,12 +36,29 @@
 
 // Check that ASan init-order checking ignores structs with trivial default
 // constructor.
+
+// CHECK: @s1 = global
+// CHECK-NOT: sanitize_address_dyninit
+// CHECK: @s2 = global
+// CHECK-NOT: sanitize_address_dyninit
+// CHECK: @s3 = global {{.*}}, sanitize_address_dyninit
+// CHECK: @{{.*}}array{{.*}} = global {{.*}}, sanitize_address_dyninit
+
 // CHECK: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]+]], ![[GLOB_4:[0-9]+]]
 // CHECK: ![[GLOB_1]] = !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
 // CHECK: ![[GLOB_2]] = !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
 // CHECK: ![[GLOB_3]] = !{%struct.PODWithCtorAndDtor* {{.*}}, i1 true, i1 false}
 // CHECK: ![[GLOB_4]] = !{{{.*}}class.NS::PODWithCtor{{.*}}, i1 true, i1 false}
 
+// IGNORELIST: @s1 = global
+// IGNORELIST-NOT: sanitize_address_dyninit
+// IGNORELIST: @s2 = global
+// IGNORELIST-NOT: sanitize_address_dyninit
+// IGNORELIST: @s3 = global
+// IGNORELIST-NOT: sanitize_address_dyninit
+// IGNORELIST: @{{.*}}array{{.*}} = global
+// IGNORELIST-NOT: sanitize_address_dyninit
+
 // IGNORELIST: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]+]], ![[GLOB_4:[0-9]+]]}
 // IGNORELIST: ![[GLOB_1]] = !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
 // IGNORELIST: ![[GLOB_2]] = !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
Index: clang/test/CodeGen/asan-globals.cpp
===================================================================
--- clang/test/CodeGen/asan-globals.cpp
+++ clang/test/CodeGen/asan-globals.cpp
@@ -23,6 +23,9 @@
   const char *literal = "Hello, world!";
 }
 
+// ASAN: @dyn_init_global = global {{.*}}, sanitize_address_dyninit
+// KASAN: @dyn_init_global = global {{.*}}, sanitize_address_dyninit
+
 // ASAN: sectioned_global{{.*}} global { i32, [28 x i8] }{{.*}}, align 32
 // KASAN: sectioned_global{{.*}} global i32
 // ASAN: @__special_global{{.*}} global { i32, [28 x i8] }{{.*}}, align 32
Index: clang/test/CodeGen/Inputs/sanitizer-special-case-list-globals.txt
===================================================================
--- /dev/null
+++ clang/test/CodeGen/Inputs/sanitizer-special-case-list-globals.txt
@@ -0,0 +1,7 @@
+global:always_ignored
+[address]
+global:asan_ignored
+[hwaddress]
+global:hwasan_ignored
+[memtag]
+global:memtag_ignored
Index: clang/lib/CodeGen/SanitizerMetadata.h
===================================================================
--- clang/lib/CodeGen/SanitizerMetadata.h
+++ clang/lib/CodeGen/SanitizerMetadata.h
@@ -14,6 +14,7 @@
 
 #include "clang/AST/Type.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/Sanitizers.h"
 #include "clang/Basic/SourceLocation.h"
 
 namespace llvm {
@@ -40,7 +41,8 @@
   void reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
                     bool IsDynInit = false);
   void reportGlobal(llvm::GlobalVariable *GV, SourceLocation Loc,
-                    StringRef Name, QualType Ty = {}, bool IsDynInit = false);
+                    StringRef Name, QualType Ty = {}, bool IsDynInit = false,
+                    SanitizerMask NoSanitizeMask = {});
   void disableSanitizerForGlobal(llvm::GlobalVariable *GV);
   void disableSanitizerForInstruction(llvm::Instruction *I);
 
Index: clang/lib/CodeGen/SanitizerMetadata.cpp
===================================================================
--- clang/lib/CodeGen/SanitizerMetadata.cpp
+++ clang/lib/CodeGen/SanitizerMetadata.cpp
@@ -17,27 +17,80 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/Constants.h"
 
+using GlobalVariable = llvm::GlobalVariable;
+using GVSanitizerMetadata = GlobalVariable::SanitizerMetadata;
+
 using namespace clang;
 using namespace CodeGen;
 
 SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
 
+// TODO(hctim): Can be removed when we migrate off of llvm.asan.globals. This
+// prevents llvm.asan.globals from being emitted for
+// __attribute__((disable_sanitizer_instrumentation)) and uses of
+// -fsanitize-ignorelist when a sanitizer isn't enabled.
 static bool isAsanHwasanOrMemTag(const SanitizerSet &SS) {
   return SS.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress |
                      SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress |
                      SanitizerKind::MemTag);
 }
 
-void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
-                                     SourceLocation Loc, StringRef Name,
-                                     QualType Ty, bool IsDynInit,
-                                     bool IsExcluded) {
-  IsDynInit &= !CGM.isInNoSanitizeList(GV, Loc, Ty, "init");
-  IsExcluded |= CGM.isInNoSanitizeList(GV, Loc, Ty);
+void SanitizerMetadata::reportGlobal(GlobalVariable *GV, SourceLocation Loc,
+                                     StringRef Name, QualType Ty,
+                                     bool IsDynInit,
+                                     SanitizerMask NoSanitizeMask) {
+
+  GVSanitizerMetadata Meta;
+  if (GV->hasSanitizerMetadata())
+    Meta = GV->getSanitizerMetadata();
+
+  auto &SanTarget = CGM.getLangOpts().Sanitize;
+
+  if (!isAsanHwasanOrMemTag(SanTarget))
+    return;
+
+  SanitizerSet NoSanitizeSet;
+  NoSanitizeSet.Mask = NoSanitizeMask;
+
+  bool IsExcluded = CGM.isInNoSanitizeList(GV, Loc, Ty);
+  IsExcluded |= (NoSanitizeMask == SanitizerKind::All);
+
+  if (SanTarget.hasOneOf(SanitizerKind::Address |
+                         SanitizerKind::KernelAddress)) {
+    IsExcluded |= CGM.isInNoSanitizeList(GV, Loc, Ty, "address");
+    IsExcluded |= NoSanitizeSet.hasOneOf(SanitizerKind::Address |
+                                         SanitizerKind::KernelAddress);
+    IsExcluded |= Meta.NoAddress;
+    Meta.NoAddress = IsExcluded;
+
+    // TODO(hctim): Make this conditional when we migrate off llvm.asan.globals.
+    IsDynInit &= !CGM.isInNoSanitizeList(GV, Loc, Ty, "init");
+    Meta.IsDynInit = IsDynInit;
+  }
+
+  if (SanTarget.hasOneOf(SanitizerKind::HWAddress |
+                         SanitizerKind::KernelHWAddress)) {
+    IsExcluded |= CGM.isInNoSanitizeList(GV, Loc, Ty, "hwaddress");
+    IsExcluded |= NoSanitizeSet.hasOneOf(SanitizerKind::HWAddress |
+                                         SanitizerKind::KernelHWAddress);
+    IsExcluded |= Meta.NoHWAddress;
+    Meta.NoHWAddress = IsExcluded;
+  }
+
+  if (SanTarget.hasOneOf(SanitizerKind::MemTag)) {
+    IsExcluded |= CGM.isInNoSanitizeList(GV, Loc, Ty, "memtag");
+    IsExcluded |= NoSanitizeSet.hasOneOf(SanitizerKind::MemTag);
+    IsExcluded |= Meta.NoMemtag;
+    Meta.NoMemtag = IsExcluded;
+  }
+
+  GV->setSanitizerMetadata(Meta);
 
+  // TODO(hctim): Code below can be removed when we migrate off of
+  // llvm.asan.globals onto the new metadata attributes.
+  llvm::LLVMContext &VMContext = CGM.getLLVMContext();
   llvm::Metadata *LocDescr = nullptr;
   llvm::Metadata *GlobalName = nullptr;
-  llvm::LLVMContext &VMContext = CGM.getLLVMContext();
   if (!IsExcluded) {
     // Don't generate source location and global name if it is on
     // the NoSanitizeList - it won't be instrumented anyway.
@@ -48,8 +101,8 @@
 
   llvm::Metadata *GlobalMetadata[] = {
       llvm::ConstantAsMetadata::get(GV), LocDescr, GlobalName,
-      llvm::ConstantAsMetadata::get(
-          llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit)),
+      llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
+          llvm::Type::getInt1Ty(VMContext), Meta.IsDynInit)),
       llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
           llvm::Type::getInt1Ty(VMContext), IsExcluded))};
 
@@ -59,41 +112,27 @@
   AsanGlobals->addOperand(ThisGlobal);
 }
 
-void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, const VarDecl &D,
+void SanitizerMetadata::reportGlobal(GlobalVariable *GV, const VarDecl &D,
                                      bool IsDynInit) {
-  if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
-    return;
+  SanitizerMask NoSanitizeMask;
+  for (auto *Attr : D.specific_attrs<NoSanitizeAttr>()) {
+    NoSanitizeMask |= Attr->getMask();
+  }
+
+  if (D.hasAttr<DisableSanitizerInstrumentationAttr>()) {
+    NoSanitizeMask = SanitizerKind::All;
+  }
+
   std::string QualName;
   llvm::raw_string_ostream OS(QualName);
   D.printQualifiedName(OS);
 
-  auto getNoSanitizeMask = [](const VarDecl &D) {
-    if (D.hasAttr<DisableSanitizerInstrumentationAttr>())
-      return SanitizerKind::All;
-
-    SanitizerMask NoSanitizeMask;
-    for (auto *Attr : D.specific_attrs<NoSanitizeAttr>())
-      NoSanitizeMask |= Attr->getMask();
-
-    return NoSanitizeMask;
-  };
   reportGlobal(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit,
-               SanitizerSet{getNoSanitizeMask(D)}.has(SanitizerKind::Address));
-}
-
-void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV,
-                                     SourceLocation Loc, StringRef Name,
-                                     QualType Ty, bool IsDynInit) {
-  if (!isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
-    return;
-  reportGlobal(GV, Loc, Name, Ty, IsDynInit, false);
+               NoSanitizeMask);
 }
 
-void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
-  // For now, just make sure the global is not modified by the ASan
-  // instrumentation.
-  if (isAsanHwasanOrMemTag(CGM.getLangOpts().Sanitize))
-    reportGlobal(GV, SourceLocation(), "", QualType(), false, true);
+void SanitizerMetadata::disableSanitizerForGlobal(GlobalVariable *GV) {
+  reportGlobal(GV, SourceLocation(), "", QualType(), false, SanitizerKind::All);
 }
 
 void SanitizerMetadata::disableSanitizerForInstruction(llvm::Instruction *I) {
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to