llvm-project/clang-tools-extra/clangd
Ilya Biryukov ddf6a33306 [clang] Fix use-after-free on code completion
Summary:
Found by asan. Fiddling with code completion AST after
FrontendAction::Exceute can lead to errors.
Calling the callback in ProcessCodeCompleteResults to make sure we
don't access uninitialized state.

This particular issue comes from the fact that Sema::TUScope is
deleted when destructor of ~Parser runs, but still present in
Sema::TUScope and accessed when building completion items.

I'm still struggling to come up with a small repro. The relevant
stackframes reported by asan are:
ERROR: AddressSanitizer: heap-use-after-free on address
READ of size 8 at 0x61400020d090 thread T175
    #0 0x5632dff7821b in llvm::SmallPtrSetImplBase::isSmall() const include/llvm/ADT/SmallPtrSet.h:195:33
    #1 0x5632e0335901 in llvm::SmallPtrSetImplBase::insert_imp(void const*) include/llvm/ADT/SmallPtrSet.h:127:9
    #2 0x5632e067347d in llvm::SmallPtrSetImpl<clang::Decl*>::insert(clang::Decl*) include/llvm/ADT/SmallPtrSet.h:372:14
    #3 0x5632e065df80 in clang::Scope::AddDecl(clang::Decl*) tools/clang/include/clang/Sema/Scope.h:287:18
    #4 0x5632e0623eea in clang::ASTReader::pushExternalDeclIntoScope(clang::NamedDecl*, clang::DeclarationName) clang/lib/Serialization/ASTReader.cpp
    #5 0x5632e062ce74 in clang::ASTReader::finishPendingActions() tools/clang/lib/Serialization/ASTReader.cpp:9164:9
    ....
    #30 0x5632e02009c4 in clang::index::generateUSRForDecl(clang::Decl const*, llvm::SmallVectorImpl<char>&) tools/clang/lib/Index/USRGeneration.cpp:1037:6
    #31 0x5632dff73eab in clang::clangd::(anonymous namespace)::getSymbolID(clang::CodeCompletionResult const&) tools/clang/tools/extra/clangd/CodeComplete.cpp:326:20
    #32 0x5632dff6fe91 in clang::clangd::CodeCompleteFlow::mergeResults(std::vector<clang::CodeCompletionResult, std::allocator<clang::CodeCompletionResult> > const&, clang::clangd::SymbolSlab const&)::'lambda'(clang::CodeCompletionResult const&)::operator()(clang::CodeCompletionResult const&) tools/clang/tools/extra/clangd/CodeComplete.cpp:938:24
    #33 0x5632dff6e426 in clang::clangd::CodeCompleteFlow::mergeResults(std::vector<clang::CodeCompletionResult, std::allocator<clang::CodeCompletionResult> > const&, clang::clangd::SymbolSlab const&) third_party/llvm/llvm/tools/clang/tools/extra/clangd/CodeComplete.cpp:949:38
    #34 0x5632dff7a34d in clang::clangd::CodeCompleteFlow::runWithSema() llvm/tools/clang/tools/extra/clangd/CodeComplete.cpp:894:16
    #35 0x5632dff6df6a in clang::clangd::CodeCompleteFlow::run(clang::clangd::(anonymous namespace)::SemaCompleteInput const&) &&::'lambda'()::operator()() const third_party/llvm/llvm/tools/clang/tools/extra/clangd/CodeComplete.cpp:858:35
    #36 0x5632dff6cd42 in clang::clangd::(anonymous namespace)::semaCodeComplete(std::unique_ptr<clang::CodeCompleteConsumer, std::default_delete<clang::CodeCompleteConsumer> >, clang::CodeCompleteOptions const&, clang::clangd::(anonymous namespace)::SemaCompleteInput const&, llvm::function_ref<void ()>) tools/clang/tools/extra/clangd/CodeComplete.cpp:735:5

