MaskRay created this revision.
MaskRay added reviewers: Sanitizers, hctim, kstoimenov, vitalybuka.
Herald added a subscriber: StephenFan.
Herald added a project: All.
MaskRay requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.

When an issue exists in the main file (caller) instead of an included file
(callee), using a `src` pattern applying to the included file may be
inappropriate if it's the caller's responsibility. Add "mainsrc" prefix to check
the main filename.

For the example below, the issue may reside in a.c (foo should not be called
with a misaligned pointer or foo should switch to an unaligned load), but with
`src` we can only apply to the innocent callee a.h. With this patch we can use
the more appropriate `mainsrc:a.c`.

  //--- a.h
  static inline int load(int *x) { return *x; }
  
  //--- a.c
  #include "a.h"
  int foo(void *x) { return load(x); }


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D129832

Files:
  clang/docs/SanitizerSpecialCaseList.rst
  clang/include/clang/Basic/NoSanitizeList.h
  clang/lib/Basic/NoSanitizeList.cpp
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/test/CodeGen/sanitize-ignorelist-mainsrc.c
  llvm/include/llvm/Support/SpecialCaseList.h

Index: llvm/include/llvm/Support/SpecialCaseList.h
===================================================================
--- llvm/include/llvm/Support/SpecialCaseList.h
+++ llvm/include/llvm/Support/SpecialCaseList.h
@@ -19,9 +19,9 @@
 //   prefix:wildcard_expression[=category]
 // If category is not specified, it is assumed to be empty string.
 // Definitions of "prefix" and "category" are sanitizer-specific. For example,
-// sanitizer exclusion support prefixes "src", "fun" and "global".
-// Wildcard expressions define, respectively, source files, functions or
-// globals which shouldn't be instrumented.
+// sanitizer exclusion support prefixes "src", "mainsrc", "fun" and "global".
+// Wildcard expressions define, respectively, source files, main source files,
+// functions or globals which shouldn't be instrumented.
 // Examples of categories:
 //   "functional": used in DFSan to list functions with pure functional
 //                 semantics.
@@ -37,6 +37,7 @@
 // type:*Namespace::ClassName*=init
 // src:file_with_tricky_code.cc
 // src:ignore-global-initializers-issues.cc=init
+// mainsrc:file_with_tricky_code.cc
 //
 // [dataflow]
 // # Functions with pure functional semantics:
Index: clang/test/CodeGen/sanitize-ignorelist-mainsrc.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/sanitize-ignorelist-mainsrc.c
@@ -0,0 +1,41 @@
+/// Test mainsrc in a sanitizer special case list.
+// RUN: rm -rf %t && split-file %s %t && cd %t
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=address,alignment a.c -o - | FileCheck %s --check-prefixes=CHECK,DEFAULT
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=address,alignment -fsanitize-ignorelist=a.list a.c -o - | FileCheck %s --check-prefixes=CHECK,IGNORE
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=address,alignment -fsanitize-ignorelist=b.list a.c -o - | FileCheck %s --check-prefixes=CHECK,IGNORE
+
+//--- a.list
+mainsrc:*a.c
+
+//--- b.list
+[address]
+mainsrc:*a.c
+
+[alignment]
+mainsrc:*.c
+
+//--- a.h
+int global_h;
+
+static inline int load(int *x) {
+  return *x;
+}
+
+//--- a.c
+#include "a.h"
+
+int global_c;
+
+int foo(void *x) {
+  return load(x);
+}
+
+// DEFAULT:     @___asan_gen_{{.*}} = {{.*}} c"global_h\00"
+// DEFAULT:     @___asan_gen_{{.*}} = {{.*}} c"global_c\00"
+// IGNORE-NOT:  @___asan_gen_
+
+// CHECK-LABEL: define {{.*}}@load(
+// DEFAULT:       call void @__ubsan_handle_type_mismatch_v1_abort(
+// DEFAULT:       call void @__asan_report_load4(
+// IGNORE-NOT:    call void @__ubsan_handle_type_mismatch_v1_abort(
+// IGNORE-NOT:    call void @__asan_report_load4(
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -2780,16 +2780,18 @@
   // NoSanitize by function name.
   if (NoSanitizeL.containsFunction(Kind, Fn->getName()))
     return true;
