[compiler-rt] faf5e0e - Add no_sanitize('hwaddress') (and 'memtag', but that's a no-op).

Mitch Phillips via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 24 12:04:33 PDT 2022


Author: Mitch Phillips
Date: 2022-06-24T12:04:11-07:00
New Revision: faf5e0ec737a676088649d7c13cb50f3f91a703a

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

LOG: Add no_sanitize('hwaddress') (and 'memtag', but that's a no-op).

Currently, `__attribute__((no_sanitize('hwaddress')))` is not possible. Add this piece of plumbing, and now that we properly support copying attributes between an old and a new global variable, add a regression test for the GlobalOpt bug that previously lost the attribute.

Reviewed By: aaron.ballman

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

Added: 
    clang/test/CodeGen/Inputs/sanitizer-extra-source.cpp
    clang/test/CodeGen/Inputs/sanitizer-ignorelist-global.txt
    clang/test/CodeGen/Inputs/sanitizer-ignorelist-src.txt
    clang/test/CodeGen/hwasan-globals.cpp
    clang/test/CodeGen/memtag-globals.cpp
    compiler-rt/test/hwasan/TestCases/global-with-reduction.c

Modified: 
    clang/lib/Sema/SemaDeclAttr.cpp
    compiler-rt/test/hwasan/TestCases/global.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 2563a07b4034..73a4be54861b 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -7859,6 +7859,11 @@ static bool isGlobalVar(const Decl *D) {
   return false;
 }
 
+static bool isSanitizerAttributeAllowedOnGlobals(StringRef Sanitizer) {
+  return Sanitizer == "address" || Sanitizer == "hwaddress" ||
+         Sanitizer == "memtag";
+}
+
 static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
   if (!AL.checkAtLeastNumArgs(S, 1))
     return;
@@ -7876,7 +7881,7 @@ static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
             SanitizerMask() &&
         SanitizerName != "coverage")
       S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName;
-    else if (isGlobalVar(D) && SanitizerName != "address")
+    else if (isGlobalVar(D) && !isSanitizerAttributeAllowedOnGlobals(SanitizerName))
       S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type)
           << AL << ExpectedFunctionOrMethod;
     Sanitizers.push_back(SanitizerName);

diff  --git a/clang/test/CodeGen/Inputs/sanitizer-extra-source.cpp b/clang/test/CodeGen/Inputs/sanitizer-extra-source.cpp
new file mode 100644
index 000000000000..21371d534255
--- /dev/null
+++ b/clang/test/CodeGen/Inputs/sanitizer-extra-source.cpp
@@ -0,0 +1 @@
+int extra_global;

diff  --git a/clang/test/CodeGen/Inputs/sanitizer-ignorelist-global.txt b/clang/test/CodeGen/Inputs/sanitizer-ignorelist-global.txt
new file mode 100644
index 000000000000..40a1d07fb895
--- /dev/null
+++ b/clang/test/CodeGen/Inputs/sanitizer-ignorelist-global.txt
@@ -0,0 +1 @@
+global:*ignorelisted_global*

diff  --git a/clang/test/CodeGen/Inputs/sanitizer-ignorelist-src.txt b/clang/test/CodeGen/Inputs/sanitizer-ignorelist-src.txt
new file mode 100644
index 000000000000..67e50c852606
--- /dev/null
+++ b/clang/test/CodeGen/Inputs/sanitizer-ignorelist-src.txt
@@ -0,0 +1 @@
+src:*-globals.cpp

