Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Out of range access occurs and a crash occurs in llvm/tools/clang/lib/Lex/HeaderSearch.cpp #30123

Open Quuxplusone opened 7 years ago

Quuxplusone commented 7 years ago
Bugzilla Link PR31150
Status NEW
Importance P normal
Reported by yaruopooner@gmail.com
Reported on 2016-11-23 20:10:23 -0800
Last modified on 2016-11-23 20:10:23 -0800
Version trunk
Hardware PC All
CC llvm-bugs@lists.llvm.org
Fixed by commit(s)
Attachments bugfix000.patch (833 bytes, application/octet-stream)
Blocks
Blocked by
See also
Created attachment 17642
patch for HeaderSearch

* libclang bug report
  This bug occurs in clang all versions.
  Also, it was platform independent.

  Problems occurred in the following source files.
  llvm/tools/clang/lib/Lex/HeaderSearch.cpp(L954)

  Out of range access occurs and a crash occurs in "HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE)".

  This function accesses 2 times "FileInfo" using "FE->getUID()".

  1st access
  ----------------------------------------
  HeaderFileInfo *HFI = &FileInfo[FE->getUID()];
  ----------------------------------------

  2nd access
  ----------------------------------------
  HFI = &FileInfo[FE->getUID()];
  ----------------------------------------

  FileInfo resize execute at top of function for 1st access.

  ----------------------------------------
  if (FE->getUID() >= FileInfo.size())
    FileInfo.resize(FE->getUID() + 1);
  ----------------------------------------

  But, UID will increase after resizing.

  Out of range access occurs at "HFI = &FileInfo[FE->getUID()];".
  This will crash at 2nd access.

  The UID is increased in deep place of call stack at the below function.

  ----------------------------------------
  auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
  ----------------------------------------

  Below function has same problem.
  Because, used same resize logic.

  ----------------------------------------
  HeaderSearch::getExistingFileInfo(const FileEntry *FE,bool WantExternal) const
  ----------------------------------------

  I can not tell if the policy for updating UIDs in deep locations of "ExternalSource->GetHeaderFileInfo(FE)" is correct.
  However, there was a way to solve this problem.
  It is to resize again immediately after "ExternalSource->GetHeaderFileInfo(FE)".

  Patch was attached.
  I confirmed that it does not crash.

