]> granicus.if.org Git - clang/commitdiff
call __asan_load_cxx_array_cookie when loading array cookie in asan mode.
authorKostya Serebryany <kcc@google.com>
Fri, 29 Aug 2014 01:01:32 +0000 (01:01 +0000)
committerKostya Serebryany <kcc@google.com>
Fri, 29 Aug 2014 01:01:32 +0000 (01:01 +0000)
Summary:
The current implementation of asan cookie is incorrect:
we add nosanitize metadata to the cookie load, but the metadata may be lost
and we will instrument the load from poisoned memory.
This change replaces the load with a call to __asan_load_cxx_array_cookie (r216692)

Reviewers: rsmith

Reviewed By: rsmith

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D5111

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@216702 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/ItaniumCXXABI.cpp
test/CodeGen/address-sanitizer-and-array-cookie.cpp

index 5df3e43f4887b93d9e2ac1265a16416b2493ba5e..f861af3e4574a193873483849230b32f2451a42b 100644 (file)
@@ -1476,8 +1476,9 @@ llvm::Value *ItaniumCXXABI::InitializeArrayCookie(CodeGenFunction &CGF,
   llvm::Value *NumElementsPtr =
       CGF.Builder.CreateBitCast(CookiePtr, NumElementsTy);
   llvm::Instruction *SI = CGF.Builder.CreateStore(NumElements, NumElementsPtr);
-  if (CGM.getLangOpts().Sanitize.Address &&
+  if (CGM.getLangOpts().Sanitize.Address && AS == 0 &&
       expr->getOperatorNew()->isReplaceableGlobalAllocationFunction()) {
+    // The store to the CookiePtr does not need to be instrumented.
     CGM.getSanitizerMetadata()->disableSanitizerForInstruction(SI);
     llvm::FunctionType *FTy =
         llvm::FunctionType::get(CGM.VoidTy, NumElementsTy, false);
@@ -1507,10 +1508,18 @@ llvm::Value *ItaniumCXXABI::readArrayCookieImpl(CodeGenFunction &CGF,
   unsigned AS = allocPtr->getType()->getPointerAddressSpace();
   numElementsPtr = 
     CGF.Builder.CreateBitCast(numElementsPtr, CGF.SizeTy->getPointerTo(AS));
-  llvm::Instruction *LI = CGF.Builder.CreateLoad(numElementsPtr);
-  if (CGM.getLangOpts().Sanitize.Address)
-    CGM.getSanitizerMetadata()->disableSanitizerForInstruction(LI);
-  return LI;
+  if (!CGM.getLangOpts().Sanitize.Address || AS != 0)
+    return CGF.Builder.CreateLoad(numElementsPtr);
+  // In asan mode emit a function call instead of a regular load and let the
+  // run-time deal with it: if the shadow is properly poisoned return the
+  // cookie, otherwise return 0 to avoid an infinite loop calling DTORs.
+  // We can't simply ignore this load using nosanitize metadata because
+  // the metadata may be lost.
+  llvm::FunctionType *FTy =
+      llvm::FunctionType::get(CGF.SizeTy, CGF.SizeTy->getPointerTo(0), false);
+  llvm::Constant *F =
+      CGM.CreateRuntimeFunction(FTy, "__asan_load_cxx_array_cookie");
+  return CGF.Builder.CreateCall(F, numElementsPtr);
 }
 
 CharUnits ARMCXXABI::getArrayCookieSizeImpl(QualType elementType) {
index c5882f807bc52bcc8137ccff3be2cf0d849ed114..ea895377891640a2ac75e983163eb4cc1cae4f78 100644 (file)
@@ -43,7 +43,8 @@ void CallDelete(C *c) {
 // PLAIN-LABEL: CallDelete
 // PLAIN-NOT: nosanitize
 // ASAN-LABEL: CallDelete
-// ASAN: load{{.*}}!nosanitize
+// ASAN-NOT: nosanitize
+// ASAN: call i64 @__asan_load_cxx_array_cookie
 // ASAN-NOT: nosanitize
 
 char Buffer[20];