diff  --git a/clang/test/CodeGen/hwasan-globals.cpp b/clang/test/CodeGen/hwasan-globals.cpp
new file mode 100644
index 000000000000..7edf6e6b7e57
--- /dev/null
+++ b/clang/test/CodeGen/hwasan-globals.cpp
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -include %S/Inputs/sanitizer-extra-source.cpp \
+// RUN:   -fsanitize-ignorelist=%S/Inputs/sanitizer-ignorelist-global.txt \
+// RUN:   -fsanitize=hwaddress -emit-llvm -o - %s | FileCheck %s
+
+// RUN: %clang_cc1 -include %S/Inputs/sanitizer-extra-source.cpp \
+// RUN:   -fsanitize-ignorelist=%S/Inputs/sanitizer-ignorelist-src.txt \
+// RUN:   -fsanitize=hwaddress -emit-llvm -o - %s | \
+// RUN:   FileCheck %s --check-prefix=IGNORELIST
+
+int global;
+int __attribute__((no_sanitize("hwaddress"))) attributed_global;
+int __attribute__((disable_sanitizer_instrumentation)) disable_instrumentation_global;
+int ignorelisted_global;
+
+void func() {
+  static int static_var = 0;
+  const char *literal = "Hello, world!";
+}
+
+// CHECK: @{{.*}}attributed_global{{.*}} ={{.*}} global {{.*}}, no_sanitize_hwaddress
+// CHECK: @{{.*}}disable_instrumentation_global{{.*}} ={{.*}} global {{.*}}, no_sanitize_hwaddress
+// CHECK: @{{.*}}ignorelisted_global{{.*}} ={{.*}} global {{.*}}, no_sanitize_hwaddress
+// CHECK: @{{.*}}extra_global{{.*}}.hwasan{{.*}} =
+// CHECK: @{{.*}}global{{.*}}.hwasan{{.*}} =
+// CHECK: @{{.*}}static_var{{.*}}.hwasan{{.*}} =
+// CHECK: @{{.*}}.hwasan{{.*}} = {{.*}} c"Hello, world!\00"
+
+// CHECK: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[DISABLE_INSTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// CHECK: ![[EXTRA_GLOBAL]] = !{{{.*}} ![[EXTRA_GLOBAL_LOC:[0-9]+]], !"extra_global", i1 false, i1 false}
+// CHECK: ![[EXTRA_GLOBAL_LOC]] = !{!"{{.*}}extra-source.cpp", i32 1, i32 5}
+// CHECK: ![[GLOBAL]] = !{{{.*}} ![[GLOBAL_LOC:[0-9]+]], !"global", i1 false, i1 false}
+// CHECK: ![[GLOBAL_LOC]] = !{!"{{.*}}hwasan-globals.cpp", i32 10, i32 5}
+// CHECK: ![[ATTR_GLOBAL]] = !{{{.*attributed_global.*}}, null, null, i1 false, i1 true}
+// CHECK: ![[DISABLE_INSTR_GLOBAL]] = !{{{.*disable_instrumentation_global.*}}, null, null, i1 false, i1 true}
+// CHECK: ![[IGNORELISTED_GLOBAL]] = !{{{.*ignorelisted_global.*}}, null, null, i1 false, i1 true}
+// CHECK: ![[STATIC_VAR]] = !{{{.*}} ![[STATIC_LOC:[0-9]+]], !"static_var", i1 false, i1 false}
+// CHECK: ![[STATIC_LOC]] = !{!"{{.*}}hwasan-globals.cpp", i32 16, i32 14}
+// CHECK: ![[LITERAL]] = !{{{.*}} ![[LITERAL_LOC:[0-9]+]], !"<string literal>", i1 false, i1 false}
+// CHECK: ![[LITERAL_LOC]] = !{!"{{.*}}hwasan-globals.cpp", i32 17, i32 25}
+
+// IGNORELIST: @{{.*}}global{{.*}} ={{.*}} global {{.*}}, no_sanitize_hwaddress
+// IGNORELIST: @{{.*}}attributed_global{{.*}} ={{.*}} global {{.*}}, no_sanitize_hwaddress
+// IGNORELIST: @{{.*}}disable_instrumentation_global{{.*}} ={{.*}} global {{.*}}, no_sanitize_hwaddress
+// IGNORELIST: @{{.*}}ignorelisted_globa{{.*}} ={{.*}} global {{.*}}, no_sanitize_hwaddress
+// IGNORELIST: @{{.*}}static_var{{.*}} ={{.*}} global {{.*}}, no_sanitize_hwaddress
+// IGNORELIST: @{{.*}} = {{.*}} c"Hello, world!\00"{{.*}}, no_sanitize_hwaddress
+// IGNORELIST: @{{.*}}extra_global{{.*}}.hwasan{{.*}} =
+
+// IGNORELIST: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[DISABLE_INSTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// IGNORELIST: ![[EXTRA_GLOBAL]] = !{{{.*}} ![[EXTRA_GLOBAL_LOC:[0-9]+]], !"extra_global", i1 false, i1 false}
+// IGNORELIST: ![[EXTRA_GLOBAL_LOC]] = !{!"{{.*}}extra-source.cpp", i32 1, i32 5}
+// IGNORELIST: ![[GLOBAL]] = !{{{.*}} null, null, i1 false, i1 true}
+// IGNORELIST: ![[ATTR_GLOBAL]] = !{{{.*attributed_global.*}}, null, null, i1 false, i1 true}
+// IGNORELIST: ![[DISABLE_INSTR_GLOBAL]] = !{{{.*disable_instrumentation_global.*}}, null, null, i1 false, i1 true}
+// IGNORELIST: ![[IGNORELISTED_GLOBAL]] = !{{{.*ignorelisted_global.*}}, null, null, i1 false, i1 true}
+// IGNORELIST: ![[STATIC_VAR]] = !{{{.*}} null, null, i1 false, i1 true}
+// IGNORELIST: ![[LITERAL]] = !{{{.*}} null, null, i1 false, i1 true}

