Issue 171784
Summary Crash lld-link on invalid archive
Labels new issue
Assignees
Reporter JVApen
    We encountered following crash on lld-link of LLVM19:
````
 #0 0x00007ff62cd7d6c6 llvm::object::ArchiveMemberHeader::ArchiveMemberHeader(class llvm::object::Archive const *, char const *, unsigned __int64, class llvm::Error *) llvm\lib\Object\Archive.cpp:108:0
 #1 0x00007ff62cd80698 llvm::ErrorAsOutParameter::~ErrorAsOutParameter llvm\include\llvm\Support\Error.h:1140:0
 #2 0x00007ff62cd80698 llvm::object::Archive::createArchiveMemberHeader(char const *, unsigned __int64, class llvm::Error *) const llvm\lib\Object\Archive.cpp:692:0
 #3 0x00007ff62cd80775 std::exchange C:\DevStudio\Vs2022\VC\Tools\MSVC\14.38.33130\INCLUDE\utility:762:0
 #4 0x00007ff62cd80775 std::unique_ptr<llvm::object::AbstractArchiveMemberHeader,std::default_delete<llvm::object::AbstractArchiveMemberHeader> >::release C:\DevStudio\Vs2022\VC\Tools\MSVC\14.38.33130\INCLUDE\memory:3309:0
 #5 0x00007ff62cd80775 std::unique_ptr<llvm::object::AbstractArchiveMemberHeader,std::default_delete<llvm::object::AbstractArchiveMemberHeader> >::operator= C:\DevStudio\Vs2022\VC\Tools\MSVC\14.38.33130\INCLUDE\memory:3267:0
 #6 0x00007ff62cd80775 llvm::object::Archive::Child::Child(class llvm::object::Archive const *, char const *, class llvm::Error *) llvm\lib\Object\Archive.cpp:476:0
 #7 0x00007ff62cd82b17 llvm::Error::getPtr llvm\include\llvm\Support\Error.h:282:0
 #8 0x00007ff62cd82b17 llvm::Error::operator bool llvm\include\llvm\Support\Error.h:242:0
 #9 0x00007ff62cd82b17 llvm::object::Archive::Symbol::getMember(void) const llvm\lib\Object\Archive.cpp:1086:0
