From: Frederic Riss Date: Mon, 9 May 2016 14:44:14 +0000 (+0000) Subject: [dsymutil] Prevent use-after-free X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=856a0143b0b25c58f726d66f222cec00b4185c61;p=llvm [dsymutil] Prevent use-after-free The BinaryHolder would query the archive member MemoryBuffer name to check if the current open archive also contains the next requested objectfile. This comparison was using a StringRef to a temporary buffer. It only happened with fat archives. This commit adds long-lived storage along with the MemoryBuffers for the fat archive filename. The added test would fail during an ASAN build without the fix. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@268924 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/dsymutil/Inputs/basic-with-libfat-test.macho.x86_64 b/test/tools/dsymutil/Inputs/basic-with-libfat-test.macho.x86_64 new file mode 100755 index 00000000000..7160e282772 Binary files /dev/null and b/test/tools/dsymutil/Inputs/basic-with-libfat-test.macho.x86_64 differ diff --git a/test/tools/dsymutil/X86/basic-with-libfat-test.test b/test/tools/dsymutil/X86/basic-with-libfat-test.test new file mode 100644 index 00000000000..0ec2d537f42 --- /dev/null +++ b/test/tools/dsymutil/X86/basic-with-libfat-test.test @@ -0,0 +1,10 @@ +RUN: llvm-dsymutil -f -o - -oso-prepend-path=%p/.. %p/../Inputs/basic-with-libfat-test.macho.x86_64 | llvm-dwarfdump - | FileCheck %s + +The test binary was created by force-linking the libfat-test.a fat archive +with the basic linking test archive, like so: +$ clang -all_load libfat-test.a libbasic.a basic1.macho.x86_64.o -Wl,-dead_strip -u _x86_64_var + +CHECK: DW_AT_name{{.*}}"x86_64_var" +CHECK: DW_AT_name{{.*}}"basic2.c" +CHECK: DW_AT_name{{.*}}"basic3.c" +CHECK: DW_AT_name{{.*}}"basic1.c" diff --git a/tools/dsymutil/BinaryHolder.cpp b/tools/dsymutil/BinaryHolder.cpp index 7644f01952f..32d176645bf 100644 --- a/tools/dsymutil/BinaryHolder.cpp +++ b/tools/dsymutil/BinaryHolder.cpp @@ -79,7 +79,8 @@ BinaryHolder::GetMemoryBuffersForFile(StringRef Filename, } CurrentFatBinary = std::move(*ErrOrFat); - return getMachOFatMemoryBuffers(Filename, *CurrentMemoryBuffer, + CurrentFatBinaryName = Filename; + return getMachOFatMemoryBuffers(CurrentFatBinaryName, *CurrentMemoryBuffer, *CurrentFatBinary); } @@ -149,8 +150,9 @@ BinaryHolder::MapArchiveAndGetMemberBuffers(StringRef Filename, ArchiveBuffers.push_back(CurrentMemoryBuffer->getMemBufferRef()); } else { CurrentFatBinary = std::move(*ErrOrFat); + CurrentFatBinaryName = ArchiveFilename; ArchiveBuffers = getMachOFatMemoryBuffers( - ArchiveFilename, *CurrentMemoryBuffer, *CurrentFatBinary); + CurrentFatBinaryName, *CurrentMemoryBuffer, *CurrentFatBinary); } for (auto MemRef : ArchiveBuffers) { diff --git a/tools/dsymutil/BinaryHolder.h b/tools/dsymutil/BinaryHolder.h index d56a39597c2..97508b9fb09 100644 --- a/tools/dsymutil/BinaryHolder.h +++ b/tools/dsymutil/BinaryHolder.h @@ -42,6 +42,7 @@ class BinaryHolder { std::unique_ptr CurrentMemoryBuffer; std::vector> CurrentObjectFiles; std::unique_ptr CurrentFatBinary; + std::string CurrentFatBinaryName; bool Verbose; /// Get the MemoryBufferRefs for the file specification in \p