diff  --git a/clang/test/CodeGen/memtag-globals.cpp b/clang/test/CodeGen/memtag-globals.cpp
new file mode 100644
index 000000000000..6deb0e2ad0bd
--- /dev/null
+++ b/clang/test/CodeGen/memtag-globals.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -include %S/Inputs/sanitizer-extra-source.cpp \
+// RUN:   -fsanitize-ignorelist=%S/Inputs/sanitizer-ignorelist-global.txt \
+// RUN:   -fsanitize=memtag-globals -emit-llvm -o - %s | FileCheck %s
+
+// RUN: %clang_cc1 -include %S/Inputs/sanitizer-extra-source.cpp \
+// RUN:   -fsanitize-ignorelist=%S/Inputs/sanitizer-ignorelist-src.txt \
+// RUN:   -fsanitize=memtag-globals -emit-llvm -o - %s | \
+// RUN:   FileCheck %s --check-prefix=IGNORELIST
+
+int global;
+int __attribute__((no_sanitize("memtag"))) attributed_global;
+int __attribute__((disable_sanitizer_instrumentation)) disable_instrumentation_global;
+int ignorelisted_global;
+
+void func() {
+  static int static_var = 0;
+  const char *literal = "Hello, world!";
+}
+
+// CHECK: @{{.*}}extra_global{{.*}} =
+// CHECK-NOT: no_sanitize_memtag
+// CHECK: @{{.*}}global{{.*}} =
+// CHECK-NOT: no_sanitize_memtag
+// CHECK: @{{.*}}attributed_global{{.*}} ={{.*}} global {{.*}}, no_sanitize_memtag
+// CHECK: @{{.*}}disable_instrumentation_global{{.*}} ={{.*}} global {{.*}}, no_sanitize_memtag
+// CHECK: @{{.*}}ignorelisted_global{{.*}} ={{.*}} global {{.*}}, no_sanitize_memtag
+// CHECK: @{{.*}}static_var{{.*}} =
+// CHECK-NOT: no_sanitize_memtag
+// CHECK: @{{.*}} = {{.*}} c"Hello, world!\00"
+// CHECK-NOT: no_sanitize_memtag
+
+// CHECK: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[DISABLE_INSTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// CHECK: ![[EXTRA_GLOBAL]] = !{{{.*}} ![[EXTRA_GLOBAL_LOC:[0-9]+]], !"extra_global", i1 false, i1 false}
+// CHECK: ![[EXTRA_GLOBAL_LOC]] = !{!"{{.*}}extra-source.cpp", i32 1, i32 5}
+// CHECK: ![[GLOBAL]] = !{{{.*}} ![[GLOBAL_LOC:[0-9]+]], !"global", i1 false, i1 false}
+// CHECK: ![[GLOBAL_LOC]] = !{!"{{.*}}memtag-globals.cpp", i32 10, i32 5}
+// CHECK: ![[ATTR_GLOBAL]] = !{{{.*attributed_global.*}}, null, null, i1 false, i1 true}
+// CHECK: ![[DISABLE_INSTR_GLOBAL]] = !{{{.*disable_instrumentation_global.*}}, null, null, i1 false, i1 true}
+// CHECK: ![[IGNORELISTED_GLOBAL]] = !{{{.*ignorelisted_global.*}}, null, null, i1 false, i1 true}
+// CHECK: ![[STATIC_VAR]] = !{{{.*}} ![[STATIC_LOC:[0-9]+]], !"static_var", i1 false, i1 false}
+// CHECK: ![[STATIC_LOC]] = !{!"{{.*}}memtag-globals.cpp", i32 16, i32 14}
+// CHECK: ![[LITERAL]] = !{{{.*}} ![[LITERAL_LOC:[0-9]+]], !"<string literal>", i1 false, i1 false}
+// CHECK: ![[LITERAL_LOC]] = !{!"{{.*}}memtag-globals.cpp", i32 17, i32 25}
+
+// IGNORELIST: @{{.*}}extra_global{{.*}} ={{.*}} global
+// IGNORELIST-NOT: no_sanitize_memtag
+// IGNORELIST: @{{.*}}global{{.*}} ={{.*}} global {{.*}}, no_sanitize_memtag
+// IGNORELIST: @{{.*}}attributed_global{{.*}} ={{.*}} global {{.*}}, no_sanitize_memtag
+// IGNORELIST: @{{.*}}disable_instrumentation_global{{.*}} ={{.*}} global {{.*}}, no_sanitize_memtag
+// IGNORELIST: @{{.*}}ignorelisted_globa{{.*}} ={{.*}} global {{.*}}, no_sanitize_memtag
+// IGNORELIST: @{{.*}}static_var{{.*}} ={{.*}} global {{.*}}, no_sanitize_memtag
+// IGNORELIST: @{{.*}} = {{.*}} c"Hello, world!\00"{{.*}}, no_sanitize_memtag
+
+// IGNORELIST: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[DISABLE_INSTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// IGNORELIST: ![[EXTRA_GLOBAL]] = !{{{.*}} ![[EXTRA_GLOBAL_LOC:[0-9]+]], !"extra_global", i1 false, i1 false}
+// IGNORELIST: ![[EXTRA_GLOBAL_LOC]] = !{!"{{.*}}extra-source.cpp", i32 1, i32 5}
+// IGNORELIST: ![[GLOBAL]] = !{{{.*}} null, null, i1 false, i1 true}
+// IGNORELIST: ![[ATTR_GLOBAL]] = !{{{.*attributed_global.*}}, null, null, i1 false, i1 true}
+// IGNORELIST: ![[DISABLE_INSTR_GLOBAL]] = !{{{.*disable_instrumentation_global.*}}, null, null, i1 false, i1 true}
+// IGNORELIST: ![[IGNORELISTED_GLOBAL]] = !{{{.*ignorelisted_global.*}}, null, null, i1 false, i1 true}
+// IGNORELIST: ![[STATIC_VAR]] = !{{{.*}} null, null, i1 false, i1 true}
+// IGNORELIST: ![[LITERAL]] = !{{{.*}} null, null, i1 false, i1 true}