-  // NoSanitize by location.
+  // NoSanitize by location. Check "mainsrc" category.
+  auto &SM = Context.getSourceManager();
+  const FileEntry &MainFile = *SM.getFileEntryForID(SM.getMainFileID());
+  if (NoSanitizeL.containsMainFile(Kind, MainFile.getName()))
+    return true;
+
+  // Check "src" category.
   if (Loc.isValid())
     return NoSanitizeL.containsLocation(Kind, Loc);
   // If location is unknown, this may be a compiler-generated function. Assume
   // it's located in the main file.
-  auto &SM = Context.getSourceManager();
-  if (const auto *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
-    return NoSanitizeL.containsFile(Kind, MainFile->getName());
-  }
-  return false;
+  return NoSanitizeL.containsFile(Kind, MainFile.getName());
 }
 
 bool CodeGenModule::isInNoSanitizeList(SanitizerMask Kind,
@@ -2799,8 +2801,13 @@
   const auto &NoSanitizeL = getContext().getNoSanitizeList();
   if (NoSanitizeL.containsGlobal(Kind, GV->getName(), Category))
     return true;
+  auto &SM = Context.getSourceManager();
+  if (NoSanitizeL.containsMainFile(
+          Kind, SM.getFileEntryForID(SM.getMainFileID())->getName(), Category))
+    return true;
   if (NoSanitizeL.containsLocation(Kind, Loc, Category))
     return true;
+
   // Check global type.
   if (!Ty.isNull()) {
     // Drill down the array types: if global variable of a fixed type is
Index: clang/lib/Basic/NoSanitizeList.cpp
===================================================================
--- clang/lib/Basic/NoSanitizeList.cpp
+++ clang/lib/Basic/NoSanitizeList.cpp
@@ -47,6 +47,11 @@
   return SSCL->inSection(Mask, "src", FileName, Category);
 }
 
+bool NoSanitizeList::containsMainFile(SanitizerMask Mask, StringRef FileName,
+                                      StringRef Category) const {
+  return SSCL->inSection(Mask, "mainsrc", FileName, Category);
+}
+
 bool NoSanitizeList::containsLocation(SanitizerMask Mask, SourceLocation Loc,
                                       StringRef Category) const {
   return Loc.isValid() &&
Index: clang/include/clang/Basic/NoSanitizeList.h
===================================================================
--- clang/include/clang/Basic/NoSanitizeList.h
+++ clang/include/clang/Basic/NoSanitizeList.h
@@ -41,6 +41,8 @@
   bool containsFunction(SanitizerMask Mask, StringRef FunctionName) const;
   bool containsFile(SanitizerMask Mask, StringRef FileName,
                     StringRef Category = StringRef()) const;
+  bool containsMainFile(SanitizerMask Mask, StringRef FileName,
+                        StringRef Category = StringRef()) const;
   bool containsLocation(SanitizerMask Mask, SourceLocation Loc,
                         StringRef Category = StringRef()) const;
 };
Index: clang/docs/SanitizerSpecialCaseList.rst
===================================================================
--- clang/docs/SanitizerSpecialCaseList.rst
+++ clang/docs/SanitizerSpecialCaseList.rst
@@ -75,6 +75,9 @@
     # Turn off checks for the source file (use absolute path or path relative
     # to the current working directory):
     src:/path/to/source/file.c
+    # Turn off checks for this main file, including files included by it.
+    # Useful when the main file instead of an included file should be ignored.
+    mainsrc:file.c
     # Turn off checks for a particular functions (use mangled names):
     fun:MyFooBar
     fun:_Z8MyFooBarv
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to