* Supplementary informations
** out of range access
*** clang_reparseTranslationUnit
**** call stack(main thread)
>   ntdll.dll!ZwWaitForSingleObject()   unknown
    KernelBase.dll!000007fefd0910ac()   unknown
    libclang.dll!llvm::llvm_execute_on_thread(void (void *) * Fn, void * UserData, unsigned int RequestedStackSize) line 107    C++
    libclang.dll!llvm::CrashRecoveryContext::RunSafelyOnThread(llvm::function_ref<void __cdecl(void)> Fn, unsigned int RequestedStackSize) line 375 C++
    libclang.dll!clang::RunSafely(llvm::CrashRecoveryContext & CRC, llvm::function_ref<void __cdecl(void)> Fn, unsigned int Size) line 7791 C++
    libclang.dll!clang_reparseTranslationUnit(CXTranslationUnitImpl * TU, unsigned int num_unsaved_files, CXUnsavedFile * unsaved_files, unsigned int options) line 3850    C++
    clang-server-debug.exe!ClangSession::CreateTranslationUnit() line 582   C++
    clang-server-debug.exe!ClangSession::Allocate() line 603    C++
    clang-server-debug.exe!ClangServer::commandCreateSession() line 320 C++
    clang-server-debug.exe!std::_Pmf_caller<void,ClangServer>::_Call_pmf<void (__cdecl ClangServer::*)(void) __ptr64,ClangServer & __ptr64>(void (void) * _Pm, ClangServer & _Fx0, std::integral_constant<bool,1> __formal) line 303    C++
    clang-server-debug.exe!std::_Pmf_caller<void,ClangServer>::_Apply_pmf<void (__cdecl ClangServer::*)(void) __ptr64,ClangServer & __ptr64>(void (void) * _Pm, ClangServer & _Fx0) line 331    C++
    clang-server-debug.exe!std::_Callable_pmf<void (__cdecl ClangServer::*)(void) __ptr64,ClangServer,0>::_ApplyX<void,ClangServer & __ptr64>(ClangServer & <_Args_0>) line 358 C++
    clang-server-debug.exe!std::_Call_wrapper<std::_Callable_pmf<void (__cdecl ClangServer::*)(void) __ptr64,ClangServer,0>,0>::operator()<ClangServer & __ptr64>(ClangServer & <_Args_0>) line 439 C++
    clang-server-debug.exe!std::_Callable_obj<std::_Mem_fn_wrap<void,void (__cdecl ClangServer::*)(void) __ptr64,ClangServer>,0>::_ApplyX<void,ClangServer & __ptr64>(ClangServer & <_Args_0>) line 284 C++
    clang-server-debug.exe!std::_Func_impl<std::_Callable_obj<std::_Mem_fn_wrap<void,void (__cdecl ClangServer::*)(void) __ptr64,ClangServer>,0>,std::allocator<std::_Func_class<void,ClangServer & __ptr64> >,void,ClangServer & __ptr64>::_Do_call(ClangServer & <_Args_0>) line 229  C++
    clang-server-debug.exe!std::_Func_class<void,ClangServer & __ptr64>::operator()(ClangServer & <_Args_0>) line 316   C++
    clang-server-debug.exe!ClangServer::ParseServerCommand() line 371   C++
    clang-server-debug.exe!ClangServer::ParseCommand() line 421 C++
    clang-server-debug.exe!main(int argc, char * * argv) line 168   C++
    clang-server-debug.exe!__tmainCRTStartup() line 626 C
    kernel32.dll!0000000076f059cd() unknown
    ntdll.dll!RtlUserThreadStart()  unknown

**** call stack(worker thread)
>   libclang.dll!clang::HeaderSearch::getFileInfo(const clang::FileEntry * FE)
line 964    C++
    libclang.dll!clang::HeaderSearch::IncrementIncludeCount(const clang::FileEntry * File) line 439 C++
    libclang.dll!clang::Preprocessor::EnterMainSourceFile() line 523    C++
    libclang.dll!clang::ParseAST(clang::Sema & S, bool PrintStats, bool SkipFunctionBodies) line 139    C++
    libclang.dll!clang::ASTFrontendAction::ExecuteAction() line 558 C++
    libclang.dll!clang::FrontendAction::Execute() line 462  C++
    libclang.dll!clang::ASTUnit::Parse(std::shared_ptr<clang::PCHContainerOperations> PCHContainerOps, std::unique_ptr<llvm::MemoryBuffer,std::default_delete<llvm::MemoryBuffer> > OverrideMainBuffer) line 1146   C++
    libclang.dll!clang::ASTUnit::Reparse(std::shared_ptr<clang::PCHContainerOperations> PCHContainerOps, llvm::ArrayRef<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,llvm::MemoryBuffer *> > RemappedFiles) line 2067 C++
    libclang.dll!clang_reparseTranslationUnit_Impl(CXTranslationUnitImpl * TU, llvm::ArrayRef<CXUnsavedFile> unsaved_files, unsigned int options) line 3819 C++
    libclang.dll!clang_reparseTranslationUnit::__l8::<lambda>() line 3840   C++
    libclang.dll!llvm::function_ref<void __cdecl(void)>::callback_fn<void <lambda>(void) >(__int64 callable) line 87    C++
    libclang.dll!llvm::function_ref<void __cdecl(void)>::operator()() line 99   C++
    libclang.dll!llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void __cdecl(void)> Fn) line 328  C++
    libclang.dll!RunSafelyOnThread_Dispatch(void * UserData) line 368   C++
    libclang.dll!ThreadCallback(void * param) line 89   C++
    msvcr120d.dll!000007fee60ca105()    unknown
    msvcr120d.dll!000007fee60ca357()    unknown
    kernel32.dll!0000000076f059cd() unknown
    ntdll.dll!RtlUserThreadStart()  unknown

