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