Hi samsonov, rsmith,

PR19838
When operator new[] is called and an array cookie is created
we want asan to detect buffer overflow bugs that touch the cookie.
For that we need to
  a) poison the shadow for the array cookie (call 
__asan_poison_cxx_array_cookie).
  b) ignore the legal accesses to the cookie generated by clang (add 
'nosanitize' metadata)

http://reviews.llvm.org/D4774

Files:
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/CodeGen/SanitizerMetadata.cpp
  lib/CodeGen/SanitizerMetadata.h
  test/CodeGen/address-sanitizer-and-array-cookie.cpp
  test/Frontend/optimization-remark.s
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -1473,10 +1473,18 @@
                                                  CookieOffset.getQuantity());
 
   // Write the number of elements into the appropriate slot.
-  llvm::Value *NumElementsPtr
-    = CGF.Builder.CreateBitCast(CookiePtr,
-                                CGF.ConvertType(SizeTy)->getPointerTo(AS));
-  CGF.Builder.CreateStore(NumElements, NumElementsPtr);
+  llvm::Type *NumElementsTy = CGF.ConvertType(SizeTy)->getPointerTo(AS);
+  llvm::Value *NumElementsPtr =
+      CGF.Builder.CreateBitCast(CookiePtr, NumElementsTy);
+  llvm::Instruction *SI = CGF.Builder.CreateStore(NumElements, NumElementsPtr);
+  if (CGM.getLangOpts().Sanitize.Address) {
+    CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
+    llvm::FunctionType *fty =
+        llvm::FunctionType::get(CGM.VoidTy, NumElementsTy, false);
+    llvm::Constant *f =
+        CGM.CreateRuntimeFunction(fty, "__asan_poison_cxx_array_cookie");
+    CGF.Builder.CreateCall(f, NumElementsPtr);
+  }
 
   // Finally, compute a pointer to the actual data buffer by skipping
   // over the cookie completely.
@@ -1499,7 +1507,10 @@
   unsigned AS = allocPtr->getType()->getPointerAddressSpace();
   numElementsPtr = 
     CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
-  return CGF.Builder.CreateLoad(numElementsPtr);
+  llvm::Instruction *LI = CGF.Builder.CreateLoad(numElementsPtr);
+  if (CGM.getLangOpts().Sanitize.Address)
+    CGM.getSanitizerMetadata()->disableSanitizerForInstruction(LI);
+  return LI;
 }
 
 CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -1683,11 +1683,8 @@
                                    llvm::BasicBlock *BB,
                                    llvm::BasicBlock::iterator InsertPt) const {
   LoopStack.InsertHelper(I);
-  if (IsSanitizerScope) {
-    I->setMetadata(
-        CGM.getModule().getMDKindID("nosanitize"),
-        llvm::MDNode::get(CGM.getLLVMContext(), ArrayRef<llvm::Value *>()));
-  }
+  if (IsSanitizerScope)
+    CGM.getSanitizerMetadata()->disableSanitizerForInstruction(I);
 }
 
 template <bool PreserveNames>
Index: lib/CodeGen/SanitizerMetadata.h
===================================================================
--- lib/CodeGen/SanitizerMetadata.h
+++ lib/CodeGen/SanitizerMetadata.h
@@ -18,6 +18,7 @@
 
 namespace llvm {
 class GlobalVariable;
+class Instruction;
 class MDNode;
 }
 
@@ -41,6 +42,7 @@
                           StringRef Name, bool IsDynInit = false,
                           bool IsBlacklisted = false);
   void disableSanitizerForGlobal(llvm::GlobalVariable *GV);
+  void disableSanitizerForInstruction(llvm::Instruction *I);
 private:
   llvm::MDNode *getLocationMetadata(SourceLocation Loc);
 };
Index: lib/CodeGen/SanitizerMetadata.cpp
===================================================================
--- lib/CodeGen/SanitizerMetadata.cpp
+++ lib/CodeGen/SanitizerMetadata.cpp
@@ -67,6 +67,12 @@
     reportGlobalToASan(GV, SourceLocation(), "", false, true);
 }
 