diff  --git a/compiler-rt/test/hwasan/TestCases/global-with-reduction.c b/compiler-rt/test/hwasan/TestCases/global-with-reduction.c
new file mode 100644
index 000000000000..22a4efccc5ed
--- /dev/null
+++ b/compiler-rt/test/hwasan/TestCases/global-with-reduction.c
@@ -0,0 +1,50 @@
+// RUN: %clang_hwasan %s -o %t
+// RUN: %run %t 0
+// RUN: not %run %t 1 2>&1 | FileCheck --check-prefixes=CHECK,RSYM %s
+// RUN: not %env_hwasan_opts=symbolize=0 %run %t 1 2>&1 | FileCheck --check-prefixes=CHECK,RNOSYM %s
+// RUN: not %run %t -1 2>&1 | FileCheck --check-prefixes=CHECK,LSYM %s
+// RUN: not %env_hwasan_opts=symbolize=0 %run %t -1 2>&1 | FileCheck --check-prefixes=CHECK,LNOSYM %s
+
+// Test with and without optimizations, with and without PIC, since 
diff erent
+// backend passes run depending on these flags.
+// RUN: %clang_hwasan -fno-pic %s -o %t
+// RUN: not %run %t 1 2>&1 | FileCheck --check-prefixes=CHECK,RSYM %s
+// RUN: %clang_hwasan -fno-pic -O2 %s -o %t
+// RUN: not %run %t 1 2>&1 | FileCheck --check-prefixes=CHECK,RSYM %s
+// RUN: %clang_hwasan -O2 %s -o %t
+// RUN: not %run %t 1 2>&1 | FileCheck --check-prefixes=CHECK,RSYM %s
+
+// RUN: %clang_hwasan -DUSE_NOSANITIZE %s -o %t && %run %t 0
+// RUN: %clang_hwasan -DUSE_NOSANITIZE %s -o %t && %run %t 1
+// RUN: %clang_hwasan -DUSE_NOSANITIZE %s -o %t -fno-pic && %run %t 1
+// RUN: %clang_hwasan -DUSE_NOSANITIZE %s -o %t -O2 && %run %t 1
+// RUN: %clang_hwasan -DUSE_NOSANITIZE %s -o %t -fno-pic -O2 && %run %t 1
+
+// REQUIRES: pointer-tagging
+
+#include <stdlib.h>
+
+// GlobalOpt may replace the current GV with a new boolean-typed GV. Previously,
+// this resulted in the "nosanitize" getting dropped because while the data/code
+// references to the GV were updated, the old metadata references weren't.
+int* f() {
+#ifdef USE_NOSANITIZE
+__attribute__((no_sanitize("hwaddress"))) static int x = 1;
+#else // USE_NOSANITIZE
+  static int x = 1;
+#endif // USE_NOSANITIZE
+  if (x == 1) x = 0;
+  return &x;
+}
+
+int main(int argc, char **argv) {
+  // CHECK: Cause: global-overflow
+  // RSYM: is located 0 bytes to the right of 4-byte global variable f.x {{.*}} in {{.*}}global-with-reduction.c.tmp
+  // RNOSYM: is located to the right of a 4-byte global variable in
+  // RNOSYM-NEXT: #0 0x{{.*}} ({{.*}}global-with-reduction.c.tmp+{{.*}})
+  // LSYM: is located 4 bytes to the left of 4-byte global variable f.x {{.*}} in {{.*}}global-with-reduction.c.tmp
+  // LNOSYM: is located to the left of a 4-byte global variable in
+  // LNOSYM-NEXT: #0 0x{{.*}} ({{.*}}global-with-reduction.c.tmp+{{.*}})
+  // CHECK-NOT: can not describe
+  f()[atoi(argv[1])] = 1;
+}