*** clang_codeCompleteAt
**** call stack(main thread)
>   ntdll.dll!ZwWaitForSingleObject()   unknown
    KernelBase.dll!000007fefd0910ac()   unknown
    libclang.dll!llvm::llvm_execute_on_thread(void (void *) * Fn, void * UserData, unsigned int RequestedStackSize) line 107    C++
    libclang.dll!llvm::CrashRecoveryContext::RunSafelyOnThread(llvm::function_ref<void __cdecl(void)> Fn, unsigned int RequestedStackSize) line 375 C++
    libclang.dll!clang::RunSafely(llvm::CrashRecoveryContext & CRC, llvm::function_ref<void __cdecl(void)> Fn, unsigned int Size) line 7791 C++
    libclang.dll!clang_codeCompleteAt(CXTranslationUnitImpl * TU, const char * complete_filename, unsigned int complete_line, unsigned int complete_column, CXUnsavedFile * unsaved_files, unsigned int num_unsaved_files, unsigned int options) line 827   C++
    clang-server-debug.exe!ClangSession::Completion::PrintCompleteCandidates() line 262 C++
    clang-server-debug.exe!ClangSession::commandCompletion() line 661   C++
    clang-server-debug.exe!std::_Pmf_caller<void,ClangSession>::_Call_pmf<void (__cdecl ClangSession::*)(void) __ptr64,ClangSession & __ptr64>(void (void) * _Pm, ClangSession & _Fx0, std::integral_constant<bool,1> __formal) line 303    C++
    clang-server-debug.exe!std::_Pmf_caller<void,ClangSession>::_Apply_pmf<void (__cdecl ClangSession::*)(void) __ptr64,ClangSession & __ptr64>(void (void) * _Pm, ClangSession & _Fx0) line 331    C++
    clang-server-debug.exe!std::_Callable_pmf<void (__cdecl ClangSession::*)(void) __ptr64,ClangSession,0>::_ApplyX<void,ClangSession & __ptr64>(ClangSession & <_Args_0>) line 358 C++
    clang-server-debug.exe!std::_Call_wrapper<std::_Callable_pmf<void (__cdecl ClangSession::*)(void) __ptr64,ClangSession,0>,0>::operator()<ClangSession & __ptr64>(ClangSession & <_Args_0>) line 439 C++
    clang-server-debug.exe!std::_Callable_obj<std::_Mem_fn_wrap<void,void (__cdecl ClangSession::*)(void) __ptr64,ClangSession>,0>::_ApplyX<void,ClangSession & __ptr64>(ClangSession & <_Args_0>) line 284 C++
    clang-server-debug.exe!std::_Func_impl<std::_Callable_obj<std::_Mem_fn_wrap<void,void (__cdecl ClangSession::*)(void) __ptr64,ClangSession>,0>,std::allocator<std::_Func_class<void,ClangSession & __ptr64> >,void,ClangSession & __ptr64>::_Do_call(ClangSession & <_Args_0>) line 229 C++
    clang-server-debug.exe!std::_Func_class<void,ClangSession & __ptr64>::operator()(ClangSession & <_Args_0>) line 316 C++
    clang-server-debug.exe!ClangServer::ParseSessionCommand() line 399  C++
    clang-server-debug.exe!ClangServer::ParseCommand() line 425 C++
    clang-server-debug.exe!main(int argc, char * * argv) line 168   C++
    clang-server-debug.exe!__tmainCRTStartup() line 626 C
    kernel32.dll!0000000076f059cd() unknown
    ntdll.dll!RtlUserThreadStart()  unknown

