mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-12 16:36:07 +00:00

Summary: 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) Reviewers: timurrrr, samsonov, rsmith Reviewed By: rsmith Subscribers: cfe-commits Differential Revision: http://reviews.llvm.org/D4774 llvm-svn: 216434
89 lines
3.4 KiB
C++
89 lines
3.4 KiB
C++
//===--- SanitizerMetadata.cpp - Blacklist for sanitizers -----------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Class which emits metadata consumed by sanitizer instrumentation passes.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "SanitizerMetadata.h"
|
|
#include "CodeGenModule.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/IR/Constants.h"
|
|
|
|
using namespace clang;
|
|
using namespace CodeGen;
|
|
|
|
SanitizerMetadata::SanitizerMetadata(CodeGenModule &CGM) : CGM(CGM) {}
|
|
|
|
void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
|
|
SourceLocation Loc, StringRef Name,
|
|
bool IsDynInit, bool IsBlacklisted) {
|
|
if (!CGM.getLangOpts().Sanitize.Address)
|
|
return;
|
|
IsDynInit &= !CGM.getSanitizerBlacklist().isIn(*GV, "init");
|
|
IsBlacklisted |= CGM.getSanitizerBlacklist().isIn(*GV);
|
|
|
|
llvm::Value *LocDescr = nullptr;
|
|
llvm::Value *GlobalName = nullptr;
|
|
llvm::LLVMContext &VMContext = CGM.getLLVMContext();
|
|
if (!IsBlacklisted) {
|
|
// Don't generate source location and global name if it is blacklisted -
|
|
// it won't be instrumented anyway.
|
|
LocDescr = getLocationMetadata(Loc);
|
|
if (!Name.empty())
|
|
GlobalName = llvm::MDString::get(VMContext, Name);
|
|
}
|
|
|
|
llvm::Value *GlobalMetadata[] = {
|
|
GV, LocDescr, GlobalName,
|
|
llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsDynInit),
|
|
llvm::ConstantInt::get(llvm::Type::getInt1Ty(VMContext), IsBlacklisted)};
|
|
|
|
llvm::MDNode *ThisGlobal = llvm::MDNode::get(VMContext, GlobalMetadata);
|
|
llvm::NamedMDNode *AsanGlobals =
|
|
CGM.getModule().getOrInsertNamedMetadata("llvm.asan.globals");
|
|
AsanGlobals->addOperand(ThisGlobal);
|
|
}
|
|
|
|
void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
|
|
const VarDecl &D, bool IsDynInit) {
|
|
if (!CGM.getLangOpts().Sanitize.Address)
|
|
return;
|
|
std::string QualName;
|
|
llvm::raw_string_ostream OS(QualName);
|
|
D.printQualifiedName(OS);
|
|
reportGlobalToASan(GV, D.getLocation(), OS.str(), IsDynInit);
|
|
}
|
|
|
|
void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
|
|
// For now, just make sure the global is not modified by the ASan
|
|
// instrumentation.
|
|
if (CGM.getLangOpts().Sanitize.Address)
|
|
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())
|
|
return nullptr;
|
|
llvm::LLVMContext &VMContext = CGM.getLLVMContext();
|
|
llvm::Value *LocMetadata[] = {
|
|
llvm::MDString::get(VMContext, PLoc.getFilename()),
|
|
llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), PLoc.getLine()),
|
|
llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext),
|
|
PLoc.getColumn()),
|
|
};
|
|
return llvm::MDNode::get(VMContext, LocMetadata);
|
|
}
|