diff  --git a/compiler-rt/test/hwasan/TestCases/global.c b/compiler-rt/test/hwasan/TestCases/global.c
index 2da3b6dce964..4a790e2d08be 100644
--- a/compiler-rt/test/hwasan/TestCases/global.c
+++ b/compiler-rt/test/hwasan/TestCases/global.c
@@ -14,9 +14,23 @@
 // RUN: %clang_hwasan -O2 %s -o %t
 // RUN: not %run %t 1 2>&1 | FileCheck --check-prefixes=CHECK,RSYM %s
 
+// RUN: %clang_hwasan -DUSE_NOSANITIZE %s -o %t && %run %t 0
+// RUN: %clang_hwasan -DUSE_NOSANITIZE %s -o %t && %run %t 1
+// RUN: %clang_hwasan -DUSE_NOSANITIZE %s -o %t -fno-pic && %run %t 1
+// RUN: %clang_hwasan -DUSE_NOSANITIZE %s -o %t -O2 && %run %t 1
+// RUN: %clang_hwasan -DUSE_NOSANITIZE %s -o %t -fno-pic -O2 && %run %t 1
+
 // REQUIRES: pointer-tagging
 
+#include <stdlib.h>
+
+int a = 1;
+#ifdef USE_NOSANITIZE
+__attribute__((no_sanitize("hwaddress"))) int x = 1;
+#else // USE_NOSANITIZE
 int x = 1;
+#endif // USE_NOSANITIZE
+int b = 1;
 
 int atoi(const char *);
 


        


More information about the llvm-commits mailing list