**** call stack(worker thread)
>   libclang.dll!clang::HeaderSearch::getFileInfo(const clang::FileEntry * FE)
line 964    C++
    libclang.dll!clang::HeaderSearch::IncrementIncludeCount(const clang::FileEntry * File) line 439 C++
    libclang.dll!clang::Preprocessor::EnterMainSourceFile() line 523    C++
    libclang.dll!clang::ParseAST(clang::Sema & S, bool PrintStats, bool SkipFunctionBodies) line 139    C++
    libclang.dll!clang::ASTFrontendAction::ExecuteAction() line 558 C++
    libclang.dll!clang::FrontendAction::Execute() line 462  C++
    libclang.dll!clang::ASTUnit::CodeComplete(llvm::StringRef File, unsigned int Line, unsigned int Column, llvm::ArrayRef<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,llvm::MemoryBuffer *> > RemappedFiles, bool IncludeMacros, bool IncludeCodePatterns, bool IncludeBriefComments, clang::CodeCompleteConsumer & Consumer, std::shared_ptr<clang::PCHContainerOperations> PCHContainerOps, clang::DiagnosticsEngine & Diag, clang::LangOptions & LangOpts, clang::SourceManager & SourceMgr, clang::FileManager & FileMgr, llvm::SmallVectorImpl<clang::StoredDiagnostic> & StoredDiagnostics, llvm::SmallVectorImpl<llvm::MemoryBuffer const *> & OwnedBuffers) line 2462   C++
    libclang.dll!clang_codeCompleteAt_Impl(CXTranslationUnitImpl * TU, const char * complete_filename, unsigned int complete_line, unsigned int complete_column, llvm::ArrayRef<CXUnsavedFile> unsaved_files, unsigned int options) line 712    C++
    libclang.dll!clang_codeCompleteAt::__l8::<lambda>() line 817    C++
    libclang.dll!llvm::function_ref<void __cdecl(void)>::callback_fn<void <lambda>(void) >(__int64 callable) line 87    C++
    libclang.dll!llvm::function_ref<void __cdecl(void)>::operator()() line 99   C++
    libclang.dll!llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void __cdecl(void)> Fn) line 328  C++
    libclang.dll!RunSafelyOnThread_Dispatch(void * UserData) line 368   C++
    libclang.dll!ThreadCallback(void * param) line 89   C++
    msvcr120d.dll!000007fece89a105()    unknown
    msvcr120d.dll!000007fece89a357()    unknown
    kernel32.dll!0000000076f059cd() unknown
    ntdll.dll!RtlUserThreadStart()  unknown

