diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2014-02-27 04:11:59 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2014-02-27 04:11:59 +0000 |
commit | 1b7ed91e44a8fdcb3217077204d60e7fc8d4561f (patch) | |
tree | 22268eb650ebd65e801631b863d68ea4a3d6bd74 /clang/lib/Frontend | |
parent | 08301dee468848e405d2a9c2ca08ad8af042be52 (diff) | |
download | bcm5719-llvm-1b7ed91e44a8fdcb3217077204d60e7fc8d4561f.tar.gz bcm5719-llvm-1b7ed91e44a8fdcb3217077204d60e7fc8d4561f.zip |
[ASTUnit] Fix use-after-free bug in ASTUnit::getMainBufferWithPrecompiledPreamble().
With r197755 we started reading the contents of buffer file entries, but the
buffers may point to ASTReader blobs that have been disposed.
Fix this by having the CompilerInstance object keep a reference to the ASTReader
as well as having the ASTContext keep reference to the ExternalASTSource.
This was very difficult to construct a test case for.
rdar://16149782
llvm-svn: 202346
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 30 | ||||
-rw-r--r-- | clang/lib/Frontend/ChainedIncludesSource.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 19 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendAction.cpp | 9 |
4 files changed, 35 insertions, 45 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 8d46a8f4a5d..93429cba887 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -718,8 +718,6 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, HeaderSearch &HeaderInfo = *AST->HeaderInfo.get(); unsigned Counter; - OwningPtr<ASTReader> Reader; - AST->PP = new Preprocessor(PPOpts, AST->getDiagnostics(), AST->ASTFileLangOpts, /*Target=*/0, AST->getSourceManager(), HeaderInfo, @@ -742,21 +740,17 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, bool disableValid = false; if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION")) disableValid = true; - Reader.reset(new ASTReader(PP, Context, + AST->Reader = new ASTReader(PP, Context, /*isysroot=*/"", /*DisableValidation=*/disableValid, - AllowPCHWithCompilerErrors)); - - // Recover resources if we crash before exiting this method. - llvm::CrashRecoveryContextCleanupRegistrar<ASTReader> - ReaderCleanup(Reader.get()); + AllowPCHWithCompilerErrors); - Reader->setListener(new ASTInfoCollector(*AST->PP, Context, + AST->Reader->setListener(new ASTInfoCollector(*AST->PP, Context, AST->ASTFileLangOpts, AST->TargetOpts, AST->Target, Counter)); - switch (Reader->ReadAST(Filename, serialization::MK_MainFile, + switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile, SourceLocation(), ASTReader::ARR_None)) { case ASTReader::Success: break; @@ -771,21 +765,14 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, return NULL; } - AST->OriginalSourceFile = Reader->getOriginalSourceFile(); + AST->OriginalSourceFile = AST->Reader->getOriginalSourceFile(); PP.setCounterValue(Counter); // Attach the AST reader to the AST context as an external AST // source, so that declarations will be deserialized from the // AST file as needed. - ASTReader *ReaderPtr = Reader.get(); - OwningPtr<ExternalASTSource> Source(Reader.take()); - - // Unregister the cleanup for ASTReader. It will get cleaned up - // by the ASTUnit cleanup. - ReaderCleanup.unregister(); - - Context.setExternalSource(Source); + Context.setExternalSource(AST->Reader); // Create an AST consumer, even though it isn't used. AST->Consumer.reset(new ASTConsumer); @@ -793,8 +780,7 @@ ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename, // Create a semantic analysis object and tell the AST reader about it. AST->TheSema.reset(new Sema(PP, Context, *AST->Consumer)); AST->TheSema->Initialize(); - ReaderPtr->InitializeSema(*AST->TheSema); - AST->Reader = ReaderPtr; + AST->Reader->InitializeSema(*AST->TheSema); // Tell the diagnostic client that we have started a source file. AST->getDiagnostics().getClient()->BeginSourceFile(Context.getLangOpts(),&PP); @@ -1173,7 +1159,7 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) { if (OverrideMainBuffer) { std::string ModName = getPreambleFile(this); - TranslateStoredDiagnostics(Clang->getModuleManager(), ModName, + TranslateStoredDiagnostics(Clang->getModuleManager().getPtr(), ModName, getSourceManager(), PreambleDiagnostics, StoredDiagnostics); } diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp index 442177ec319..ab5c81fb588 100644 --- a/clang/lib/Frontend/ChainedIncludesSource.cpp +++ b/clang/lib/Frontend/ChainedIncludesSource.cpp @@ -62,12 +62,13 @@ ChainedIncludesSource::~ChainedIncludesSource() { delete CIs[i]; } -ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) { +IntrusiveRefCntPtr<ChainedIncludesSource> +ChainedIncludesSource::create(CompilerInstance &CI) { std::vector<std::string> &includes = CI.getPreprocessorOpts().ChainedIncludes; assert(!includes.empty() && "No '-chain-include' in options!"); - OwningPtr<ChainedIncludesSource> source(new ChainedIncludesSource()); + IntrusiveRefCntPtr<ChainedIncludesSource> source(new ChainedIncludesSource()); InputKind IK = CI.getFrontendOpts().Inputs[0].getKind(); SmallVector<llvm::MemoryBuffer *, 4> serialBufs; @@ -137,13 +138,12 @@ ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) { serialBufNames.push_back(pchName); - OwningPtr<ExternalASTSource> Reader; - - Reader.reset(createASTReader(*Clang, pchName, bufs, serialBufNames, - Clang->getASTConsumer().GetASTDeserializationListener())); + IntrusiveRefCntPtr<ASTReader> Reader; + Reader = createASTReader(*Clang, pchName, bufs, serialBufNames, + Clang->getASTConsumer().GetASTDeserializationListener()); if (!Reader) return 0; - Clang->setModuleManager(static_cast<ASTReader*>(Reader.get())); + Clang->setModuleManager(Reader); Clang->getASTContext().setExternalSource(Reader); } @@ -162,13 +162,13 @@ ChainedIncludesSource *ChainedIncludesSource::create(CompilerInstance &CI) { assert(!serialBufs.empty()); std::string pchName = includes.back() + ".pch-final"; serialBufNames.push_back(pchName); - OwningPtr<ASTReader> Reader; - Reader.reset(createASTReader(CI, pchName, serialBufs, serialBufNames)); + IntrusiveRefCntPtr<ASTReader> Reader; + Reader = createASTReader(CI, pchName, serialBufs, serialBufNames); if (!Reader) return 0; - source->FinalReader.reset(Reader.take()); - return source.take(); + source->FinalReader = Reader; + return source; } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index 3fe8f0e82f7..cdc4b64af77 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -104,6 +104,13 @@ void CompilerInstance::setASTConsumer(ASTConsumer *Value) { void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) { CompletionConsumer.reset(Value); } + +IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const { + return ModuleManager; +} +void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) { + ModuleManager = Reader; +} // Diagnostics static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts, @@ -301,16 +308,16 @@ void CompilerInstance::createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, void *DeserializationListener){ - OwningPtr<ExternalASTSource> Source; + IntrusiveRefCntPtr<ExternalASTSource> Source; bool Preamble = getPreprocessorOpts().PrecompiledPreambleBytes.first != 0; - Source.reset(createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot, + Source = createPCHExternalASTSource(Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation, AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(), DeserializationListener, Preamble, - getFrontendOpts().UseGlobalModuleIndex)); - ModuleManager = static_cast<ASTReader*>(Source.get()); + getFrontendOpts().UseGlobalModuleIndex); + ModuleManager = static_cast<ASTReader*>(Source.getPtr()); getASTContext().setExternalSource(Source); } @@ -1176,9 +1183,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, getASTContext().setASTMutationListener( getASTConsumer().GetASTMutationListener()); } - OwningPtr<ExternalASTSource> Source; - Source.reset(ModuleManager); - getASTContext().setExternalSource(Source); + getASTContext().setExternalSource(ModuleManager); if (hasSema()) ModuleManager->InitializeSema(getSema()); if (hasASTConsumer()) diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 6cfa12168db..f028a56053d 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -316,12 +316,11 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) { // Convert headers to PCH and chain them. - OwningPtr<ExternalASTSource> source; - source.reset(ChainedIncludesSource::create(CI)); + IntrusiveRefCntPtr<ChainedIncludesSource> source; + source = ChainedIncludesSource::create(CI); if (!source) goto failure; - CI.setModuleManager(static_cast<ASTReader*>( - &static_cast<ChainedIncludesSource*>(source.get())->getFinalReader())); + CI.setModuleManager(static_cast<ASTReader*>(&source->getFinalReader())); CI.getASTContext().setExternalSource(source); } else if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) { @@ -361,7 +360,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI, // provides the layouts from that file. if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && CI.hasASTContext() && !CI.getASTContext().getExternalSource()) { - OwningPtr<ExternalASTSource> + IntrusiveRefCntPtr<ExternalASTSource> Override(new LayoutOverrideSource( CI.getFrontendOpts().OverrideRecordLayoutsFile)); CI.getASTContext().setExternalSource(Override); |