From: Kostya Serebryany Date: Fri, 29 Aug 2014 01:01:32 +0000 (+0000) Subject: call __asan_load_cxx_array_cookie when loading array cookie in asan mode. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a29d00b06890cc52c7c886e3e80e3f9625a283ae;p=clang call __asan_load_cxx_array_cookie when loading array cookie in asan mode. 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 --- diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 5df3e43f48..f861af3e45 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -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) { diff --git a/test/CodeGen/address-sanitizer-and-array-cookie.cpp b/test/CodeGen/address-sanitizer-and-array-cookie.cpp index c5882f807b..ea89537789 100644 --- a/test/CodeGen/address-sanitizer-and-array-cookie.cpp +++ b/test/CodeGen/address-sanitizer-and-array-cookie.cpp @@ -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];