** Below is the call stack when UID was updated at inside "ExternalSource-
>GetHeaderFileInfo(FE)"
*** call stack(worker thread)
>   libclang.dll!clang::FileManager::getFile(llvm::StringRef Filename, bool
openFile, bool CacheFailure) line 309   C++
    libclang.dll!clang::serialization::reader::HeaderFileInfoTrait::EqualKey::__l9::<lambda>(const clang::serialization::reader::HeaderFileInfoTrait::internal_key_type & Key) line 1558    C++
    libclang.dll!clang::serialization::reader::HeaderFileInfoTrait::EqualKey(const clang::serialization::reader::HeaderFileInfoTrait::internal_key_type & a, const clang::serialization::reader::HeaderFileInfoTrait::internal_key_type & b) line 1561  C++
    libclang.dll!llvm::OnDiskChainedHashTable<clang::serialization::reader::HeaderFileInfoTrait>::find_hashed(const clang::serialization::reader::HeaderFileInfoTrait::internal_key_type & IKey, unsigned int KeyHash, clang::serialization::reader::HeaderFileInfoTrait * InfoPtr) line 391    C++
    libclang.dll!llvm::OnDiskChainedHashTable<clang::serialization::reader::HeaderFileInfoTrait>::find(const clang::FileEntry * const & EKey, clang::serialization::reader::HeaderFileInfoTrait * InfoPtr) line 346 C++
    libclang.dll!`anonymous namespace'::HeaderFileInfoVisitor::operator()(clang::serialization::ModuleFile & M) line 5117   C++
    libclang.dll!llvm::function_ref<bool __cdecl(clang::serialization::ModuleFile & __ptr64)>::callback_fn<`anonymous namespace'::HeaderFileInfoVisitor>(__int64 callable, clang::serialization::ModuleFile & <params_0>) line 87   C++
    libclang.dll!llvm::function_ref<bool __cdecl(clang::serialization::ModuleFile & __ptr64)>::operator()(clang::serialization::ModuleFile & <params_0>) line 99    C++
    libclang.dll!clang::serialization::ModuleManager::visit(llvm::function_ref<bool __cdecl(clang::serialization::ModuleFile &)> Visitor, llvm::SmallPtrSetImpl<clang::serialization::ModuleFile *> * ModuleFilesHit) line 381  C++
    libclang.dll!clang::ASTReader::GetHeaderFileInfo(const clang::FileEntry * FE) line 5131 C++
    libclang.dll!clang::HeaderSearch::getFileInfo(const clang::FileEntry * FE) line 964 C++
    libclang.dll!clang::HeaderSearch::IncrementIncludeCount(const clang::FileEntry * File) line 439 C++
    libclang.dll!clang::Preprocessor::EnterMainSourceFile() line 523    C++
    libclang.dll!clang::ParseAST(clang::Sema & S, bool PrintStats, bool SkipFunctionBodies) line 139    C++
    libclang.dll!clang::ASTFrontendAction::ExecuteAction() line 558 C++
    libclang.dll!clang::FrontendAction::Execute() line 462  C++
    libclang.dll!clang::ASTUnit::Parse(std::shared_ptr<clang::PCHContainerOperations> PCHContainerOps, std::unique_ptr<llvm::MemoryBuffer,std::default_delete<llvm::MemoryBuffer> > OverrideMainBuffer) line 1146   C++
    libclang.dll!clang::ASTUnit::Reparse(std::shared_ptr<clang::PCHContainerOperations> PCHContainerOps, llvm::ArrayRef<std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,llvm::MemoryBuffer *> > RemappedFiles) line 2067 C++
    libclang.dll!clang_reparseTranslationUnit_Impl(CXTranslationUnitImpl * TU, llvm::ArrayRef<CXUnsavedFile> unsaved_files, unsigned int options) line 3819 C++
    libclang.dll!clang_reparseTranslationUnit::__l8::<lambda>() line 3840   C++
    libclang.dll!llvm::function_ref<void __cdecl(void)>::callback_fn<void <lambda>(void) >(__int64 callable) line 87    C++
    libclang.dll!llvm::function_ref<void __cdecl(void)>::operator()() line 99   C++
    libclang.dll!llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void __cdecl(void)> Fn) line 328  C++
    libclang.dll!RunSafelyOnThread_Dispatch(void * UserData) line 368   C++
    libclang.dll!ThreadCallback(void * param) line 89   C++
    msvcr120d.dll!000007fee60ca105()    unknown
    msvcr120d.dll!000007fee60ca357()    unknown
    kernel32.dll!0000000076f059cd() unknown
    ntdll.dll!RtlUserThreadStart()  unknown

    llvm/tools/clang/lib/Basic/FileManager.cpp(L212)
    ----------------------------------------
  const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
                                        bool CacheFailure) {
      ~~~

      UFE.Name    = InterndFileName;
      UFE.Size = Data.Size;
      UFE.ModTime = Data.ModTime;
      UFE.Dir     = DirInfo;
  --> UFE.UID     = NextFileUID++;
      UFE.UniqueID = Data.UniqueID;
      UFE.IsNamedPipe = Data.IsNamedPipe;
      UFE.InPCH = Data.InPCH;
      UFE.File = std::move(F);
      UFE.IsValid = true;
      if (UFE.File)
          if (auto RealPathName = UFE.File->getName())
              UFE.RealPathName = *RealPathName;
      return &UFE;
  }
    ----------------------------------------
Quuxplusone commented 7 years ago

Attached bugfix000.patch (833 bytes, application/octet-stream): patch for HeaderSearch