+void SanitizerMetadata::disableSanitizerForInstruction(llvm::Instruction *I) {
+  I->setMetadata(
+      CGM.getModule().getMDKindID("nosanitize"),
+      llvm::MDNode::get(CGM.getLLVMContext(), ArrayRef<llvm::Value *>()));
+}
+
 llvm::MDNode *SanitizerMetadata::getLocationMetadata(SourceLocation Loc) {
   PresumedLoc PLoc = CGM.getContext().getSourceManager().getPresumedLoc(Loc);
   if (!PLoc.isValid())
Index: test/CodeGen/address-sanitizer-and-array-cookie.cpp
===================================================================
--- /dev/null
+++ test/CodeGen/address-sanitizer-and-array-cookie.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple x86_64-gnu-linux -emit-llvm -o - %s | FileCheck %s -check-prefix=PLAIN
+// RUN: %clang_cc1 -triple x86_64-gnu-linux -emit-llvm -o - -fsanitize=address %s | FileCheck %s -check-prefix=ASAN
+
+struct C {
+  int x;
+  ~C();
+};
+
+C *CallNew() {
+  return new C[10];
+}
+// PLAIN-LABEL: CallNew
+// PLAIN-NOT: nosanitize
+// PLAIN-NOT: __asan_poison_cxx_array_cookie
+// ASAN-LABEL: CallNew
+// ASAN: store{{.*}}nosanitize
+// ASAN-NOT: nosanitize
+// ASAN: call void @__asan_poison_cxx_array_cookie
+
+void CallDelete(C *c) {
+  delete [] c;
+}
+
+// PLAIN-LABEL: CallDelete
+// PLAIN-NOT: nosanitize
+// ASAN-LABEL: CallDelete
+// ASAN: load{{.*}}!nosanitize
+// ASAN-NOT: nosanitize
Index: test/Frontend/optimization-remark.s
===================================================================
--- /dev/null
+++ test/Frontend/optimization-remark.s
@@ -0,0 +1,59 @@
+	.text
+	.file	"/home/kcc/llvm/tools/clang/test/Frontend/optimization-remark.c"
+	.globl	foo
+	.align	16, 0x90
+	.type	foo,@function
+foo:
+	movl	%edi, -4(%rsp)
+	movl	%esi, -8(%rsp)
+	movl	-4(%rsp), %esi
+	addl	-8(%rsp), %esi
+	movl	%esi, %eax
+	retq
+.Ltmp0:
+	.size	foo, .Ltmp0-foo
+
+	.globl	foz
+	.align	16, 0x90
+	.type	foz,@function
+foz:
+	movl	%edi, -4(%rsp)
+	movl	%esi, -8(%rsp)
+	movl	-4(%rsp), %esi
+	imull	-8(%rsp), %esi
+	cvtsi2ssl	%esi, %xmm0
+	retq
+.Ltmp1:
+	.size	foz, .Ltmp1-foz
+
+	.globl	bar
+	.align	16, 0x90
+	.type	bar,@function
+bar:
+	subq	$24, %rsp
+	movl	%edi, 12(%rsp)
+	movl	12(%rsp), %edi
+	movl	12(%rsp), %eax
+	subl	$2, %eax
+	movl	%edi, 20(%rsp)
+	movl	%eax, 16(%rsp)
+	movl	20(%rsp), %eax
+	addl	16(%rsp), %eax
+	cvtsi2ssl	%eax, %xmm0
+	movl	12(%rsp), %eax
+	subl	$2, %eax
+	movl	12(%rsp), %esi
+	movl	%eax, %edi
+	movss	%xmm0, 8(%rsp)
+	callq	foz@PLT
+	movss	8(%rsp), %xmm1
+	mulss	%xmm0, %xmm1
+	cvttss2si	%xmm1, %eax
+	addq	$24, %rsp
+	retq
+.Ltmp2:
+	.size	bar, .Ltmp2-bar
+
+
+	.ident	"clang version 3.5.0 (210318)"
+	.section	".note.GNU-stack","",@progbits
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to