#10 0x00007ff62cd84767 lld::coff::ArchiveFile::addMember(class llvm::object::Archive::Symbol const &) lld\COFF\InputFiles.cpp:110:0
#11 0x00007ff62cd386df lld::coff::SymbolTable::addLazyArchive(class lld::coff::ArchiveFile *, class llvm::object::Archive::Symbol const &) lld\COFF\SymbolTable.cpp:611:0
#12 0x00007ff62cd846b9 lld::coff::ArchiveFile::parse(void) lld\COFF\InputFiles.cpp:105:0
#13 0x00007ff62cd33634 lld::coff::InputFile::kind lld\COFF\InputFiles.h:75:0
#14 0x00007ff62cd33634 lld::coff::ObjFile::classof lld\COFF\InputFiles.h:133:0
#15 0x00007ff62cd33634 llvm::isa_impl<lld::coff::ObjFile,lld::coff::InputFile,void>::doit llvm\include\llvm\Support\Casting.h:64:0
#16 0x00007ff62cd33634 llvm::isa_impl_cl<lld::coff::ObjFile,const lld::coff::InputFile *>::doit llvm\include\llvm\Support\Casting.h:110:0
#17 0x00007ff62cd33634 llvm::isa_impl_wrap<lld::coff::ObjFile,const lld::coff::InputFile *,const lld::coff::InputFile *>::doit llvm\include\llvm\Support\Casting.h:137:0
#18 0x00007ff62cd33634 llvm::isa_impl_wrap<lld::coff::ObjFile,lld::coff::InputFile *const,const lld::coff::InputFile *>::doit llvm\include\llvm\Support\Casting.h:127:0
#19 0x00007ff62cd33634 llvm::CastIsPossible<lld::coff::ObjFile,lld::coff::InputFile *,void>::isPossible llvm\include\llvm\Support\Casting.h:255:0
#20 0x00007ff62cd33634 llvm::CastInfo<lld::coff::ObjFile,lld::coff::InputFile *,void>::doCastIfPossible llvm\include\llvm\Support\Casting.h:493:0
#21 0x00007ff62cd33634 llvm::dyn_cast llvm\include\llvm\Support\Casting.h:663:0
#22 0x00007ff62cd33634 lld::coff::SymbolTable::addFile(class lld::coff::InputFile *) lld\COFF\SymbolTable.cpp:61:0
#23 0x00007ff62cb9d769 lld::coff::LinkerDriver::addBuffer(class std::unique_ptr<class llvm::MemoryBuffer, struct std::default_delete<class llvm::MemoryBuffer>>, bool, bool) lld\COFF\Driver.cpp:202:0
#24 0x00007ff62cbb3dd4 lld::coff::LinkerDriver::enqueuePath::<lambda_2>::operator() lld\COFF\Driver.cpp:261:0
#25 0x00007ff62cbb3dd4 std::invoke C:\DevStudio\Vs2022\VC\Tools\MSVC\14.38.33130\INCLUDE\type_traits:1731:0
#26 0x00007ff62cbb3dd4 std::_Func_impl_no_alloc<`lambda at E:/agt/_work/408/s/lld/COFF/Driver.cpp:238:15',void>::_Do_call C:\DevStudio\Vs2022\VC\Tools\MSVC\14.38.33130\INCLUDE\functional:808:0
#27 0x00007ff62cba80ea std::list<std::function<void ()>,std::allocator<std::function<void ()> > >::pop_front C:\DevStudio\Vs2022\VC\Tools\MSVC\14.38.33130\INCLUDE\list:1254:0
#28 0x00007ff62cba80ea lld::coff::LinkerDriver::run(void) lld\COFF\Driver.cpp:1060:0
#29 0x00007ff62cb99fa1 lld::coff::LinkerDriver::linkerMain(class llvm::ArrayRef<char const *>) lld\COFF\Driver.cpp:2136:0
#30 0x00007ff62cb8e0fc lld::coff::link(class llvm::ArrayRef<char const *>, class llvm::raw_ostream &, class llvm::raw_ostream &, bool, bool) lld\COFF\Driver.cpp:77:0
#31 0x00007ff62cb834ff lld::unsafeLldMain(class llvm::ArrayRef<char const *>, class llvm::raw_ostream &, class llvm::raw_ostream &, class llvm::ArrayRef<struct lld::DriverDef>, bool) lld\Common\DriverDispatcher.cpp:164:0
#32 0x00007ff62cb613ed lld_main(int, char **, struct llvm::ToolContext const &) lld\tools\lld\lld.cpp:89:0
#33 0x00007ff62cb61c97 main build\production-windows\tools\lld\tools\lld\lld-driver.cpp:17:0
#34 0x00007ff62f1a4704 invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78:0
#35 0x00007ff62f1a4704 __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288:0
#36 0x00007ff85f504cb0 (C:\Windows\System32\KERNEL32.DLL+0x14cb0)
#37 0x00007ff85f81edcb (C:\Windows\SYSTEM32\ntdll.dll+0x7edcb)
````
Unfortunately, while triaging the underlying problem, we removed the invalid archive file (created via nuget which most likely was interrupted).
My understanding of the problem here is:
 - Due to corrupted state of the .lib file, we end up in the error handling code for the terminator.
 - This starts by using the ArMemHdr and terminator. Given the line number in the crash, we should be in if (ArMemHdr->Terminator[0] != '' || ArMemHdr->Terminator[1] != '\n') {`
 - This is the first usage of ArMemHdr, so if this is an invalid pointer, asking for the Terminator value will crash.
 - We are doing some validity checks on the pointer, like its size being large enough, though we should be missing some check that the pointer value is correct. (aka: is it an address in the binary blob)
 - The function Archive::Symbol::getMember() calculates an offset and determines the pointer via `  const char *Loc = Parent->getData().begin() + Offset;`, though, it never validated that the Offset is within the range of the blob

If this is all correct, the following code should solve it:
````
  if (Offset >= Parent->getData().size())
    return malformedError("symbol offset " + Twine(Offset) +
                          " is past the end of the archive");
````
Due to the early return, the constructor of `C` (the Child) is never called and the crash should be prevented.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to