0x61400020d090 is located 80 bytes inside of 432-byte region [0x61400020d040,0x61400020d1f0)
freed by thread T175  here:
    #0 0x5632df74e115 in operator delete(void*, unsigned long) projects/compiler-rt/lib/asan/asan_new_delete.cc:161:3
    #1 0x5632e0b06973 in clang::Parser::~Parser() tools/clang/lib/Parse/Parser.cpp:410:3
    #2 0x5632e0b06ddd in clang::Parser::~Parser() clang/lib/Parse/Parser.cpp:408:19
    #3 0x5632e0b03286 in std::unique_ptr<clang::Parser, std::default_delete<clang::Parser> >::~unique_ptr() .../bits/unique_ptr.h:236:4
    #4 0x5632e0b021c4 in clang::ParseAST(clang::Sema&, bool, bool) tools/clang/lib/Parse/ParseAST.cpp:182:1
    #5 0x5632e0726544 in clang::FrontendAction::Execute() tools/clang/lib/Frontend/FrontendAction.cpp:904:8
    #6 0x5632dff6cd05 in clang::clangd::(anonymous namespace)::semaCodeComplete(std::unique_ptr<clang::CodeCompleteConsumer, std::default_delete<clang::CodeCompleteConsumer> >, clang::CodeCompleteOptions const&, clang::clangd::(anonymous namespace)::SemaCompleteInput const&, llvm::function_ref<void ()>) tools/clang/tools/extra/clangd/CodeComplete.cpp:728:15

Reviewers: sammccall

Reviewed By: sammccall

Subscribers: klimek, jkorous-apple, cfe-commits, ioeric

Differential Revision: https://reviews.llvm.org/D44000

llvm-svn: 326569
2018-03-02 12:28:27 +00:00
..
clients/clangd-vscode [clangd:vscode] Bump clangd-vscode version to 0.0.4. 2018-03-02 09:26:17 +00:00
fuzzer [clangd-fuzzer] Update ClangdLSPServer constructor call. 2017-12-20 22:29:23 +00:00
global-symbol-builder Revert "[Tooling] [1/1] Refactor FrontendActionFactory::create() to return std::unique_ptr<>" 2018-02-27 15:54:41 +00:00
index [clangd] Make symbol name a required parameter for CanonicalIncludes::mapHeader 2018-03-01 18:30:48 +00:00
tool [clangd] Address FIXME and fix comment 2018-02-25 07:21:16 +00:00
CMakeLists.txt [clangd] collect symbol #include & insert #include in global code completion. 2018-02-16 14:15:55 +00:00
ClangdLSPServer.cpp [clangd] Debounce streams of updates. 2018-03-02 08:56:37 +00:00
ClangdLSPServer.h [clangd] DidChangeConfiguration Notification 2018-02-22 14:00:39 +00:00
ClangdServer.cpp [clangd] Debounce streams of updates. 2018-03-02 08:56:37 +00:00
ClangdServer.h [clangd] Debounce streams of updates. 2018-03-02 08:56:37 +00:00
ClangdUnit.cpp [clangd] #include statements support for Open definition 2018-02-21 02:39:08 +00:00
ClangdUnit.h [clangd] #include statements support for Open definition 2018-02-21 02:39:08 +00:00
CodeComplete.cpp [clang] Fix use-after-free on code completion 2018-03-02 12:28:27 +00:00
CodeComplete.h [clangd] Pass Context implicitly using TLS. 2018-01-31 13:40:48 +00:00
CodeCompletionStrings.cpp [clangd] Pull CodeCompletionString handling logic into its own file and add unit test. 2017-12-20 17:24:31 +00:00
CodeCompletionStrings.h [clangd] Pull CodeCompletionString handling logic into its own file and add unit test. 2017-12-20 17:24:31 +00:00
CompileArgsCache.cpp [clangd] Fixed the file comment of new file. NFC 2018-01-25 14:30:46 +00:00
CompileArgsCache.h [clangd] Added forgotten files 2018-01-25 14:29:29 +00:00
Compiler.cpp [clangd] Log all ignored diagnostics. 2018-02-12 12:48:51 +00:00
Compiler.h [clangd] Log all ignored diagnostics. 2018-02-12 12:48:51 +00:00
Context.cpp [clangd] Address FIXME and fix comment 2018-02-25 07:21:16 +00:00
Context.h [clangd] Pass Context implicitly using TLS. 2018-01-31 13:40:48 +00:00
DraftStore.cpp [clangd] DidChangeConfiguration Notification 2018-02-22 14:00:39 +00:00
DraftStore.h [clangd] DidChangeConfiguration Notification 2018-02-22 14:00:39 +00:00
Function.h [clangd] BindWithForward -> Bind. NFC 2018-02-23 07:54:17 +00:00
FuzzyMatch.cpp [clangd] Fix memcpy(?, null, 0) UB by switching to std::copy 2018-01-19 15:03:49 +00:00
FuzzyMatch.h [clangd] Merge index-provided completions with those from Sema. 2018-01-19 14:34:02 +00:00
GlobalCompilationDatabase.cpp [clangd] DidChangeConfiguration Notification 2018-02-22 14:00:39 +00:00
GlobalCompilationDatabase.h [clangd] DidChangeConfiguration Notification 2018-02-22 14:00:39 +00:00
Headers.cpp [clangd] don't insert new includes if either original header or canonical header is already included. 2018-02-26 08:32:13 +00:00
Headers.h [clangd] don't insert new includes if either original header or canonical header is already included. 2018-02-26 08:32:13 +00:00
JSONExpr.cpp [clangd] Put all #includes in one block in clangd source files. NFC 2017-12-14 21:22:03 +00:00
JSONExpr.h [clangd] Put all #includes in one block in clangd source files. NFC 2017-12-14 21:22:03 +00:00
JSONRPCDispatcher.cpp [clangd] Include timestamps in log messages. 2018-02-16 16:41:42 +00:00
JSONRPCDispatcher.h [clangd] Support simpler JSON-RPC stream parsing for lit tests. 2018-02-06 10:47:30 +00:00
Logger.cpp [clangd] Pass Context implicitly using TLS. 2018-01-31 13:40:48 +00:00
Logger.h [clangd] Pass Context implicitly using TLS. 2018-01-31 13:40:48 +00:00
Path.h Restored r303067 and fixed failing test. 2017-05-16 09:38:59 +00:00
Protocol.cpp [clangd] don't insert new includes if either original header or canonical header is already included. 2018-02-26 08:32:13 +00:00
Protocol.h [clangd] don't insert new includes if either original header or canonical header is already included. 2018-02-26 08:32:13 +00:00
ProtocolHandlers.cpp [clangd] DidChangeConfiguration Notification 2018-02-22 14:00:39 +00:00
ProtocolHandlers.h [clangd] DidChangeConfiguration Notification 2018-02-22 14:00:39 +00:00
SourceCode.cpp [clangd] #include statements support for Open definition 2018-02-21 02:39:08 +00:00
SourceCode.h [clangd] #include statements support for Open definition 2018-02-21 02:39:08 +00:00
TUScheduler.cpp [clangd] Debounce streams of updates. 2018-03-02 08:56:37 +00:00
TUScheduler.h [clangd] Debounce streams of updates. 2018-03-02 08:56:37 +00:00
Threading.cpp [clangd] Debounce streams of updates. 2018-03-02 08:56:37 +00:00
Threading.h [clangd] Debounce streams of updates. 2018-03-02 08:56:37 +00:00
Trace.cpp [clangd] Tracing: name worker threads, and enforce naming scheduled async tasks 2018-02-19 09:56:28 +00:00
Trace.h [clangd] Tracing: name worker threads, and enforce naming scheduled async tasks 2018-02-19 09:56:28 +00:00
URI.cpp [clangd] Do not precent-encode numbers in URI. 2018-02-07 12:12:06 +00:00
URI.h [clangd] Use new URI with scheme support in place of the existing LSP URI 2018-01-29 15:37:46 +00:00
XRefs.cpp [clangd] #include statements support for Open definition 2018-02-21 02:39:08 +00:00
XRefs.h [clangd] Implement textDocument/hover 2018-02-16 21:38:15 +00:00